Changes in / [7951100:b067d9b]
- Files:
-
- 968 added
- 640 deleted
- 194 edited
-
.autom4te.cfg (added)
-
.gitignore (modified) (3 diffs)
-
INSTALL (modified) (1 diff)
-
Jenkins/FullBuild (modified) (6 diffs)
-
Jenkins/TestRegen (modified) (1 diff)
-
Jenkinsfile (modified) (10 diffs)
-
Makefile.am (modified) (1 diff)
-
Makefile.in (modified) (22 diffs)
-
aclocal.m4 (modified) (3 diffs)
-
automake/cfa.m4 (added)
-
automake/compile (modified) (1 diff, 1 prop)
-
automake/config.guess (modified) (1 diff, 1 prop)
-
automake/config.sub (modified) (1 diff, 1 prop)
-
automake/depcomp (modified) (1 diff, 1 prop)
-
automake/install-sh (modified) (1 diff, 1 prop)
-
automake/libtool.m4 (added)
-
automake/ltmain.sh (added)
-
automake/ltoptions.m4 (added)
-
automake/ltsugar.m4 (added)
-
automake/ltversion.m4 (added)
-
automake/lt~obsolete.m4 (added)
-
automake/missing (modified) (1 diff, 1 prop)
-
automake/test-driver (modified) (1 diff, 1 prop)
-
automake/ylwrap (modified) (1 diff, 1 prop)
-
benchmark/Makefile.am (added)
-
benchmark/Makefile.in (added)
-
benchmark/Monitor.c (added)
-
benchmark/baselines/calc.py (added)
-
benchmark/baselines/x64/compile.csv (added)
-
benchmark/baselines/x64/ctxswitch.csv (added)
-
benchmark/baselines/x64/mutex.csv (added)
-
benchmark/baselines/x64/signal.csv (added)
-
benchmark/baselines/x86/compile.csv (added)
-
benchmark/baselines/x86/ctxswitch.csv (added)
-
benchmark/baselines/x86/mutex.csv (added)
-
benchmark/baselines/x86/signal.csv (added)
-
benchmark/bench.h (added)
-
benchmark/c.c (added)
-
benchmark/compile/empty.cfa (added)
-
benchmark/creation/JavaThread.java (added)
-
benchmark/creation/cfa_cor.cfa (added)
-
benchmark/creation/cfa_thrd.cfa (added)
-
benchmark/creation/goroutine.go (added)
-
benchmark/creation/pthreads.c (added)
-
benchmark/creation/upp_cor.cc (added)
-
benchmark/creation/upp_thrd.cc (added)
-
benchmark/ctxswitch/JavaThread.java (added)
-
benchmark/ctxswitch/cfa_cor.cfa (added)
-
benchmark/ctxswitch/cfa_cor_then.cfa (added)
-
benchmark/ctxswitch/cfa_gen.cfa (added)
-
benchmark/ctxswitch/cfa_thrd.cfa (added)
-
benchmark/ctxswitch/cfa_thrd2.cfa (added)
-
benchmark/ctxswitch/goroutine.go (added)
-
benchmark/ctxswitch/kos_fibre.cpp (added)
-
benchmark/ctxswitch/kos_fibre2.cpp (added)
-
benchmark/ctxswitch/pthreads.c (added)
-
benchmark/ctxswitch/upp_cor.cc (added)
-
benchmark/ctxswitch/upp_thrd.cc (added)
-
benchmark/cxx.cpp (added)
-
benchmark/fetch_add.c (added)
-
benchmark/fixcsv.sh (added)
-
benchmark/function.c (added)
-
benchmark/interrupt_linux.c (added)
-
benchmark/loop.c (added)
-
benchmark/mutex/JavaThread.java (added)
-
benchmark/mutex/cfa1.cfa (added)
-
benchmark/mutex/cfa2.cfa (added)
-
benchmark/mutex/cfa4.cfa (added)
-
benchmark/mutex/pthreads.c (added)
-
benchmark/mutex/upp.cc (added)
-
benchmark/schedext/cfa1.cfa (added)
-
benchmark/schedext/cfa2.cfa (added)
-
benchmark/schedext/cfa4.cfa (added)
-
benchmark/schedext/upp.cc (added)
-
benchmark/schedint/JavaThread.java (added)
-
benchmark/schedint/cfa1.cfa (added)
-
benchmark/schedint/cfa2.cfa (added)
-
benchmark/schedint/cfa4.cfa (added)
-
benchmark/schedint/pthreads.c (added)
-
benchmark/schedint/upp.cc (added)
-
benchmark/tls-fetch_add.c (added)
-
benchmark/ttst_lock.c (added)
-
config.h.in (deleted)
-
configure (modified) (52 diffs)
-
configure.ac (modified) (5 diffs)
-
doc/LaTeXmacros/common.tex (modified) (3 diffs)
-
doc/LaTeXmacros/lstlang.sty (modified) (2 diffs)
-
doc/bibliography/pl.bib (modified) (99 diffs)
-
doc/papers/AMA/AMA-stix/ama/WileyNJD-v2.cls (modified) (5 diffs)
-
doc/papers/OOPSLA17/Makefile (modified) (4 diffs)
-
doc/papers/concurrency/Makefile (modified) (4 diffs)
-
doc/papers/concurrency/Paper.tex (modified) (33 diffs)
-
doc/papers/concurrency/SPEOldPaper.pdf (added)
-
doc/papers/concurrency/annex/local.bib (modified) (2 diffs)
-
doc/papers/concurrency/examples/C++Cor-ts.cpp (added)
-
doc/papers/concurrency/examples/Fib.c (added)
-
doc/papers/concurrency/examples/Fib.cfa (added)
-
doc/papers/concurrency/examples/Fib.cpp (added)
-
doc/papers/concurrency/examples/Fib.py (added)
-
doc/papers/concurrency/examples/Fib.sim (added)
-
doc/papers/concurrency/examples/Fib1.c (added)
-
doc/papers/concurrency/examples/Fib2.c (added)
-
doc/papers/concurrency/examples/Fib2.cfa (added)
-
doc/papers/concurrency/examples/Fib2.cpp (added)
-
doc/papers/concurrency/examples/Fib2.py (added)
-
doc/papers/concurrency/examples/Fib3.c (added)
-
doc/papers/concurrency/examples/Fib3.cc (added)
-
doc/papers/concurrency/examples/FibRefactor.py (added)
-
doc/papers/concurrency/examples/Fmt.sim (added)
-
doc/papers/concurrency/examples/Format.c (added)
-
doc/papers/concurrency/examples/Format.cc (added)
-
doc/papers/concurrency/examples/Format.cfa (added)
-
doc/papers/concurrency/examples/Format.cpp (added)
-
doc/papers/concurrency/examples/Format.data (added)
-
doc/papers/concurrency/examples/Format.py (added)
-
doc/papers/concurrency/examples/Format.sim (added)
-
doc/papers/concurrency/examples/Format1.c (added)
-
doc/papers/concurrency/examples/PingPong.c (added)
-
doc/papers/concurrency/examples/PingPong.cc (added)
-
doc/papers/concurrency/examples/Pingpong.cc (added)
-
doc/papers/concurrency/examples/Pingpong.cfa (added)
-
doc/papers/concurrency/examples/Pingpong.py (added)
-
doc/papers/concurrency/examples/Pingpong2.cfa (added)
-
doc/papers/concurrency/examples/ProdCons.cfa (added)
-
doc/papers/concurrency/examples/ProdCons.cpp (added)
-
doc/papers/concurrency/examples/ProdCons.py (added)
-
doc/papers/concurrency/examples/ProdCons.sim (added)
-
doc/papers/concurrency/examples/RWMonitor.cfa (added)
-
doc/papers/concurrency/examples/Refactor.py (added)
-
doc/papers/concurrency/examples/counter.cpp (added)
-
doc/papers/concurrency/figures/CondSigWait.fig (added)
-
doc/papers/concurrency/figures/FullCoroutinePhases.fig (added)
-
doc/papers/concurrency/figures/FullProdConsStack.fig (added)
-
doc/papers/concurrency/figures/RunTimeStructure.fig (added)
-
doc/papers/concurrency/figures/corlayout.fig (added)
-
doc/papers/concurrency/figures/ext_monitor.fig (modified) (1 diff)
-
doc/papers/concurrency/figures/monitor.fig (modified) (1 diff)
-
doc/papers/concurrency/figures/monitor.old.fig (added)
-
doc/papers/concurrency/mail (added)
-
doc/papers/concurrency/mail2 (added)
-
doc/papers/concurrency/notes/cor-thread-traits.c (deleted)
-
doc/papers/concurrency/notes/lit-review.md (deleted)
-
doc/papers/concurrency/notes/notes.md (deleted)
-
doc/papers/concurrency/style/cfa-format.tex (deleted)
-
doc/papers/concurrency/style/style.tex (deleted)
-
doc/papers/general/.gitignore (modified) (1 diff)
-
doc/papers/general/Makefile (modified) (5 diffs)
-
doc/papers/general/Paper.tex (modified) (124 diffs)
-
doc/papers/general/fig.tex (added)
-
doc/proposals/approx-equal.md (added)
-
doc/proposals/ctordtor/Makefile (modified) (3 diffs)
-
doc/proposals/ctordtor/ctor.tex (modified) (5 diffs)
-
doc/proposals/flags.md (modified) (2 diffs)
-
doc/proposals/interned_string.cc (added)
-
doc/proposals/interned_string.h (added)
-
doc/proposals/operator-defaults.md (added)
-
doc/proposals/specialized_casts.md (added)
-
doc/proposals/tuples/Makefile (modified) (3 diffs)
-
doc/proposals/tuples/tuples.tex (modified) (4 diffs)
-
doc/proposals/unicode.html (added)
-
doc/proposals/user_conversions.md (modified) (9 diffs)
-
doc/proposals/virtual.txt (deleted)
-
doc/proposals/vtable.md (added)
-
doc/refrat/Makefile (modified) (2 diffs)
-
doc/theses/aaron_moss/comp_II/.gitignore (deleted)
-
doc/theses/aaron_moss/comp_II/Efficient Type Resolution in Cforall.pptx (deleted)
-
doc/theses/aaron_moss/comp_II/Makefile (deleted)
-
doc/theses/aaron_moss/comp_II/comp_II.tex (deleted)
-
doc/theses/aaron_moss/comp_II/conversion_dag.eps (deleted)
-
doc/theses/aaron_moss/comp_II/conversion_dag.odg (deleted)
-
doc/theses/aaron_moss/comp_II/conversion_dag.png (deleted)
-
doc/theses/aaron_moss/comp_II/resolution_dag.eps (deleted)
-
doc/theses/aaron_moss/comp_II/resolution_dag.odg (deleted)
-
doc/theses/aaron_moss/comp_II/resolution_dag.png (deleted)
-
doc/theses/aaron_moss/comp_II/resolution_dag2.odg (deleted)
-
doc/theses/aaron_moss/comp_II/resolution_dag2.png (deleted)
-
doc/theses/aaron_moss_PhD/comp_II/.gitignore (added)
-
doc/theses/aaron_moss_PhD/comp_II/Efficient Type Resolution in Cforall.pptx (added)
-
doc/theses/aaron_moss_PhD/comp_II/Makefile (added)
-
doc/theses/aaron_moss_PhD/comp_II/comp_II.tex (added)
-
doc/theses/aaron_moss_PhD/comp_II/conversion_dag.eps (added)
-
doc/theses/aaron_moss_PhD/comp_II/conversion_dag.odg (added)
-
doc/theses/aaron_moss_PhD/comp_II/conversion_dag.png (added)
-
doc/theses/aaron_moss_PhD/comp_II/resolution_dag.eps (added)
-
doc/theses/aaron_moss_PhD/comp_II/resolution_dag.odg (added)
-
doc/theses/aaron_moss_PhD/comp_II/resolution_dag.png (added)
-
doc/theses/aaron_moss_PhD/comp_II/resolution_dag2.odg (added)
-
doc/theses/aaron_moss_PhD/comp_II/resolution_dag2.png (added)
-
doc/theses/aaron_moss_PhD/phd/.gitignore (added)
-
doc/theses/aaron_moss_PhD/phd/Makefile (added)
-
doc/theses/aaron_moss_PhD/phd/background.tex (added)
-
doc/theses/aaron_moss_PhD/phd/cfa-macros.tex (added)
-
doc/theses/aaron_moss_PhD/phd/code/bespoke-generic.c (added)
-
doc/theses/aaron_moss_PhD/phd/code/cfa-generic.cfa (added)
-
doc/theses/aaron_moss_PhD/phd/code/macro-generic.c (added)
-
doc/theses/aaron_moss_PhD/phd/code/void-generic.c (added)
-
doc/theses/aaron_moss_PhD/phd/conclusion.tex (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/algo-summary.dat (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/algo-summary.gp (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/bu-summary.dat (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-cc/cfa-bu.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-cc/cfa-co.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-cc/cfa-dca.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-cc/cfa-def.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-cc/cfa-imm.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-mem-by-time.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-mem.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-plots.gp (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/cfa-time.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/data.xlsx (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/generic-timing.dat (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/generic-timing.gp (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/mem-by-max-assns.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/mem-by-max-depth.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/metric-plots.gp (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per-prob-scatter.gp (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per-prob.gp (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per-prob.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/imgui-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/io1-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/io2-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/kernel-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/math1-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/math2-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/math3-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/math4-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/minmax-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/preemption-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/rational-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/searchsort-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/per_prob/swap-per-prob.csv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/time-by-max-assns.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/evaluation/time-by-max-depth.tsv (added)
-
doc/theses/aaron_moss_PhD/phd/experiments.tex (added)
-
doc/theses/aaron_moss_PhD/phd/figures/bilson-conv-graph.eps (added)
-
doc/theses/aaron_moss_PhD/phd/figures/bilson-conv-graph.odg (added)
-
doc/theses/aaron_moss_PhD/phd/figures/extended-conv-graph.eps (added)
-
doc/theses/aaron_moss_PhD/phd/figures/extended-conv-graph.odg (added)
-
doc/theses/aaron_moss_PhD/phd/figures/persistent-union-find.eps (added)
-
doc/theses/aaron_moss_PhD/phd/figures/persistent-union-find.odg (added)
-
doc/theses/aaron_moss_PhD/phd/figures/resolution-dag.eps (added)
-
doc/theses/aaron_moss_PhD/phd/figures/resolution-dag.odg (added)
-
doc/theses/aaron_moss_PhD/phd/figures/safe-conv-graph.eps (added)
-
doc/theses/aaron_moss_PhD/phd/figures/safe-conv-graph.odg (added)
-
doc/theses/aaron_moss_PhD/phd/figures/union-find-with-classes.eps (added)
-
doc/theses/aaron_moss_PhD/phd/figures/union-find-with-classes.odg (added)
-
doc/theses/aaron_moss_PhD/phd/frontpgs.tex (added)
-
doc/theses/aaron_moss_PhD/phd/generic-bench.tex (added)
-
doc/theses/aaron_moss_PhD/phd/generic-types.tex (added)
-
doc/theses/aaron_moss_PhD/phd/introduction.tex (added)
-
doc/theses/aaron_moss_PhD/phd/macros.tex (added)
-
doc/theses/aaron_moss_PhD/phd/resolution-heuristics.tex (added)
-
doc/theses/aaron_moss_PhD/phd/thesis.tex (added)
-
doc/theses/aaron_moss_PhD/phd/timeline.md (added)
-
doc/theses/aaron_moss_PhD/phd/type-environment.tex (added)
-
doc/theses/lynn_tran_SE499/Bibliography.bib (added)
-
doc/theses/lynn_tran_SE499/Chapters/CFA.tex (added)
-
doc/theses/lynn_tran_SE499/Chapters/Conclusion.tex (added)
-
doc/theses/lynn_tran_SE499/Chapters/Demangler.tex (added)
-
doc/theses/lynn_tran_SE499/Chapters/Extensions.tex (added)
-
doc/theses/lynn_tran_SE499/Chapters/GDB.tex (added)
-
doc/theses/lynn_tran_SE499/Chapters/Introduction.tex (added)
-
doc/theses/lynn_tran_SE499/Chapters/uCPP.tex (added)
-
doc/theses/lynn_tran_SE499/LICENSE (added)
-
doc/theses/lynn_tran_SE499/SE499-master.zip (added)
-
doc/theses/lynn_tran_SE499/SE499-master/.gdbinit (added)
-
doc/theses/lynn_tran_SE499/SE499-master/README.md (added)
-
doc/theses/lynn_tran_SE499/SE499-master/test.cc (added)
-
doc/theses/lynn_tran_SE499/SE499-master/utils-gdb.gdb (added)
-
doc/theses/lynn_tran_SE499/SE499-master/utils-gdb.py (added)
-
doc/theses/lynn_tran_SE499/SE499-master/utils.cpp (added)
-
doc/theses/lynn_tran_SE499/Thesis.cls (added)
-
doc/theses/lynn_tran_SE499/lstpatch.sty (added)
-
doc/theses/lynn_tran_SE499/se499-report.tex (added)
-
doc/theses/lynn_tran_SE499/uContext_stack.png (added)
-
doc/theses/lynn_tran_SE499/vector.sty (added)
-
doc/theses/rob_schluntz/.gitignore (deleted)
-
doc/theses/rob_schluntz/Makefile (deleted)
-
doc/theses/rob_schluntz/cfa-format.tex (deleted)
-
doc/theses/rob_schluntz/conclusions.tex (deleted)
-
doc/theses/rob_schluntz/ctordtor.tex (deleted)
-
doc/theses/rob_schluntz/examples/conclusions/dtor.c (deleted)
-
doc/theses/rob_schluntz/examples/conclusions/except.c (deleted)
-
doc/theses/rob_schluntz/examples/conclusions/except.cc (deleted)
-
doc/theses/rob_schluntz/examples/ctor/array_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/copy_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/cv_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/enum_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/expr_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/global_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/hide_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/member.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/placement_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/return_dtor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/static_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/ctor/union_ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/intro/FileOutputStream.java (deleted)
-
doc/theses/rob_schluntz/examples/intro/compound_lit.c (deleted)
-
doc/theses/rob_schluntz/examples/intro/designation.c (deleted)
-
doc/theses/rob_schluntz/examples/intro/ignore.c (deleted)
-
doc/theses/rob_schluntz/examples/intro/ires.java (deleted)
-
doc/theses/rob_schluntz/examples/intro/res.java (deleted)
-
doc/theses/rob_schluntz/examples/intro/res1.java (deleted)
-
doc/theses/rob_schluntz/examples/intro/res2.java (deleted)
-
doc/theses/rob_schluntz/examples/intro/res3.java (deleted)
-
doc/theses/rob_schluntz/examples/intro/tuple.cc (deleted)
-
doc/theses/rob_schluntz/examples/intro/variadic.java (deleted)
-
doc/theses/rob_schluntz/examples/malloc.cc (deleted)
-
doc/theses/rob_schluntz/examples/nested.c (deleted)
-
doc/theses/rob_schluntz/examples/poly.c (deleted)
-
doc/theses/rob_schluntz/examples/scope_guard.h (deleted)
-
doc/theses/rob_schluntz/examples/test_scoped_guard.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/assign.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/cast.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/ctor.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/mrv.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/mrv_1.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/mrv_2.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/mrv_3.c (deleted)
-
doc/theses/rob_schluntz/examples/tuples/named.c (deleted)
-
doc/theses/rob_schluntz/examples/variadic/new.c (deleted)
-
doc/theses/rob_schluntz/examples/variadic/print.c (deleted)
-
doc/theses/rob_schluntz/examples/variadic/sum1.c (deleted)
-
doc/theses/rob_schluntz/examples/variadic/sum2.c (deleted)
-
doc/theses/rob_schluntz/intro.tex (deleted)
-
doc/theses/rob_schluntz/thesis-frontpgs.tex (deleted)
-
doc/theses/rob_schluntz/thesis.bib (deleted)
-
doc/theses/rob_schluntz/thesis.tex (deleted)
-
doc/theses/rob_schluntz/tuples.tex (deleted)
-
doc/theses/rob_schluntz/variadic.tex (deleted)
-
doc/theses/rob_schluntz_MMath/.gitignore (added)
-
doc/theses/rob_schluntz_MMath/Makefile (added)
-
doc/theses/rob_schluntz_MMath/cfa-format.tex (added)
-
doc/theses/rob_schluntz_MMath/conclusions.tex (added)
-
doc/theses/rob_schluntz_MMath/ctordtor.tex (added)
-
doc/theses/rob_schluntz_MMath/examples/conclusions/dtor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/conclusions/except.c (added)
-
doc/theses/rob_schluntz_MMath/examples/conclusions/except.cc (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/array_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/copy_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/cv_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/enum_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/expr_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/global_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/hide_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/member.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/placement_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/return_dtor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/static_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/ctor/union_ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/FileOutputStream.java (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/compound_lit.c (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/designation.c (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/ignore.c (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/ires.java (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/res.java (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/res1.java (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/res2.java (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/res3.java (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/tuple.cc (added)
-
doc/theses/rob_schluntz_MMath/examples/intro/variadic.java (added)
-
doc/theses/rob_schluntz_MMath/examples/malloc.cc (added)
-
doc/theses/rob_schluntz_MMath/examples/nested.c (added)
-
doc/theses/rob_schluntz_MMath/examples/poly.c (added)
-
doc/theses/rob_schluntz_MMath/examples/scope_guard.h (added)
-
doc/theses/rob_schluntz_MMath/examples/test_scoped_guard.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/assign.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/cast.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/ctor.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/mrv.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/mrv_1.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/mrv_2.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/mrv_3.c (added)
-
doc/theses/rob_schluntz_MMath/examples/tuples/named.c (added)
-
doc/theses/rob_schluntz_MMath/examples/variadic/new.c (added)
-
doc/theses/rob_schluntz_MMath/examples/variadic/print.c (added)
-
doc/theses/rob_schluntz_MMath/examples/variadic/sum1.c (added)
-
doc/theses/rob_schluntz_MMath/examples/variadic/sum2.c (added)
-
doc/theses/rob_schluntz_MMath/intro.tex (added)
-
doc/theses/rob_schluntz_MMath/thesis-frontpgs.tex (added)
-
doc/theses/rob_schluntz_MMath/thesis.bib (added)
-
doc/theses/rob_schluntz_MMath/thesis.tex (added)
-
doc/theses/rob_schluntz_MMath/tuples.tex (added)
-
doc/theses/rob_schluntz_MMath/variadic.tex (added)
-
doc/theses/thierry_delisle/.gitignore (deleted)
-
doc/theses/thierry_delisle/Makefile (deleted)
-
doc/theses/thierry_delisle/annex/glossary.tex (deleted)
-
doc/theses/thierry_delisle/annex/local.bib (deleted)
-
doc/theses/thierry_delisle/figures/dependency.fig (deleted)
-
doc/theses/thierry_delisle/figures/ext_monitor.fig (deleted)
-
doc/theses/thierry_delisle/figures/int_monitor.fig (deleted)
-
doc/theses/thierry_delisle/figures/monitor.fig (deleted)
-
doc/theses/thierry_delisle/figures/monitor_structs.fig (deleted)
-
doc/theses/thierry_delisle/figures/system.fig (deleted)
-
doc/theses/thierry_delisle/notes/cor-thread-traits.c (deleted)
-
doc/theses/thierry_delisle/notes/lit-review.md (deleted)
-
doc/theses/thierry_delisle/notes/notes.md (deleted)
-
doc/theses/thierry_delisle/style/cfa-format.tex (deleted)
-
doc/theses/thierry_delisle/style/style.tex (deleted)
-
doc/theses/thierry_delisle/text/basics.tex (deleted)
-
doc/theses/thierry_delisle/text/cforall.tex (deleted)
-
doc/theses/thierry_delisle/text/concurrency.tex (deleted)
-
doc/theses/thierry_delisle/text/frontpgs.tex (deleted)
-
doc/theses/thierry_delisle/text/future.tex (deleted)
-
doc/theses/thierry_delisle/text/internals.tex (deleted)
-
doc/theses/thierry_delisle/text/intro.tex (deleted)
-
doc/theses/thierry_delisle/text/parallelism.tex (deleted)
-
doc/theses/thierry_delisle/text/results.tex (deleted)
-
doc/theses/thierry_delisle/text/together.tex (deleted)
-
doc/theses/thierry_delisle/thePlan.md (deleted)
-
doc/theses/thierry_delisle/thesis.tex (deleted)
-
doc/theses/thierry_delisle/version (deleted)
-
doc/theses/thierry_delisle/version.sh (deleted)
-
doc/theses/thierry_delisle_MMath/.gitignore (added)
-
doc/theses/thierry_delisle_MMath/Makefile (added)
-
doc/theses/thierry_delisle_MMath/annex/glossary.tex (added)
-
doc/theses/thierry_delisle_MMath/annex/local.bib (added)
-
doc/theses/thierry_delisle_MMath/figures/dependency.fig (added)
-
doc/theses/thierry_delisle_MMath/figures/ext_monitor.fig (added)
-
doc/theses/thierry_delisle_MMath/figures/int_monitor.fig (added)
-
doc/theses/thierry_delisle_MMath/figures/monitor.fig (added)
-
doc/theses/thierry_delisle_MMath/figures/monitor_structs.fig (added)
-
doc/theses/thierry_delisle_MMath/figures/system.fig (added)
-
doc/theses/thierry_delisle_MMath/notes/cor-thread-traits.c (added)
-
doc/theses/thierry_delisle_MMath/notes/lit-review.md (added)
-
doc/theses/thierry_delisle_MMath/notes/notes.md (added)
-
doc/theses/thierry_delisle_MMath/style/cfa-format.tex (added)
-
doc/theses/thierry_delisle_MMath/style/style.tex (added)
-
doc/theses/thierry_delisle_MMath/text/basics.tex (added)
-
doc/theses/thierry_delisle_MMath/text/cforall.tex (added)
-
doc/theses/thierry_delisle_MMath/text/concurrency.tex (added)
-
doc/theses/thierry_delisle_MMath/text/frontpgs.tex (added)
-
doc/theses/thierry_delisle_MMath/text/future.tex (added)
-
doc/theses/thierry_delisle_MMath/text/internals.tex (added)
-
doc/theses/thierry_delisle_MMath/text/intro.tex (added)
-
doc/theses/thierry_delisle_MMath/text/parallelism.tex (added)
-
doc/theses/thierry_delisle_MMath/text/results.tex (added)
-
doc/theses/thierry_delisle_MMath/text/together.tex (added)
-
doc/theses/thierry_delisle_MMath/thePlan.md (added)
-
doc/theses/thierry_delisle_MMath/thesis.tex (added)
-
doc/theses/thierry_delisle_MMath/version (added)
-
doc/theses/thierry_delisle_MMath/version.sh (added)
-
doc/theses/thierry_delisle_PhD/code/assert.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/prefetch.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/processor.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/processor_list.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/processor_list_fast.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/processor_list_good.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/relaxed_list.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/utils.hpp (added)
-
doc/user/Makefile (modified) (4 diffs)
-
doc/user/user.tex (modified) (172 diffs)
-
doc/working/exception/impl/Makefile (added)
-
doc/working/exception/impl/exception.c (modified) (4 diffs)
-
doc/working/exception/impl/pdc.s (added)
-
doc/working/exception/impl/pic.s (added)
-
doc/working/exception/impl/test.c (added)
-
doc/working/glen_conversions/float_promo.dia (added)
-
doc/working/glen_conversions/float_promo.png (added)
-
doc/working/glen_conversions/index.html (added)
-
driver/Makefile.am (added)
-
driver/Makefile.in (added)
-
driver/as.cc (added)
-
driver/cc1.cc (added)
-
driver/cfa.cc (added)
-
examples/ArrayN.c (added)
-
examples/Initialization.c (added)
-
examples/Initialization2.c (added)
-
examples/Makefile.example (added)
-
examples/Members.c (added)
-
examples/Misc.c (added)
-
examples/MiscError.c (added)
-
examples/Rank2.c (added)
-
examples/Tuple.c (added)
-
examples/abstype.c (added)
-
examples/constructors.c (added)
-
examples/forward.c (added)
-
examples/gc_no_raii/.gitignore (added)
-
examples/gc_no_raii/bug-repro/assert.c (added)
-
examples/gc_no_raii/bug-repro/blockers.tar.gz (added)
-
examples/gc_no_raii/bug-repro/blockers/explicit_cast.c (added)
-
examples/gc_no_raii/bug-repro/blockers/file_scope.c (added)
-
examples/gc_no_raii/bug-repro/blockers/recursive_realloc.c (added)
-
examples/gc_no_raii/bug-repro/crash.c (added)
-
examples/gc_no_raii/bug-repro/deref.c (added)
-
examples/gc_no_raii/bug-repro/field.c (added)
-
examples/gc_no_raii/bug-repro/find.c (added)
-
examples/gc_no_raii/bug-repro/inline.c (added)
-
examples/gc_no_raii/bug-repro/malloc.c (added)
-
examples/gc_no_raii/bug-repro/not_equal.c (added)
-
examples/gc_no_raii/bug-repro/oddtype.c (added)
-
examples/gc_no_raii/bug-repro/push_back.c (added)
-
examples/gc_no_raii/bug-repro/push_back.h (added)
-
examples/gc_no_raii/bug-repro/realloc.c (added)
-
examples/gc_no_raii/bug-repro/return.c (added)
-
examples/gc_no_raii/bug-repro/return_template.c (added)
-
examples/gc_no_raii/bug-repro/slow_malloc.c (added)
-
examples/gc_no_raii/bug-repro/static_const_local.c (added)
-
examples/gc_no_raii/bug-repro/test-assert.cpp (added)
-
examples/gc_no_raii/bug-repro/void_pointer.c (added)
-
examples/gc_no_raii/bug-repro/while.c (added)
-
examples/gc_no_raii/bug-repro/zero.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-malign.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-malloc.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-mmap.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-win-valloc.c (added)
-
examples/gc_no_raii/premake4.lua (added)
-
examples/gc_no_raii/src/allocate-pool.c (added)
-
examples/gc_no_raii/src/allocate-pool.h (added)
-
examples/gc_no_raii/src/gc.h (added)
-
examples/gc_no_raii/src/gcpointers.c (added)
-
examples/gc_no_raii/src/gcpointers.h (added)
-
examples/gc_no_raii/src/internal/card_table.h (added)
-
examples/gc_no_raii/src/internal/collector.c (added)
-
examples/gc_no_raii/src/internal/collector.h (added)
-
examples/gc_no_raii/src/internal/gc_tools.h (added)
-
examples/gc_no_raii/src/internal/globals.h (added)
-
examples/gc_no_raii/src/internal/memory_pool.c (added)
-
examples/gc_no_raii/src/internal/memory_pool.h (added)
-
examples/gc_no_raii/src/internal/object_header.c (added)
-
examples/gc_no_raii/src/internal/object_header.h (added)
-
examples/gc_no_raii/src/internal/state.c (added)
-
examples/gc_no_raii/src/internal/state.h (added)
-
examples/gc_no_raii/src/test_include.c (added)
-
examples/gc_no_raii/src/tools.h (added)
-
examples/gc_no_raii/src/tools/checks.h (added)
-
examples/gc_no_raii/src/tools/print.c (added)
-
examples/gc_no_raii/src/tools/print.h (added)
-
examples/gc_no_raii/src/tools/worklist.h (added)
-
examples/gc_no_raii/test/badlll.c (added)
-
examples/gc_no_raii/test/gctest.c (added)
-
examples/gc_no_raii/test/operators.c (added)
-
examples/huge.c (added)
-
examples/includes.c (added)
-
examples/index.h (added)
-
examples/it_out.c (added)
-
examples/multicore.c (added)
-
examples/new.c (added)
-
examples/poly-bench.c (added)
-
examples/prolog.c (added)
-
examples/quad.c (added)
-
examples/s.c (added)
-
examples/simplePoly.c (added)
-
examples/simpler.c (added)
-
examples/specialize.c (added)
-
examples/square.c (added)
-
examples/twice.c (added)
-
examples/wrapper/.gitignore (added)
-
examples/wrapper/premake4.lua (added)
-
examples/wrapper/src/main.c (added)
-
examples/wrapper/src/pointer.h (added)
-
examples/zero_one.c (added)
-
libcfa/.autom4te.cfg (added)
-
libcfa/Makefile.am (added)
-
libcfa/Makefile.in (added)
-
libcfa/aclocal.m4 (added)
-
libcfa/automake/compile (added)
-
libcfa/automake/config.guess (added)
-
libcfa/automake/config.sub (added)
-
libcfa/automake/depcomp (added)
-
libcfa/automake/install-sh (added)
-
libcfa/automake/libtool.m4 (added)
-
libcfa/automake/ltmain.sh (added)
-
libcfa/automake/ltoptions.m4 (added)
-
libcfa/automake/ltsugar.m4 (added)
-
libcfa/automake/ltversion.m4 (added)
-
libcfa/automake/lt~obsolete.m4 (added)
-
libcfa/automake/missing (added)
-
libcfa/configure (added)
-
libcfa/configure.ac (added)
-
libcfa/prelude/Makefile.am (added)
-
libcfa/prelude/Makefile.in (added)
-
libcfa/prelude/bootloader.cf (added)
-
libcfa/prelude/builtins.c (added)
-
libcfa/prelude/builtins.def (added)
-
libcfa/prelude/extras.c (added)
-
libcfa/prelude/extras.regx (added)
-
libcfa/prelude/prelude-gen.cc (added)
-
libcfa/prelude/prelude.old.cf (added)
-
libcfa/prelude/prototypes.awk (added)
-
libcfa/prelude/prototypes.c (added)
-
libcfa/prelude/prototypes.sed (added)
-
libcfa/prelude/sync-builtins.cf (added)
-
libcfa/prelude/sync-builtins.def (added)
-
libcfa/src/Makefile.am (added)
-
libcfa/src/Makefile.in (added)
-
libcfa/src/assert.cfa (added)
-
libcfa/src/bits/algorithm.hfa (added)
-
libcfa/src/bits/align.hfa (added)
-
libcfa/src/bits/containers.hfa (added)
-
libcfa/src/bits/debug.cfa (added)
-
libcfa/src/bits/debug.hfa (added)
-
libcfa/src/bits/defs.hfa (added)
-
libcfa/src/bits/locks.hfa (added)
-
libcfa/src/bits/signal.hfa (added)
-
libcfa/src/clock.hfa (added)
-
libcfa/src/common.cfa (added)
-
libcfa/src/common.hfa (added)
-
libcfa/src/concurrency/CtxSwitch-arm.S (added)
-
libcfa/src/concurrency/CtxSwitch-i386.S (added)
-
libcfa/src/concurrency/CtxSwitch-i686.S (added)
-
libcfa/src/concurrency/CtxSwitch-x64.S (added)
-
libcfa/src/concurrency/CtxSwitch-x86.S (added)
-
libcfa/src/concurrency/CtxSwitch-x86_64.S (added)
-
libcfa/src/concurrency/alarm.cfa (added)
-
libcfa/src/concurrency/alarm.hfa (added)
-
libcfa/src/concurrency/coroutine.cfa (added)
-
libcfa/src/concurrency/coroutine.hfa (added)
-
libcfa/src/concurrency/invoke.c (added)
-
libcfa/src/concurrency/invoke.h (added)
-
libcfa/src/concurrency/kernel.cfa (added)
-
libcfa/src/concurrency/kernel.hfa (added)
-
libcfa/src/concurrency/kernel_private.hfa (added)
-
libcfa/src/concurrency/monitor.cfa (added)
-
libcfa/src/concurrency/monitor.hfa (added)
-
libcfa/src/concurrency/mutex.cfa (added)
-
libcfa/src/concurrency/mutex.hfa (added)
-
libcfa/src/concurrency/preemption.cfa (added)
-
libcfa/src/concurrency/preemption.hfa (added)
-
libcfa/src/concurrency/thread.cfa (added)
-
libcfa/src/concurrency/thread.hfa (added)
-
libcfa/src/containers/maybe.cfa (added)
-
libcfa/src/containers/maybe.hfa (added)
-
libcfa/src/containers/pair.cfa (added)
-
libcfa/src/containers/pair.hfa (added)
-
libcfa/src/containers/result.cfa (added)
-
libcfa/src/containers/result.hfa (added)
-
libcfa/src/containers/vector.cfa (added)
-
libcfa/src/containers/vector.hfa (added)
-
libcfa/src/exception.c (added)
-
libcfa/src/exception.h (added)
-
libcfa/src/executor.cfa (added)
-
libcfa/src/fstream.cfa (added)
-
libcfa/src/fstream.hfa (added)
-
libcfa/src/gmp.hfa (added)
-
libcfa/src/heap.cfa (added)
-
libcfa/src/interpose.cfa (added)
-
libcfa/src/iostream.cfa (added)
-
libcfa/src/iostream.hfa (added)
-
libcfa/src/iterator.cfa (added)
-
libcfa/src/iterator.hfa (added)
-
libcfa/src/limits.cfa (added)
-
libcfa/src/limits.hfa (added)
-
libcfa/src/lsda.h (added)
-
libcfa/src/math.hfa (added)
-
libcfa/src/memcheck.awk (added)
-
libcfa/src/rational.cfa (added)
-
libcfa/src/rational.hfa (added)
-
libcfa/src/startup.cfa (added)
-
libcfa/src/startup.hfa (added)
-
libcfa/src/stdhdr/assert.h (added)
-
libcfa/src/stdhdr/bfdlink.h (added)
-
libcfa/src/stdhdr/complex.h (added)
-
libcfa/src/stdhdr/ctype.h (added)
-
libcfa/src/stdhdr/errno.h (added)
-
libcfa/src/stdhdr/fenv.h (added)
-
libcfa/src/stdhdr/float.h (added)
-
libcfa/src/stdhdr/gmp.h (added)
-
libcfa/src/stdhdr/hwloc.h (added)
-
libcfa/src/stdhdr/inttypes.h (added)
-
libcfa/src/stdhdr/iso646.h (added)
-
libcfa/src/stdhdr/krb5.h (added)
-
libcfa/src/stdhdr/limits.h (added)
-
libcfa/src/stdhdr/locale.h (added)
-
libcfa/src/stdhdr/malloc.h (added)
-
libcfa/src/stdhdr/math.h (added)
-
libcfa/src/stdhdr/setjmp.h (added)
-
libcfa/src/stdhdr/signal.h (added)
-
libcfa/src/stdhdr/stdalign.h (added)
-
libcfa/src/stdhdr/stdarg.h (added)
-
libcfa/src/stdhdr/stdatomic.h (added)
-
libcfa/src/stdhdr/stdbool.h (added)
-
libcfa/src/stdhdr/stddef.h (added)
-
libcfa/src/stdhdr/stdint.h (added)
-
libcfa/src/stdhdr/stdio.h (added)
-
libcfa/src/stdhdr/stdlib.h (added)
-
libcfa/src/stdhdr/stdnoreturn.h (added)
-
libcfa/src/stdhdr/string.h (added)
-
libcfa/src/stdhdr/sys/ucontext.h (added)
-
libcfa/src/stdhdr/tgmath.h (added)
-
libcfa/src/stdhdr/threads.h (added)
-
libcfa/src/stdhdr/time.h (added)
-
libcfa/src/stdhdr/uchar.h (added)
-
libcfa/src/stdhdr/unistd.h (added)
-
libcfa/src/stdhdr/wchar.h (added)
-
libcfa/src/stdhdr/wctype.h (added)
-
libcfa/src/stdlib.cfa (added)
-
libcfa/src/stdlib.hfa (added)
-
libcfa/src/time.cfa (added)
-
libcfa/src/time.hfa (added)
-
libcfa/src/time_t.hfa (added)
-
libcfa/src/virtual.c (added)
-
libcfa/src/virtual.h (added)
-
longrun_tests/Makefile.am (added)
-
longrun_tests/Makefile.in (added)
-
longrun_tests/block.cfa (added)
-
longrun_tests/coroutine.cfa (added)
-
longrun_tests/create.cfa (added)
-
longrun_tests/disjoint.cfa (added)
-
longrun_tests/enter.cfa (added)
-
longrun_tests/enter3.cfa (added)
-
longrun_tests/preempt.cfa (added)
-
longrun_tests/processor.cfa (added)
-
longrun_tests/stack.cfa (added)
-
longrun_tests/update-type (added)
-
longrun_tests/wait.cfa (added)
-
longrun_tests/yield.cfa (added)
-
src/AST/AssertAcyclic.cpp (added)
-
src/AST/AssertAcyclic.hpp (added)
-
src/AST/Attribute.cpp (added)
-
src/AST/Attribute.hpp (added)
-
src/AST/Bitfield.hpp (added)
-
src/AST/CVQualifiers.hpp (added)
-
src/AST/Chain.hpp (added)
-
src/AST/Convert.cpp (added)
-
src/AST/Convert.hpp (added)
-
src/AST/Decl.cpp (added)
-
src/AST/Decl.hpp (added)
-
src/AST/DeclReplacer.cpp (added)
-
src/AST/DeclReplacer.hpp (added)
-
src/AST/Expr.cpp (added)
-
src/AST/Expr.hpp (added)
-
src/AST/FunctionSpec.hpp (added)
-
src/AST/Fwd.hpp (added)
-
src/AST/GenericSubstitution.cpp (added)
-
src/AST/GenericSubstitution.hpp (added)
-
src/AST/Init.cpp (added)
-
src/AST/Init.hpp (added)
-
src/AST/Label.hpp (added)
-
src/AST/LinkageSpec.cpp (added)
-
src/AST/LinkageSpec.hpp (added)
-
src/AST/Node.cpp (added)
-
src/AST/Node.hpp (added)
-
src/AST/ParseNode.hpp (added)
-
src/AST/Pass.cpp (added)
-
src/AST/Pass.hpp (added)
-
src/AST/Pass.impl.hpp (added)
-
src/AST/Pass.proto.hpp (added)
-
src/AST/Print.cpp (added)
-
src/AST/Print.hpp (added)
-
src/AST/Stmt.cpp (added)
-
src/AST/Stmt.hpp (added)
-
src/AST/StorageClasses.hpp (added)
-
src/AST/SymbolTable.cpp (added)
-
src/AST/SymbolTable.hpp (added)
-
src/AST/Type.cpp (added)
-
src/AST/Type.hpp (added)
-
src/AST/TypeEnvironment.cpp (added)
-
src/AST/TypeEnvironment.hpp (added)
-
src/AST/TypeSubstitution.cpp (added)
-
src/AST/TypeSubstitution.hpp (added)
-
src/AST/TypeVar.hpp (added)
-
src/AST/Visitor.hpp (added)
-
src/AST/module.mk (added)
-
src/AST/porting.md (added)
-
src/BasicTypes-gen.cc (added)
-
src/CodeGen/CodeGenerator.cc (modified) (39 diffs)
-
src/CodeGen/CodeGenerator.h (modified) (5 diffs)
-
src/CodeGen/GenType.cc (modified) (19 diffs)
-
src/CodeGen/GenType.h (modified) (2 diffs)
-
src/CodeGen/Options.h (added)
-
src/CodeGen/module.mk (modified) (1 diff)
-
src/CodeTools/ResolvProtoDump.cc (added)
-
src/CodeTools/ResolvProtoDump.h (added)
-
src/CodeTools/module.mk (modified) (1 diff)
-
src/Common/Assert.cc (modified) (1 diff)
-
src/Common/Debug.h (modified) (1 diff)
-
src/Common/Eval.cc (added)
-
src/Common/FilterCombos.h (added)
-
src/Common/Heap.cc (deleted)
-
src/Common/Heap.h (deleted)
-
src/Common/Indenter.h (modified) (2 diffs)
-
src/Common/PassVisitor.cc (added)
-
src/Common/PassVisitor.h (modified) (15 diffs)
-
src/Common/PassVisitor.impl.h (modified) (119 diffs)
-
src/Common/PassVisitor.proto.h (modified) (7 diffs)
-
src/Common/PersistentMap.h (added)
-
src/Common/ScopedMap.h (modified) (18 diffs)
-
src/Common/SemanticError.h (modified) (4 diffs)
-
src/Common/Stats.h (added)
-
src/Common/Stats/Base.h (added)
-
src/Common/Stats/Counter.cc (added)
-
src/Common/Stats/Counter.h (added)
-
src/Common/Stats/Heap.cc (added)
-
src/Common/Stats/Heap.h (added)
-
src/Common/Stats/Stats.cc (added)
-
src/Common/Stats/Time.cc (added)
-
src/Common/Stats/Time.h (added)
-
src/Common/module.mk (modified) (1 diff)
-
src/Common/utility.h (modified) (5 diffs)
-
src/CompilationState.cc (added)
-
src/CompilationState.h (added)
-
src/Concurrency/Keywords.cc (modified) (8 diffs)
-
src/Concurrency/Waitfor.cc (modified) (6 diffs)
-
src/Concurrency/module.mk (modified) (1 diff)
-
src/ControlStruct/ExceptTranslate.cc (modified) (4 diffs)
-
src/ControlStruct/ForExprMutator.cc (modified) (4 diffs)
-
src/ControlStruct/LabelFixer.cc (modified) (7 diffs)
-
src/ControlStruct/LabelGenerator.cc (modified) (3 diffs)
-
src/ControlStruct/MLEMutator.cc (modified) (2 diffs)
-
src/ControlStruct/MLEMutator.h (modified) (3 diffs)
-
src/ControlStruct/module.mk (modified) (1 diff)
-
src/Docs/Makefile (deleted)
-
src/Docs/cfa-cpp.1 (deleted)
-
src/Docs/design.tex (deleted)
-
src/Docs/uml.dia (deleted)
-
src/GenPoly/Box.cc (modified) (9 diffs)
-
src/GenPoly/GenPoly.cc (modified) (5 diffs)
-
src/GenPoly/GenPoly.h (modified) (3 diffs)
-
src/GenPoly/InstantiateGeneric.cc (modified) (1 diff)
-
src/GenPoly/Lvalue.cc (modified) (13 diffs)
-
src/GenPoly/ScopedSet.h (modified) (7 diffs)
-
src/GenPoly/ScrubTyVars.cc (modified) (1 diff)
-
src/GenPoly/Specialize.cc (modified) (6 diffs)
-
src/GenPoly/module.mk (modified) (1 diff)
-
src/InitTweak/FixGlobalInit.cc (modified) (5 diffs)
-
src/InitTweak/FixGlobalInit.h (modified) (1 diff)
-
src/InitTweak/FixInit.cc (modified) (27 diffs)
-
src/InitTweak/FixInit.h (modified) (1 diff)
-
src/InitTweak/GenInit.cc (modified) (6 diffs)
-
src/InitTweak/GenInit.h (modified) (2 diffs)
-
src/InitTweak/InitTweak.cc (modified) (32 diffs)
-
src/InitTweak/InitTweak.h (modified) (9 diffs)
-
src/InitTweak/module.mk (modified) (1 diff)
-
src/MakeLibCfa.cc (modified) (2 diffs)
-
src/Makefile.am (modified) (2 diffs)
-
src/Makefile.in (modified) (39 diffs)
-
src/Parser/DeclarationNode.cc (modified) (20 diffs)
-
src/Parser/ExpressionNode.cc (modified) (7 diffs)
-
src/Parser/LinkageSpec.cc (modified) (2 diffs)
-
src/Parser/LinkageSpec.h (modified) (3 diffs)
-
src/Parser/ParseNode.h (modified) (19 diffs)
-
src/Parser/StatementNode.cc (modified) (6 diffs)
-
src/Parser/TypeData.cc (modified) (29 diffs)
-
src/Parser/TypeData.h (modified) (6 diffs)
-
src/Parser/TypedefTable.cc (modified) (4 diffs)
-
src/Parser/TypedefTable.h (modified) (2 diffs)
-
src/Parser/lex.ll (modified) (16 diffs)
-
src/Parser/module.mk (modified) (2 diffs)
-
src/Parser/parser.yy (modified) (69 diffs)
-
src/ResolvExpr/AdjustExprType.cc (modified) (6 diffs)
-
src/ResolvExpr/Alternative.cc (modified) (7 diffs)
-
src/ResolvExpr/Alternative.h (modified) (3 diffs)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (61 diffs)
-
src/ResolvExpr/AlternativeFinder.h (modified) (4 diffs)
-
src/ResolvExpr/Candidate.cpp (added)
-
src/ResolvExpr/Candidate.hpp (added)
-
src/ResolvExpr/CandidateFinder.cpp (added)
-
src/ResolvExpr/CandidateFinder.hpp (added)
-
src/ResolvExpr/CastCost.cc (modified) (5 diffs)
-
src/ResolvExpr/CommonType.cc (modified) (15 diffs)
-
src/ResolvExpr/ConversionCost.cc (modified) (19 diffs)
-
src/ResolvExpr/ConversionCost.h (modified) (4 diffs)
-
src/ResolvExpr/Cost.h (modified) (2 diffs)
-
src/ResolvExpr/CurrentObject.cc (modified) (4 diffs)
-
src/ResolvExpr/CurrentObject.h (modified) (2 diffs)
-
src/ResolvExpr/ExplodedActual.cc (modified) (2 diffs)
-
src/ResolvExpr/ExplodedActual.h (modified) (2 diffs)
-
src/ResolvExpr/ExplodedArg.cpp (added)
-
src/ResolvExpr/ExplodedArg.hpp (added)
-
src/ResolvExpr/FindOpenVars.cc (modified) (7 diffs)
-
src/ResolvExpr/FindOpenVars.h (modified) (1 diff)
-
src/ResolvExpr/Occurs.cc (modified) (3 diffs)
-
src/ResolvExpr/PolyCost.cc (modified) (2 diffs)
-
src/ResolvExpr/PtrsAssignable.cc (modified) (5 diffs)
-
src/ResolvExpr/PtrsCastable.cc (modified) (6 diffs)
-
src/ResolvExpr/RenameVars.cc (modified) (5 diffs)
-
src/ResolvExpr/RenameVars.h (modified) (1 diff)
-
src/ResolvExpr/ResolvMode.h (added)
-
src/ResolvExpr/ResolveAssertions.cc (added)
-
src/ResolvExpr/ResolveAssertions.h (added)
-
src/ResolvExpr/ResolveTypeof.cc (modified) (4 diffs)
-
src/ResolvExpr/ResolveTypeof.h (modified) (1 diff)
-
src/ResolvExpr/Resolver.cc (modified) (45 diffs)
-
src/ResolvExpr/Resolver.h (modified) (2 diffs)
-
src/ResolvExpr/SatisfyAssertions.cpp (added)
-
src/ResolvExpr/SatisfyAssertions.hpp (added)
-
src/ResolvExpr/SpecCost.cc (added)
-
src/ResolvExpr/TypeEnvironment.cc (modified) (13 diffs)
-
src/ResolvExpr/TypeEnvironment.h (modified) (8 diffs)
-
src/ResolvExpr/Unify.cc (modified) (27 diffs)
-
src/ResolvExpr/Unify.h (modified) (3 diffs)
-
src/ResolvExpr/WidenMode.h (added)
-
src/ResolvExpr/module.mk (modified) (1 diff)
-
src/ResolvExpr/typeops.h (modified) (6 diffs)
-
src/SymTab/Autogen.cc (modified) (8 diffs)
-
src/SymTab/Autogen.h (modified) (8 diffs)
-
src/SymTab/Demangle.cc (added)
-
src/SymTab/FixFunction.cc (modified) (4 diffs)
-
src/SymTab/FixFunction.h (modified) (1 diff)
-
src/SymTab/Indexer.cc (modified) (10 diffs)
-
src/SymTab/Indexer.h (modified) (3 diffs)
-
src/SymTab/Mangler.cc (modified) (16 diffs)
-
src/SymTab/Mangler.h (modified) (1 diff)
-
src/SymTab/ManglerCommon.cc (added)
-
src/SymTab/Validate.cc (modified) (48 diffs)
-
src/SymTab/Validate.h (modified) (2 diffs)
-
src/SymTab/demangler.cc (added)
-
src/SymTab/module.mk (modified) (1 diff)
-
src/SynTree/AddressExpr.cc (modified) (2 diffs)
-
src/SynTree/AggregateDecl.cc (modified) (2 diffs)
-
src/SynTree/ApplicationExpr.cc (modified) (4 diffs)
-
src/SynTree/ArrayType.cc (modified) (1 diff)
-
src/SynTree/Attribute.cc (modified) (1 diff)
-
src/SynTree/Attribute.h (modified) (1 diff)
-
src/SynTree/BaseSyntaxNode.h (modified) (4 diffs)
-
src/SynTree/BasicType.cc (modified) (2 diffs)
-
src/SynTree/CommaExpr.cc (modified) (3 diffs)
-
src/SynTree/Constant.cc (modified) (5 diffs)
-
src/SynTree/Constant.h (modified) (4 diffs)
-
src/SynTree/DeclReplacer.cc (modified) (5 diffs)
-
src/SynTree/DeclReplacer.h (modified) (1 diff)
-
src/SynTree/Declaration.cc (modified) (2 diffs)
-
src/SynTree/Declaration.h (modified) (17 diffs)
-
src/SynTree/Expression.cc (modified) (52 diffs)
-
src/SynTree/Expression.h (modified) (53 diffs)
-
src/SynTree/FunctionDecl.cc (modified) (1 diff)
-
src/SynTree/FunctionType.cc (modified) (1 diff)
-
src/SynTree/Initializer.h (modified) (5 diffs)
-
src/SynTree/Label.h (modified) (1 diff)
-
src/SynTree/Mutator.h (modified) (7 diffs)
-
src/SynTree/ObjectDecl.cc (modified) (1 diff)
-
src/SynTree/ReferenceToType.cc (modified) (7 diffs)
-
src/SynTree/Statement.cc (modified) (1 diff)
-
src/SynTree/Statement.h (modified) (23 diffs)
-
src/SynTree/SynTree.h (modified) (8 diffs)
-
src/SynTree/TupleExpr.cc (modified) (5 diffs)
-
src/SynTree/Type.cc (modified) (6 diffs)
-
src/SynTree/Type.h (modified) (30 diffs)
-
src/SynTree/TypeSubstitution.cc (modified) (3 diffs)
-
src/SynTree/TypeSubstitution.h (modified) (11 diffs)
-
src/SynTree/TypeofType.cc (modified) (2 diffs)
-
src/SynTree/Visitor.h (modified) (3 diffs)
-
src/SynTree/module.mk (modified) (1 diff)
-
src/Tuples/Explode.cc (modified) (2 diffs)
-
src/Tuples/Explode.h (modified) (6 diffs)
-
src/Tuples/TupleAssignment.cc (modified) (11 diffs)
-
src/Tuples/TupleExpansion.cc (modified) (10 diffs)
-
src/Tuples/Tuples.cc (added)
-
src/Tuples/Tuples.h (modified) (4 diffs)
-
src/Tuples/module.mk (modified) (1 diff)
-
src/Validate/FindSpecialDecls.cc (added)
-
src/Validate/FindSpecialDecls.h (added)
-
src/Validate/HandleAttributes.cc (added)
-
src/Validate/HandleAttributes.h (added)
-
src/Validate/module.mk (added)
-
src/Virtual/ExpandCasts.cc (modified) (1 diff)
-
src/benchmark/Makefile.am (deleted)
-
src/benchmark/Makefile.in (deleted)
-
src/benchmark/Monitor.c (deleted)
-
src/benchmark/bench.h (deleted)
-
src/benchmark/compile/empty.c (deleted)
-
src/benchmark/creation/JavaThread.java (deleted)
-
src/benchmark/creation/cfa_cor.c (deleted)
-
src/benchmark/creation/cfa_thrd.c (deleted)
-
src/benchmark/creation/goroutine.go (deleted)
-
src/benchmark/creation/pthreads.c (deleted)
-
src/benchmark/creation/upp_cor.cc (deleted)
-
src/benchmark/creation/upp_thrd.cc (deleted)
-
src/benchmark/ctxswitch/JavaThread.java (deleted)
-
src/benchmark/ctxswitch/cfa_cor.c (deleted)
-
src/benchmark/ctxswitch/cfa_thrd.c (deleted)
-
src/benchmark/ctxswitch/cfa_thrd2.c (deleted)
-
src/benchmark/ctxswitch/goroutine.go (deleted)
-
src/benchmark/ctxswitch/kos_fibre.cpp (deleted)
-
src/benchmark/ctxswitch/kos_fibre2.cpp (deleted)
-
src/benchmark/ctxswitch/pthreads.c (deleted)
-
src/benchmark/ctxswitch/upp_cor.cc (deleted)
-
src/benchmark/ctxswitch/upp_thrd.cc (deleted)
-
src/benchmark/fetch_add.c (deleted)
-
src/benchmark/function.c (deleted)
-
src/benchmark/interrupt_linux.c (deleted)
-
src/benchmark/loop.c (deleted)
-
src/benchmark/mutex/JavaThread.java (deleted)
-
src/benchmark/mutex/cfa1.c (deleted)
-
src/benchmark/mutex/cfa2.c (deleted)
-
src/benchmark/mutex/cfa4.c (deleted)
-
src/benchmark/mutex/pthreads.c (deleted)
-
src/benchmark/mutex/upp.cc (deleted)
-
src/benchmark/schedext/cfa1.c (deleted)
-
src/benchmark/schedext/cfa2.c (deleted)
-
src/benchmark/schedext/cfa4.c (deleted)
-
src/benchmark/schedext/upp.cc (deleted)
-
src/benchmark/schedint/JavaThread.java (deleted)
-
src/benchmark/schedint/cfa1.c (deleted)
-
src/benchmark/schedint/cfa2.c (deleted)
-
src/benchmark/schedint/cfa4.c (deleted)
-
src/benchmark/schedint/pthreads.c (deleted)
-
src/benchmark/schedint/upp.cc (deleted)
-
src/cfa.make (added)
-
src/config.h.in (added)
-
src/driver/Makefile.am (deleted)
-
src/driver/Makefile.in (deleted)
-
src/driver/cc1.cc (deleted)
-
src/driver/cfa.cc (deleted)
-
src/examples/ArrayN.c (deleted)
-
src/examples/Attributes.c (deleted)
-
src/examples/Initialization.c (deleted)
-
src/examples/Initialization2.c (deleted)
-
src/examples/Makefile.am (deleted)
-
src/examples/Makefile.example (deleted)
-
src/examples/Makefile.in (deleted)
-
src/examples/Members.c (deleted)
-
src/examples/Misc.c (deleted)
-
src/examples/MiscError.c (deleted)
-
src/examples/Rank2.c (deleted)
-
src/examples/Tuple.c (deleted)
-
src/examples/abstype.c (deleted)
-
src/examples/constructors.c (deleted)
-
src/examples/forward.c (deleted)
-
src/examples/gc_no_raii/.gitignore (deleted)
-
src/examples/gc_no_raii/bug-repro/assert.c (deleted)
-
src/examples/gc_no_raii/bug-repro/blockers.tar.gz (deleted)
-
src/examples/gc_no_raii/bug-repro/blockers/explicit_cast.c (deleted)
-
src/examples/gc_no_raii/bug-repro/blockers/file_scope.c (deleted)
-
src/examples/gc_no_raii/bug-repro/blockers/recursive_realloc.c (deleted)
-
src/examples/gc_no_raii/bug-repro/crash.c (deleted)
-
src/examples/gc_no_raii/bug-repro/deref.c (deleted)
-
src/examples/gc_no_raii/bug-repro/field.c (deleted)
-
src/examples/gc_no_raii/bug-repro/find.c (deleted)
-
src/examples/gc_no_raii/bug-repro/inline.c (deleted)
-
src/examples/gc_no_raii/bug-repro/malloc.c (deleted)
-
src/examples/gc_no_raii/bug-repro/not_equal.c (deleted)
-
src/examples/gc_no_raii/bug-repro/oddtype.c (deleted)
-
src/examples/gc_no_raii/bug-repro/push_back.c (deleted)
-
src/examples/gc_no_raii/bug-repro/push_back.h (deleted)
-
src/examples/gc_no_raii/bug-repro/realloc.c (deleted)
-
src/examples/gc_no_raii/bug-repro/return.c (deleted)
-
src/examples/gc_no_raii/bug-repro/return_template.c (deleted)
-
src/examples/gc_no_raii/bug-repro/slow_malloc.c (deleted)
-
src/examples/gc_no_raii/bug-repro/static_const_local.c (deleted)
-
src/examples/gc_no_raii/bug-repro/test-assert.cpp (deleted)
-
src/examples/gc_no_raii/bug-repro/void_pointer.c (deleted)
-
src/examples/gc_no_raii/bug-repro/while.c (deleted)
-
src/examples/gc_no_raii/bug-repro/zero.c (deleted)
-
src/examples/gc_no_raii/pool-alloc/allocate-malign.c (deleted)
-
src/examples/gc_no_raii/pool-alloc/allocate-malloc.c (deleted)
-
src/examples/gc_no_raii/pool-alloc/allocate-mmap.c (deleted)
-
src/examples/gc_no_raii/pool-alloc/allocate-win-valloc.c (deleted)
-
src/examples/gc_no_raii/premake4.lua (deleted)
-
src/examples/gc_no_raii/src/allocate-pool.c (deleted)
-
src/examples/gc_no_raii/src/allocate-pool.h (deleted)
-
src/examples/gc_no_raii/src/gc.h (deleted)
-
src/examples/gc_no_raii/src/gcpointers.c (deleted)
-
src/examples/gc_no_raii/src/gcpointers.h (deleted)
-
src/examples/gc_no_raii/src/internal/card_table.h (deleted)
-
src/examples/gc_no_raii/src/internal/collector.c (deleted)
-
src/examples/gc_no_raii/src/internal/collector.h (deleted)
-
src/examples/gc_no_raii/src/internal/gc_tools.h (deleted)
-
src/examples/gc_no_raii/src/internal/globals.h (deleted)
-
src/examples/gc_no_raii/src/internal/memory_pool.c (deleted)
-
src/examples/gc_no_raii/src/internal/memory_pool.h (deleted)
-
src/examples/gc_no_raii/src/internal/object_header.c (deleted)
-
src/examples/gc_no_raii/src/internal/object_header.h (deleted)
-
src/examples/gc_no_raii/src/internal/state.c (deleted)
-
src/examples/gc_no_raii/src/internal/state.h (deleted)
-
src/examples/gc_no_raii/src/test_include.c (deleted)
-
src/examples/gc_no_raii/src/tools.h (deleted)
-
src/examples/gc_no_raii/src/tools/checks.h (deleted)
-
src/examples/gc_no_raii/src/tools/print.c (deleted)
-
src/examples/gc_no_raii/src/tools/print.h (deleted)
-
src/examples/gc_no_raii/src/tools/worklist.h (deleted)
-
src/examples/gc_no_raii/test/badlll.c (deleted)
-
src/examples/gc_no_raii/test/gctest.c (deleted)
-
src/examples/gc_no_raii/test/operators.c (deleted)
-
src/examples/huge.c (deleted)
-
src/examples/includes.c (deleted)
-
src/examples/index.h (deleted)
-
src/examples/it_out.c (deleted)
-
src/examples/multicore.c (deleted)
-
src/examples/new.c (deleted)
-
src/examples/poly-bench.c (deleted)
-
src/examples/prolog.c (deleted)
-
src/examples/quad.c (deleted)
-
src/examples/s.c (deleted)
-
src/examples/simplePoly.c (deleted)
-
src/examples/simpler.c (deleted)
-
src/examples/specialize.c (deleted)
-
src/examples/square.c (deleted)
-
src/examples/twice.c (deleted)
-
src/examples/wrapper/.gitignore (deleted)
-
src/examples/wrapper/premake4.lua (deleted)
-
src/examples/wrapper/src/main.c (deleted)
-
src/examples/wrapper/src/pointer.h (deleted)
-
src/examples/zero_one.c (deleted)
-
src/include/cassert (modified) (4 diffs)
-
src/include/optional (added)
-
src/libcfa/Makefile.am (deleted)
-
src/libcfa/Makefile.in (deleted)
-
src/libcfa/assert.c (deleted)
-
src/libcfa/bits/algorithms.h (deleted)
-
src/libcfa/bits/align.h (deleted)
-
src/libcfa/bits/containers.h (deleted)
-
src/libcfa/bits/debug.c (deleted)
-
src/libcfa/bits/debug.h (deleted)
-
src/libcfa/bits/defs.h (deleted)
-
src/libcfa/bits/locks.h (deleted)
-
src/libcfa/bits/signal.h (deleted)
-
src/libcfa/clock (deleted)
-
src/libcfa/concurrency/CtxSwitch-armv7l.S (deleted)
-
src/libcfa/concurrency/CtxSwitch-i386.S (deleted)
-
src/libcfa/concurrency/CtxSwitch-i686.S (deleted)
-
src/libcfa/concurrency/CtxSwitch-x86_64.S (deleted)
-
src/libcfa/concurrency/alarm.c (deleted)
-
src/libcfa/concurrency/alarm.h (deleted)
-
src/libcfa/concurrency/coroutine (deleted)
-
src/libcfa/concurrency/coroutine.c (deleted)
-
src/libcfa/concurrency/invoke.c (deleted)
-
src/libcfa/concurrency/invoke.h (deleted)
-
src/libcfa/concurrency/kernel (deleted)
-
src/libcfa/concurrency/kernel.c (deleted)
-
src/libcfa/concurrency/kernel_private.h (deleted)
-
src/libcfa/concurrency/monitor (deleted)
-
src/libcfa/concurrency/monitor.c (deleted)
-
src/libcfa/concurrency/mutex (deleted)
-
src/libcfa/concurrency/mutex.c (deleted)
-
src/libcfa/concurrency/preemption.c (deleted)
-
src/libcfa/concurrency/preemption.h (deleted)
-
src/libcfa/concurrency/thread (deleted)
-
src/libcfa/concurrency/thread.c (deleted)
-
src/libcfa/containers/maybe (deleted)
-
src/libcfa/containers/maybe.c (deleted)
-
src/libcfa/containers/pair (deleted)
-
src/libcfa/containers/pair.c (deleted)
-
src/libcfa/containers/result (deleted)
-
src/libcfa/containers/result.c (deleted)
-
src/libcfa/containers/vector (deleted)
-
src/libcfa/containers/vector.c (deleted)
-
src/libcfa/exception.c (deleted)
-
src/libcfa/exception.h (deleted)
-
src/libcfa/expat.h (deleted)
-
src/libcfa/fstream (deleted)
-
src/libcfa/fstream.c (deleted)
-
src/libcfa/gmp (deleted)
-
src/libcfa/interpose.c (deleted)
-
src/libcfa/iostream (deleted)
-
src/libcfa/iostream.c (deleted)
-
src/libcfa/iterator (deleted)
-
src/libcfa/iterator.c (deleted)
-
src/libcfa/limits (deleted)
-
src/libcfa/limits.c (deleted)
-
src/libcfa/lsda.h (deleted)
-
src/libcfa/math (deleted)
-
src/libcfa/memcheck.awk (deleted)
-
src/libcfa/rational (deleted)
-
src/libcfa/rational.c (deleted)
-
src/libcfa/startup.h (deleted)
-
src/libcfa/stdhdr/assert.h (deleted)
-
src/libcfa/stdhdr/bfdlink.h (deleted)
-
src/libcfa/stdhdr/complex.h (deleted)
-
src/libcfa/stdhdr/ctype.h (deleted)
-
src/libcfa/stdhdr/errno.h (deleted)
-
src/libcfa/stdhdr/fenv.h (deleted)
-
src/libcfa/stdhdr/float.h (deleted)
-
src/libcfa/stdhdr/gmp.h (deleted)
-
src/libcfa/stdhdr/hwloc.h (deleted)
-
src/libcfa/stdhdr/inttypes.h (deleted)
-
src/libcfa/stdhdr/iso646.h (deleted)
-
src/libcfa/stdhdr/krb5.h (deleted)
-
src/libcfa/stdhdr/limits.h (deleted)
-
src/libcfa/stdhdr/locale.h (deleted)
-
src/libcfa/stdhdr/malloc.h (deleted)
-
src/libcfa/stdhdr/math.h (deleted)
-
src/libcfa/stdhdr/setjmp.h (deleted)
-
src/libcfa/stdhdr/signal.h (deleted)
-
src/libcfa/stdhdr/stdalign.h (deleted)
-
src/libcfa/stdhdr/stdarg.h (deleted)
-
src/libcfa/stdhdr/stdatomic.h (deleted)
-
src/libcfa/stdhdr/stdbool.h (deleted)
-
src/libcfa/stdhdr/stddef.h (deleted)
-
src/libcfa/stdhdr/stdint.h (deleted)
-
src/libcfa/stdhdr/stdio.h (deleted)
-
src/libcfa/stdhdr/stdlib.h (deleted)
-
src/libcfa/stdhdr/stdnoreturn.h (deleted)
-
src/libcfa/stdhdr/string.h (deleted)
-
src/libcfa/stdhdr/sys/ucontext.h (deleted)
-
src/libcfa/stdhdr/tgmath.h (deleted)
-
src/libcfa/stdhdr/threads.h (deleted)
-
src/libcfa/stdhdr/time.h (deleted)
-
src/libcfa/stdhdr/uchar.h (deleted)
-
src/libcfa/stdhdr/unistd.h (deleted)
-
src/libcfa/stdhdr/wchar.h (deleted)
-
src/libcfa/stdhdr/wctype.h (deleted)
-
src/libcfa/stdlib (deleted)
-
src/libcfa/stdlib.c (deleted)
-
src/libcfa/time (deleted)
-
src/libcfa/time.c (deleted)
-
src/libcfa/time_t.h (deleted)
-
src/libcfa/virtual.c (deleted)
-
src/libcfa/virtual.h (deleted)
-
src/main.cc (modified) (22 diffs)
-
src/prelude/Makefile.am (deleted)
-
src/prelude/Makefile.in (deleted)
-
src/prelude/bootloader.cf (deleted)
-
src/prelude/builtins.c (deleted)
-
src/prelude/builtins.def (deleted)
-
src/prelude/extras.c (deleted)
-
src/prelude/extras.regx (deleted)
-
src/prelude/prelude.cf (deleted)
-
src/prelude/prototypes.awk (deleted)
-
src/prelude/prototypes.c (deleted)
-
src/prelude/prototypes.sed (deleted)
-
src/prelude/sync-builtins.cf (deleted)
-
src/prelude/sync-builtins.def (deleted)
-
src/tests/.expect/KRfunctions.x64.txt (deleted)
-
src/tests/.expect/KRfunctions.x86.txt (deleted)
-
src/tests/.expect/abs.txt (deleted)
-
src/tests/.expect/alloc-ERROR.txt (deleted)
-
src/tests/.expect/alloc.txt (deleted)
-
src/tests/.expect/array.txt (deleted)
-
src/tests/.expect/ato.txt (deleted)
-
src/tests/.expect/attributes.x64.txt (deleted)
-
src/tests/.expect/attributes.x86.txt (deleted)
-
src/tests/.expect/avl_test.txt (deleted)
-
src/tests/.expect/cast.txt (deleted)
-
src/tests/.expect/castError.txt (deleted)
-
src/tests/.expect/completeTypeError.txt (deleted)
-
src/tests/.expect/complex.txt (deleted)
-
src/tests/.expect/counter.txt (deleted)
-
src/tests/.expect/declarationErrors.txt (deleted)
-
src/tests/.expect/declarationSpecifier.x64.txt (deleted)
-
src/tests/.expect/declarationSpecifier.x86.txt (deleted)
-
src/tests/.expect/designations.txt (deleted)
-
src/tests/.expect/div.txt (deleted)
-
src/tests/.expect/enum.txt (deleted)
-
src/tests/.expect/expression.txt (deleted)
-
src/tests/.expect/extension.x64.txt (deleted)
-
src/tests/.expect/extension.x86.txt (deleted)
-
src/tests/.expect/fallthrough.txt (deleted)
-
src/tests/.expect/fstream_test.txt (deleted)
-
src/tests/.expect/function-operator.txt (deleted)
-
src/tests/.expect/functions.x64.txt (deleted)
-
src/tests/.expect/functions.x86.txt (deleted)
-
src/tests/.expect/gccExtensions.x64.txt (deleted)
-
src/tests/.expect/gccExtensions.x86.txt (deleted)
-
src/tests/.expect/genericUnion.txt (deleted)
-
src/tests/.expect/gmp.x64.txt (deleted)
-
src/tests/.expect/hello.txt (deleted)
-
src/tests/.expect/identFuncDeclarator.txt (deleted)
-
src/tests/.expect/identParamDeclarator.txt (deleted)
-
src/tests/.expect/identity.txt (deleted)
-
src/tests/.expect/ifwhileCtl.txt (deleted)
-
src/tests/.expect/io1.txt (deleted)
-
src/tests/.expect/io2.txt (deleted)
-
src/tests/.expect/labelledExit.txt (deleted)
-
src/tests/.expect/limits.txt (deleted)
-
src/tests/.expect/literals.txt (deleted)
-
src/tests/.expect/math1.x64.txt (deleted)
-
src/tests/.expect/math1.x86.txt (deleted)
-
src/tests/.expect/math2.x64.txt (deleted)
-
src/tests/.expect/math2.x86.txt (deleted)
-
src/tests/.expect/math3.x64.txt (deleted)
-
src/tests/.expect/math3.x86.txt (deleted)
-
src/tests/.expect/math4.x64.txt (deleted)
-
src/tests/.expect/maybe.txt (deleted)
-
src/tests/.expect/minmax.txt (deleted)
-
src/tests/.expect/numericConstants.txt (deleted)
-
src/tests/.expect/operators.txt (deleted)
-
src/tests/.expect/polymorphism.txt (deleted)
-
src/tests/.expect/quoted_keyword.txt (deleted)
-
src/tests/.expect/random.txt (deleted)
-
src/tests/.expect/rational.txt (deleted)
-
src/tests/.expect/references.txt (deleted)
-
src/tests/.expect/result.txt (deleted)
-
src/tests/.expect/scopeErrors.txt (deleted)
-
src/tests/.expect/searchsort.txt (deleted)
-
src/tests/.expect/shortCircuit.txt (deleted)
-
src/tests/.expect/simpleGenericTriple.txt (deleted)
-
src/tests/.expect/stdincludes.txt (deleted)
-
src/tests/.expect/sum.txt (deleted)
-
src/tests/.expect/swap.txt (deleted)
-
src/tests/.expect/switch.txt (deleted)
-
src/tests/.expect/time.x64.txt (deleted)
-
src/tests/.expect/time.x86.txt (deleted)
-
src/tests/.expect/typedefRedef-ERR1.txt (deleted)
-
src/tests/.expect/typedefRedef.txt (deleted)
-
src/tests/.expect/typeof.txt (deleted)
-
src/tests/.expect/user_literals.txt (deleted)
-
src/tests/.expect/variableDeclarator.txt (deleted)
-
src/tests/.expect/vector.txt (deleted)
-
src/tests/.expect/voidPtr.txt (deleted)
-
src/tests/.expect/with-statement.txt (deleted)
-
src/tests/.gitignore (deleted)
-
src/tests/.in/fstream_test.txt (deleted)
-
src/tests/.in/gmp.txt (deleted)
-
src/tests/.in/rational.txt (deleted)
-
src/tests/KRfunctions.c (deleted)
-
src/tests/Makefile.am (deleted)
-
src/tests/Makefile.in (deleted)
-
src/tests/abs.c (deleted)
-
src/tests/alloc.c (deleted)
-
src/tests/array.c (deleted)
-
src/tests/ato.c (deleted)
-
src/tests/attributes.c (deleted)
-
src/tests/avltree/avl-private.c (deleted)
-
src/tests/avltree/avl-private.h (deleted)
-
src/tests/avltree/avl.h (deleted)
-
src/tests/avltree/avl0.c (deleted)
-
src/tests/avltree/avl1.c (deleted)
-
src/tests/avltree/avl2.c (deleted)
-
src/tests/avltree/avl3.c (deleted)
-
src/tests/avltree/avl4.c (deleted)
-
src/tests/avltree/avl_test.c (deleted)
-
src/tests/builtins/.expect/sync.txt (deleted)
-
src/tests/builtins/sync.c (deleted)
-
src/tests/cast.c (deleted)
-
src/tests/castError.c (deleted)
-
src/tests/commentMisc.c (deleted)
-
src/tests/completeTypeError.c (deleted)
-
src/tests/complex.c (deleted)
-
src/tests/concurrent/.expect/coroutineYield.txt (deleted)
-
src/tests/concurrent/.expect/monitor.txt (deleted)
-
src/tests/concurrent/.expect/multi-monitor.txt (deleted)
-
src/tests/concurrent/.expect/preempt.txt (deleted)
-
src/tests/concurrent/.expect/thread.txt (deleted)
-
src/tests/concurrent/coroutineYield.c (deleted)
-
src/tests/concurrent/examples/.expect/boundedBufferEXT.txt (deleted)
-
src/tests/concurrent/examples/.expect/boundedBufferINT.txt (deleted)
-
src/tests/concurrent/examples/.expect/datingService.txt (deleted)
-
src/tests/concurrent/examples/.expect/matrixSum.txt (deleted)
-
src/tests/concurrent/examples/.expect/quickSort.txt (deleted)
-
src/tests/concurrent/examples/.in/quickSort.txt (deleted)
-
src/tests/concurrent/examples/boundedBufferEXT.c (deleted)
-
src/tests/concurrent/examples/boundedBufferINT.c (deleted)
-
src/tests/concurrent/examples/datingService.c (deleted)
-
src/tests/concurrent/examples/matrixSum.c (deleted)
-
src/tests/concurrent/examples/quickSort.c (deleted)
-
src/tests/concurrent/monitor.c (deleted)
-
src/tests/concurrent/multi-monitor.c (deleted)
-
src/tests/concurrent/preempt.c (deleted)
-
src/tests/concurrent/signal/.expect/block.txt (deleted)
-
src/tests/concurrent/signal/.expect/disjoint.txt (deleted)
-
src/tests/concurrent/signal/.expect/wait.txt (deleted)
-
src/tests/concurrent/signal/block.c (deleted)
-
src/tests/concurrent/signal/disjoint.c (deleted)
-
src/tests/concurrent/signal/wait.c (deleted)
-
src/tests/concurrent/thread.c (deleted)
-
src/tests/concurrent/waitfor/.expect/barge.txt (deleted)
-
src/tests/concurrent/waitfor/.expect/dtor.txt (deleted)
-
src/tests/concurrent/waitfor/.expect/else.txt (deleted)
-
src/tests/concurrent/waitfor/.expect/recurse.txt (deleted)
-
src/tests/concurrent/waitfor/.expect/statment.txt (deleted)
-
src/tests/concurrent/waitfor/.expect/when.txt (deleted)
-
src/tests/concurrent/waitfor/barge.c (deleted)
-
src/tests/concurrent/waitfor/dtor.c (deleted)
-
src/tests/concurrent/waitfor/else.c (deleted)
-
src/tests/concurrent/waitfor/parse.c (deleted)
-
src/tests/concurrent/waitfor/parse2.c (deleted)
-
src/tests/concurrent/waitfor/recurse.c (deleted)
-
src/tests/concurrent/waitfor/simple.c (deleted)
-
src/tests/concurrent/waitfor/statment.c (deleted)
-
src/tests/concurrent/waitfor/when.c (deleted)
-
src/tests/context.c (deleted)
-
src/tests/coroutine/.expect/fibonacci.txt (deleted)
-
src/tests/coroutine/.expect/fmtLines.txt (deleted)
-
src/tests/coroutine/.expect/pingpong.txt (deleted)
-
src/tests/coroutine/.expect/prodcons.txt (deleted)
-
src/tests/coroutine/.expect/runningTotal.txt (deleted)
-
src/tests/coroutine/.in/fmtLines.txt (deleted)
-
src/tests/coroutine/fibonacci.c (deleted)
-
src/tests/coroutine/fmtLines.c (deleted)
-
src/tests/coroutine/pingpong.c (deleted)
-
src/tests/coroutine/prodcons.c (deleted)
-
src/tests/coroutine/runningTotal.c (deleted)
-
src/tests/counter.c (deleted)
-
src/tests/declarationErrors.c (deleted)
-
src/tests/declarationSpecifier.c (deleted)
-
src/tests/designations.c (deleted)
-
src/tests/div.c (deleted)
-
src/tests/enum.c (deleted)
-
src/tests/except-0.c (deleted)
-
src/tests/except-1.c (deleted)
-
src/tests/except-2.c (deleted)
-
src/tests/except-3.c (deleted)
-
src/tests/except-mac.h (deleted)
-
src/tests/expression.c (deleted)
-
src/tests/extension.c (deleted)
-
src/tests/fallthrough.c (deleted)
-
src/tests/forall.c (deleted)
-
src/tests/fstream_test.c (deleted)
-
src/tests/function-operator.c (deleted)
-
src/tests/functions.c (deleted)
-
src/tests/gccExtensions.c (deleted)
-
src/tests/genericUnion.c (deleted)
-
src/tests/gmp.c (deleted)
-
src/tests/hello.c (deleted)
-
src/tests/identFuncDeclarator.c (deleted)
-
src/tests/identParamDeclarator.c (deleted)
-
src/tests/identity.c (deleted)
-
src/tests/ifwhileCtl.c (deleted)
-
src/tests/io.data (deleted)
-
src/tests/io1.c (deleted)
-
src/tests/io2.c (deleted)
-
src/tests/labelledExit.c (deleted)
-
src/tests/limits.c (deleted)
-
src/tests/literals.c (deleted)
-
src/tests/math1.c (deleted)
-
src/tests/math2.c (deleted)
-
src/tests/math3.c (deleted)
-
src/tests/math4.c (deleted)
-
src/tests/maybe.c (deleted)
-
src/tests/minmax.c (deleted)
-
src/tests/namedParmArg.c (deleted)
-
src/tests/numericConstants.c (deleted)
-
src/tests/occursError.c (deleted)
-
src/tests/operators.c (deleted)
-
src/tests/polymorphism.c (deleted)
-
src/tests/preempt_longrun/Makefile.am (deleted)
-
src/tests/preempt_longrun/Makefile.in (deleted)
-
src/tests/preempt_longrun/block.c (deleted)
-
src/tests/preempt_longrun/coroutine.c (deleted)
-
src/tests/preempt_longrun/create.c (deleted)
-
src/tests/preempt_longrun/disjoint.c (deleted)
-
src/tests/preempt_longrun/enter.c (deleted)
-
src/tests/preempt_longrun/enter3.c (deleted)
-
src/tests/preempt_longrun/preempt.c (deleted)
-
src/tests/preempt_longrun/processor.c (deleted)
-
src/tests/preempt_longrun/stack.c (deleted)
-
src/tests/preempt_longrun/wait.c (deleted)
-
src/tests/preempt_longrun/yield.c (deleted)
-
src/tests/pybin/__init__.py (deleted)
-
src/tests/pybin/settings.py (deleted)
-
src/tests/pybin/test_run.py (deleted)
-
src/tests/pybin/tools.py (deleted)
-
src/tests/quoted_keyword.c (deleted)
-
src/tests/raii/.expect/ctor-autogen-ERR1.txt (deleted)
-
src/tests/raii/.expect/ctor-autogen.txt (deleted)
-
src/tests/raii/.expect/dtor-early-exit-ERR1.txt (deleted)
-
src/tests/raii/.expect/dtor-early-exit-ERR2.txt (deleted)
-
src/tests/raii/.expect/dtor-early-exit.txt (deleted)
-
src/tests/raii/.expect/globals.txt (deleted)
-
src/tests/raii/.expect/init_once.txt (deleted)
-
src/tests/raii/.expect/memberCtors-ERR1.txt (deleted)
-
src/tests/raii/.expect/memberCtors.txt (deleted)
-
src/tests/raii/ctor-autogen.c (deleted)
-
src/tests/raii/dtor-early-exit.c (deleted)
-
src/tests/raii/globals.c (deleted)
-
src/tests/raii/init_once.c (deleted)
-
src/tests/raii/memberCtors.c (deleted)
-
src/tests/raii/multiDimension.c (deleted)
-
src/tests/raii/multiDimension.txt (deleted)
-
src/tests/random.c (deleted)
-
src/tests/rational.c (deleted)
-
src/tests/references.c (deleted)
-
src/tests/result.c (deleted)
-
src/tests/scope.c (deleted)
-
src/tests/scopeErrors.c (deleted)
-
src/tests/searchsort.c (deleted)
-
src/tests/shortCircuit.c (deleted)
-
src/tests/simpleGenericTriple.c (deleted)
-
src/tests/stdincludes.c (deleted)
-
src/tests/structMember.c (deleted)
-
src/tests/subrange.c (deleted)
-
src/tests/sum.c (deleted)
-
src/tests/swap.c (deleted)
-
src/tests/switch.c (deleted)
-
src/tests/test.py (deleted)
-
src/tests/time.c (deleted)
-
src/tests/tuple/.expect/tupleAssign.txt (deleted)
-
src/tests/tuple/.expect/tupleCast.txt (deleted)
-
src/tests/tuple/.expect/tupleFunction.txt (deleted)
-
src/tests/tuple/.expect/tupleMember.txt (deleted)
-
src/tests/tuple/.expect/tuplePolymorphism.txt (deleted)
-
src/tests/tuple/.expect/tupleVariadic.txt (deleted)
-
src/tests/tuple/tupleAssign.c (deleted)
-
src/tests/tuple/tupleCast.c (deleted)
-
src/tests/tuple/tupleFunction.c (deleted)
-
src/tests/tuple/tupleMember.c (deleted)
-
src/tests/tuple/tuplePolymorphism.c (deleted)
-
src/tests/tuple/tupleVariadic.c (deleted)
-
src/tests/tuple/tuples.c (deleted)
-
src/tests/typeGenerator.c (deleted)
-
src/tests/typedef.c (deleted)
-
src/tests/typedefDeclarator.c (deleted)
-
src/tests/typedefRedef.c (deleted)
-
src/tests/typeof.c (deleted)
-
src/tests/user_literals.c (deleted)
-
src/tests/variableDeclarator.c (deleted)
-
src/tests/vector.c (deleted)
-
src/tests/virtualCast.c (deleted)
-
src/tests/voidPtr.c (deleted)
-
src/tests/warnings/.expect/self-assignment.txt (deleted)
-
src/tests/warnings/self-assignment.c (deleted)
-
src/tests/with-statement.c (deleted)
-
tests/.expect/KRfunctions.x64.txt (added)
-
tests/.expect/KRfunctions.x86.txt (added)
-
tests/.expect/abs.txt (added)
-
tests/.expect/alloc-ERROR.txt (added)
-
tests/.expect/alloc.txt (added)
-
tests/.expect/array.txt (added)
-
tests/.expect/ato.txt (added)
-
tests/.expect/attributes.x64.txt (added)
-
tests/.expect/attributes.x86.txt (added)
-
tests/.expect/avl_test.txt (added)
-
tests/.expect/cast.txt (added)
-
tests/.expect/castError.txt (added)
-
tests/.expect/completeTypeError.txt (added)
-
tests/.expect/complex.txt (added)
-
tests/.expect/copyfile.txt (added)
-
tests/.expect/counter.txt (added)
-
tests/.expect/declarationErrors.txt (added)
-
tests/.expect/declarationSpecifier.x64.txt (added)
-
tests/.expect/declarationSpecifier.x86.txt (added)
-
tests/.expect/designations.txt (added)
-
tests/.expect/div.txt (added)
-
tests/.expect/enum.txt (added)
-
tests/.expect/expression.txt (added)
-
tests/.expect/extension.x64.txt (added)
-
tests/.expect/extension.x86.txt (added)
-
tests/.expect/fallthrough.txt (added)
-
tests/.expect/forall.txt (added)
-
tests/.expect/fstream_test.txt (added)
-
tests/.expect/function-operator.txt (added)
-
tests/.expect/functions.x64.txt (added)
-
tests/.expect/functions.x86.txt (added)
-
tests/.expect/gccExtensions.x64.txt (added)
-
tests/.expect/gccExtensions.x86.txt (added)
-
tests/.expect/genericUnion.txt (added)
-
tests/.expect/gmp.x64.txt (added)
-
tests/.expect/heap.txt (added)
-
tests/.expect/hello.txt (added)
-
tests/.expect/identFuncDeclarator.txt (added)
-
tests/.expect/identParamDeclarator.txt (added)
-
tests/.expect/identity.txt (added)
-
tests/.expect/ifwhileCtl.txt (added)
-
tests/.expect/io1.txt (added)
-
tests/.expect/io2.txt (added)
-
tests/.expect/labelledExit.txt (added)
-
tests/.expect/limits.txt (added)
-
tests/.expect/literals.txt (added)
-
tests/.expect/loopctrl.txt (added)
-
tests/.expect/manipulatorsInput.txt (added)
-
tests/.expect/manipulatorsOutput1.txt (added)
-
tests/.expect/manipulatorsOutput2.x64.txt (added)
-
tests/.expect/manipulatorsOutput2.x86.txt (added)
-
tests/.expect/math1.txt (added)
-
tests/.expect/math2.txt (added)
-
tests/.expect/math3.txt (added)
-
tests/.expect/math4.txt (added)
-
tests/.expect/maybe.txt (added)
-
tests/.expect/minmax.txt (added)
-
tests/.expect/nested-types-ERR1.txt (added)
-
tests/.expect/nested-types-ERR2.txt (added)
-
tests/.expect/nested-types.txt (added)
-
tests/.expect/numericConstants.txt (added)
-
tests/.expect/operators.txt (added)
-
tests/.expect/polymorphism.txt (added)
-
tests/.expect/quotedKeyword.txt (added)
-
tests/.expect/random.txt (added)
-
tests/.expect/rational.txt (added)
-
tests/.expect/references.txt (added)
-
tests/.expect/result.txt (added)
-
tests/.expect/scopeErrors.txt (added)
-
tests/.expect/searchsort.txt (added)
-
tests/.expect/shortCircuit.txt (added)
-
tests/.expect/simpleGenericTriple.txt (added)
-
tests/.expect/stdincludes.txt (added)
-
tests/.expect/sum.txt (added)
-
tests/.expect/swap.txt (added)
-
tests/.expect/switch.txt (added)
-
tests/.expect/time.txt (added)
-
tests/.expect/typedefRedef-ERR1.txt (added)
-
tests/.expect/typedefRedef.txt (added)
-
tests/.expect/typeof.txt (added)
-
tests/.expect/variableDeclarator.txt (added)
-
tests/.expect/vector.txt (added)
-
tests/.expect/voidPtr.txt (added)
-
tests/.gitignore (added)
-
tests/.in/copyfile.txt (added)
-
tests/.in/fstream_test.txt (added)
-
tests/.in/gmp.txt (added)
-
tests/.in/io.data (added)
-
tests/.in/manipulatorsInput.txt (added)
-
tests/.in/rational.txt (added)
-
tests/KRfunctions.cfa (added)
-
tests/Makefile.am (added)
-
tests/Makefile.in (added)
-
tests/abort.cfa (added)
-
tests/abs.cfa (added)
-
tests/alloc.cfa (added)
-
tests/array.cfa (added)
-
tests/ato.cfa (added)
-
tests/attributes.cfa (added)
-
tests/avltree/avl-private.cfa (added)
-
tests/avltree/avl-private.h (added)
-
tests/avltree/avl.h (added)
-
tests/avltree/avl0.cfa (added)
-
tests/avltree/avl1.cfa (added)
-
tests/avltree/avl2.cfa (added)
-
tests/avltree/avl3.cfa (added)
-
tests/avltree/avl4.cfa (added)
-
tests/avltree/avl_test.cfa (added)
-
tests/builtins/.expect/sync.txt (added)
-
tests/builtins/sync.cfa (added)
-
tests/cast.cfa (added)
-
tests/castError.cfa (added)
-
tests/commentMisc.cfa (added)
-
tests/completeTypeError.cfa (added)
-
tests/complex.cfa (added)
-
tests/concurrent/.expect/coroutineYield.txt (added)
-
tests/concurrent/.expect/monitor.txt (added)
-
tests/concurrent/.expect/multi-monitor.txt (added)
-
tests/concurrent/.expect/preempt.txt (added)
-
tests/concurrent/.expect/thread.txt (added)
-
tests/concurrent/coroutineThen.cfa (added)
-
tests/concurrent/coroutineYield.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/quickSort.cfa (added)
-
tests/concurrent/examples/quickSort.generic.cfa (added)
-
tests/concurrent/monitor.cfa (added)
-
tests/concurrent/multi-monitor.cfa (added)
-
tests/concurrent/preempt.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/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/config.py.in (added)
-
tests/context.cfa (added)
-
tests/copyfile.cfa (added)
-
tests/coroutine/.expect/devicedriver.txt (added)
-
tests/coroutine/.expect/fibonacci.txt (added)
-
tests/coroutine/.expect/fmtLines.txt (added)
-
tests/coroutine/.expect/pingpong.txt (added)
-
tests/coroutine/.expect/prodcons.txt (added)
-
tests/coroutine/.expect/raii.txt (added)
-
tests/coroutine/.expect/runningTotal.txt (added)
-
tests/coroutine/.in/devicedriver.txt (added)
-
tests/coroutine/.in/fmtLines.txt (added)
-
tests/coroutine/cntparens.cfa (added)
-
tests/coroutine/devicedriver.cfa (added)
-
tests/coroutine/fibonacci.cfa (added)
-
tests/coroutine/fibonacci_1.cfa (added)
-
tests/coroutine/fmtLines.cfa (added)
-
tests/coroutine/pingpong.cfa (added)
-
tests/coroutine/prodcons.cfa (added)
-
tests/coroutine/raii.cfa (added)
-
tests/coroutine/runningTotal.cfa (added)
-
tests/coroutine/suspend_then.cfa (added)
-
tests/counter.cfa (added)
-
tests/declarationErrors.cfa (added)
-
tests/declarationSpecifier.cfa (added)
-
tests/designations.cfa (added)
-
tests/div.cfa (added)
-
tests/enum.cfa (added)
-
tests/except-0.cfa (added)
-
tests/except-1.cfa (added)
-
tests/except-2.cfa (added)
-
tests/except-3.cfa (added)
-
tests/except-mac.hfa (added)
-
tests/expression.cfa (added)
-
tests/extension.cfa (added)
-
tests/fallthrough.cfa (added)
-
tests/forall.cfa (added)
-
tests/fstream_test.cfa (added)
-
tests/function-operator.cfa (added)
-
tests/functions.cfa (added)
-
tests/gccExtensions.cfa (added)
-
tests/genericUnion.cfa (added)
-
tests/gmp.cfa (added)
-
tests/heap.cfa (added)
-
tests/hello.cfa (added)
-
tests/identFuncDeclarator.cfa (added)
-
tests/identParamDeclarator.cfa (added)
-
tests/identity.cfa (added)
-
tests/ifwhileCtl.cfa (added)
-
tests/io1.cfa (added)
-
tests/io2.cfa (added)
-
tests/labelledExit.cfa (added)
-
tests/limits.cfa (added)
-
tests/linking/.expect/nothreads.txt (added)
-
tests/linking/.expect/withthreads.txt (added)
-
tests/linking/nothreads.cfa (added)
-
tests/linking/withthreads.cfa (added)
-
tests/literals.cfa (added)
-
tests/long_tests.hfa (added)
-
tests/loopctrl.cfa (added)
-
tests/manipulatorsInput.cfa (added)
-
tests/manipulatorsOutput1.cfa (added)
-
tests/manipulatorsOutput2.cfa (added)
-
tests/math1.cfa (added)
-
tests/math2.cfa (added)
-
tests/math3.cfa (added)
-
tests/math4.cfa (added)
-
tests/maybe.cfa (added)
-
tests/minmax.cfa (added)
-
tests/namedParmArg.cfa (added)
-
tests/nested-types.cfa (added)
-
tests/numericConstants.cfa (added)
-
tests/occursError.cfa (added)
-
tests/operators.cfa (added)
-
tests/polymorphism.cfa (added)
-
tests/pybin/__init__.py (added)
-
tests/pybin/print-core.gdb (added)
-
tests/pybin/settings.py (added)
-
tests/pybin/test_run.py (added)
-
tests/pybin/tools.py (added)
-
tests/quotedKeyword.cfa (added)
-
tests/raii/.expect/ctor-autogen-ERR1.txt (added)
-
tests/raii/.expect/ctor-autogen.txt (added)
-
tests/raii/.expect/dtor-early-exit-ERR1.txt (added)
-
tests/raii/.expect/dtor-early-exit-ERR2.txt (added)
-
tests/raii/.expect/dtor-early-exit.txt (added)
-
tests/raii/.expect/globals.txt (added)
-
tests/raii/.expect/init_once.txt (added)
-
tests/raii/.expect/memberCtors-ERR1.txt (added)
-
tests/raii/.expect/memberCtors.txt (added)
-
tests/raii/ctor-autogen.cfa (added)
-
tests/raii/dtor-early-exit.cfa (added)
-
tests/raii/globals.cfa (added)
-
tests/raii/init_once.cfa (added)
-
tests/raii/memberCtors.cfa (added)
-
tests/raii/multiDimension.cfa (added)
-
tests/raii/multiDimension.txt (added)
-
tests/random.cfa (added)
-
tests/rational.cfa (added)
-
tests/references.cfa (added)
-
tests/result.cfa (added)
-
tests/scope.cfa (added)
-
tests/scopeErrors.cfa (added)
-
tests/searchsort.cfa (added)
-
tests/shortCircuit.cfa (added)
-
tests/simpleGenericTriple.cfa (added)
-
tests/stdincludes.cfa (added)
-
tests/structMember.cfa (added)
-
tests/subrange.cfa (added)
-
tests/sum.cfa (added)
-
tests/swap.cfa (added)
-
tests/switch.cfa (added)
-
tests/test.py (added)
-
tests/time.cfa (added)
-
tests/tuple/.expect/tupleAssign.txt (added)
-
tests/tuple/.expect/tupleCast.txt (added)
-
tests/tuple/.expect/tupleFunction.txt (added)
-
tests/tuple/.expect/tupleMember.txt (added)
-
tests/tuple/.expect/tuplePolymorphism.txt (added)
-
tests/tuple/.expect/tupleVariadic.txt (added)
-
tests/tuple/tupleAssign.cfa (added)
-
tests/tuple/tupleCast.cfa (added)
-
tests/tuple/tupleFunction.cfa (added)
-
tests/tuple/tupleMember.cfa (added)
-
tests/tuple/tuplePolymorphism.cfa (added)
-
tests/tuple/tupleVariadic.cfa (added)
-
tests/tuple/tuples.cfa (added)
-
tests/typeGenerator.cfa (added)
-
tests/typedef.cfa (added)
-
tests/typedefDeclarator.cfa (added)
-
tests/typedefRedef.cfa (added)
-
tests/typeof.cfa (added)
-
tests/userLiterals.cfa (added)
-
tests/variableDeclarator.cfa (added)
-
tests/vector.cfa (added)
-
tests/virtualCast.cfa (added)
-
tests/voidPtr.cfa (added)
-
tests/warnings/.expect/self-assignment.txt (added)
-
tests/warnings/self-assignment.cfa (added)
-
tests/withStatement.cfa (added)
-
tools/Makefile.am (modified) (2 diffs)
-
tools/Makefile.in (modified) (19 diffs)
-
tools/baseline.py (added)
-
tools/build/distcc_hash (added)
-
tools/build/push2dist.sh (added)
-
tools/busy (added)
-
tools/cfa.nanorc (modified) (3 diffs)
-
tools/error (added)
-
tools/error.c (added)
-
tools/expanded-line-count.sh (added)
-
tools/prettyprinter/Makefile.am (modified) (2 diffs)
-
tools/prettyprinter/Makefile.in (modified) (25 diffs)
-
tools/stat.py (modified) (1 diff)
-
tools/watchdog (added)
-
tools/watchdog.c (added)
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r7951100 rb067d9b 8 8 config.status 9 9 config.log 10 config.py 10 11 stamp-h1 12 libtool 11 13 /Makefile 12 src/**/Makefile 13 tools/**/Makefile 14 **/Makefile 14 15 /version 15 16 … … 20 21 .deps 21 22 .dirstamp 22 bin 23 lib 24 include 25 share 23 /bin 24 /lib 25 /include 26 /share 27 /build 26 28 *.class 27 29 28 30 # src executables, for lib and bin 29 src/driver/cc1 30 src/driver/cfa 31 src/driver/cfa-cpp 31 driver/as 32 driver/cfa 33 driver/cfa-cpp 34 driver/cc1 32 35 33 src/prelude/builtins.cf 34 src/prelude/gcc-builtins.cf 35 src/prelude/gcc-builtins.c 36 src/prelude/extras.cf 37 src/prelude/bootloader.c 38 src/libcfa/libcfa-prelude.c 36 libcfa/prelude/bootloader.c 37 libcfa/prelude/builtins.cf 38 libcfa/prelude/extras.cf 39 libcfa/prelude/gcc-builtins.cf 40 libcfa/prelude/gcc-builtins.c 41 libcfa/prelude/prelude.cfa 42 libcfa/x64-debug/ 43 libcfa/x64-nodebug/ 44 libcfa/x64-nolib/ 45 libcfa/x86-debug/ 46 libcfa/x86-nodebug/ 47 libcfa/x86-nolib/ 48 libcfa/arm-debug/ 49 libcfa/arm-nodebug/ 50 libcfa/arm-nolib/ 39 51 40 52 # generated by bison and lex from parser.yy and lex.ll … … 44 56 src/Parser/parser.h 45 57 src/Parser/parser.hh 58 src/demangler 46 59 47 60 tools/prettyprinter/parser.output -
INSTALL
r7951100 rb067d9b 22 22 it is important not to put quotes around the directory path; Cforall may 23 23 appear to build, but the installed version may not work properly. 24 25 --with-backend-compiler=PROGRAM specifies the installed path of gcc. It26 defaults to the first command named 'gcc' in the current PATH.27 28 cfa-cc itself is built with the version of g++ specified by the environment29 variable CXX. If CXX is unset, cfa-cc is built using the first command named30 'g++' in the current PATH. -
Jenkins/FullBuild
r7951100 rb067d9b 17 17 18 18 parallel ( 19 gcc_6_x64: { trigger_build( 'gcc-6', 'x64', true ) }, 20 gcc_6_x86: { trigger_build( 'gcc-6', 'x86', true ) }, 21 gcc_5_x64: { trigger_build( 'gcc-5', 'x64', false ) }, 22 gcc_5_x86: { trigger_build( 'gcc-5', 'x86', false ) }, 23 gcc_4_x64: { trigger_build( 'gcc-4.9', 'x64', false ) }, 24 gcc_4_x86: { trigger_build( 'gcc-4.9', 'x86', false ) }, 25 clang_x64: { trigger_build( 'clang', 'x64', false ) }, 26 clang_x86: { trigger_build( 'clang', 'x86', false ) }, 19 gcc_6_x64: { trigger_build( 'gcc-6', 'x64' ) }, 20 gcc_6_x86: { trigger_build( 'gcc-6', 'x86' ) }, 21 gcc_5_x64: { trigger_build( 'gcc-5', 'x64' ) }, 22 gcc_5_x86: { trigger_build( 'gcc-5', 'x86' ) }, 23 clang_x64: { trigger_build( 'clang', 'x64' ) }, 24 clang_x86: { trigger_build( 'clang', 'x86' ) }, 27 25 ) 28 26 } 27 } 29 28 30 //Push latest changes to do-lang repo 31 push_build() 32 } 29 promote_email(true) 33 30 } 34 31 … … 45 42 46 43 //Send email to notify the failure 47 promote_ failure_email()44 promote_email(false) 48 45 } 49 46 … … 59 56 //=========================================================================================================== 60 57 61 def trigger_build(String cc, String arch , Boolean publish) {58 def trigger_build(String cc, String arch) { 62 59 def result = build job: 'Cforall/master', \ 63 60 parameters: [ \ 64 61 [$class: 'StringParameterValue', \ 65 name: ' pCompiler', \62 name: 'Compiler', \ 66 63 value: cc], \ 67 64 [$class: 'StringParameterValue', \ 68 name: ' pArchitecture', \65 name: 'Architecture', \ 69 66 value: arch], \ 70 67 [$class: 'BooleanParameterValue', \ 71 name: ' pRunAllTests',\68 name: 'RunAllTests', \ 72 69 value: true], \ 73 70 [$class: 'BooleanParameterValue', \ 74 name: ' pRunBenchmark', \71 name: 'RunBenchmark', \ 75 72 value: true], \ 76 73 [$class: 'BooleanParameterValue', \ 77 name: ' pBuildDocumentation', \74 name: 'BuildDocumentation', \ 78 75 value: true], \ 79 76 [$class: 'BooleanParameterValue', \ 80 name: ' pPublish', \81 value: publish],\77 name: 'Publish', \ 78 value: true], \ 82 79 [$class: 'BooleanParameterValue', \ 83 name: ' pSilent', \80 name: 'Silent', \ 84 81 value: true], \ 85 82 ], \ … … 89 86 90 87 if(result.result != 'SUCCESS') { 91 sh("wget -q -O - ${result.absoluteUrl}/consoleText")88 sh("wget -q -O - http://localhost:8084/jenkins/job/Cforall/job/master/${result.number}/consoleText") 92 89 error(result.result) 93 }94 }95 96 def push_build() {97 //Don't use the build_stage function which outputs the compiler98 stage('Push') {99 100 status_prefix = 'Push'101 102 def out_dir = pwd tmp: true103 sh "mkdir -p ${out_dir}"104 105 //checkout the code to make sure this is a valid git repo106 checkout scm107 108 collect_git_info()109 110 //parse git logs to find what changed111 sh "git remote > ${out_dir}/GIT_REMOTE"112 git_remote = readFile("${out_dir}/GIT_REMOTE")113 remoteDoLangExists = git_remote.contains("DoLang")114 115 if( !remoteDoLangExists ) {116 sh 'git remote add DoLang git@gitlab.do-lang.org:internal/cfa-cc.git'117 }118 119 //sh "GIT_SSH_COMMAND=\"ssh -v\" git push DoLang ${gitRefNewValue}:master"120 echo('BUILD NOT PUSH SINCE DO-LANG SERVER WAS DOWN')121 90 } 122 91 } … … 143 112 144 113 //Email notification on a full build failure 145 def promote_ failure_email() {114 def promote_email(boolean success) { 146 115 echo('notifying users') 116 117 def result = success ? "PROMOTE - SUCCESS" : "PROMOTE - FAILURE" 147 118 148 119 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line 149 120 //Configurations for email format 150 def email_subject = "[cforall git][PROMOTE - FAILURE]" 151 def email_body = """This is an automated email from the Jenkins build machine. It was 152 generated because of a git hooks/post-receive script following 153 a ref change was pushed to the repository containing 154 the project "UNNAMED PROJECT". 121 def email_subject = "[cforall git][${result}]" 122 def email_body = """<p>This is an automated email from the Jenkins build machine. It was 123 generated following the result of the C\u2200 nightly build.</p> 155 124 156 Check console output at ${env.BUILD_URL} to view the results. 125 <p>Check console output at ${env.BUILD_URL} to view the results.</p> 157 126 158 - Status -------------------------------------------------------------- 127 <p>- Status --------------------------------------------------------------</p> 159 128 160 PROMOTE FAILURE 129 <p>${result}</p> 130 131 <p>- Performance ---------------------------------------------------------</p> 132 133 <img src="https://cforall.uwaterloo.ca/jenkins/job/Cforall/job/master/plot/Compilation/getPlot?index=0" > 134 <img src="https://cforall.uwaterloo.ca/jenkins/job/Cforall/job/master/plot/Compilation/getPlot?index=1" > 135 136 <p>- Logs ----------------------------------------------------------------</p> 161 137 """ 162 138 … … 164 140 165 141 //send email notification 166 emailext body: email_body, subject: email_subject, to: email_to, attachLog: true142 emailext body: email_body, subject: email_subject, to: email_to, attachLog: !success 167 143 } -
Jenkins/TestRegen
r7951100 rb067d9b 70 70 //escapes the sandbox 71 71 //Also specify the compiler by hand 72 sh "./configure CXX=clang++ --host=${arch} --with-backend-compiler=gcc-6 --prefix=${install_dir} --enable-silent-rules --quiet"72 sh "./configure CXX=clang++ CC=gcc-6 --host=${arch} --enable-silent-rules --quiet" 73 73 74 74 //Compile the project 75 sh 'make -j 8 --no-print-directory install'75 sh 'make -j 8 --no-print-directory' 76 76 77 77 //Regenerate the desired tests -
Jenkinsfile
r7951100 rb067d9b 1 1 #!groovy 2 2 3 import groovy.transform.Field 4 5 // For skipping stages 6 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils 7 3 8 //=========================================================================================================== 4 9 // Main loop of the compilation 5 10 //=========================================================================================================== 6 node ('master'){ 7 8 boolean bIsSandbox = env.BRANCH_NAME == "jenkins-sandbox" 11 12 node('master') { 13 // Globals 14 BuildDir = pwd tmp: true 15 SrcDir = pwd tmp: false 16 Settings = null 17 StageName = '' 18 19 // Local variables 9 20 def err = null 10 21 def log_needed = false 11 12 stage_name = ''13 14 compiler = null15 arch_name = ''16 architecture = ''17 18 do_alltests = false19 do_benchmark = false20 do_doc = false21 do_publish = false22 do_sendemail = true23 22 24 23 currentBuild.result = "SUCCESS" … … 28 27 wrap([$class: 'TimestamperBuildWrapper']) { 29 28 30 notify_server(0) 31 32 prepare_build() 33 34 checkout() 35 36 notify_server(0) 37 38 build() 39 40 test() 41 42 benchmark() 43 44 clean() 45 46 build_doc() 47 48 publish() 49 50 notify_server(45) 29 Settings = prepare_build() 30 31 node(Settings.Architecture.node) { 32 BuildDir = pwd tmp: true 33 SrcDir = pwd tmp: false 34 35 clean() 36 37 checkout() 38 39 build() 40 41 test() 42 43 benchmark() 44 45 build_doc() 46 47 publish() 48 } 49 50 // Update the build directories when exiting the node 51 BuildDir = pwd tmp: true 52 SrcDir = pwd tmp: false 51 53 } 52 54 } … … 58 60 err = caughtError 59 61 62 echo err.toString() 63 60 64 //An error has occured, the build log is relevent 61 65 log_needed = true 62 66 63 67 //Store the result of the build log 64 currentBuild.result = "${ stage_name} FAILURE".trim()68 currentBuild.result = "${StageName} FAILURE".trim() 65 69 } 66 70 67 71 finally { 68 72 //Send email with final results if this is not a full build 69 if( do_sendemail && !bIsSandbox ) { 70 echo 'Notifying users of result' 71 email(currentBuild.result, log_needed) 72 } 73 email(log_needed) 73 74 74 75 echo 'Build Completed' … … 80 81 } 81 82 } 83 //=========================================================================================================== 84 // Main compilation routines 85 //=========================================================================================================== 86 def clean() { 87 build_stage('Cleanup', true) { 88 // clean the build by wipping the build directory 89 dir(BuildDir) { 90 deleteDir() 91 } 92 } 93 } 94 95 //Compilation script is done here but environnement set-up and error handling is done in main loop 96 def checkout() { 97 build_stage('Checkout', true) { 98 //checkout the source code and clean the repo 99 final scmVars = checkout scm 100 Settings.GitNewRef = scmVars.GIT_COMMIT 101 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT 102 103 echo GitLogMessage() 104 } 105 } 106 107 def build() { 108 debug = true 109 release = Settings.RunAllTests || Settings.RunBenchmark 110 build_stage('Build : configure', true) { 111 // Build outside of the src tree to ease cleaning 112 dir (BuildDir) { 113 //Configure the conpilation (Output is not relevant) 114 //Use the current directory as the installation target so nothing escapes the sandbox 115 //Also specify the compiler by hand 116 targets="" 117 if( Settings.RunAllTests || Settings.RunBenchmark ) { 118 targets="--with-target-hosts='host:debug,host:nodebug'" 119 } else { 120 targets="--with-target-hosts='host:debug'" 121 } 122 123 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet" 124 125 // Configure libcfa 126 sh 'make -j 8 --no-print-directory configure-libcfa' 127 } 128 } 129 130 build_stage('Build : cfa-cpp', true) { 131 // Build outside of the src tree to ease cleaning 132 dir (BuildDir) { 133 // Build driver 134 sh 'make -j 8 --no-print-directory -C driver' 135 136 // Build translator 137 sh 'make -j 8 --no-print-directory -C src' 138 } 139 } 140 141 build_stage('Build : libcfa(debug)', debug) { 142 // Build outside of the src tree to ease cleaning 143 dir (BuildDir) { 144 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug" 145 } 146 } 147 148 build_stage('Build : libcfa(nodebug)', release) { 149 // Build outside of the src tree to ease cleaning 150 dir (BuildDir) { 151 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug" 152 } 153 } 154 } 155 156 def test() { 157 try { 158 build_stage('Test: short', !Settings.RunAllTests) { 159 dir (BuildDir) { 160 //Run the tests from the tests directory 161 sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short" 162 } 163 } 164 165 build_stage('Test: full', Settings.RunAllTests) { 166 dir (BuildDir) { 167 //Run the tests from the tests directory 168 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug""" 169 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no archiveerrors=${BuildDir}/tests/crashes/full-nodebug""" 170 } 171 } 172 } 173 catch (Exception err) { 174 echo "Archiving core dumps" 175 dir (BuildDir) { 176 archiveArtifacts artifacts: "tests/crashes/**/*", fingerprint: true 177 } 178 throw err 179 } 180 } 181 182 def benchmark() { 183 build_stage('Benchmark', Settings.RunBenchmark) { 184 dir (BuildDir) { 185 //Append bench results 186 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}" 187 } 188 } 189 } 190 191 def build_doc() { 192 build_stage('Documentation', Settings.BuildDocumentation) { 193 dir ('doc/user') { 194 make_doc() 195 } 196 197 dir ('doc/refrat') { 198 make_doc() 199 } 200 } 201 } 202 203 def publish() { 204 build_stage('Publish', true) { 205 206 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' } 207 208 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true) 209 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false) 210 211 //Then publish the results 212 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , false, 'Compilation') 213 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff' , groupCompile , true , 'Compilation (relative)') 214 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch' , groupConcurrency, false, 'Context Switching') 215 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff', groupConcurrency, true , 'Context Switching (relative)') 216 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, false, 'Mutual Exclusion') 217 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff' , groupConcurrency, true , 'Mutual Exclusion (relative)') 218 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal' , groupConcurrency, false, 'Internal and External Scheduling') 219 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal.diff' , groupConcurrency, true , 'Internal and External Scheduling (relative)') 220 } 221 } 222 223 //=========================================================================================================== 224 //Routine responsible of sending the email notification once the build is completed 225 //=========================================================================================================== 226 @NonCPS 227 def SplitLines(String text) { 228 def list = [] 229 230 text.eachLine { 231 list += it 232 } 233 234 return list 235 } 236 237 def GitLogMessage() { 238 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n" 239 240 def oldRef = Settings.GitOldRef 241 def newRef = Settings.GitNewRef 242 243 def revText = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim() 244 def revList = SplitLines( revText ) 245 246 def gitUpdate = "" 247 revList.each { rev -> 248 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim() 249 gitUpdate = gitUpdate + " via ${rev} (${type})" 250 } 251 252 def rev = oldRef 253 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim() 254 gitUpdate = gitUpdate + " from ${rev} (${type})" 255 256 def gitLog = sh(returnStdout: true, script: "git rev-list --format=short ${oldRef}...${newRef}").trim() 257 258 def gitDiff = sh(returnStdout: true, script: "git diff --stat --color ${newRef} ${oldRef}").trim() 259 gitDiff = gitDiff.replace('[32m', '<span style="color: #00AA00;">') 260 gitDiff = gitDiff.replace('[31m', '<span style="color: #AA0000;">') 261 gitDiff = gitDiff.replace('[m', '</span>') 262 263 return """ 264 <pre> 265 The branch ${env.BRANCH_NAME} has been updated. 266 ${gitUpdate} 267 </pre> 268 269 <p>Check console output at ${env.BUILD_URL} to view the results.</p> 270 271 <p>- Status --------------------------------------------------------------</p> 272 273 <p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p> 274 275 <p>- Log -----------------------------------------------------------------</p> 276 277 <pre> 278 ${gitLog} 279 </pre> 280 281 <p>-----------------------------------------------------------------------</p> 282 <pre> 283 Summary of changes: 284 ${gitDiff} 285 </pre> 286 """ 287 } 288 289 //Standard build email notification 290 def email(boolean log) { 291 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line 292 //Configurations for email format 293 echo 'Notifying users of result' 294 295 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase() 296 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}" 297 def email_body = """<p>This is an automated email from the Jenkins build machine. It was 298 generated because of a git hooks/post-receive script following 299 a ref change which was pushed to the C\u2200 repository.</p> 300 """ + GitLogMessage() 301 302 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca" 303 304 if( Settings && !Settings.Silent ) { 305 //send email notification 306 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log 307 } else { 308 echo "Would send email to: ${email_to}" 309 echo "With title: ${email_subject}" 310 echo "Content: \n${email_body}" 311 } 312 } 82 313 83 314 //=========================================================================================================== 84 315 // Helper classes/variables/routines 85 316 //=========================================================================================================== 86 //Helper routine to collect information about the git history 87 def collect_git_info() { 88 89 checkout scm 90 91 //create the temporary output directory in case it doesn't already exist 92 def out_dir = pwd tmp: true 93 sh "mkdir -p ${out_dir}" 94 95 //parse git logs to find what changed 96 gitRefName = env.BRANCH_NAME 97 sh "git reflog > ${out_dir}/GIT_COMMIT" 98 git_reflog = readFile("${out_dir}/GIT_COMMIT") 99 gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1] 100 gitRefNewValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][2] 317 //Description of a compiler (Must be serializable since pipelines are persistent) 318 class CC_Desc implements Serializable { 319 public String name 320 public String CXX 321 public String CC 322 323 CC_Desc(String name, String CXX, String CC) { 324 this.name = name 325 this.CXX = CXX 326 this.CC = CC 327 } 328 } 329 330 //Description of an architecture (Must be serializable since pipelines are persistent) 331 class Arch_Desc implements Serializable { 332 public String name 333 public String flags 334 public String node 335 336 Arch_Desc(String name, String flags, String node) { 337 this.name = name 338 this.flags = flags 339 this.node = node 340 } 341 } 342 343 class BuildSettings implements Serializable { 344 public final CC_Desc Compiler 345 public final Arch_Desc Architecture 346 public final Boolean RunAllTests 347 public final Boolean RunBenchmark 348 public final Boolean BuildDocumentation 349 public final Boolean Publish 350 public final Boolean Silent 351 public final Boolean IsSandbox 352 public final String DescLong 353 public final String DescShort 354 355 public String GitNewRef 356 public String GitOldRef 357 358 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) { 359 switch( param.Compiler ) { 360 case 'gcc-6': 361 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6') 362 break 363 case 'gcc-5': 364 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5') 365 break 366 case 'gcc-4.9': 367 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9') 368 break 369 case 'clang': 370 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6') 371 break 372 default : 373 error "Unhandled compiler : ${cc}" 374 } 375 376 switch( param.Architecture ) { 377 case 'x64': 378 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64') 379 break 380 case 'x86': 381 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86') 382 break 383 default : 384 error "Unhandled architecture : ${arch}" 385 } 386 387 this.IsSandbox = (branch == "jenkins-sandbox") 388 this.RunAllTests = param.RunAllTests 389 this.RunBenchmark = param.RunBenchmark 390 this.BuildDocumentation = param.BuildDocumentation 391 this.Publish = param.Publish 392 this.Silent = param.Silent 393 394 def full = param.RunAllTests ? " (Full)" : "" 395 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}" 396 397 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC }) 398 Architecture : ${ this.Architecture.name } 399 Arc Flags : ${ this.Architecture.flags } 400 Run All Tests : ${ this.RunAllTests.toString() } 401 Run Benchmark : ${ this.RunBenchmark.toString() } 402 Build Documentation : ${ this.BuildDocumentation.toString() } 403 Publish : ${ this.Publish.toString() } 404 Silent : ${ this.Silent.toString() } 405 """ 406 407 this.GitNewRef = '' 408 this.GitOldRef = '' 409 } 410 } 411 412 class PlotGroup implements Serializable { 413 public String name 414 public String unit 415 public boolean log 416 417 PlotGroup(String name, String unit, boolean log) { 418 this.name = name 419 this.unit = unit 420 this.log = log 421 } 101 422 } 102 423 103 424 def prepare_build() { 425 // prepare the properties 104 426 properties ([ \ 105 427 [$class: 'ParametersDefinitionProperty', \ … … 107 429 [$class: 'ChoiceParameterDefinition', \ 108 430 description: 'Which compiler to use', \ 109 name: ' pCompiler',\431 name: 'Compiler', \ 110 432 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \ 111 433 defaultValue: 'gcc-6', \ … … 113 435 [$class: 'ChoiceParameterDefinition', \ 114 436 description: 'The target architecture', \ 115 name: ' pArchitecture', \437 name: 'Architecture', \ 116 438 choices: 'x64\nx86', \ 117 439 defaultValue: 'x64', \ … … 119 441 [$class: 'BooleanParameterDefinition', \ 120 442 description: 'If false, only the quick test suite is ran', \ 121 name: ' pRunAllTests', \443 name: 'RunAllTests', \ 122 444 defaultValue: false, \ 123 445 ], \ 124 446 [$class: 'BooleanParameterDefinition', \ 125 447 description: 'If true, jenkins also runs benchmarks', \ 126 name: ' pRunBenchmark', \127 defaultValue: true, \448 name: 'RunBenchmark', \ 449 defaultValue: false, \ 128 450 ], \ 129 451 [$class: 'BooleanParameterDefinition', \ 130 452 description: 'If true, jenkins also builds documentation', \ 131 name: ' pBuildDocumentation', \453 name: 'BuildDocumentation', \ 132 454 defaultValue: true, \ 133 455 ], \ 134 456 [$class: 'BooleanParameterDefinition', \ 135 457 description: 'If true, jenkins also publishes results', \ 136 name: ' pPublish',\458 name: 'Publish', \ 137 459 defaultValue: false, \ 138 460 ], \ 139 461 [$class: 'BooleanParameterDefinition', \ 140 462 description: 'If true, jenkins will not send emails', \ 141 name: ' pSilent', \463 name: 'Silent', \ 142 464 defaultValue: false, \ 143 465 ], \ … … 145 467 ]]) 146 468 147 compiler = compiler_from_params( pCompiler ) 148 arch_name = pArchitecture 149 architecture = architecture_from_params( arch_name ) 150 151 do_alltests = (pRunAllTests == 'true') 152 do_benchmark = (pRunBenchmark == 'true') 153 do_doc = (pBuildDocumentation == 'true') 154 do_publish = (pPublish == 'true') 155 do_sendemail = ! (pSilent == 'true') 156 157 echo """Compiler : ${compiler.cc_name} (${compiler.cpp_cc}/${compiler.cfa_cc}) 158 Architecture : ${arch_name} 159 Arc Flags : ${architecture} 160 Run All Tests : ${ pRunAllTests.toString() } 161 Run Benchmark : ${ pRunBenchmark.toString() } 162 Build Documentation : ${ pBuildDocumentation.toString() } 163 Publish : ${ pPublish.toString() } 164 Silent : ${ pSilent.toString() } 165 """ 166 167 collect_git_info() 168 } 169 170 def build_stage(String name, Closure block ) { 171 stage_name = name 172 stage(name, block) 173 } 174 175 def notify_server(int wait) { 176 sh """curl --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true""" 177 return 469 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer 470 checkout scm 471 472 final settings = new BuildSettings(params, env.BRANCH_NAME) 473 474 currentBuild.description = settings.DescShort 475 echo settings.DescLong 476 477 return settings 478 } 479 480 def build_stage(String name, boolean run, Closure block ) { 481 StageName = name 482 echo " -------- ${StageName} -------- " 483 if(run) { 484 stage(name, block) 485 } else { 486 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) } 487 } 178 488 } 179 489 … … 186 496 catch (Exception caughtError) { 187 497 err = caughtError //rethrow error later 188 sh 'cat *.log'498 sh 'cat build/*.log' 189 499 } 190 500 finally { … … 193 503 } 194 504 195 //Description of a compiler (Must be serializable since pipelines are persistent) 196 class CC_Desc implements Serializable { 197 public String cc_name 198 public String cpp_cc 199 public String cfa_cc 200 201 CC_Desc(String cc_name, String cpp_cc, String cfa_cc) { 202 this.cc_name = cc_name 203 this.cpp_cc = cpp_cc 204 this.cfa_cc = cfa_cc 205 } 206 } 207 208 def compiler_from_params(cc) { 209 switch( cc ) { 210 case 'gcc-6': 211 return new CC_Desc('gcc-6', 'g++-6', 'gcc-6') 212 break 213 case 'gcc-5': 214 return new CC_Desc('gcc-5', 'g++-5', 'gcc-5') 215 break 216 case 'gcc-4.9': 217 return new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9') 218 break 219 case 'clang': 220 return new CC_Desc('clang', 'clang++', 'gcc-6') 221 break 222 default : 223 error "Unhandled compiler : ${cc}" 224 } 225 } 226 227 def architecture_from_params( arch ) { 228 switch( arch ) { 229 case 'x64': 230 return '--host=x86_64' 231 break 232 case 'x86': 233 return '--host=i386' 234 break 235 default : 236 error "Unhandled architecture : ${arch}" 237 } 238 } 239 240 //=========================================================================================================== 241 // Main compilation routines 242 //=========================================================================================================== 243 //Compilation script is done here but environnement set-up and error handling is done in main loop 244 def checkout() { 245 build_stage('Checkout') { 246 //checkout the source code and clean the repo 247 checkout scm 248 249 //Clean all temporary files to make sure no artifacts of the previous build remain 250 sh 'git clean -fdqx' 251 252 //Reset the git repo so no local changes persist 253 sh 'git reset --hard' 254 } 255 } 256 257 def build() { 258 build_stage('Build') { 259 260 def install_dir = pwd tmp: true 261 262 //Output compiler version to help with debug 263 echo """C++ Compiler :""" 264 sh "which ${compiler.cpp_cc} && ${compiler.cpp_cc} --version" 265 echo """C Compiler :""" 266 sh "which ${compiler.cfa_cc} && ${compiler.cfa_cc} --version" 267 268 //Configure the conpilation (Output is not relevant) 269 //Use the current directory as the installation target so nothing escapes the sandbox 270 //Also specify the compiler by hand 271 sh "./configure CXX=${compiler.cpp_cc} ${architecture} --with-backend-compiler=${compiler.cfa_cc} --prefix=${install_dir} --enable-silent-rules --quiet" 272 273 //Compile the project 274 sh 'make -j 8 --no-print-directory V=0 install' 275 } 276 } 277 278 def test() { 279 build_stage('Test') { 280 281 //Run the tests from the tests directory 282 if ( do_alltests ) { 283 sh 'make -C src/tests all-tests debug=yes --no-print-directory' 284 sh 'make -C src/tests all-tests debug=no --no-print-directory' 285 } 286 else { 287 sh 'make -C src/tests --no-print-directory' 288 } 289 } 290 } 291 292 def benchmark() { 293 build_stage('Benchmark') { 294 295 if( !do_benchmark ) return 296 297 //Append bench results 298 sh 'make -C src/benchmark --no-print-directory jenkins githash=' + gitRefNewValue + ' arch=' + arch_name + ' | tee bench.json' 299 } 300 } 301 302 def clean() { 303 build_stage('Cleanup') { 304 305 //do a maintainer-clean to make sure we need to remake from scratch 306 sh 'make maintainer-clean > /dev/null' 307 } 308 } 309 310 def build_doc() { 311 build_stage('Documentation') { 312 313 if( !do_doc ) return 314 315 dir ('doc/user') { 316 make_doc() 317 } 318 319 dir ('doc/refrat') { 320 make_doc() 321 } 322 } 323 } 324 325 def publish() { 326 build_stage('Publish') { 327 328 if( !do_publish ) return 329 330 //Then publish the results 331 sh 'curl -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true' 332 } 333 } 334 335 //=========================================================================================================== 336 //Routine responsible of sending the email notification once the build is completed 337 //=========================================================================================================== 338 //Standard build email notification 339 def email(String status, boolean log) { 340 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line 341 //Configurations for email format 342 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase() 343 344 def gitLog = 'Error retrieving git logs' 345 def gitDiff = 'Error retrieving git diff' 346 347 try { 348 349 sh "git rev-list --format=short ${gitRefOldValue}...${gitRefNewValue} > GIT_LOG" 350 gitLog = readFile('GIT_LOG') 351 352 sh "git diff --stat ${gitRefNewValue} ${gitRefOldValue} > GIT_DIFF" 353 gitDiff = readFile('GIT_DIFF') 354 } 355 catch (Exception error) {} 356 357 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}" 358 def email_body = """This is an automated email from the Jenkins build machine. It was 359 generated because of a git hooks/post-receive script following 360 a ref change was pushed to the repository containing 361 the project "UNNAMED PROJECT". 362 363 The branch ${env.BRANCH_NAME} has been updated. 364 via ${gitRefOldValue} (commit) 365 from ${gitRefNewValue} (commit) 366 367 Check console output at ${env.BUILD_URL} to view the results. 368 369 - Status -------------------------------------------------------------- 370 371 BUILD# ${env.BUILD_NUMBER} - ${status} 372 373 - Log ----------------------------------------------------------------- 374 ${gitLog} 375 ----------------------------------------------------------------------- 376 Summary of changes: 377 ${gitDiff} 378 """ 379 380 def email_to = "cforall@lists.uwaterloo.ca" 381 382 //send email notification 383 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log 384 } 505 def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) { 506 507 if(new_data) { 508 echo "Publishing new data" 509 } 510 511 def series = new_data ? [[ 512 file: "${file}.csv", 513 exclusionValues: '', 514 displayTableFlag: false, 515 inclusionFlag: 'OFF', 516 url: '' 517 ]] : []; 518 519 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}" 520 dir("${BuildDir}/benchmark/") { 521 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv", 522 csvSeries: series, 523 group: "${group.name}", 524 title: "${title}", 525 style: 'lineSimple', 526 exclZero: false, 527 keepRecords: false, 528 logarithmic: !relative && group.log, 529 numBuilds: '120', 530 useDescr: true, 531 yaxis: group.unit, 532 yaxisMaximum: '', 533 yaxisMinimum: '' 534 } 535 } -
Makefile.am
r7951100 rb067d9b 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## Makefile.am -- 8 ## Makefile.am -- 9 9 ## 10 10 ## Author : Peter A. Buhr 11 11 ## Created On : Sun May 31 22:14:18 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Wed Dec 14 14:20:48 201614 ## Update Count : 1513 ## Last Modified On : Sat Feb 2 16:54:42 2019 14 ## Update Count : 21 15 15 ############################################################################### 16 16 17 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 18 SUBDIRS = src/driver src src/prelude src/libcfa # order important, src before prelude because cfa-cpp used to build prelude 19 EXTRA_DIST = Docs # non-source files 20 BACKEND_CC = @BACKEND_CC@ # C compiler used to compile Cforall programs, versus C++ compiler used to build cfa command 17 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 18 ACLOCAL_AMFLAGS = -I automake 21 19 22 MAINTAINERCLEANFILES = lib/* bin/* src/examples/.deps/* src/tests/.deps/* src/tests/.out/* 20 MAINTAINERCLEANFILES = lib/* bin/* tests/.deps/* tests/.out/* # order important 21 22 SUBDIRS = driver src . @LIBCFA_TARGET_DIRS@ 23 24 @LIBCFA_TARGET_MAKEFILES@ : Makefile $(srcdir)/libcfa/configure 25 @$(eval config_file = $(dir $@)config.data) 26 @ls $(config_file) || (echo "Missing config.data, re-run configure script again" && false) 27 @$(eval config_data = $(shell cat $(config_file))) 28 @echo "Configuring libcfa with '$(config_data)''" 29 @cd $(dir $@) && $(abs_top_srcdir)/libcfa/configure $(config_data) 30 31 noinst_DATA = @LIBCFA_TARGET_MAKEFILES@ 23 32 24 33 man1_MANS = doc/man/cfa.1 34 35 debug=yes 36 check: 37 $(MAKE) -C tests all-tests installed=no debug=${debug} 38 39 installcheck: 40 $(MAKE) -C tests all-tests installed=yes debug=${debug} 41 42 configure-libcfa: @LIBCFA_TARGET_MAKEFILES@ 43 @true 44 45 status: @LIBCFA_TARGET_MAKEFILES@ 46 @echo -ne "translator\n\t" 47 @./config.status --config | sed "s/ /\n\t/g; s/\t'/\t/g; s/'\n/\n/g; s/^'//g; s/'$$//g" 48 @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" -
Makefile.in
r7951100 rb067d9b 17 17 ######################## -*- Mode: Makefile-Automake -*- ###################### 18 18 ############################################################################### 19 19 20 VPATH = @srcdir@ 20 21 am__is_gnu_make = { \ … … 93 94 subdir = . 94 95 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 95 am__aclocal_m4_deps = $(top_srcdir)/configure.ac 96 am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \ 97 $(top_srcdir)/automake/ltoptions.m4 \ 98 $(top_srcdir)/automake/ltsugar.m4 \ 99 $(top_srcdir)/automake/ltversion.m4 \ 100 $(top_srcdir)/automake/lt~obsolete.m4 \ 101 $(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac 96 102 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 97 103 $(ACLOCAL_M4) … … 162 168 NROFF = nroff 163 169 MANS = $(man1_MANS) 170 DATA = $(noinst_DATA) 164 171 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ 165 172 distclean-recursive maintainer-clean-recursive … … 170 177 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ 171 178 cscope distdir dist dist-all distcheck 172 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ 173 $(LISP)config.h.in 179 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 174 180 # Read a list of newline-separated strings from the standard input, 175 181 # and print each of them once, without duplicates. Input order is … … 192 198 CSCOPE = cscope 193 199 DIST_SUBDIRS = $(SUBDIRS) 194 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ 195 $(top_srcdir)/automake/compile \ 200 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/automake/compile \ 196 201 $(top_srcdir)/automake/config.guess \ 197 202 $(top_srcdir)/automake/config.sub \ 198 203 $(top_srcdir)/automake/install-sh \ 199 $(top_srcdir)/automake/missing INSTALL README automake/compile \ 200 automake/config.guess automake/config.sub automake/depcomp \ 201 automake/install-sh automake/missing automake/ylwrap 204 $(top_srcdir)/automake/ltmain.sh \ 205 $(top_srcdir)/automake/missing $(top_srcdir)/src/config.h.in \ 206 INSTALL README automake/compile automake/config.guess \ 207 automake/config.sub automake/depcomp automake/install-sh \ 208 automake/ltmain.sh automake/missing automake/ylwrap 202 209 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 203 210 distdir = $(PACKAGE)-$(VERSION) … … 243 250 distcleancheck_listfiles = find . -type f -print 244 251 ACLOCAL = @ACLOCAL@ 245 ALLOCA = @ALLOCA@246 252 AMTAR = @AMTAR@ 247 253 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 254 AR = @AR@ 248 255 AUTOCONF = @AUTOCONF@ 249 256 AUTOHEADER = @AUTOHEADER@ 250 257 AUTOMAKE = @AUTOMAKE@ 251 258 AWK = @AWK@ 252 B ACKEND_CC = @BACKEND_CC@ # C compiler used to compile Cforall programs, versus C++ compiler used to build cfa command259 BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@ 253 260 CC = @CC@ 254 261 CCAS = @CCAS@ … … 256 263 CCASFLAGS = @CCASFLAGS@ 257 264 CCDEPMODE = @CCDEPMODE@ 265 CFACC = @CFACC@ 266 CFACC_INSTALL = @CFACC_INSTALL@ 267 CFACPP = @CFACPP@ 258 268 CFA_BACKEND_CC = @CFA_BACKEND_CC@ 259 269 CFA_BINDIR = @CFA_BINDIR@ … … 267 277 CPPFLAGS = @CPPFLAGS@ 268 278 CXX = @CXX@ 279 CXXCPP = @CXXCPP@ 269 280 CXXDEPMODE = @CXXDEPMODE@ 270 281 CXXFLAGS = @CXXFLAGS@ 271 282 CYGPATH_W = @CYGPATH_W@ 272 283 DEFS = @DEFS@ 284 DEMANGLER = @DEMANGLER@ 273 285 DEPDIR = @DEPDIR@ 286 DLLTOOL = @DLLTOOL@ 287 DRIVER_DIR = @DRIVER_DIR@ 288 DSYMUTIL = @DSYMUTIL@ 289 DUMPBIN = @DUMPBIN@ 274 290 ECHO_C = @ECHO_C@ 275 291 ECHO_N = @ECHO_N@ … … 277 293 EGREP = @EGREP@ 278 294 EXEEXT = @EXEEXT@ 295 FGREP = @FGREP@ 279 296 GREP = @GREP@ 297 HAS_DISTCC = @HAS_DISTCC@ 298 HOST_FLAGS = @HOST_FLAGS@ 280 299 INSTALL = @INSTALL@ 281 300 INSTALL_DATA = @INSTALL_DATA@ … … 283 302 INSTALL_SCRIPT = @INSTALL_SCRIPT@ 284 303 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 304 LD = @LD@ 285 305 LDFLAGS = @LDFLAGS@ 286 306 LEX = @LEX@ 287 307 LEXLIB = @LEXLIB@ 288 308 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ 309 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 310 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 311 LIBDEMANGLE = @LIBDEMANGLE@ 289 312 LIBOBJS = @LIBOBJS@ 290 313 LIBS = @LIBS@ 314 LIBTOOL = @LIBTOOL@ 315 LIPO = @LIPO@ 316 LN_S = @LN_S@ 291 317 LTLIBOBJS = @LTLIBOBJS@ 292 MACHINE_TYPE = @MACHINE_TYPE@ 293 MAINT = @MAINT@ 318 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ 294 319 MAKEINFO = @MAKEINFO@ 320 MANIFEST_TOOL = @MANIFEST_TOOL@ 295 321 MKDIR_P = @MKDIR_P@ 322 NM = @NM@ 323 NMEDIT = @NMEDIT@ 324 OBJDUMP = @OBJDUMP@ 296 325 OBJEXT = @OBJEXT@ 326 OTOOL = @OTOOL@ 327 OTOOL64 = @OTOOL64@ 297 328 PACKAGE = @PACKAGE@ 298 329 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ … … 304 335 PATH_SEPARATOR = @PATH_SEPARATOR@ 305 336 RANLIB = @RANLIB@ 337 SED = @SED@ 306 338 SET_MAKE = @SET_MAKE@ 307 339 SHELL = @SHELL@ 308 340 STRIP = @STRIP@ 341 TARGET_HOSTS = @TARGET_HOSTS@ 309 342 VERSION = @VERSION@ 310 343 YACC = @YACC@ … … 314 347 abs_top_builddir = @abs_top_builddir@ 315 348 abs_top_srcdir = @abs_top_srcdir@ 349 ac_ct_AR = @ac_ct_AR@ 316 350 ac_ct_CC = @ac_ct_CC@ 317 351 ac_ct_CXX = @ac_ct_CXX@ 352 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 318 353 am__include = @am__include@ 319 354 am__leading_dot = @am__leading_dot@ … … 362 397 top_builddir = @top_builddir@ 363 398 top_srcdir = @top_srcdir@ 364 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 365 SUBDIRS = src/driver src src/prelude src/libcfa # order important, src before prelude because cfa-cpp used to build prelude 366 EXTRA_DIST = Docs # non-source files 367 MAINTAINERCLEANFILES = lib/* bin/* src/examples/.deps/* src/tests/.deps/* src/tests/.out/* 399 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 400 ACLOCAL_AMFLAGS = -I automake 401 MAINTAINERCLEANFILES = lib/* bin/* tests/.deps/* tests/.out/* # order important 402 SUBDIRS = driver src . @LIBCFA_TARGET_DIRS@ 403 noinst_DATA = @LIBCFA_TARGET_MAKEFILES@ 368 404 man1_MANS = doc/man/cfa.1 405 debug = yes 369 406 all: config.h 370 407 $(MAKE) $(AM_MAKEFLAGS) all-recursive … … 373 410 am--refresh: Makefile 374 411 @: 375 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@$(srcdir)/Makefile.am $(am__configure_deps)412 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 376 413 @for dep in $?; do \ 377 414 case '$(am__configure_deps)' in \ … … 399 436 $(SHELL) ./config.status --recheck 400 437 401 $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@$(am__configure_deps)438 $(top_srcdir)/configure: $(am__configure_deps) 402 439 $(am__cd) $(srcdir) && $(AUTOCONF) 403 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@$(am__aclocal_m4_deps)440 $(ACLOCAL_M4): $(am__aclocal_m4_deps) 404 441 $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) 405 442 $(am__aclocal_m4_deps): … … 409 446 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 410 447 411 stamp-h1: $( srcdir)/config.h.in $(top_builddir)/config.status448 stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status 412 449 @rm -f stamp-h1 413 450 cd $(top_builddir) && $(SHELL) ./config.status config.h 414 $( srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(am__configure_deps)451 $(top_srcdir)/src/config.h.in: $(am__configure_deps) 415 452 ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) 416 453 rm -f stamp-h1 … … 419 456 distclean-hdr: 420 457 -rm -f config.h stamp-h1 458 459 mostlyclean-libtool: 460 -rm -f *.lo 461 462 clean-libtool: 463 -rm -rf .libs _libs 464 465 distclean-libtool: 466 -rm -f libtool config.lt 421 467 install-man1: $(man1_MANS) 422 468 @$(NORMAL_INSTALL) … … 757 803 check-am: all-am 758 804 check: check-recursive 759 all-am: Makefile $(MANS) config.h805 all-am: Makefile $(MANS) $(DATA) config.h 760 806 installdirs: installdirs-recursive 761 807 installdirs-am: … … 770 816 install-am: all-am 771 817 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 772 773 installcheck: installcheck-recursive774 818 install-strip: 775 819 if test -z '$(STRIP)'; then \ … … 796 840 clean: clean-recursive 797 841 798 clean-am: clean-generic mostlyclean-am842 clean-am: clean-generic clean-libtool mostlyclean-am 799 843 800 844 distclean: distclean-recursive 801 845 -rm -f $(am__CONFIG_DISTCLEAN_FILES) 802 846 -rm -f Makefile 803 distclean-am: clean-am distclean-generic distclean-hdr distclean-tags 847 distclean-am: clean-am distclean-generic distclean-hdr \ 848 distclean-libtool distclean-tags 804 849 805 850 dvi: dvi-recursive … … 851 896 mostlyclean: mostlyclean-recursive 852 897 853 mostlyclean-am: mostlyclean-generic 898 mostlyclean-am: mostlyclean-generic mostlyclean-libtool 854 899 855 900 pdf: pdf-recursive … … 869 914 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ 870 915 am--refresh check check-am clean clean-cscope clean-generic \ 871 cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ 872 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ 873 distcheck distclean distclean-generic distclean-hdr \ 874 distclean-tags distcleancheck distdir distuninstallcheck dvi \ 875 dvi-am html html-am info info-am install install-am \ 876 install-data install-data-am install-dvi install-dvi-am \ 877 install-exec install-exec-am install-html install-html-am \ 878 install-info install-info-am install-man install-man1 \ 879 install-pdf install-pdf-am install-ps install-ps-am \ 880 install-strip installcheck installcheck-am installdirs \ 881 installdirs-am maintainer-clean maintainer-clean-generic \ 882 mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ 883 tags-am uninstall uninstall-am uninstall-man uninstall-man1 916 clean-libtool cscope cscopelist-am ctags ctags-am dist \ 917 dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ 918 dist-xz dist-zip distcheck distclean distclean-generic \ 919 distclean-hdr distclean-libtool distclean-tags distcleancheck \ 920 distdir distuninstallcheck dvi dvi-am html html-am info \ 921 info-am install install-am install-data install-data-am \ 922 install-dvi install-dvi-am install-exec install-exec-am \ 923 install-html install-html-am install-info install-info-am \ 924 install-man install-man1 install-pdf install-pdf-am install-ps \ 925 install-ps-am install-strip installcheck installcheck-am \ 926 installdirs installdirs-am maintainer-clean \ 927 maintainer-clean-generic mostlyclean mostlyclean-generic \ 928 mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ 929 uninstall-am uninstall-man uninstall-man1 884 930 885 931 .PRECIOUS: Makefile 886 932 933 934 @LIBCFA_TARGET_MAKEFILES@ : Makefile $(srcdir)/libcfa/configure 935 @$(eval config_file = $(dir $@)config.data) 936 @ls $(config_file) || (echo "Missing config.data, re-run configure script again" && false) 937 @$(eval config_data = $(shell cat $(config_file))) 938 @echo "Configuring libcfa with '$(config_data)''" 939 @cd $(dir $@) && $(abs_top_srcdir)/libcfa/configure $(config_data) 940 check: 941 $(MAKE) -C tests all-tests installed=no debug=${debug} 942 943 installcheck: 944 $(MAKE) -C tests all-tests installed=yes debug=${debug} 945 946 configure-libcfa: @LIBCFA_TARGET_MAKEFILES@ 947 @true 948 949 status: @LIBCFA_TARGET_MAKEFILES@ 950 @echo -ne "translator\n\t" 951 @./config.status --config | sed "s/ /\n\t/g; s/\t'/\t/g; s/'\n/\n/g; s/^'//g; s/'$$//g" 952 @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" 887 953 888 954 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
aclocal.m4
r7951100 rb067d9b 127 127 # Expand $ac_aux_dir to an absolute path. 128 128 am_aux_dir=`cd "$ac_aux_dir" && pwd` 129 ])130 131 # AM_COND_IF -*- Autoconf -*-132 133 # Copyright (C) 2008-2014 Free Software Foundation, Inc.134 #135 # This file is free software; the Free Software Foundation136 # gives unlimited permission to copy and/or distribute it,137 # with or without modifications, as long as this notice is preserved.138 139 # _AM_COND_IF140 # _AM_COND_ELSE141 # _AM_COND_ENDIF142 # --------------143 # These macros are only used for tracing.144 m4_define([_AM_COND_IF])145 m4_define([_AM_COND_ELSE])146 m4_define([_AM_COND_ENDIF])147 148 # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE])149 # ---------------------------------------150 # If the shell condition COND is true, execute IF-TRUE, otherwise execute151 # IF-FALSE. Allow automake to learn about conditional instantiating macros152 # (the AC_CONFIG_FOOS).153 AC_DEFUN([AM_COND_IF],154 [m4_ifndef([_AM_COND_VALUE_$1],155 [m4_fatal([$0: no such condition "$1"])])dnl156 _AM_COND_IF([$1])dnl157 if test -z "$$1_TRUE"; then :158 m4_n([$2])[]dnl159 m4_ifval([$3],160 [_AM_COND_ELSE([$1])dnl161 else162 $3163 ])dnl164 _AM_COND_ENDIF([$1])dnl165 fi[]dnl166 129 ]) 167 130 … … 703 666 AC_SUBST([am__leading_dot])]) 704 667 705 # Add --enable-maintainer-mode option to configure. -*- Autoconf -*-706 # From Jim Meyering707 708 # Copyright (C) 1996-2014 Free Software Foundation, Inc.709 #710 # This file is free software; the Free Software Foundation711 # gives unlimited permission to copy and/or distribute it,712 # with or without modifications, as long as this notice is preserved.713 714 # AM_MAINTAINER_MODE([DEFAULT-MODE])715 # ----------------------------------716 # Control maintainer-specific portions of Makefiles.717 # Default is to disable them, unless 'enable' is passed literally.718 # For symmetry, 'disable' may be passed as well. Anyway, the user719 # can override the default with the --enable/--disable switch.720 AC_DEFUN([AM_MAINTAINER_MODE],721 [m4_case(m4_default([$1], [disable]),722 [enable], [m4_define([am_maintainer_other], [disable])],723 [disable], [m4_define([am_maintainer_other], [enable])],724 [m4_define([am_maintainer_other], [enable])725 m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])726 AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])727 dnl maintainer-mode's default is 'disable' unless 'enable' is passed728 AC_ARG_ENABLE([maintainer-mode],729 [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],730 am_maintainer_other[ make rules and dependencies not useful731 (and sometimes confusing) to the casual installer])],732 [USE_MAINTAINER_MODE=$enableval],733 [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))734 AC_MSG_RESULT([$USE_MAINTAINER_MODE])735 AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])736 MAINT=$MAINTAINER_MODE_TRUE737 AC_SUBST([MAINT])dnl738 ]739 )740 741 668 # Check to see how 'make' treats includes. -*- Autoconf -*- 742 669 … … 1244 1171 ]) # _AM_PROG_TAR 1245 1172 1173 m4_include([automake/libtool.m4]) 1174 m4_include([automake/ltoptions.m4]) 1175 m4_include([automake/ltsugar.m4]) 1176 m4_include([automake/ltversion.m4]) 1177 m4_include([automake/lt~obsolete.m4]) -
automake/compile
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #! /bin/sh 2 # Wrapper for compilers which do not understand '-c -o'. 3 4 scriptversion=2012-10-14.11; # UTC 5 6 # Copyright (C) 1999-2014 Free Software Foundation, Inc. 7 # Written by Tom Tromey <tromey@cygnus.com>. 8 # 9 # This program is free software; you can redistribute it and/or modify 10 # it under the terms of the GNU General Public License as published by 11 # the Free Software Foundation; either version 2, or (at your option) 12 # any later version. 13 # 14 # This program is distributed in the hope that it will be useful, 15 # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 # GNU General Public License for more details. 18 # 19 # You should have received a copy of the GNU General Public License 20 # along with this program. If not, see <http://www.gnu.org/licenses/>. 21 22 # As a special exception to the GNU General Public License, if you 23 # distribute this file as part of a program that contains a 24 # configuration script generated by Autoconf, you may include it under 25 # the same distribution terms that you use for the rest of that program. 26 27 # This file is maintained in Automake, please report 28 # bugs to <bug-automake@gnu.org> or send patches to 29 # <automake-patches@gnu.org>. 30 31 nl=' 32 ' 33 34 # We need space, tab and new line, in precisely that order. Quoting is 35 # there to prevent tools from complaining about whitespace usage. 36 IFS=" "" $nl" 37 38 file_conv= 39 40 # func_file_conv build_file lazy 41 # Convert a $build file to $host form and store it in $file 42 # Currently only supports Windows hosts. If the determined conversion 43 # type is listed in (the comma separated) LAZY, no conversion will 44 # take place. 45 func_file_conv () 46 { 47 file=$1 48 case $file in 49 / | /[!/]*) # absolute file, and not a UNC file 50 if test -z "$file_conv"; then 51 # lazily determine how to convert abs files 52 case `uname -s` in 53 MINGW*) 54 file_conv=mingw 55 ;; 56 CYGWIN*) 57 file_conv=cygwin 58 ;; 59 *) 60 file_conv=wine 61 ;; 62 esac 63 fi 64 case $file_conv/,$2, in 65 *,$file_conv,*) 66 ;; 67 mingw/*) 68 file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` 69 ;; 70 cygwin/*) 71 file=`cygpath -m "$file" || echo "$file"` 72 ;; 73 wine/*) 74 file=`winepath -w "$file" || echo "$file"` 75 ;; 76 esac 77 ;; 78 esac 79 } 80 81 # func_cl_dashL linkdir 82 # Make cl look for libraries in LINKDIR 83 func_cl_dashL () 84 { 85 func_file_conv "$1" 86 if test -z "$lib_path"; then 87 lib_path=$file 88 else 89 lib_path="$lib_path;$file" 90 fi 91 linker_opts="$linker_opts -LIBPATH:$file" 92 } 93 94 # func_cl_dashl library 95 # Do a library search-path lookup for cl 96 func_cl_dashl () 97 { 98 lib=$1 99 found=no 100 save_IFS=$IFS 101 IFS=';' 102 for dir in $lib_path $LIB 103 do 104 IFS=$save_IFS 105 if $shared && test -f "$dir/$lib.dll.lib"; then 106 found=yes 107 lib=$dir/$lib.dll.lib 108 break 109 fi 110 if test -f "$dir/$lib.lib"; then 111 found=yes 112 lib=$dir/$lib.lib 113 break 114 fi 115 if test -f "$dir/lib$lib.a"; then 116 found=yes 117 lib=$dir/lib$lib.a 118 break 119 fi 120 done 121 IFS=$save_IFS 122 123 if test "$found" != yes; then 124 lib=$lib.lib 125 fi 126 } 127 128 # func_cl_wrapper cl arg... 129 # Adjust compile command to suit cl 130 func_cl_wrapper () 131 { 132 # Assume a capable shell 133 lib_path= 134 shared=: 135 linker_opts= 136 for arg 137 do 138 if test -n "$eat"; then 139 eat= 140 else 141 case $1 in 142 -o) 143 # configure might choose to run compile as 'compile cc -o foo foo.c'. 144 eat=1 145 case $2 in 146 *.o | *.[oO][bB][jJ]) 147 func_file_conv "$2" 148 set x "$@" -Fo"$file" 149 shift 150 ;; 151 *) 152 func_file_conv "$2" 153 set x "$@" -Fe"$file" 154 shift 155 ;; 156 esac 157 ;; 158 -I) 159 eat=1 160 func_file_conv "$2" mingw 161 set x "$@" -I"$file" 162 shift 163 ;; 164 -I*) 165 func_file_conv "${1#-I}" mingw 166 set x "$@" -I"$file" 167 shift 168 ;; 169 -l) 170 eat=1 171 func_cl_dashl "$2" 172 set x "$@" "$lib" 173 shift 174 ;; 175 -l*) 176 func_cl_dashl "${1#-l}" 177 set x "$@" "$lib" 178 shift 179 ;; 180 -L) 181 eat=1 182 func_cl_dashL "$2" 183 ;; 184 -L*) 185 func_cl_dashL "${1#-L}" 186 ;; 187 -static) 188 shared=false 189 ;; 190 -Wl,*) 191 arg=${1#-Wl,} 192 save_ifs="$IFS"; IFS=',' 193 for flag in $arg; do 194 IFS="$save_ifs" 195 linker_opts="$linker_opts $flag" 196 done 197 IFS="$save_ifs" 198 ;; 199 -Xlinker) 200 eat=1 201 linker_opts="$linker_opts $2" 202 ;; 203 -*) 204 set x "$@" "$1" 205 shift 206 ;; 207 *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) 208 func_file_conv "$1" 209 set x "$@" -Tp"$file" 210 shift 211 ;; 212 *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) 213 func_file_conv "$1" mingw 214 set x "$@" "$file" 215 shift 216 ;; 217 *) 218 set x "$@" "$1" 219 shift 220 ;; 221 esac 222 fi 223 shift 224 done 225 if test -n "$linker_opts"; then 226 linker_opts="-link$linker_opts" 227 fi 228 exec "$@" $linker_opts 229 exit 1 230 } 231 232 eat= 233 234 case $1 in 235 '') 236 echo "$0: No command. Try '$0 --help' for more information." 1>&2 237 exit 1; 238 ;; 239 -h | --h*) 240 cat <<\EOF 241 Usage: compile [--help] [--version] PROGRAM [ARGS] 242 243 Wrapper for compilers which do not understand '-c -o'. 244 Remove '-o dest.o' from ARGS, run PROGRAM with the remaining 245 arguments, and rename the output as expected. 246 247 If you are trying to build a whole package this is not the 248 right script to run: please start by reading the file 'INSTALL'. 249 250 Report bugs to <bug-automake@gnu.org>. 251 EOF 252 exit $? 253 ;; 254 -v | --v*) 255 echo "compile $scriptversion" 256 exit $? 257 ;; 258 cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) 259 func_cl_wrapper "$@" # Doesn't return... 260 ;; 261 esac 262 263 ofile= 264 cfile= 265 266 for arg 267 do 268 if test -n "$eat"; then 269 eat= 270 else 271 case $1 in 272 -o) 273 # configure might choose to run compile as 'compile cc -o foo foo.c'. 274 # So we strip '-o arg' only if arg is an object. 275 eat=1 276 case $2 in 277 *.o | *.obj) 278 ofile=$2 279 ;; 280 *) 281 set x "$@" -o "$2" 282 shift 283 ;; 284 esac 285 ;; 286 *.c) 287 cfile=$1 288 set x "$@" "$1" 289 shift 290 ;; 291 *) 292 set x "$@" "$1" 293 shift 294 ;; 295 esac 296 fi 297 shift 298 done 299 300 if test -z "$ofile" || test -z "$cfile"; then 301 # If no '-o' option was seen then we might have been invoked from a 302 # pattern rule where we don't need one. That is ok -- this is a 303 # normal compilation that the losing compiler can handle. If no 304 # '.c' file was seen then we are probably linking. That is also 305 # ok. 306 exec "$@" 307 fi 308 309 # Name of file we expect compiler to create. 310 cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` 311 312 # Create the lock directory. 313 # Note: use '[/\\:.-]' here to ensure that we don't use the same name 314 # that we are using for the .o file. Also, base the name on the expected 315 # object file name, since that is what matters with a parallel build. 316 lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d 317 while true; do 318 if mkdir "$lockdir" >/dev/null 2>&1; then 319 break 320 fi 321 sleep 1 322 done 323 # FIXME: race condition here if user kills between mkdir and trap. 324 trap "rmdir '$lockdir'; exit 1" 1 2 15 325 326 # Run the compile. 327 "$@" 328 ret=$? 329 330 if test -f "$cofile"; then 331 test "$cofile" = "$ofile" || mv "$cofile" "$ofile" 332 elif test -f "${cofile}bj"; then 333 test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" 334 fi 335 336 rmdir "$lockdir" 337 exit $ret 338 339 # Local Variables: 340 # mode: shell-script 341 # sh-indentation: 2 342 # eval: (add-hook 'write-file-hooks 'time-stamp) 343 # time-stamp-start: "scriptversion=" 344 # time-stamp-format: "%:y-%02m-%02d.%02H" 345 # time-stamp-time-zone: "UTC" 346 # time-stamp-end: "; # UTC" 347 # End: 1 /usr/share/automake-1.15/compile -
Property mode
changed from
-
automake/config.guess
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #! /bin/sh 2 # Attempt to guess a canonical system name. 3 # Copyright 1992-2015 Free Software Foundation, Inc. 4 5 timestamp='2015-08-20' 6 7 # This file is free software; you can redistribute it and/or modify it 8 # under the terms of the GNU General Public License as published by 9 # the Free Software Foundation; either version 3 of the License, or 10 # (at your option) any later version. 11 # 12 # This program is distributed in the hope that it will be useful, but 13 # WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 # General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with this program; if not, see <http://www.gnu.org/licenses/>. 19 # 20 # As a special exception to the GNU General Public License, if you 21 # distribute this file as part of a program that contains a 22 # configuration script generated by Autoconf, you may include it under 23 # the same distribution terms that you use for the rest of that 24 # program. This Exception is an additional permission under section 7 25 # of the GNU General Public License, version 3 ("GPLv3"). 26 # 27 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. 28 # 29 # You can get the latest version of this script from: 30 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD 31 # 32 # Please send patches to <config-patches@gnu.org>. 33 34 35 me=`echo "$0" | sed -e 's,.*/,,'` 36 37 usage="\ 38 Usage: $0 [OPTION] 39 40 Output the configuration name of the system \`$me' is run on. 41 42 Operation modes: 43 -h, --help print this help, then exit 44 -t, --time-stamp print date of last modification, then exit 45 -v, --version print version number, then exit 46 47 Report bugs and patches to <config-patches@gnu.org>." 48 49 version="\ 50 GNU config.guess ($timestamp) 51 52 Originally written by Per Bothner. 53 Copyright 1992-2015 Free Software Foundation, Inc. 54 55 This is free software; see the source for copying conditions. There is NO 56 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 57 58 help=" 59 Try \`$me --help' for more information." 60 61 # Parse command line 62 while test $# -gt 0 ; do 63 case $1 in 64 --time-stamp | --time* | -t ) 65 echo "$timestamp" ; exit ;; 66 --version | -v ) 67 echo "$version" ; exit ;; 68 --help | --h* | -h ) 69 echo "$usage"; exit ;; 70 -- ) # Stop option processing 71 shift; break ;; 72 - ) # Use stdin as input. 73 break ;; 74 -* ) 75 echo "$me: invalid option $1$help" >&2 76 exit 1 ;; 77 * ) 78 break ;; 79 esac 80 done 81 82 if test $# != 0; then 83 echo "$me: too many arguments$help" >&2 84 exit 1 85 fi 86 87 trap 'exit 1' 1 2 15 88 89 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a 90 # compiler to aid in system detection is discouraged as it requires 91 # temporary files to be created and, as you can see below, it is a 92 # headache to deal with in a portable fashion. 93 94 # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still 95 # use `HOST_CC' if defined, but it is deprecated. 96 97 # Portable tmp directory creation inspired by the Autoconf team. 98 99 set_cc_for_build=' 100 trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; 101 trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; 102 : ${TMPDIR=/tmp} ; 103 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || 104 { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || 105 { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || 106 { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; 107 dummy=$tmp/dummy ; 108 tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; 109 case $CC_FOR_BUILD,$HOST_CC,$CC in 110 ,,) echo "int x;" > $dummy.c ; 111 for c in cc gcc c89 c99 ; do 112 if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then 113 CC_FOR_BUILD="$c"; break ; 114 fi ; 115 done ; 116 if test x"$CC_FOR_BUILD" = x ; then 117 CC_FOR_BUILD=no_compiler_found ; 118 fi 119 ;; 120 ,,*) CC_FOR_BUILD=$CC ;; 121 ,*,*) CC_FOR_BUILD=$HOST_CC ;; 122 esac ; set_cc_for_build= ;' 123 124 # This is needed to find uname on a Pyramid OSx when run in the BSD universe. 125 # (ghazi@noc.rutgers.edu 1994-08-24) 126 if (test -f /.attbin/uname) >/dev/null 2>&1 ; then 127 PATH=$PATH:/.attbin ; export PATH 128 fi 129 130 UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown 131 UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown 132 UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown 133 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown 134 135 case "${UNAME_SYSTEM}" in 136 Linux|GNU|GNU/*) 137 # If the system lacks a compiler, then just pick glibc. 138 # We could probably try harder. 139 LIBC=gnu 140 141 eval $set_cc_for_build 142 cat <<-EOF > $dummy.c 143 #include <features.h> 144 #if defined(__UCLIBC__) 145 LIBC=uclibc 146 #elif defined(__dietlibc__) 147 LIBC=dietlibc 148 #else 149 LIBC=gnu 150 #endif 151 EOF 152 eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` 153 ;; 154 esac 155 156 # Note: order is significant - the case branches are not exclusive. 157 158 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in 159 *:NetBSD:*:*) 160 # NetBSD (nbsd) targets should (where applicable) match one or 161 # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, 162 # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently 163 # switched to ELF, *-*-netbsd* would select the old 164 # object file format. This provides both forward 165 # compatibility and a consistent mechanism for selecting the 166 # object file format. 167 # 168 # Note: NetBSD doesn't particularly care about the vendor 169 # portion of the name. We always set it to "unknown". 170 sysctl="sysctl -n hw.machine_arch" 171 UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ 172 /sbin/$sysctl 2>/dev/null || \ 173 /usr/sbin/$sysctl 2>/dev/null || \ 174 echo unknown)` 175 case "${UNAME_MACHINE_ARCH}" in 176 armeb) machine=armeb-unknown ;; 177 arm*) machine=arm-unknown ;; 178 sh3el) machine=shl-unknown ;; 179 sh3eb) machine=sh-unknown ;; 180 sh5el) machine=sh5le-unknown ;; 181 earmv*) 182 arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` 183 endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` 184 machine=${arch}${endian}-unknown 185 ;; 186 *) machine=${UNAME_MACHINE_ARCH}-unknown ;; 187 esac 188 # The Operating System including object format, if it has switched 189 # to ELF recently, or will in the future. 190 case "${UNAME_MACHINE_ARCH}" in 191 arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) 192 eval $set_cc_for_build 193 if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ 194 | grep -q __ELF__ 195 then 196 # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). 197 # Return netbsd for either. FIX? 198 os=netbsd 199 else 200 os=netbsdelf 201 fi 202 ;; 203 *) 204 os=netbsd 205 ;; 206 esac 207 # Determine ABI tags. 208 case "${UNAME_MACHINE_ARCH}" in 209 earm*) 210 expr='s/^earmv[0-9]/-eabi/;s/eb$//' 211 abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` 212 ;; 213 esac 214 # The OS release 215 # Debian GNU/NetBSD machines have a different userland, and 216 # thus, need a distinct triplet. However, they do not need 217 # kernel version information, so it can be replaced with a 218 # suitable tag, in the style of linux-gnu. 219 case "${UNAME_VERSION}" in 220 Debian*) 221 release='-gnu' 222 ;; 223 *) 224 release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` 225 ;; 226 esac 227 # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: 228 # contains redundant information, the shorter form: 229 # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. 230 echo "${machine}-${os}${release}${abi}" 231 exit ;; 232 *:Bitrig:*:*) 233 UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` 234 echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} 235 exit ;; 236 *:OpenBSD:*:*) 237 UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` 238 echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} 239 exit ;; 240 *:ekkoBSD:*:*) 241 echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} 242 exit ;; 243 *:SolidBSD:*:*) 244 echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} 245 exit ;; 246 macppc:MirBSD:*:*) 247 echo powerpc-unknown-mirbsd${UNAME_RELEASE} 248 exit ;; 249 *:MirBSD:*:*) 250 echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} 251 exit ;; 252 *:Sortix:*:*) 253 echo ${UNAME_MACHINE}-unknown-sortix 254 exit ;; 255 alpha:OSF1:*:*) 256 case $UNAME_RELEASE in 257 *4.0) 258 UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` 259 ;; 260 *5.*) 261 UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` 262 ;; 263 esac 264 # According to Compaq, /usr/sbin/psrinfo has been available on 265 # OSF/1 and Tru64 systems produced since 1995. I hope that 266 # covers most systems running today. This code pipes the CPU 267 # types through head -n 1, so we only detect the type of CPU 0. 268 ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` 269 case "$ALPHA_CPU_TYPE" in 270 "EV4 (21064)") 271 UNAME_MACHINE="alpha" ;; 272 "EV4.5 (21064)") 273 UNAME_MACHINE="alpha" ;; 274 "LCA4 (21066/21068)") 275 UNAME_MACHINE="alpha" ;; 276 "EV5 (21164)") 277 UNAME_MACHINE="alphaev5" ;; 278 "EV5.6 (21164A)") 279 UNAME_MACHINE="alphaev56" ;; 280 "EV5.6 (21164PC)") 281 UNAME_MACHINE="alphapca56" ;; 282 "EV5.7 (21164PC)") 283 UNAME_MACHINE="alphapca57" ;; 284 "EV6 (21264)") 285 UNAME_MACHINE="alphaev6" ;; 286 "EV6.7 (21264A)") 287 UNAME_MACHINE="alphaev67" ;; 288 "EV6.8CB (21264C)") 289 UNAME_MACHINE="alphaev68" ;; 290 "EV6.8AL (21264B)") 291 UNAME_MACHINE="alphaev68" ;; 292 "EV6.8CX (21264D)") 293 UNAME_MACHINE="alphaev68" ;; 294 "EV6.9A (21264/EV69A)") 295 UNAME_MACHINE="alphaev69" ;; 296 "EV7 (21364)") 297 UNAME_MACHINE="alphaev7" ;; 298 "EV7.9 (21364A)") 299 UNAME_MACHINE="alphaev79" ;; 300 esac 301 # A Pn.n version is a patched version. 302 # A Vn.n version is a released version. 303 # A Tn.n version is a released field test version. 304 # A Xn.n version is an unreleased experimental baselevel. 305 # 1.2 uses "1.2" for uname -r. 306 echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` 307 # Reset EXIT trap before exiting to avoid spurious non-zero exit code. 308 exitcode=$? 309 trap '' 0 310 exit $exitcode ;; 311 Alpha\ *:Windows_NT*:*) 312 # How do we know it's Interix rather than the generic POSIX subsystem? 313 # Should we change UNAME_MACHINE based on the output of uname instead 314 # of the specific Alpha model? 315 echo alpha-pc-interix 316 exit ;; 317 21064:Windows_NT:50:3) 318 echo alpha-dec-winnt3.5 319 exit ;; 320 Amiga*:UNIX_System_V:4.0:*) 321 echo m68k-unknown-sysv4 322 exit ;; 323 *:[Aa]miga[Oo][Ss]:*:*) 324 echo ${UNAME_MACHINE}-unknown-amigaos 325 exit ;; 326 *:[Mm]orph[Oo][Ss]:*:*) 327 echo ${UNAME_MACHINE}-unknown-morphos 328 exit ;; 329 *:OS/390:*:*) 330 echo i370-ibm-openedition 331 exit ;; 332 *:z/VM:*:*) 333 echo s390-ibm-zvmoe 334 exit ;; 335 *:OS400:*:*) 336 echo powerpc-ibm-os400 337 exit ;; 338 arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) 339 echo arm-acorn-riscix${UNAME_RELEASE} 340 exit ;; 341 arm*:riscos:*:*|arm*:RISCOS:*:*) 342 echo arm-unknown-riscos 343 exit ;; 344 SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) 345 echo hppa1.1-hitachi-hiuxmpp 346 exit ;; 347 Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) 348 # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. 349 if test "`(/bin/universe) 2>/dev/null`" = att ; then 350 echo pyramid-pyramid-sysv3 351 else 352 echo pyramid-pyramid-bsd 353 fi 354 exit ;; 355 NILE*:*:*:dcosx) 356 echo pyramid-pyramid-svr4 357 exit ;; 358 DRS?6000:unix:4.0:6*) 359 echo sparc-icl-nx6 360 exit ;; 361 DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) 362 case `/usr/bin/uname -p` in 363 sparc) echo sparc-icl-nx7; exit ;; 364 esac ;; 365 s390x:SunOS:*:*) 366 echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 367 exit ;; 368 sun4H:SunOS:5.*:*) 369 echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 370 exit ;; 371 sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) 372 echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 373 exit ;; 374 i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) 375 echo i386-pc-auroraux${UNAME_RELEASE} 376 exit ;; 377 i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) 378 eval $set_cc_for_build 379 SUN_ARCH="i386" 380 # If there is a compiler, see if it is configured for 64-bit objects. 381 # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. 382 # This test works for both compilers. 383 if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then 384 if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ 385 (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ 386 grep IS_64BIT_ARCH >/dev/null 387 then 388 SUN_ARCH="x86_64" 389 fi 390 fi 391 echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 392 exit ;; 393 sun4*:SunOS:6*:*) 394 # According to config.sub, this is the proper way to canonicalize 395 # SunOS6. Hard to guess exactly what SunOS6 will be like, but 396 # it's likely to be more like Solaris than SunOS4. 397 echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 398 exit ;; 399 sun4*:SunOS:*:*) 400 case "`/usr/bin/arch -k`" in 401 Series*|S4*) 402 UNAME_RELEASE=`uname -v` 403 ;; 404 esac 405 # Japanese Language versions have a version number like `4.1.3-JL'. 406 echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` 407 exit ;; 408 sun3*:SunOS:*:*) 409 echo m68k-sun-sunos${UNAME_RELEASE} 410 exit ;; 411 sun*:*:4.2BSD:*) 412 UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` 413 test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 414 case "`/bin/arch`" in 415 sun3) 416 echo m68k-sun-sunos${UNAME_RELEASE} 417 ;; 418 sun4) 419 echo sparc-sun-sunos${UNAME_RELEASE} 420 ;; 421 esac 422 exit ;; 423 aushp:SunOS:*:*) 424 echo sparc-auspex-sunos${UNAME_RELEASE} 425 exit ;; 426 # The situation for MiNT is a little confusing. The machine name 427 # can be virtually everything (everything which is not 428 # "atarist" or "atariste" at least should have a processor 429 # > m68000). The system name ranges from "MiNT" over "FreeMiNT" 430 # to the lowercase version "mint" (or "freemint"). Finally 431 # the system name "TOS" denotes a system which is actually not 432 # MiNT. But MiNT is downward compatible to TOS, so this should 433 # be no problem. 434 atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) 435 echo m68k-atari-mint${UNAME_RELEASE} 436 exit ;; 437 atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) 438 echo m68k-atari-mint${UNAME_RELEASE} 439 exit ;; 440 *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) 441 echo m68k-atari-mint${UNAME_RELEASE} 442 exit ;; 443 milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) 444 echo m68k-milan-mint${UNAME_RELEASE} 445 exit ;; 446 hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) 447 echo m68k-hades-mint${UNAME_RELEASE} 448 exit ;; 449 *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) 450 echo m68k-unknown-mint${UNAME_RELEASE} 451 exit ;; 452 m68k:machten:*:*) 453 echo m68k-apple-machten${UNAME_RELEASE} 454 exit ;; 455 powerpc:machten:*:*) 456 echo powerpc-apple-machten${UNAME_RELEASE} 457 exit ;; 458 RISC*:Mach:*:*) 459 echo mips-dec-mach_bsd4.3 460 exit ;; 461 RISC*:ULTRIX:*:*) 462 echo mips-dec-ultrix${UNAME_RELEASE} 463 exit ;; 464 VAX*:ULTRIX*:*:*) 465 echo vax-dec-ultrix${UNAME_RELEASE} 466 exit ;; 467 2020:CLIX:*:* | 2430:CLIX:*:*) 468 echo clipper-intergraph-clix${UNAME_RELEASE} 469 exit ;; 470 mips:*:*:UMIPS | mips:*:*:RISCos) 471 eval $set_cc_for_build 472 sed 's/^ //' << EOF >$dummy.c 473 #ifdef __cplusplus 474 #include <stdio.h> /* for printf() prototype */ 475 int main (int argc, char *argv[]) { 476 #else 477 int main (argc, argv) int argc; char *argv[]; { 478 #endif 479 #if defined (host_mips) && defined (MIPSEB) 480 #if defined (SYSTYPE_SYSV) 481 printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); 482 #endif 483 #if defined (SYSTYPE_SVR4) 484 printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); 485 #endif 486 #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) 487 printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); 488 #endif 489 #endif 490 exit (-1); 491 } 492 EOF 493 $CC_FOR_BUILD -o $dummy $dummy.c && 494 dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && 495 SYSTEM_NAME=`$dummy $dummyarg` && 496 { echo "$SYSTEM_NAME"; exit; } 497 echo mips-mips-riscos${UNAME_RELEASE} 498 exit ;; 499 Motorola:PowerMAX_OS:*:*) 500 echo powerpc-motorola-powermax 501 exit ;; 502 Motorola:*:4.3:PL8-*) 503 echo powerpc-harris-powermax 504 exit ;; 505 Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) 506 echo powerpc-harris-powermax 507 exit ;; 508 Night_Hawk:Power_UNIX:*:*) 509 echo powerpc-harris-powerunix 510 exit ;; 511 m88k:CX/UX:7*:*) 512 echo m88k-harris-cxux7 513 exit ;; 514 m88k:*:4*:R4*) 515 echo m88k-motorola-sysv4 516 exit ;; 517 m88k:*:3*:R3*) 518 echo m88k-motorola-sysv3 519 exit ;; 520 AViiON:dgux:*:*) 521 # DG/UX returns AViiON for all architectures 522 UNAME_PROCESSOR=`/usr/bin/uname -p` 523 if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] 524 then 525 if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ 526 [ ${TARGET_BINARY_INTERFACE}x = x ] 527 then 528 echo m88k-dg-dgux${UNAME_RELEASE} 529 else 530 echo m88k-dg-dguxbcs${UNAME_RELEASE} 531 fi 532 else 533 echo i586-dg-dgux${UNAME_RELEASE} 534 fi 535 exit ;; 536 M88*:DolphinOS:*:*) # DolphinOS (SVR3) 537 echo m88k-dolphin-sysv3 538 exit ;; 539 M88*:*:R3*:*) 540 # Delta 88k system running SVR3 541 echo m88k-motorola-sysv3 542 exit ;; 543 XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) 544 echo m88k-tektronix-sysv3 545 exit ;; 546 Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) 547 echo m68k-tektronix-bsd 548 exit ;; 549 *:IRIX*:*:*) 550 echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` 551 exit ;; 552 ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. 553 echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id 554 exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' 555 i*86:AIX:*:*) 556 echo i386-ibm-aix 557 exit ;; 558 ia64:AIX:*:*) 559 if [ -x /usr/bin/oslevel ] ; then 560 IBM_REV=`/usr/bin/oslevel` 561 else 562 IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} 563 fi 564 echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} 565 exit ;; 566 *:AIX:2:3) 567 if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then 568 eval $set_cc_for_build 569 sed 's/^ //' << EOF >$dummy.c 570 #include <sys/systemcfg.h> 571 572 main() 573 { 574 if (!__power_pc()) 575 exit(1); 576 puts("powerpc-ibm-aix3.2.5"); 577 exit(0); 578 } 579 EOF 580 if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` 581 then 582 echo "$SYSTEM_NAME" 583 else 584 echo rs6000-ibm-aix3.2.5 585 fi 586 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then 587 echo rs6000-ibm-aix3.2.4 588 else 589 echo rs6000-ibm-aix3.2 590 fi 591 exit ;; 592 *:AIX:*:[4567]) 593 IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` 594 if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then 595 IBM_ARCH=rs6000 596 else 597 IBM_ARCH=powerpc 598 fi 599 if [ -x /usr/bin/lslpp ] ; then 600 IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | 601 awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` 602 else 603 IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} 604 fi 605 echo ${IBM_ARCH}-ibm-aix${IBM_REV} 606 exit ;; 607 *:AIX:*:*) 608 echo rs6000-ibm-aix 609 exit ;; 610 ibmrt:4.4BSD:*|romp-ibm:BSD:*) 611 echo romp-ibm-bsd4.4 612 exit ;; 613 ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and 614 echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to 615 exit ;; # report: romp-ibm BSD 4.3 616 *:BOSX:*:*) 617 echo rs6000-bull-bosx 618 exit ;; 619 DPX/2?00:B.O.S.:*:*) 620 echo m68k-bull-sysv3 621 exit ;; 622 9000/[34]??:4.3bsd:1.*:*) 623 echo m68k-hp-bsd 624 exit ;; 625 hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) 626 echo m68k-hp-bsd4.4 627 exit ;; 628 9000/[34678]??:HP-UX:*:*) 629 HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` 630 case "${UNAME_MACHINE}" in 631 9000/31? ) HP_ARCH=m68000 ;; 632 9000/[34]?? ) HP_ARCH=m68k ;; 633 9000/[678][0-9][0-9]) 634 if [ -x /usr/bin/getconf ]; then 635 sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` 636 sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` 637 case "${sc_cpu_version}" in 638 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 639 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 640 532) # CPU_PA_RISC2_0 641 case "${sc_kernel_bits}" in 642 32) HP_ARCH="hppa2.0n" ;; 643 64) HP_ARCH="hppa2.0w" ;; 644 '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 645 esac ;; 646 esac 647 fi 648 if [ "${HP_ARCH}" = "" ]; then 649 eval $set_cc_for_build 650 sed 's/^ //' << EOF >$dummy.c 651 652 #define _HPUX_SOURCE 653 #include <stdlib.h> 654 #include <unistd.h> 655 656 int main () 657 { 658 #if defined(_SC_KERNEL_BITS) 659 long bits = sysconf(_SC_KERNEL_BITS); 660 #endif 661 long cpu = sysconf (_SC_CPU_VERSION); 662 663 switch (cpu) 664 { 665 case CPU_PA_RISC1_0: puts ("hppa1.0"); break; 666 case CPU_PA_RISC1_1: puts ("hppa1.1"); break; 667 case CPU_PA_RISC2_0: 668 #if defined(_SC_KERNEL_BITS) 669 switch (bits) 670 { 671 case 64: puts ("hppa2.0w"); break; 672 case 32: puts ("hppa2.0n"); break; 673 default: puts ("hppa2.0"); break; 674 } break; 675 #else /* !defined(_SC_KERNEL_BITS) */ 676 puts ("hppa2.0"); break; 677 #endif 678 default: puts ("hppa1.0"); break; 679 } 680 exit (0); 681 } 682 EOF 683 (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` 684 test -z "$HP_ARCH" && HP_ARCH=hppa 685 fi ;; 686 esac 687 if [ ${HP_ARCH} = "hppa2.0w" ] 688 then 689 eval $set_cc_for_build 690 691 # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating 692 # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler 693 # generating 64-bit code. GNU and HP use different nomenclature: 694 # 695 # $ CC_FOR_BUILD=cc ./config.guess 696 # => hppa2.0w-hp-hpux11.23 697 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess 698 # => hppa64-hp-hpux11.23 699 700 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | 701 grep -q __LP64__ 702 then 703 HP_ARCH="hppa2.0w" 704 else 705 HP_ARCH="hppa64" 706 fi 707 fi 708 echo ${HP_ARCH}-hp-hpux${HPUX_REV} 709 exit ;; 710 ia64:HP-UX:*:*) 711 HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` 712 echo ia64-hp-hpux${HPUX_REV} 713 exit ;; 714 3050*:HI-UX:*:*) 715 eval $set_cc_for_build 716 sed 's/^ //' << EOF >$dummy.c 717 #include <unistd.h> 718 int 719 main () 720 { 721 long cpu = sysconf (_SC_CPU_VERSION); 722 /* The order matters, because CPU_IS_HP_MC68K erroneously returns 723 true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct 724 results, however. */ 725 if (CPU_IS_PA_RISC (cpu)) 726 { 727 switch (cpu) 728 { 729 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; 730 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; 731 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; 732 default: puts ("hppa-hitachi-hiuxwe2"); break; 733 } 734 } 735 else if (CPU_IS_HP_MC68K (cpu)) 736 puts ("m68k-hitachi-hiuxwe2"); 737 else puts ("unknown-hitachi-hiuxwe2"); 738 exit (0); 739 } 740 EOF 741 $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && 742 { echo "$SYSTEM_NAME"; exit; } 743 echo unknown-hitachi-hiuxwe2 744 exit ;; 745 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) 746 echo hppa1.1-hp-bsd 747 exit ;; 748 9000/8??:4.3bsd:*:*) 749 echo hppa1.0-hp-bsd 750 exit ;; 751 *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) 752 echo hppa1.0-hp-mpeix 753 exit ;; 754 hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) 755 echo hppa1.1-hp-osf 756 exit ;; 757 hp8??:OSF1:*:*) 758 echo hppa1.0-hp-osf 759 exit ;; 760 i*86:OSF1:*:*) 761 if [ -x /usr/sbin/sysversion ] ; then 762 echo ${UNAME_MACHINE}-unknown-osf1mk 763 else 764 echo ${UNAME_MACHINE}-unknown-osf1 765 fi 766 exit ;; 767 parisc*:Lites*:*:*) 768 echo hppa1.1-hp-lites 769 exit ;; 770 C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) 771 echo c1-convex-bsd 772 exit ;; 773 C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) 774 if getsysinfo -f scalar_acc 775 then echo c32-convex-bsd 776 else echo c2-convex-bsd 777 fi 778 exit ;; 779 C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) 780 echo c34-convex-bsd 781 exit ;; 782 C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) 783 echo c38-convex-bsd 784 exit ;; 785 C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) 786 echo c4-convex-bsd 787 exit ;; 788 CRAY*Y-MP:*:*:*) 789 echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 790 exit ;; 791 CRAY*[A-Z]90:*:*:*) 792 echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ 793 | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ 794 -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ 795 -e 's/\.[^.]*$/.X/' 796 exit ;; 797 CRAY*TS:*:*:*) 798 echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 799 exit ;; 800 CRAY*T3E:*:*:*) 801 echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 802 exit ;; 803 CRAY*SV1:*:*:*) 804 echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 805 exit ;; 806 *:UNICOS/mp:*:*) 807 echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 808 exit ;; 809 F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) 810 FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` 811 FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` 812 FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` 813 echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" 814 exit ;; 815 5000:UNIX_System_V:4.*:*) 816 FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` 817 FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` 818 echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" 819 exit ;; 820 i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) 821 echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} 822 exit ;; 823 sparc*:BSD/OS:*:*) 824 echo sparc-unknown-bsdi${UNAME_RELEASE} 825 exit ;; 826 *:BSD/OS:*:*) 827 echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} 828 exit ;; 829 *:FreeBSD:*:*) 830 UNAME_PROCESSOR=`/usr/bin/uname -p` 831 case ${UNAME_PROCESSOR} in 832 amd64) 833 echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; 834 *) 835 echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; 836 esac 837 exit ;; 838 i*:CYGWIN*:*) 839 echo ${UNAME_MACHINE}-pc-cygwin 840 exit ;; 841 *:MINGW64*:*) 842 echo ${UNAME_MACHINE}-pc-mingw64 843 exit ;; 844 *:MINGW*:*) 845 echo ${UNAME_MACHINE}-pc-mingw32 846 exit ;; 847 *:MSYS*:*) 848 echo ${UNAME_MACHINE}-pc-msys 849 exit ;; 850 i*:windows32*:*) 851 # uname -m includes "-pc" on this system. 852 echo ${UNAME_MACHINE}-mingw32 853 exit ;; 854 i*:PW*:*) 855 echo ${UNAME_MACHINE}-pc-pw32 856 exit ;; 857 *:Interix*:*) 858 case ${UNAME_MACHINE} in 859 x86) 860 echo i586-pc-interix${UNAME_RELEASE} 861 exit ;; 862 authenticamd | genuineintel | EM64T) 863 echo x86_64-unknown-interix${UNAME_RELEASE} 864 exit ;; 865 IA64) 866 echo ia64-unknown-interix${UNAME_RELEASE} 867 exit ;; 868 esac ;; 869 [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) 870 echo i${UNAME_MACHINE}-pc-mks 871 exit ;; 872 8664:Windows_NT:*) 873 echo x86_64-pc-mks 874 exit ;; 875 i*:Windows_NT*:* | Pentium*:Windows_NT*:*) 876 # How do we know it's Interix rather than the generic POSIX subsystem? 877 # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we 878 # UNAME_MACHINE based on the output of uname instead of i386? 879 echo i586-pc-interix 880 exit ;; 881 i*:UWIN*:*) 882 echo ${UNAME_MACHINE}-pc-uwin 883 exit ;; 884 amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) 885 echo x86_64-unknown-cygwin 886 exit ;; 887 p*:CYGWIN*:*) 888 echo powerpcle-unknown-cygwin 889 exit ;; 890 prep*:SunOS:5.*:*) 891 echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 892 exit ;; 893 *:GNU:*:*) 894 # the GNU system 895 echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` 896 exit ;; 897 *:GNU/*:*:*) 898 # other systems with GNU libc and userland 899 echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} 900 exit ;; 901 i*86:Minix:*:*) 902 echo ${UNAME_MACHINE}-pc-minix 903 exit ;; 904 aarch64:Linux:*:*) 905 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 906 exit ;; 907 aarch64_be:Linux:*:*) 908 UNAME_MACHINE=aarch64_be 909 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 910 exit ;; 911 alpha:Linux:*:*) 912 case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in 913 EV5) UNAME_MACHINE=alphaev5 ;; 914 EV56) UNAME_MACHINE=alphaev56 ;; 915 PCA56) UNAME_MACHINE=alphapca56 ;; 916 PCA57) UNAME_MACHINE=alphapca56 ;; 917 EV6) UNAME_MACHINE=alphaev6 ;; 918 EV67) UNAME_MACHINE=alphaev67 ;; 919 EV68*) UNAME_MACHINE=alphaev68 ;; 920 esac 921 objdump --private-headers /bin/sh | grep -q ld.so.1 922 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi 923 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 924 exit ;; 925 arc:Linux:*:* | arceb:Linux:*:*) 926 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 927 exit ;; 928 arm*:Linux:*:*) 929 eval $set_cc_for_build 930 if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ 931 | grep -q __ARM_EABI__ 932 then 933 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 934 else 935 if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ 936 | grep -q __ARM_PCS_VFP 937 then 938 echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi 939 else 940 echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf 941 fi 942 fi 943 exit ;; 944 avr32*:Linux:*:*) 945 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 946 exit ;; 947 cris:Linux:*:*) 948 echo ${UNAME_MACHINE}-axis-linux-${LIBC} 949 exit ;; 950 crisv32:Linux:*:*) 951 echo ${UNAME_MACHINE}-axis-linux-${LIBC} 952 exit ;; 953 e2k:Linux:*:*) 954 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 955 exit ;; 956 frv:Linux:*:*) 957 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 958 exit ;; 959 hexagon:Linux:*:*) 960 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 961 exit ;; 962 i*86:Linux:*:*) 963 echo ${UNAME_MACHINE}-pc-linux-${LIBC} 964 exit ;; 965 ia64:Linux:*:*) 966 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 967 exit ;; 968 m32r*:Linux:*:*) 969 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 970 exit ;; 971 m68*:Linux:*:*) 972 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 973 exit ;; 974 mips:Linux:*:* | mips64:Linux:*:*) 975 eval $set_cc_for_build 976 sed 's/^ //' << EOF >$dummy.c 977 #undef CPU 978 #undef ${UNAME_MACHINE} 979 #undef ${UNAME_MACHINE}el 980 #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) 981 CPU=${UNAME_MACHINE}el 982 #else 983 #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) 984 CPU=${UNAME_MACHINE} 985 #else 986 CPU= 987 #endif 988 #endif 989 EOF 990 eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` 991 test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } 992 ;; 993 openrisc*:Linux:*:*) 994 echo or1k-unknown-linux-${LIBC} 995 exit ;; 996 or32:Linux:*:* | or1k*:Linux:*:*) 997 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 998 exit ;; 999 padre:Linux:*:*) 1000 echo sparc-unknown-linux-${LIBC} 1001 exit ;; 1002 parisc64:Linux:*:* | hppa64:Linux:*:*) 1003 echo hppa64-unknown-linux-${LIBC} 1004 exit ;; 1005 parisc:Linux:*:* | hppa:Linux:*:*) 1006 # Look for CPU level 1007 case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in 1008 PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; 1009 PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; 1010 *) echo hppa-unknown-linux-${LIBC} ;; 1011 esac 1012 exit ;; 1013 ppc64:Linux:*:*) 1014 echo powerpc64-unknown-linux-${LIBC} 1015 exit ;; 1016 ppc:Linux:*:*) 1017 echo powerpc-unknown-linux-${LIBC} 1018 exit ;; 1019 ppc64le:Linux:*:*) 1020 echo powerpc64le-unknown-linux-${LIBC} 1021 exit ;; 1022 ppcle:Linux:*:*) 1023 echo powerpcle-unknown-linux-${LIBC} 1024 exit ;; 1025 s390:Linux:*:* | s390x:Linux:*:*) 1026 echo ${UNAME_MACHINE}-ibm-linux-${LIBC} 1027 exit ;; 1028 sh64*:Linux:*:*) 1029 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1030 exit ;; 1031 sh*:Linux:*:*) 1032 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1033 exit ;; 1034 sparc:Linux:*:* | sparc64:Linux:*:*) 1035 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1036 exit ;; 1037 tile*:Linux:*:*) 1038 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1039 exit ;; 1040 vax:Linux:*:*) 1041 echo ${UNAME_MACHINE}-dec-linux-${LIBC} 1042 exit ;; 1043 x86_64:Linux:*:*) 1044 echo ${UNAME_MACHINE}-pc-linux-${LIBC} 1045 exit ;; 1046 xtensa*:Linux:*:*) 1047 echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1048 exit ;; 1049 i*86:DYNIX/ptx:4*:*) 1050 # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. 1051 # earlier versions are messed up and put the nodename in both 1052 # sysname and nodename. 1053 echo i386-sequent-sysv4 1054 exit ;; 1055 i*86:UNIX_SV:4.2MP:2.*) 1056 # Unixware is an offshoot of SVR4, but it has its own version 1057 # number series starting with 2... 1058 # I am not positive that other SVR4 systems won't match this, 1059 # I just have to hope. -- rms. 1060 # Use sysv4.2uw... so that sysv4* matches it. 1061 echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} 1062 exit ;; 1063 i*86:OS/2:*:*) 1064 # If we were able to find `uname', then EMX Unix compatibility 1065 # is probably installed. 1066 echo ${UNAME_MACHINE}-pc-os2-emx 1067 exit ;; 1068 i*86:XTS-300:*:STOP) 1069 echo ${UNAME_MACHINE}-unknown-stop 1070 exit ;; 1071 i*86:atheos:*:*) 1072 echo ${UNAME_MACHINE}-unknown-atheos 1073 exit ;; 1074 i*86:syllable:*:*) 1075 echo ${UNAME_MACHINE}-pc-syllable 1076 exit ;; 1077 i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) 1078 echo i386-unknown-lynxos${UNAME_RELEASE} 1079 exit ;; 1080 i*86:*DOS:*:*) 1081 echo ${UNAME_MACHINE}-pc-msdosdjgpp 1082 exit ;; 1083 i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) 1084 UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` 1085 if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then 1086 echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} 1087 else 1088 echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} 1089 fi 1090 exit ;; 1091 i*86:*:5:[678]*) 1092 # UnixWare 7.x, OpenUNIX and OpenServer 6. 1093 case `/bin/uname -X | grep "^Machine"` in 1094 *486*) UNAME_MACHINE=i486 ;; 1095 *Pentium) UNAME_MACHINE=i586 ;; 1096 *Pent*|*Celeron) UNAME_MACHINE=i686 ;; 1097 esac 1098 echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} 1099 exit ;; 1100 i*86:*:3.2:*) 1101 if test -f /usr/options/cb.name; then 1102 UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` 1103 echo ${UNAME_MACHINE}-pc-isc$UNAME_REL 1104 elif /bin/uname -X 2>/dev/null >/dev/null ; then 1105 UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` 1106 (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 1107 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ 1108 && UNAME_MACHINE=i586 1109 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ 1110 && UNAME_MACHINE=i686 1111 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ 1112 && UNAME_MACHINE=i686 1113 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL 1114 else 1115 echo ${UNAME_MACHINE}-pc-sysv32 1116 fi 1117 exit ;; 1118 pc:*:*:*) 1119 # Left here for compatibility: 1120 # uname -m prints for DJGPP always 'pc', but it prints nothing about 1121 # the processor, so we play safe by assuming i586. 1122 # Note: whatever this is, it MUST be the same as what config.sub 1123 # prints for the "djgpp" host, or else GDB configury will decide that 1124 # this is a cross-build. 1125 echo i586-pc-msdosdjgpp 1126 exit ;; 1127 Intel:Mach:3*:*) 1128 echo i386-pc-mach3 1129 exit ;; 1130 paragon:*:*:*) 1131 echo i860-intel-osf1 1132 exit ;; 1133 i860:*:4.*:*) # i860-SVR4 1134 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then 1135 echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 1136 else # Add other i860-SVR4 vendors below as they are discovered. 1137 echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 1138 fi 1139 exit ;; 1140 mini*:CTIX:SYS*5:*) 1141 # "miniframe" 1142 echo m68010-convergent-sysv 1143 exit ;; 1144 mc68k:UNIX:SYSTEM5:3.51m) 1145 echo m68k-convergent-sysv 1146 exit ;; 1147 M680?0:D-NIX:5.3:*) 1148 echo m68k-diab-dnix 1149 exit ;; 1150 M68*:*:R3V[5678]*:*) 1151 test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 1152 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) 1153 OS_REL='' 1154 test -r /etc/.relid \ 1155 && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` 1156 /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ 1157 && { echo i486-ncr-sysv4.3${OS_REL}; exit; } 1158 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ 1159 && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 1160 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) 1161 /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ 1162 && { echo i486-ncr-sysv4; exit; } ;; 1163 NCR*:*:4.2:* | MPRAS*:*:4.2:*) 1164 OS_REL='.3' 1165 test -r /etc/.relid \ 1166 && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` 1167 /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ 1168 && { echo i486-ncr-sysv4.3${OS_REL}; exit; } 1169 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ 1170 && { echo i586-ncr-sysv4.3${OS_REL}; exit; } 1171 /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ 1172 && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 1173 m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) 1174 echo m68k-unknown-lynxos${UNAME_RELEASE} 1175 exit ;; 1176 mc68030:UNIX_System_V:4.*:*) 1177 echo m68k-atari-sysv4 1178 exit ;; 1179 TSUNAMI:LynxOS:2.*:*) 1180 echo sparc-unknown-lynxos${UNAME_RELEASE} 1181 exit ;; 1182 rs6000:LynxOS:2.*:*) 1183 echo rs6000-unknown-lynxos${UNAME_RELEASE} 1184 exit ;; 1185 PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) 1186 echo powerpc-unknown-lynxos${UNAME_RELEASE} 1187 exit ;; 1188 SM[BE]S:UNIX_SV:*:*) 1189 echo mips-dde-sysv${UNAME_RELEASE} 1190 exit ;; 1191 RM*:ReliantUNIX-*:*:*) 1192 echo mips-sni-sysv4 1193 exit ;; 1194 RM*:SINIX-*:*:*) 1195 echo mips-sni-sysv4 1196 exit ;; 1197 *:SINIX-*:*:*) 1198 if uname -p 2>/dev/null >/dev/null ; then 1199 UNAME_MACHINE=`(uname -p) 2>/dev/null` 1200 echo ${UNAME_MACHINE}-sni-sysv4 1201 else 1202 echo ns32k-sni-sysv 1203 fi 1204 exit ;; 1205 PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort 1206 # says <Richard.M.Bartel@ccMail.Census.GOV> 1207 echo i586-unisys-sysv4 1208 exit ;; 1209 *:UNIX_System_V:4*:FTX*) 1210 # From Gerald Hewes <hewes@openmarket.com>. 1211 # How about differentiating between stratus architectures? -djm 1212 echo hppa1.1-stratus-sysv4 1213 exit ;; 1214 *:*:*:FTX*) 1215 # From seanf@swdc.stratus.com. 1216 echo i860-stratus-sysv4 1217 exit ;; 1218 i*86:VOS:*:*) 1219 # From Paul.Green@stratus.com. 1220 echo ${UNAME_MACHINE}-stratus-vos 1221 exit ;; 1222 *:VOS:*:*) 1223 # From Paul.Green@stratus.com. 1224 echo hppa1.1-stratus-vos 1225 exit ;; 1226 mc68*:A/UX:*:*) 1227 echo m68k-apple-aux${UNAME_RELEASE} 1228 exit ;; 1229 news*:NEWS-OS:6*:*) 1230 echo mips-sony-newsos6 1231 exit ;; 1232 R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) 1233 if [ -d /usr/nec ]; then 1234 echo mips-nec-sysv${UNAME_RELEASE} 1235 else 1236 echo mips-unknown-sysv${UNAME_RELEASE} 1237 fi 1238 exit ;; 1239 BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. 1240 echo powerpc-be-beos 1241 exit ;; 1242 BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. 1243 echo powerpc-apple-beos 1244 exit ;; 1245 BePC:BeOS:*:*) # BeOS running on Intel PC compatible. 1246 echo i586-pc-beos 1247 exit ;; 1248 BePC:Haiku:*:*) # Haiku running on Intel PC compatible. 1249 echo i586-pc-haiku 1250 exit ;; 1251 x86_64:Haiku:*:*) 1252 echo x86_64-unknown-haiku 1253 exit ;; 1254 SX-4:SUPER-UX:*:*) 1255 echo sx4-nec-superux${UNAME_RELEASE} 1256 exit ;; 1257 SX-5:SUPER-UX:*:*) 1258 echo sx5-nec-superux${UNAME_RELEASE} 1259 exit ;; 1260 SX-6:SUPER-UX:*:*) 1261 echo sx6-nec-superux${UNAME_RELEASE} 1262 exit ;; 1263 SX-7:SUPER-UX:*:*) 1264 echo sx7-nec-superux${UNAME_RELEASE} 1265 exit ;; 1266 SX-8:SUPER-UX:*:*) 1267 echo sx8-nec-superux${UNAME_RELEASE} 1268 exit ;; 1269 SX-8R:SUPER-UX:*:*) 1270 echo sx8r-nec-superux${UNAME_RELEASE} 1271 exit ;; 1272 Power*:Rhapsody:*:*) 1273 echo powerpc-apple-rhapsody${UNAME_RELEASE} 1274 exit ;; 1275 *:Rhapsody:*:*) 1276 echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} 1277 exit ;; 1278 *:Darwin:*:*) 1279 UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown 1280 eval $set_cc_for_build 1281 if test "$UNAME_PROCESSOR" = unknown ; then 1282 UNAME_PROCESSOR=powerpc 1283 fi 1284 if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then 1285 if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then 1286 if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ 1287 (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ 1288 grep IS_64BIT_ARCH >/dev/null 1289 then 1290 case $UNAME_PROCESSOR in 1291 i386) UNAME_PROCESSOR=x86_64 ;; 1292 powerpc) UNAME_PROCESSOR=powerpc64 ;; 1293 esac 1294 fi 1295 fi 1296 elif test "$UNAME_PROCESSOR" = i386 ; then 1297 # Avoid executing cc on OS X 10.9, as it ships with a stub 1298 # that puts up a graphical alert prompting to install 1299 # developer tools. Any system running Mac OS X 10.7 or 1300 # later (Darwin 11 and later) is required to have a 64-bit 1301 # processor. This is not true of the ARM version of Darwin 1302 # that Apple uses in portable devices. 1303 UNAME_PROCESSOR=x86_64 1304 fi 1305 echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} 1306 exit ;; 1307 *:procnto*:*:* | *:QNX:[0123456789]*:*) 1308 UNAME_PROCESSOR=`uname -p` 1309 if test "$UNAME_PROCESSOR" = "x86"; then 1310 UNAME_PROCESSOR=i386 1311 UNAME_MACHINE=pc 1312 fi 1313 echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} 1314 exit ;; 1315 *:QNX:*:4*) 1316 echo i386-pc-qnx 1317 exit ;; 1318 NEO-?:NONSTOP_KERNEL:*:*) 1319 echo neo-tandem-nsk${UNAME_RELEASE} 1320 exit ;; 1321 NSE-*:NONSTOP_KERNEL:*:*) 1322 echo nse-tandem-nsk${UNAME_RELEASE} 1323 exit ;; 1324 NSR-?:NONSTOP_KERNEL:*:*) 1325 echo nsr-tandem-nsk${UNAME_RELEASE} 1326 exit ;; 1327 *:NonStop-UX:*:*) 1328 echo mips-compaq-nonstopux 1329 exit ;; 1330 BS2000:POSIX*:*:*) 1331 echo bs2000-siemens-sysv 1332 exit ;; 1333 DS/*:UNIX_System_V:*:*) 1334 echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} 1335 exit ;; 1336 *:Plan9:*:*) 1337 # "uname -m" is not consistent, so use $cputype instead. 386 1338 # is converted to i386 for consistency with other x86 1339 # operating systems. 1340 if test "$cputype" = "386"; then 1341 UNAME_MACHINE=i386 1342 else 1343 UNAME_MACHINE="$cputype" 1344 fi 1345 echo ${UNAME_MACHINE}-unknown-plan9 1346 exit ;; 1347 *:TOPS-10:*:*) 1348 echo pdp10-unknown-tops10 1349 exit ;; 1350 *:TENEX:*:*) 1351 echo pdp10-unknown-tenex 1352 exit ;; 1353 KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) 1354 echo pdp10-dec-tops20 1355 exit ;; 1356 XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) 1357 echo pdp10-xkl-tops20 1358 exit ;; 1359 *:TOPS-20:*:*) 1360 echo pdp10-unknown-tops20 1361 exit ;; 1362 *:ITS:*:*) 1363 echo pdp10-unknown-its 1364 exit ;; 1365 SEI:*:*:SEIUX) 1366 echo mips-sei-seiux${UNAME_RELEASE} 1367 exit ;; 1368 *:DragonFly:*:*) 1369 echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` 1370 exit ;; 1371 *:*VMS:*:*) 1372 UNAME_MACHINE=`(uname -p) 2>/dev/null` 1373 case "${UNAME_MACHINE}" in 1374 A*) echo alpha-dec-vms ; exit ;; 1375 I*) echo ia64-dec-vms ; exit ;; 1376 V*) echo vax-dec-vms ; exit ;; 1377 esac ;; 1378 *:XENIX:*:SysV) 1379 echo i386-pc-xenix 1380 exit ;; 1381 i*86:skyos:*:*) 1382 echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' 1383 exit ;; 1384 i*86:rdos:*:*) 1385 echo ${UNAME_MACHINE}-pc-rdos 1386 exit ;; 1387 i*86:AROS:*:*) 1388 echo ${UNAME_MACHINE}-pc-aros 1389 exit ;; 1390 x86_64:VMkernel:*:*) 1391 echo ${UNAME_MACHINE}-unknown-esx 1392 exit ;; 1393 esac 1394 1395 cat >&2 <<EOF 1396 $0: unable to guess system type 1397 1398 This script, last modified $timestamp, has failed to recognize 1399 the operating system you are using. It is advised that you 1400 download the most up to date version of the config scripts from 1401 1402 http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD 1403 and 1404 http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD 1405 1406 If the version you run ($0) is already up to date, please 1407 send the following data and any information you think might be 1408 pertinent to <config-patches@gnu.org> in order to provide the needed 1409 information to handle your system. 1410 1411 config.guess timestamp = $timestamp 1412 1413 uname -m = `(uname -m) 2>/dev/null || echo unknown` 1414 uname -r = `(uname -r) 2>/dev/null || echo unknown` 1415 uname -s = `(uname -s) 2>/dev/null || echo unknown` 1416 uname -v = `(uname -v) 2>/dev/null || echo unknown` 1417 1418 /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` 1419 /bin/uname -X = `(/bin/uname -X) 2>/dev/null` 1420 1421 hostinfo = `(hostinfo) 2>/dev/null` 1422 /bin/universe = `(/bin/universe) 2>/dev/null` 1423 /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` 1424 /bin/arch = `(/bin/arch) 2>/dev/null` 1425 /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` 1426 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` 1427 1428 UNAME_MACHINE = ${UNAME_MACHINE} 1429 UNAME_RELEASE = ${UNAME_RELEASE} 1430 UNAME_SYSTEM = ${UNAME_SYSTEM} 1431 UNAME_VERSION = ${UNAME_VERSION} 1432 EOF 1433 1434 exit 1 1435 1436 # Local variables: 1437 # eval: (add-hook 'write-file-hooks 'time-stamp) 1438 # time-stamp-start: "timestamp='" 1439 # time-stamp-format: "%:y-%02m-%02d" 1440 # time-stamp-end: "'" 1441 # End: 1 /usr/share/automake-1.15/config.guess -
Property mode
changed from
-
automake/config.sub
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #! /bin/sh 2 # Configuration validation subroutine script. 3 # Copyright 1992-2015 Free Software Foundation, Inc. 4 5 timestamp='2015-08-20' 6 7 # This file is free software; you can redistribute it and/or modify it 8 # under the terms of the GNU General Public License as published by 9 # the Free Software Foundation; either version 3 of the License, or 10 # (at your option) any later version. 11 # 12 # This program is distributed in the hope that it will be useful, but 13 # WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 # General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with this program; if not, see <http://www.gnu.org/licenses/>. 19 # 20 # As a special exception to the GNU General Public License, if you 21 # distribute this file as part of a program that contains a 22 # configuration script generated by Autoconf, you may include it under 23 # the same distribution terms that you use for the rest of that 24 # program. This Exception is an additional permission under section 7 25 # of the GNU General Public License, version 3 ("GPLv3"). 26 27 28 # Please send patches to <config-patches@gnu.org>. 29 # 30 # Configuration subroutine to validate and canonicalize a configuration type. 31 # Supply the specified configuration type as an argument. 32 # If it is invalid, we print an error message on stderr and exit with code 1. 33 # Otherwise, we print the canonical config type on stdout and succeed. 34 35 # You can get the latest version of this script from: 36 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD 37 38 # This file is supposed to be the same for all GNU packages 39 # and recognize all the CPU types, system types and aliases 40 # that are meaningful with *any* GNU software. 41 # Each package is responsible for reporting which valid configurations 42 # it does not support. The user should be able to distinguish 43 # a failure to support a valid configuration from a meaningless 44 # configuration. 45 46 # The goal of this file is to map all the various variations of a given 47 # machine specification into a single specification in the form: 48 # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM 49 # or in some cases, the newer four-part form: 50 # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM 51 # It is wrong to echo any other type of specification. 52 53 me=`echo "$0" | sed -e 's,.*/,,'` 54 55 usage="\ 56 Usage: $0 [OPTION] CPU-MFR-OPSYS 57 $0 [OPTION] ALIAS 58 59 Canonicalize a configuration name. 60 61 Operation modes: 62 -h, --help print this help, then exit 63 -t, --time-stamp print date of last modification, then exit 64 -v, --version print version number, then exit 65 66 Report bugs and patches to <config-patches@gnu.org>." 67 68 version="\ 69 GNU config.sub ($timestamp) 70 71 Copyright 1992-2015 Free Software Foundation, Inc. 72 73 This is free software; see the source for copying conditions. There is NO 74 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 75 76 help=" 77 Try \`$me --help' for more information." 78 79 # Parse command line 80 while test $# -gt 0 ; do 81 case $1 in 82 --time-stamp | --time* | -t ) 83 echo "$timestamp" ; exit ;; 84 --version | -v ) 85 echo "$version" ; exit ;; 86 --help | --h* | -h ) 87 echo "$usage"; exit ;; 88 -- ) # Stop option processing 89 shift; break ;; 90 - ) # Use stdin as input. 91 break ;; 92 -* ) 93 echo "$me: invalid option $1$help" 94 exit 1 ;; 95 96 *local*) 97 # First pass through any local machine types. 98 echo $1 99 exit ;; 100 101 * ) 102 break ;; 103 esac 104 done 105 106 case $# in 107 0) echo "$me: missing argument$help" >&2 108 exit 1;; 109 1) ;; 110 *) echo "$me: too many arguments$help" >&2 111 exit 1;; 112 esac 113 114 # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). 115 # Here we must recognize all the valid KERNEL-OS combinations. 116 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` 117 case $maybe_os in 118 nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ 119 linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ 120 knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ 121 kopensolaris*-gnu* | \ 122 storm-chaos* | os2-emx* | rtmk-nova*) 123 os=-$maybe_os 124 basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` 125 ;; 126 android-linux) 127 os=-linux-android 128 basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown 129 ;; 130 *) 131 basic_machine=`echo $1 | sed 's/-[^-]*$//'` 132 if [ $basic_machine != $1 ] 133 then os=`echo $1 | sed 's/.*-/-/'` 134 else os=; fi 135 ;; 136 esac 137 138 ### Let's recognize common machines as not being operating systems so 139 ### that things like config.sub decstation-3100 work. We also 140 ### recognize some manufacturers as not being operating systems, so we 141 ### can provide default operating systems below. 142 case $os in 143 -sun*os*) 144 # Prevent following clause from handling this invalid input. 145 ;; 146 -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ 147 -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ 148 -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ 149 -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ 150 -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ 151 -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ 152 -apple | -axis | -knuth | -cray | -microblaze*) 153 os= 154 basic_machine=$1 155 ;; 156 -bluegene*) 157 os=-cnk 158 ;; 159 -sim | -cisco | -oki | -wec | -winbond) 160 os= 161 basic_machine=$1 162 ;; 163 -scout) 164 ;; 165 -wrs) 166 os=-vxworks 167 basic_machine=$1 168 ;; 169 -chorusos*) 170 os=-chorusos 171 basic_machine=$1 172 ;; 173 -chorusrdb) 174 os=-chorusrdb 175 basic_machine=$1 176 ;; 177 -hiux*) 178 os=-hiuxwe2 179 ;; 180 -sco6) 181 os=-sco5v6 182 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 183 ;; 184 -sco5) 185 os=-sco3.2v5 186 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 187 ;; 188 -sco4) 189 os=-sco3.2v4 190 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 191 ;; 192 -sco3.2.[4-9]*) 193 os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` 194 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 195 ;; 196 -sco3.2v[4-9]*) 197 # Don't forget version if it is 3.2v4 or newer. 198 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 199 ;; 200 -sco5v6*) 201 # Don't forget version if it is 3.2v4 or newer. 202 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 203 ;; 204 -sco*) 205 os=-sco3.2v2 206 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 207 ;; 208 -udk*) 209 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 210 ;; 211 -isc) 212 os=-isc2.2 213 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 214 ;; 215 -clix*) 216 basic_machine=clipper-intergraph 217 ;; 218 -isc*) 219 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 220 ;; 221 -lynx*178) 222 os=-lynxos178 223 ;; 224 -lynx*5) 225 os=-lynxos5 226 ;; 227 -lynx*) 228 os=-lynxos 229 ;; 230 -ptx*) 231 basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` 232 ;; 233 -windowsnt*) 234 os=`echo $os | sed -e 's/windowsnt/winnt/'` 235 ;; 236 -psos*) 237 os=-psos 238 ;; 239 -mint | -mint[0-9]*) 240 basic_machine=m68k-atari 241 os=-mint 242 ;; 243 esac 244 245 # Decode aliases for certain CPU-COMPANY combinations. 246 case $basic_machine in 247 # Recognize the basic CPU types without company name. 248 # Some are omitted here because they have special meanings below. 249 1750a | 580 \ 250 | a29k \ 251 | aarch64 | aarch64_be \ 252 | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ 253 | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ 254 | am33_2.0 \ 255 | arc | arceb \ 256 | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ 257 | avr | avr32 \ 258 | ba \ 259 | be32 | be64 \ 260 | bfin \ 261 | c4x | c8051 | clipper \ 262 | d10v | d30v | dlx | dsp16xx \ 263 | e2k | epiphany \ 264 | fido | fr30 | frv | ft32 \ 265 | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ 266 | hexagon \ 267 | i370 | i860 | i960 | ia64 \ 268 | ip2k | iq2000 \ 269 | k1om \ 270 | le32 | le64 \ 271 | lm32 \ 272 | m32c | m32r | m32rle | m68000 | m68k | m88k \ 273 | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ 274 | mips | mipsbe | mipseb | mipsel | mipsle \ 275 | mips16 \ 276 | mips64 | mips64el \ 277 | mips64octeon | mips64octeonel \ 278 | mips64orion | mips64orionel \ 279 | mips64r5900 | mips64r5900el \ 280 | mips64vr | mips64vrel \ 281 | mips64vr4100 | mips64vr4100el \ 282 | mips64vr4300 | mips64vr4300el \ 283 | mips64vr5000 | mips64vr5000el \ 284 | mips64vr5900 | mips64vr5900el \ 285 | mipsisa32 | mipsisa32el \ 286 | mipsisa32r2 | mipsisa32r2el \ 287 | mipsisa32r6 | mipsisa32r6el \ 288 | mipsisa64 | mipsisa64el \ 289 | mipsisa64r2 | mipsisa64r2el \ 290 | mipsisa64r6 | mipsisa64r6el \ 291 | mipsisa64sb1 | mipsisa64sb1el \ 292 | mipsisa64sr71k | mipsisa64sr71kel \ 293 | mipsr5900 | mipsr5900el \ 294 | mipstx39 | mipstx39el \ 295 | mn10200 | mn10300 \ 296 | moxie \ 297 | mt \ 298 | msp430 \ 299 | nds32 | nds32le | nds32be \ 300 | nios | nios2 | nios2eb | nios2el \ 301 | ns16k | ns32k \ 302 | open8 | or1k | or1knd | or32 \ 303 | pdp10 | pdp11 | pj | pjl \ 304 | powerpc | powerpc64 | powerpc64le | powerpcle \ 305 | pyramid \ 306 | riscv32 | riscv64 \ 307 | rl78 | rx \ 308 | score \ 309 | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ 310 | sh64 | sh64le \ 311 | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ 312 | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ 313 | spu \ 314 | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ 315 | ubicom32 \ 316 | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ 317 | visium \ 318 | we32k \ 319 | x86 | xc16x | xstormy16 | xtensa \ 320 | z8k | z80) 321 basic_machine=$basic_machine-unknown 322 ;; 323 c54x) 324 basic_machine=tic54x-unknown 325 ;; 326 c55x) 327 basic_machine=tic55x-unknown 328 ;; 329 c6x) 330 basic_machine=tic6x-unknown 331 ;; 332 leon|leon[3-9]) 333 basic_machine=sparc-$basic_machine 334 ;; 335 m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) 336 basic_machine=$basic_machine-unknown 337 os=-none 338 ;; 339 m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) 340 ;; 341 ms1) 342 basic_machine=mt-unknown 343 ;; 344 345 strongarm | thumb | xscale) 346 basic_machine=arm-unknown 347 ;; 348 xgate) 349 basic_machine=$basic_machine-unknown 350 os=-none 351 ;; 352 xscaleeb) 353 basic_machine=armeb-unknown 354 ;; 355 356 xscaleel) 357 basic_machine=armel-unknown 358 ;; 359 360 # We use `pc' rather than `unknown' 361 # because (1) that's what they normally are, and 362 # (2) the word "unknown" tends to confuse beginning users. 363 i*86 | x86_64) 364 basic_machine=$basic_machine-pc 365 ;; 366 # Object if more than one company name word. 367 *-*-*) 368 echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 369 exit 1 370 ;; 371 # Recognize the basic CPU types with company name. 372 580-* \ 373 | a29k-* \ 374 | aarch64-* | aarch64_be-* \ 375 | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ 376 | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ 377 | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ 378 | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ 379 | avr-* | avr32-* \ 380 | ba-* \ 381 | be32-* | be64-* \ 382 | bfin-* | bs2000-* \ 383 | c[123]* | c30-* | [cjt]90-* | c4x-* \ 384 | c8051-* | clipper-* | craynv-* | cydra-* \ 385 | d10v-* | d30v-* | dlx-* \ 386 | e2k-* | elxsi-* \ 387 | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ 388 | h8300-* | h8500-* \ 389 | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ 390 | hexagon-* \ 391 | i*86-* | i860-* | i960-* | ia64-* \ 392 | ip2k-* | iq2000-* \ 393 | k1om-* \ 394 | le32-* | le64-* \ 395 | lm32-* \ 396 | m32c-* | m32r-* | m32rle-* \ 397 | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ 398 | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ 399 | microblaze-* | microblazeel-* \ 400 | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ 401 | mips16-* \ 402 | mips64-* | mips64el-* \ 403 | mips64octeon-* | mips64octeonel-* \ 404 | mips64orion-* | mips64orionel-* \ 405 | mips64r5900-* | mips64r5900el-* \ 406 | mips64vr-* | mips64vrel-* \ 407 | mips64vr4100-* | mips64vr4100el-* \ 408 | mips64vr4300-* | mips64vr4300el-* \ 409 | mips64vr5000-* | mips64vr5000el-* \ 410 | mips64vr5900-* | mips64vr5900el-* \ 411 | mipsisa32-* | mipsisa32el-* \ 412 | mipsisa32r2-* | mipsisa32r2el-* \ 413 | mipsisa32r6-* | mipsisa32r6el-* \ 414 | mipsisa64-* | mipsisa64el-* \ 415 | mipsisa64r2-* | mipsisa64r2el-* \ 416 | mipsisa64r6-* | mipsisa64r6el-* \ 417 | mipsisa64sb1-* | mipsisa64sb1el-* \ 418 | mipsisa64sr71k-* | mipsisa64sr71kel-* \ 419 | mipsr5900-* | mipsr5900el-* \ 420 | mipstx39-* | mipstx39el-* \ 421 | mmix-* \ 422 | mt-* \ 423 | msp430-* \ 424 | nds32-* | nds32le-* | nds32be-* \ 425 | nios-* | nios2-* | nios2eb-* | nios2el-* \ 426 | none-* | np1-* | ns16k-* | ns32k-* \ 427 | open8-* \ 428 | or1k*-* \ 429 | orion-* \ 430 | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ 431 | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ 432 | pyramid-* \ 433 | riscv32-* | riscv64-* \ 434 | rl78-* | romp-* | rs6000-* | rx-* \ 435 | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ 436 | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ 437 | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ 438 | sparclite-* \ 439 | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ 440 | tahoe-* \ 441 | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ 442 | tile*-* \ 443 | tron-* \ 444 | ubicom32-* \ 445 | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ 446 | vax-* \ 447 | visium-* \ 448 | we32k-* \ 449 | x86-* | x86_64-* | xc16x-* | xps100-* \ 450 | xstormy16-* | xtensa*-* \ 451 | ymp-* \ 452 | z8k-* | z80-*) 453 ;; 454 # Recognize the basic CPU types without company name, with glob match. 455 xtensa*) 456 basic_machine=$basic_machine-unknown 457 ;; 458 # Recognize the various machine names and aliases which stand 459 # for a CPU type and a company and sometimes even an OS. 460 386bsd) 461 basic_machine=i386-unknown 462 os=-bsd 463 ;; 464 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) 465 basic_machine=m68000-att 466 ;; 467 3b*) 468 basic_machine=we32k-att 469 ;; 470 a29khif) 471 basic_machine=a29k-amd 472 os=-udi 473 ;; 474 abacus) 475 basic_machine=abacus-unknown 476 ;; 477 adobe68k) 478 basic_machine=m68010-adobe 479 os=-scout 480 ;; 481 alliant | fx80) 482 basic_machine=fx80-alliant 483 ;; 484 altos | altos3068) 485 basic_machine=m68k-altos 486 ;; 487 am29k) 488 basic_machine=a29k-none 489 os=-bsd 490 ;; 491 amd64) 492 basic_machine=x86_64-pc 493 ;; 494 amd64-*) 495 basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` 496 ;; 497 amdahl) 498 basic_machine=580-amdahl 499 os=-sysv 500 ;; 501 amiga | amiga-*) 502 basic_machine=m68k-unknown 503 ;; 504 amigaos | amigados) 505 basic_machine=m68k-unknown 506 os=-amigaos 507 ;; 508 amigaunix | amix) 509 basic_machine=m68k-unknown 510 os=-sysv4 511 ;; 512 apollo68) 513 basic_machine=m68k-apollo 514 os=-sysv 515 ;; 516 apollo68bsd) 517 basic_machine=m68k-apollo 518 os=-bsd 519 ;; 520 aros) 521 basic_machine=i386-pc 522 os=-aros 523 ;; 524 asmjs) 525 basic_machine=asmjs-unknown 526 ;; 527 aux) 528 basic_machine=m68k-apple 529 os=-aux 530 ;; 531 balance) 532 basic_machine=ns32k-sequent 533 os=-dynix 534 ;; 535 blackfin) 536 basic_machine=bfin-unknown 537 os=-linux 538 ;; 539 blackfin-*) 540 basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` 541 os=-linux 542 ;; 543 bluegene*) 544 basic_machine=powerpc-ibm 545 os=-cnk 546 ;; 547 c54x-*) 548 basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` 549 ;; 550 c55x-*) 551 basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` 552 ;; 553 c6x-*) 554 basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` 555 ;; 556 c90) 557 basic_machine=c90-cray 558 os=-unicos 559 ;; 560 cegcc) 561 basic_machine=arm-unknown 562 os=-cegcc 563 ;; 564 convex-c1) 565 basic_machine=c1-convex 566 os=-bsd 567 ;; 568 convex-c2) 569 basic_machine=c2-convex 570 os=-bsd 571 ;; 572 convex-c32) 573 basic_machine=c32-convex 574 os=-bsd 575 ;; 576 convex-c34) 577 basic_machine=c34-convex 578 os=-bsd 579 ;; 580 convex-c38) 581 basic_machine=c38-convex 582 os=-bsd 583 ;; 584 cray | j90) 585 basic_machine=j90-cray 586 os=-unicos 587 ;; 588 craynv) 589 basic_machine=craynv-cray 590 os=-unicosmp 591 ;; 592 cr16 | cr16-*) 593 basic_machine=cr16-unknown 594 os=-elf 595 ;; 596 crds | unos) 597 basic_machine=m68k-crds 598 ;; 599 crisv32 | crisv32-* | etraxfs*) 600 basic_machine=crisv32-axis 601 ;; 602 cris | cris-* | etrax*) 603 basic_machine=cris-axis 604 ;; 605 crx) 606 basic_machine=crx-unknown 607 os=-elf 608 ;; 609 da30 | da30-*) 610 basic_machine=m68k-da30 611 ;; 612 decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) 613 basic_machine=mips-dec 614 ;; 615 decsystem10* | dec10*) 616 basic_machine=pdp10-dec 617 os=-tops10 618 ;; 619 decsystem20* | dec20*) 620 basic_machine=pdp10-dec 621 os=-tops20 622 ;; 623 delta | 3300 | motorola-3300 | motorola-delta \ 624 | 3300-motorola | delta-motorola) 625 basic_machine=m68k-motorola 626 ;; 627 delta88) 628 basic_machine=m88k-motorola 629 os=-sysv3 630 ;; 631 dicos) 632 basic_machine=i686-pc 633 os=-dicos 634 ;; 635 djgpp) 636 basic_machine=i586-pc 637 os=-msdosdjgpp 638 ;; 639 dpx20 | dpx20-*) 640 basic_machine=rs6000-bull 641 os=-bosx 642 ;; 643 dpx2* | dpx2*-bull) 644 basic_machine=m68k-bull 645 os=-sysv3 646 ;; 647 ebmon29k) 648 basic_machine=a29k-amd 649 os=-ebmon 650 ;; 651 elxsi) 652 basic_machine=elxsi-elxsi 653 os=-bsd 654 ;; 655 encore | umax | mmax) 656 basic_machine=ns32k-encore 657 ;; 658 es1800 | OSE68k | ose68k | ose | OSE) 659 basic_machine=m68k-ericsson 660 os=-ose 661 ;; 662 fx2800) 663 basic_machine=i860-alliant 664 ;; 665 genix) 666 basic_machine=ns32k-ns 667 ;; 668 gmicro) 669 basic_machine=tron-gmicro 670 os=-sysv 671 ;; 672 go32) 673 basic_machine=i386-pc 674 os=-go32 675 ;; 676 h3050r* | hiux*) 677 basic_machine=hppa1.1-hitachi 678 os=-hiuxwe2 679 ;; 680 h8300hms) 681 basic_machine=h8300-hitachi 682 os=-hms 683 ;; 684 h8300xray) 685 basic_machine=h8300-hitachi 686 os=-xray 687 ;; 688 h8500hms) 689 basic_machine=h8500-hitachi 690 os=-hms 691 ;; 692 harris) 693 basic_machine=m88k-harris 694 os=-sysv3 695 ;; 696 hp300-*) 697 basic_machine=m68k-hp 698 ;; 699 hp300bsd) 700 basic_machine=m68k-hp 701 os=-bsd 702 ;; 703 hp300hpux) 704 basic_machine=m68k-hp 705 os=-hpux 706 ;; 707 hp3k9[0-9][0-9] | hp9[0-9][0-9]) 708 basic_machine=hppa1.0-hp 709 ;; 710 hp9k2[0-9][0-9] | hp9k31[0-9]) 711 basic_machine=m68000-hp 712 ;; 713 hp9k3[2-9][0-9]) 714 basic_machine=m68k-hp 715 ;; 716 hp9k6[0-9][0-9] | hp6[0-9][0-9]) 717 basic_machine=hppa1.0-hp 718 ;; 719 hp9k7[0-79][0-9] | hp7[0-79][0-9]) 720 basic_machine=hppa1.1-hp 721 ;; 722 hp9k78[0-9] | hp78[0-9]) 723 # FIXME: really hppa2.0-hp 724 basic_machine=hppa1.1-hp 725 ;; 726 hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) 727 # FIXME: really hppa2.0-hp 728 basic_machine=hppa1.1-hp 729 ;; 730 hp9k8[0-9][13679] | hp8[0-9][13679]) 731 basic_machine=hppa1.1-hp 732 ;; 733 hp9k8[0-9][0-9] | hp8[0-9][0-9]) 734 basic_machine=hppa1.0-hp 735 ;; 736 hppa-next) 737 os=-nextstep3 738 ;; 739 hppaosf) 740 basic_machine=hppa1.1-hp 741 os=-osf 742 ;; 743 hppro) 744 basic_machine=hppa1.1-hp 745 os=-proelf 746 ;; 747 i370-ibm* | ibm*) 748 basic_machine=i370-ibm 749 ;; 750 i*86v32) 751 basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 752 os=-sysv32 753 ;; 754 i*86v4*) 755 basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 756 os=-sysv4 757 ;; 758 i*86v) 759 basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 760 os=-sysv 761 ;; 762 i*86sol2) 763 basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 764 os=-solaris2 765 ;; 766 i386mach) 767 basic_machine=i386-mach 768 os=-mach 769 ;; 770 i386-vsta | vsta) 771 basic_machine=i386-unknown 772 os=-vsta 773 ;; 774 iris | iris4d) 775 basic_machine=mips-sgi 776 case $os in 777 -irix*) 778 ;; 779 *) 780 os=-irix4 781 ;; 782 esac 783 ;; 784 isi68 | isi) 785 basic_machine=m68k-isi 786 os=-sysv 787 ;; 788 leon-*|leon[3-9]-*) 789 basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` 790 ;; 791 m68knommu) 792 basic_machine=m68k-unknown 793 os=-linux 794 ;; 795 m68knommu-*) 796 basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` 797 os=-linux 798 ;; 799 m88k-omron*) 800 basic_machine=m88k-omron 801 ;; 802 magnum | m3230) 803 basic_machine=mips-mips 804 os=-sysv 805 ;; 806 merlin) 807 basic_machine=ns32k-utek 808 os=-sysv 809 ;; 810 microblaze*) 811 basic_machine=microblaze-xilinx 812 ;; 813 mingw64) 814 basic_machine=x86_64-pc 815 os=-mingw64 816 ;; 817 mingw32) 818 basic_machine=i686-pc 819 os=-mingw32 820 ;; 821 mingw32ce) 822 basic_machine=arm-unknown 823 os=-mingw32ce 824 ;; 825 miniframe) 826 basic_machine=m68000-convergent 827 ;; 828 *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) 829 basic_machine=m68k-atari 830 os=-mint 831 ;; 832 mips3*-*) 833 basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` 834 ;; 835 mips3*) 836 basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown 837 ;; 838 monitor) 839 basic_machine=m68k-rom68k 840 os=-coff 841 ;; 842 morphos) 843 basic_machine=powerpc-unknown 844 os=-morphos 845 ;; 846 moxiebox) 847 basic_machine=moxie-unknown 848 os=-moxiebox 849 ;; 850 msdos) 851 basic_machine=i386-pc 852 os=-msdos 853 ;; 854 ms1-*) 855 basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` 856 ;; 857 msys) 858 basic_machine=i686-pc 859 os=-msys 860 ;; 861 mvs) 862 basic_machine=i370-ibm 863 os=-mvs 864 ;; 865 nacl) 866 basic_machine=le32-unknown 867 os=-nacl 868 ;; 869 ncr3000) 870 basic_machine=i486-ncr 871 os=-sysv4 872 ;; 873 netbsd386) 874 basic_machine=i386-unknown 875 os=-netbsd 876 ;; 877 netwinder) 878 basic_machine=armv4l-rebel 879 os=-linux 880 ;; 881 news | news700 | news800 | news900) 882 basic_machine=m68k-sony 883 os=-newsos 884 ;; 885 news1000) 886 basic_machine=m68030-sony 887 os=-newsos 888 ;; 889 news-3600 | risc-news) 890 basic_machine=mips-sony 891 os=-newsos 892 ;; 893 necv70) 894 basic_machine=v70-nec 895 os=-sysv 896 ;; 897 next | m*-next ) 898 basic_machine=m68k-next 899 case $os in 900 -nextstep* ) 901 ;; 902 -ns2*) 903 os=-nextstep2 904 ;; 905 *) 906 os=-nextstep3 907 ;; 908 esac 909 ;; 910 nh3000) 911 basic_machine=m68k-harris 912 os=-cxux 913 ;; 914 nh[45]000) 915 basic_machine=m88k-harris 916 os=-cxux 917 ;; 918 nindy960) 919 basic_machine=i960-intel 920 os=-nindy 921 ;; 922 mon960) 923 basic_machine=i960-intel 924 os=-mon960 925 ;; 926 nonstopux) 927 basic_machine=mips-compaq 928 os=-nonstopux 929 ;; 930 np1) 931 basic_machine=np1-gould 932 ;; 933 neo-tandem) 934 basic_machine=neo-tandem 935 ;; 936 nse-tandem) 937 basic_machine=nse-tandem 938 ;; 939 nsr-tandem) 940 basic_machine=nsr-tandem 941 ;; 942 op50n-* | op60c-*) 943 basic_machine=hppa1.1-oki 944 os=-proelf 945 ;; 946 openrisc | openrisc-*) 947 basic_machine=or32-unknown 948 ;; 949 os400) 950 basic_machine=powerpc-ibm 951 os=-os400 952 ;; 953 OSE68000 | ose68000) 954 basic_machine=m68000-ericsson 955 os=-ose 956 ;; 957 os68k) 958 basic_machine=m68k-none 959 os=-os68k 960 ;; 961 pa-hitachi) 962 basic_machine=hppa1.1-hitachi 963 os=-hiuxwe2 964 ;; 965 paragon) 966 basic_machine=i860-intel 967 os=-osf 968 ;; 969 parisc) 970 basic_machine=hppa-unknown 971 os=-linux 972 ;; 973 parisc-*) 974 basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` 975 os=-linux 976 ;; 977 pbd) 978 basic_machine=sparc-tti 979 ;; 980 pbb) 981 basic_machine=m68k-tti 982 ;; 983 pc532 | pc532-*) 984 basic_machine=ns32k-pc532 985 ;; 986 pc98) 987 basic_machine=i386-pc 988 ;; 989 pc98-*) 990 basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` 991 ;; 992 pentium | p5 | k5 | k6 | nexgen | viac3) 993 basic_machine=i586-pc 994 ;; 995 pentiumpro | p6 | 6x86 | athlon | athlon_*) 996 basic_machine=i686-pc 997 ;; 998 pentiumii | pentium2 | pentiumiii | pentium3) 999 basic_machine=i686-pc 1000 ;; 1001 pentium4) 1002 basic_machine=i786-pc 1003 ;; 1004 pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) 1005 basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` 1006 ;; 1007 pentiumpro-* | p6-* | 6x86-* | athlon-*) 1008 basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` 1009 ;; 1010 pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) 1011 basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` 1012 ;; 1013 pentium4-*) 1014 basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` 1015 ;; 1016 pn) 1017 basic_machine=pn-gould 1018 ;; 1019 power) basic_machine=power-ibm 1020 ;; 1021 ppc | ppcbe) basic_machine=powerpc-unknown 1022 ;; 1023 ppc-* | ppcbe-*) 1024 basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` 1025 ;; 1026 ppcle | powerpclittle | ppc-le | powerpc-little) 1027 basic_machine=powerpcle-unknown 1028 ;; 1029 ppcle-* | powerpclittle-*) 1030 basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` 1031 ;; 1032 ppc64) basic_machine=powerpc64-unknown 1033 ;; 1034 ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` 1035 ;; 1036 ppc64le | powerpc64little | ppc64-le | powerpc64-little) 1037 basic_machine=powerpc64le-unknown 1038 ;; 1039 ppc64le-* | powerpc64little-*) 1040 basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` 1041 ;; 1042 ps2) 1043 basic_machine=i386-ibm 1044 ;; 1045 pw32) 1046 basic_machine=i586-unknown 1047 os=-pw32 1048 ;; 1049 rdos | rdos64) 1050 basic_machine=x86_64-pc 1051 os=-rdos 1052 ;; 1053 rdos32) 1054 basic_machine=i386-pc 1055 os=-rdos 1056 ;; 1057 rom68k) 1058 basic_machine=m68k-rom68k 1059 os=-coff 1060 ;; 1061 rm[46]00) 1062 basic_machine=mips-siemens 1063 ;; 1064 rtpc | rtpc-*) 1065 basic_machine=romp-ibm 1066 ;; 1067 s390 | s390-*) 1068 basic_machine=s390-ibm 1069 ;; 1070 s390x | s390x-*) 1071 basic_machine=s390x-ibm 1072 ;; 1073 sa29200) 1074 basic_machine=a29k-amd 1075 os=-udi 1076 ;; 1077 sb1) 1078 basic_machine=mipsisa64sb1-unknown 1079 ;; 1080 sb1el) 1081 basic_machine=mipsisa64sb1el-unknown 1082 ;; 1083 sde) 1084 basic_machine=mipsisa32-sde 1085 os=-elf 1086 ;; 1087 sei) 1088 basic_machine=mips-sei 1089 os=-seiux 1090 ;; 1091 sequent) 1092 basic_machine=i386-sequent 1093 ;; 1094 sh) 1095 basic_machine=sh-hitachi 1096 os=-hms 1097 ;; 1098 sh5el) 1099 basic_machine=sh5le-unknown 1100 ;; 1101 sh64) 1102 basic_machine=sh64-unknown 1103 ;; 1104 sparclite-wrs | simso-wrs) 1105 basic_machine=sparclite-wrs 1106 os=-vxworks 1107 ;; 1108 sps7) 1109 basic_machine=m68k-bull 1110 os=-sysv2 1111 ;; 1112 spur) 1113 basic_machine=spur-unknown 1114 ;; 1115 st2000) 1116 basic_machine=m68k-tandem 1117 ;; 1118 stratus) 1119 basic_machine=i860-stratus 1120 os=-sysv4 1121 ;; 1122 strongarm-* | thumb-*) 1123 basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` 1124 ;; 1125 sun2) 1126 basic_machine=m68000-sun 1127 ;; 1128 sun2os3) 1129 basic_machine=m68000-sun 1130 os=-sunos3 1131 ;; 1132 sun2os4) 1133 basic_machine=m68000-sun 1134 os=-sunos4 1135 ;; 1136 sun3os3) 1137 basic_machine=m68k-sun 1138 os=-sunos3 1139 ;; 1140 sun3os4) 1141 basic_machine=m68k-sun 1142 os=-sunos4 1143 ;; 1144 sun4os3) 1145 basic_machine=sparc-sun 1146 os=-sunos3 1147 ;; 1148 sun4os4) 1149 basic_machine=sparc-sun 1150 os=-sunos4 1151 ;; 1152 sun4sol2) 1153 basic_machine=sparc-sun 1154 os=-solaris2 1155 ;; 1156 sun3 | sun3-*) 1157 basic_machine=m68k-sun 1158 ;; 1159 sun4) 1160 basic_machine=sparc-sun 1161 ;; 1162 sun386 | sun386i | roadrunner) 1163 basic_machine=i386-sun 1164 ;; 1165 sv1) 1166 basic_machine=sv1-cray 1167 os=-unicos 1168 ;; 1169 symmetry) 1170 basic_machine=i386-sequent 1171 os=-dynix 1172 ;; 1173 t3e) 1174 basic_machine=alphaev5-cray 1175 os=-unicos 1176 ;; 1177 t90) 1178 basic_machine=t90-cray 1179 os=-unicos 1180 ;; 1181 tile*) 1182 basic_machine=$basic_machine-unknown 1183 os=-linux-gnu 1184 ;; 1185 tx39) 1186 basic_machine=mipstx39-unknown 1187 ;; 1188 tx39el) 1189 basic_machine=mipstx39el-unknown 1190 ;; 1191 toad1) 1192 basic_machine=pdp10-xkl 1193 os=-tops20 1194 ;; 1195 tower | tower-32) 1196 basic_machine=m68k-ncr 1197 ;; 1198 tpf) 1199 basic_machine=s390x-ibm 1200 os=-tpf 1201 ;; 1202 udi29k) 1203 basic_machine=a29k-amd 1204 os=-udi 1205 ;; 1206 ultra3) 1207 basic_machine=a29k-nyu 1208 os=-sym1 1209 ;; 1210 v810 | necv810) 1211 basic_machine=v810-nec 1212 os=-none 1213 ;; 1214 vaxv) 1215 basic_machine=vax-dec 1216 os=-sysv 1217 ;; 1218 vms) 1219 basic_machine=vax-dec 1220 os=-vms 1221 ;; 1222 vpp*|vx|vx-*) 1223 basic_machine=f301-fujitsu 1224 ;; 1225 vxworks960) 1226 basic_machine=i960-wrs 1227 os=-vxworks 1228 ;; 1229 vxworks68) 1230 basic_machine=m68k-wrs 1231 os=-vxworks 1232 ;; 1233 vxworks29k) 1234 basic_machine=a29k-wrs 1235 os=-vxworks 1236 ;; 1237 w65*) 1238 basic_machine=w65-wdc 1239 os=-none 1240 ;; 1241 w89k-*) 1242 basic_machine=hppa1.1-winbond 1243 os=-proelf 1244 ;; 1245 xbox) 1246 basic_machine=i686-pc 1247 os=-mingw32 1248 ;; 1249 xps | xps100) 1250 basic_machine=xps100-honeywell 1251 ;; 1252 xscale-* | xscalee[bl]-*) 1253 basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` 1254 ;; 1255 ymp) 1256 basic_machine=ymp-cray 1257 os=-unicos 1258 ;; 1259 z8k-*-coff) 1260 basic_machine=z8k-unknown 1261 os=-sim 1262 ;; 1263 z80-*-coff) 1264 basic_machine=z80-unknown 1265 os=-sim 1266 ;; 1267 none) 1268 basic_machine=none-none 1269 os=-none 1270 ;; 1271 1272 # Here we handle the default manufacturer of certain CPU types. It is in 1273 # some cases the only manufacturer, in others, it is the most popular. 1274 w89k) 1275 basic_machine=hppa1.1-winbond 1276 ;; 1277 op50n) 1278 basic_machine=hppa1.1-oki 1279 ;; 1280 op60c) 1281 basic_machine=hppa1.1-oki 1282 ;; 1283 romp) 1284 basic_machine=romp-ibm 1285 ;; 1286 mmix) 1287 basic_machine=mmix-knuth 1288 ;; 1289 rs6000) 1290 basic_machine=rs6000-ibm 1291 ;; 1292 vax) 1293 basic_machine=vax-dec 1294 ;; 1295 pdp10) 1296 # there are many clones, so DEC is not a safe bet 1297 basic_machine=pdp10-unknown 1298 ;; 1299 pdp11) 1300 basic_machine=pdp11-dec 1301 ;; 1302 we32k) 1303 basic_machine=we32k-att 1304 ;; 1305 sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) 1306 basic_machine=sh-unknown 1307 ;; 1308 sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) 1309 basic_machine=sparc-sun 1310 ;; 1311 cydra) 1312 basic_machine=cydra-cydrome 1313 ;; 1314 orion) 1315 basic_machine=orion-highlevel 1316 ;; 1317 orion105) 1318 basic_machine=clipper-highlevel 1319 ;; 1320 mac | mpw | mac-mpw) 1321 basic_machine=m68k-apple 1322 ;; 1323 pmac | pmac-mpw) 1324 basic_machine=powerpc-apple 1325 ;; 1326 *-unknown) 1327 # Make sure to match an already-canonicalized machine name. 1328 ;; 1329 *) 1330 echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 1331 exit 1 1332 ;; 1333 esac 1334 1335 # Here we canonicalize certain aliases for manufacturers. 1336 case $basic_machine in 1337 *-digital*) 1338 basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` 1339 ;; 1340 *-commodore*) 1341 basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` 1342 ;; 1343 *) 1344 ;; 1345 esac 1346 1347 # Decode manufacturer-specific aliases for certain operating systems. 1348 1349 if [ x"$os" != x"" ] 1350 then 1351 case $os in 1352 # First match some system type aliases 1353 # that might get confused with valid system types. 1354 # -solaris* is a basic system type, with this one exception. 1355 -auroraux) 1356 os=-auroraux 1357 ;; 1358 -solaris1 | -solaris1.*) 1359 os=`echo $os | sed -e 's|solaris1|sunos4|'` 1360 ;; 1361 -solaris) 1362 os=-solaris2 1363 ;; 1364 -svr4*) 1365 os=-sysv4 1366 ;; 1367 -unixware*) 1368 os=-sysv4.2uw 1369 ;; 1370 -gnu/linux*) 1371 os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` 1372 ;; 1373 # First accept the basic system types. 1374 # The portable systems comes first. 1375 # Each alternative MUST END IN A *, to match a version number. 1376 # -sysv* is not here because it comes later, after sysvr4. 1377 -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ 1378 | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ 1379 | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ 1380 | -sym* | -kopensolaris* | -plan9* \ 1381 | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 1382 | -aos* | -aros* | -cloudabi* | -sortix* \ 1383 | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 1384 | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 1385 | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 1386 | -bitrig* | -openbsd* | -solidbsd* \ 1387 | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ 1388 | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ 1389 | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ 1390 | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ 1391 | -chorusos* | -chorusrdb* | -cegcc* \ 1392 | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ 1393 | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ 1394 | -linux-newlib* | -linux-musl* | -linux-uclibc* \ 1395 | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ 1396 | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ 1397 | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ 1398 | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ 1399 | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ 1400 | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ 1401 | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ 1402 | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) 1403 # Remember, each alternative MUST END IN *, to match a version number. 1404 ;; 1405 -qnx*) 1406 case $basic_machine in 1407 x86-* | i*86-*) 1408 ;; 1409 *) 1410 os=-nto$os 1411 ;; 1412 esac 1413 ;; 1414 -nto-qnx*) 1415 ;; 1416 -nto*) 1417 os=`echo $os | sed -e 's|nto|nto-qnx|'` 1418 ;; 1419 -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ 1420 | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ 1421 | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) 1422 ;; 1423 -mac*) 1424 os=`echo $os | sed -e 's|mac|macos|'` 1425 ;; 1426 -linux-dietlibc) 1427 os=-linux-dietlibc 1428 ;; 1429 -linux*) 1430 os=`echo $os | sed -e 's|linux|linux-gnu|'` 1431 ;; 1432 -sunos5*) 1433 os=`echo $os | sed -e 's|sunos5|solaris2|'` 1434 ;; 1435 -sunos6*) 1436 os=`echo $os | sed -e 's|sunos6|solaris3|'` 1437 ;; 1438 -opened*) 1439 os=-openedition 1440 ;; 1441 -os400*) 1442 os=-os400 1443 ;; 1444 -wince*) 1445 os=-wince 1446 ;; 1447 -osfrose*) 1448 os=-osfrose 1449 ;; 1450 -osf*) 1451 os=-osf 1452 ;; 1453 -utek*) 1454 os=-bsd 1455 ;; 1456 -dynix*) 1457 os=-bsd 1458 ;; 1459 -acis*) 1460 os=-aos 1461 ;; 1462 -atheos*) 1463 os=-atheos 1464 ;; 1465 -syllable*) 1466 os=-syllable 1467 ;; 1468 -386bsd) 1469 os=-bsd 1470 ;; 1471 -ctix* | -uts*) 1472 os=-sysv 1473 ;; 1474 -nova*) 1475 os=-rtmk-nova 1476 ;; 1477 -ns2 ) 1478 os=-nextstep2 1479 ;; 1480 -nsk*) 1481 os=-nsk 1482 ;; 1483 # Preserve the version number of sinix5. 1484 -sinix5.*) 1485 os=`echo $os | sed -e 's|sinix|sysv|'` 1486 ;; 1487 -sinix*) 1488 os=-sysv4 1489 ;; 1490 -tpf*) 1491 os=-tpf 1492 ;; 1493 -triton*) 1494 os=-sysv3 1495 ;; 1496 -oss*) 1497 os=-sysv3 1498 ;; 1499 -svr4) 1500 os=-sysv4 1501 ;; 1502 -svr3) 1503 os=-sysv3 1504 ;; 1505 -sysvr4) 1506 os=-sysv4 1507 ;; 1508 # This must come after -sysvr4. 1509 -sysv*) 1510 ;; 1511 -ose*) 1512 os=-ose 1513 ;; 1514 -es1800*) 1515 os=-ose 1516 ;; 1517 -xenix) 1518 os=-xenix 1519 ;; 1520 -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) 1521 os=-mint 1522 ;; 1523 -aros*) 1524 os=-aros 1525 ;; 1526 -zvmoe) 1527 os=-zvmoe 1528 ;; 1529 -dicos*) 1530 os=-dicos 1531 ;; 1532 -nacl*) 1533 ;; 1534 -none) 1535 ;; 1536 *) 1537 # Get rid of the `-' at the beginning of $os. 1538 os=`echo $os | sed 's/[^-]*-//'` 1539 echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 1540 exit 1 1541 ;; 1542 esac 1543 else 1544 1545 # Here we handle the default operating systems that come with various machines. 1546 # The value should be what the vendor currently ships out the door with their 1547 # machine or put another way, the most popular os provided with the machine. 1548 1549 # Note that if you're going to try to match "-MANUFACTURER" here (say, 1550 # "-sun"), then you have to tell the case statement up towards the top 1551 # that MANUFACTURER isn't an operating system. Otherwise, code above 1552 # will signal an error saying that MANUFACTURER isn't an operating 1553 # system, and we'll never get to this point. 1554 1555 case $basic_machine in 1556 score-*) 1557 os=-elf 1558 ;; 1559 spu-*) 1560 os=-elf 1561 ;; 1562 *-acorn) 1563 os=-riscix1.2 1564 ;; 1565 arm*-rebel) 1566 os=-linux 1567 ;; 1568 arm*-semi) 1569 os=-aout 1570 ;; 1571 c4x-* | tic4x-*) 1572 os=-coff 1573 ;; 1574 c8051-*) 1575 os=-elf 1576 ;; 1577 hexagon-*) 1578 os=-elf 1579 ;; 1580 tic54x-*) 1581 os=-coff 1582 ;; 1583 tic55x-*) 1584 os=-coff 1585 ;; 1586 tic6x-*) 1587 os=-coff 1588 ;; 1589 # This must come before the *-dec entry. 1590 pdp10-*) 1591 os=-tops20 1592 ;; 1593 pdp11-*) 1594 os=-none 1595 ;; 1596 *-dec | vax-*) 1597 os=-ultrix4.2 1598 ;; 1599 m68*-apollo) 1600 os=-domain 1601 ;; 1602 i386-sun) 1603 os=-sunos4.0.2 1604 ;; 1605 m68000-sun) 1606 os=-sunos3 1607 ;; 1608 m68*-cisco) 1609 os=-aout 1610 ;; 1611 mep-*) 1612 os=-elf 1613 ;; 1614 mips*-cisco) 1615 os=-elf 1616 ;; 1617 mips*-*) 1618 os=-elf 1619 ;; 1620 or32-*) 1621 os=-coff 1622 ;; 1623 *-tti) # must be before sparc entry or we get the wrong os. 1624 os=-sysv3 1625 ;; 1626 sparc-* | *-sun) 1627 os=-sunos4.1.1 1628 ;; 1629 *-be) 1630 os=-beos 1631 ;; 1632 *-haiku) 1633 os=-haiku 1634 ;; 1635 *-ibm) 1636 os=-aix 1637 ;; 1638 *-knuth) 1639 os=-mmixware 1640 ;; 1641 *-wec) 1642 os=-proelf 1643 ;; 1644 *-winbond) 1645 os=-proelf 1646 ;; 1647 *-oki) 1648 os=-proelf 1649 ;; 1650 *-hp) 1651 os=-hpux 1652 ;; 1653 *-hitachi) 1654 os=-hiux 1655 ;; 1656 i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) 1657 os=-sysv 1658 ;; 1659 *-cbm) 1660 os=-amigaos 1661 ;; 1662 *-dg) 1663 os=-dgux 1664 ;; 1665 *-dolphin) 1666 os=-sysv3 1667 ;; 1668 m68k-ccur) 1669 os=-rtu 1670 ;; 1671 m88k-omron*) 1672 os=-luna 1673 ;; 1674 *-next ) 1675 os=-nextstep 1676 ;; 1677 *-sequent) 1678 os=-ptx 1679 ;; 1680 *-crds) 1681 os=-unos 1682 ;; 1683 *-ns) 1684 os=-genix 1685 ;; 1686 i370-*) 1687 os=-mvs 1688 ;; 1689 *-next) 1690 os=-nextstep3 1691 ;; 1692 *-gould) 1693 os=-sysv 1694 ;; 1695 *-highlevel) 1696 os=-bsd 1697 ;; 1698 *-encore) 1699 os=-bsd 1700 ;; 1701 *-sgi) 1702 os=-irix 1703 ;; 1704 *-siemens) 1705 os=-sysv4 1706 ;; 1707 *-masscomp) 1708 os=-rtu 1709 ;; 1710 f30[01]-fujitsu | f700-fujitsu) 1711 os=-uxpv 1712 ;; 1713 *-rom68k) 1714 os=-coff 1715 ;; 1716 *-*bug) 1717 os=-coff 1718 ;; 1719 *-apple) 1720 os=-macos 1721 ;; 1722 *-atari*) 1723 os=-mint 1724 ;; 1725 *) 1726 os=-none 1727 ;; 1728 esac 1729 fi 1730 1731 # Here we handle the case where we know the os, and the CPU type, but not the 1732 # manufacturer. We pick the logical manufacturer. 1733 vendor=unknown 1734 case $basic_machine in 1735 *-unknown) 1736 case $os in 1737 -riscix*) 1738 vendor=acorn 1739 ;; 1740 -sunos*) 1741 vendor=sun 1742 ;; 1743 -cnk*|-aix*) 1744 vendor=ibm 1745 ;; 1746 -beos*) 1747 vendor=be 1748 ;; 1749 -hpux*) 1750 vendor=hp 1751 ;; 1752 -mpeix*) 1753 vendor=hp 1754 ;; 1755 -hiux*) 1756 vendor=hitachi 1757 ;; 1758 -unos*) 1759 vendor=crds 1760 ;; 1761 -dgux*) 1762 vendor=dg 1763 ;; 1764 -luna*) 1765 vendor=omron 1766 ;; 1767 -genix*) 1768 vendor=ns 1769 ;; 1770 -mvs* | -opened*) 1771 vendor=ibm 1772 ;; 1773 -os400*) 1774 vendor=ibm 1775 ;; 1776 -ptx*) 1777 vendor=sequent 1778 ;; 1779 -tpf*) 1780 vendor=ibm 1781 ;; 1782 -vxsim* | -vxworks* | -windiss*) 1783 vendor=wrs 1784 ;; 1785 -aux*) 1786 vendor=apple 1787 ;; 1788 -hms*) 1789 vendor=hitachi 1790 ;; 1791 -mpw* | -macos*) 1792 vendor=apple 1793 ;; 1794 -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) 1795 vendor=atari 1796 ;; 1797 -vos*) 1798 vendor=stratus 1799 ;; 1800 esac 1801 basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` 1802 ;; 1803 esac 1804 1805 echo $basic_machine$os 1806 exit 1807 1808 # Local variables: 1809 # eval: (add-hook 'write-file-hooks 'time-stamp) 1810 # time-stamp-start: "timestamp='" 1811 # time-stamp-format: "%:y-%02m-%02d" 1812 # time-stamp-end: "'" 1813 # End: 1 /usr/share/automake-1.15/config.sub -
Property mode
changed from
-
automake/depcomp
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #! /bin/sh 2 # depcomp - compile a program generating dependencies as side-effects 3 4 scriptversion=2013-05-30.07; # UTC 5 6 # Copyright (C) 1999-2014 Free Software Foundation, Inc. 7 8 # This program is free software; you can redistribute it and/or modify 9 # it under the terms of the GNU General Public License as published by 10 # the Free Software Foundation; either version 2, or (at your option) 11 # any later version. 12 13 # This program is distributed in the hope that it will be useful, 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 # GNU General Public License for more details. 17 18 # You should have received a copy of the GNU General Public License 19 # along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 # As a special exception to the GNU General Public License, if you 22 # distribute this file as part of a program that contains a 23 # configuration script generated by Autoconf, you may include it under 24 # the same distribution terms that you use for the rest of that program. 25 26 # Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. 27 28 case $1 in 29 '') 30 echo "$0: No command. Try '$0 --help' for more information." 1>&2 31 exit 1; 32 ;; 33 -h | --h*) 34 cat <<\EOF 35 Usage: depcomp [--help] [--version] PROGRAM [ARGS] 36 37 Run PROGRAMS ARGS to compile a file, generating dependencies 38 as side-effects. 39 40 Environment variables: 41 depmode Dependency tracking mode. 42 source Source file read by 'PROGRAMS ARGS'. 43 object Object file output by 'PROGRAMS ARGS'. 44 DEPDIR directory where to store dependencies. 45 depfile Dependency file to output. 46 tmpdepfile Temporary file to use when outputting dependencies. 47 libtool Whether libtool is used (yes/no). 48 49 Report bugs to <bug-automake@gnu.org>. 50 EOF 51 exit $? 52 ;; 53 -v | --v*) 54 echo "depcomp $scriptversion" 55 exit $? 56 ;; 57 esac 58 59 # Get the directory component of the given path, and save it in the 60 # global variables '$dir'. Note that this directory component will 61 # be either empty or ending with a '/' character. This is deliberate. 62 set_dir_from () 63 { 64 case $1 in 65 */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; 66 *) dir=;; 67 esac 68 } 69 70 # Get the suffix-stripped basename of the given path, and save it the 71 # global variable '$base'. 72 set_base_from () 73 { 74 base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` 75 } 76 77 # If no dependency file was actually created by the compiler invocation, 78 # we still have to create a dummy depfile, to avoid errors with the 79 # Makefile "include basename.Plo" scheme. 80 make_dummy_depfile () 81 { 82 echo "#dummy" > "$depfile" 83 } 84 85 # Factor out some common post-processing of the generated depfile. 86 # Requires the auxiliary global variable '$tmpdepfile' to be set. 87 aix_post_process_depfile () 88 { 89 # If the compiler actually managed to produce a dependency file, 90 # post-process it. 91 if test -f "$tmpdepfile"; then 92 # Each line is of the form 'foo.o: dependency.h'. 93 # Do two passes, one to just change these to 94 # $object: dependency.h 95 # and one to simply output 96 # dependency.h: 97 # which is needed to avoid the deleted-header problem. 98 { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" 99 sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" 100 } > "$depfile" 101 rm -f "$tmpdepfile" 102 else 103 make_dummy_depfile 104 fi 105 } 106 107 # A tabulation character. 108 tab=' ' 109 # A newline character. 110 nl=' 111 ' 112 # Character ranges might be problematic outside the C locale. 113 # These definitions help. 114 upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ 115 lower=abcdefghijklmnopqrstuvwxyz 116 digits=0123456789 117 alpha=${upper}${lower} 118 119 if test -z "$depmode" || test -z "$source" || test -z "$object"; then 120 echo "depcomp: Variables source, object and depmode must be set" 1>&2 121 exit 1 122 fi 123 124 # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. 125 depfile=${depfile-`echo "$object" | 126 sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} 127 tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} 128 129 rm -f "$tmpdepfile" 130 131 # Avoid interferences from the environment. 132 gccflag= dashmflag= 133 134 # Some modes work just like other modes, but use different flags. We 135 # parameterize here, but still list the modes in the big case below, 136 # to make depend.m4 easier to write. Note that we *cannot* use a case 137 # here, because this file can only contain one case statement. 138 if test "$depmode" = hp; then 139 # HP compiler uses -M and no extra arg. 140 gccflag=-M 141 depmode=gcc 142 fi 143 144 if test "$depmode" = dashXmstdout; then 145 # This is just like dashmstdout with a different argument. 146 dashmflag=-xM 147 depmode=dashmstdout 148 fi 149 150 cygpath_u="cygpath -u -f -" 151 if test "$depmode" = msvcmsys; then 152 # This is just like msvisualcpp but w/o cygpath translation. 153 # Just convert the backslash-escaped backslashes to single forward 154 # slashes to satisfy depend.m4 155 cygpath_u='sed s,\\\\,/,g' 156 depmode=msvisualcpp 157 fi 158 159 if test "$depmode" = msvc7msys; then 160 # This is just like msvc7 but w/o cygpath translation. 161 # Just convert the backslash-escaped backslashes to single forward 162 # slashes to satisfy depend.m4 163 cygpath_u='sed s,\\\\,/,g' 164 depmode=msvc7 165 fi 166 167 if test "$depmode" = xlc; then 168 # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. 169 gccflag=-qmakedep=gcc,-MF 170 depmode=gcc 171 fi 172 173 case "$depmode" in 174 gcc3) 175 ## gcc 3 implements dependency tracking that does exactly what 176 ## we want. Yay! Note: for some reason libtool 1.4 doesn't like 177 ## it if -MD -MP comes after the -MF stuff. Hmm. 178 ## Unfortunately, FreeBSD c89 acceptance of flags depends upon 179 ## the command line argument order; so add the flags where they 180 ## appear in depend2.am. Note that the slowdown incurred here 181 ## affects only configure: in makefiles, %FASTDEP% shortcuts this. 182 for arg 183 do 184 case $arg in 185 -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; 186 *) set fnord "$@" "$arg" ;; 187 esac 188 shift # fnord 189 shift # $arg 190 done 191 "$@" 192 stat=$? 193 if test $stat -ne 0; then 194 rm -f "$tmpdepfile" 195 exit $stat 196 fi 197 mv "$tmpdepfile" "$depfile" 198 ;; 199 200 gcc) 201 ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. 202 ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. 203 ## (see the conditional assignment to $gccflag above). 204 ## There are various ways to get dependency output from gcc. Here's 205 ## why we pick this rather obscure method: 206 ## - Don't want to use -MD because we'd like the dependencies to end 207 ## up in a subdir. Having to rename by hand is ugly. 208 ## (We might end up doing this anyway to support other compilers.) 209 ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like 210 ## -MM, not -M (despite what the docs say). Also, it might not be 211 ## supported by the other compilers which use the 'gcc' depmode. 212 ## - Using -M directly means running the compiler twice (even worse 213 ## than renaming). 214 if test -z "$gccflag"; then 215 gccflag=-MD, 216 fi 217 "$@" -Wp,"$gccflag$tmpdepfile" 218 stat=$? 219 if test $stat -ne 0; then 220 rm -f "$tmpdepfile" 221 exit $stat 222 fi 223 rm -f "$depfile" 224 echo "$object : \\" > "$depfile" 225 # The second -e expression handles DOS-style file names with drive 226 # letters. 227 sed -e 's/^[^:]*: / /' \ 228 -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" 229 ## This next piece of magic avoids the "deleted header file" problem. 230 ## The problem is that when a header file which appears in a .P file 231 ## is deleted, the dependency causes make to die (because there is 232 ## typically no way to rebuild the header). We avoid this by adding 233 ## dummy dependencies for each header file. Too bad gcc doesn't do 234 ## this for us directly. 235 ## Some versions of gcc put a space before the ':'. On the theory 236 ## that the space means something, we add a space to the output as 237 ## well. hp depmode also adds that space, but also prefixes the VPATH 238 ## to the object. Take care to not repeat it in the output. 239 ## Some versions of the HPUX 10.20 sed can't process this invocation 240 ## correctly. Breaking it into two sed invocations is a workaround. 241 tr ' ' "$nl" < "$tmpdepfile" \ 242 | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ 243 | sed -e 's/$/ :/' >> "$depfile" 244 rm -f "$tmpdepfile" 245 ;; 246 247 hp) 248 # This case exists only to let depend.m4 do its work. It works by 249 # looking at the text of this script. This case will never be run, 250 # since it is checked for above. 251 exit 1 252 ;; 253 254 sgi) 255 if test "$libtool" = yes; then 256 "$@" "-Wp,-MDupdate,$tmpdepfile" 257 else 258 "$@" -MDupdate "$tmpdepfile" 259 fi 260 stat=$? 261 if test $stat -ne 0; then 262 rm -f "$tmpdepfile" 263 exit $stat 264 fi 265 rm -f "$depfile" 266 267 if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files 268 echo "$object : \\" > "$depfile" 269 # Clip off the initial element (the dependent). Don't try to be 270 # clever and replace this with sed code, as IRIX sed won't handle 271 # lines with more than a fixed number of characters (4096 in 272 # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; 273 # the IRIX cc adds comments like '#:fec' to the end of the 274 # dependency line. 275 tr ' ' "$nl" < "$tmpdepfile" \ 276 | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ 277 | tr "$nl" ' ' >> "$depfile" 278 echo >> "$depfile" 279 # The second pass generates a dummy entry for each header file. 280 tr ' ' "$nl" < "$tmpdepfile" \ 281 | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ 282 >> "$depfile" 283 else 284 make_dummy_depfile 285 fi 286 rm -f "$tmpdepfile" 287 ;; 288 289 xlc) 290 # This case exists only to let depend.m4 do its work. It works by 291 # looking at the text of this script. This case will never be run, 292 # since it is checked for above. 293 exit 1 294 ;; 295 296 aix) 297 # The C for AIX Compiler uses -M and outputs the dependencies 298 # in a .u file. In older versions, this file always lives in the 299 # current directory. Also, the AIX compiler puts '$object:' at the 300 # start of each line; $object doesn't have directory information. 301 # Version 6 uses the directory in both cases. 302 set_dir_from "$object" 303 set_base_from "$object" 304 if test "$libtool" = yes; then 305 tmpdepfile1=$dir$base.u 306 tmpdepfile2=$base.u 307 tmpdepfile3=$dir.libs/$base.u 308 "$@" -Wc,-M 309 else 310 tmpdepfile1=$dir$base.u 311 tmpdepfile2=$dir$base.u 312 tmpdepfile3=$dir$base.u 313 "$@" -M 314 fi 315 stat=$? 316 if test $stat -ne 0; then 317 rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" 318 exit $stat 319 fi 320 321 for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" 322 do 323 test -f "$tmpdepfile" && break 324 done 325 aix_post_process_depfile 326 ;; 327 328 tcc) 329 # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 330 # FIXME: That version still under development at the moment of writing. 331 # Make that this statement remains true also for stable, released 332 # versions. 333 # It will wrap lines (doesn't matter whether long or short) with a 334 # trailing '\', as in: 335 # 336 # foo.o : \ 337 # foo.c \ 338 # foo.h \ 339 # 340 # It will put a trailing '\' even on the last line, and will use leading 341 # spaces rather than leading tabs (at least since its commit 0394caf7 342 # "Emit spaces for -MD"). 343 "$@" -MD -MF "$tmpdepfile" 344 stat=$? 345 if test $stat -ne 0; then 346 rm -f "$tmpdepfile" 347 exit $stat 348 fi 349 rm -f "$depfile" 350 # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. 351 # We have to change lines of the first kind to '$object: \'. 352 sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" 353 # And for each line of the second kind, we have to emit a 'dep.h:' 354 # dummy dependency, to avoid the deleted-header problem. 355 sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" 356 rm -f "$tmpdepfile" 357 ;; 358 359 ## The order of this option in the case statement is important, since the 360 ## shell code in configure will try each of these formats in the order 361 ## listed in this file. A plain '-MD' option would be understood by many 362 ## compilers, so we must ensure this comes after the gcc and icc options. 363 pgcc) 364 # Portland's C compiler understands '-MD'. 365 # Will always output deps to 'file.d' where file is the root name of the 366 # source file under compilation, even if file resides in a subdirectory. 367 # The object file name does not affect the name of the '.d' file. 368 # pgcc 10.2 will output 369 # foo.o: sub/foo.c sub/foo.h 370 # and will wrap long lines using '\' : 371 # foo.o: sub/foo.c ... \ 372 # sub/foo.h ... \ 373 # ... 374 set_dir_from "$object" 375 # Use the source, not the object, to determine the base name, since 376 # that's sadly what pgcc will do too. 377 set_base_from "$source" 378 tmpdepfile=$base.d 379 380 # For projects that build the same source file twice into different object 381 # files, the pgcc approach of using the *source* file root name can cause 382 # problems in parallel builds. Use a locking strategy to avoid stomping on 383 # the same $tmpdepfile. 384 lockdir=$base.d-lock 385 trap " 386 echo '$0: caught signal, cleaning up...' >&2 387 rmdir '$lockdir' 388 exit 1 389 " 1 2 13 15 390 numtries=100 391 i=$numtries 392 while test $i -gt 0; do 393 # mkdir is a portable test-and-set. 394 if mkdir "$lockdir" 2>/dev/null; then 395 # This process acquired the lock. 396 "$@" -MD 397 stat=$? 398 # Release the lock. 399 rmdir "$lockdir" 400 break 401 else 402 # If the lock is being held by a different process, wait 403 # until the winning process is done or we timeout. 404 while test -d "$lockdir" && test $i -gt 0; do 405 sleep 1 406 i=`expr $i - 1` 407 done 408 fi 409 i=`expr $i - 1` 410 done 411 trap - 1 2 13 15 412 if test $i -le 0; then 413 echo "$0: failed to acquire lock after $numtries attempts" >&2 414 echo "$0: check lockdir '$lockdir'" >&2 415 exit 1 416 fi 417 418 if test $stat -ne 0; then 419 rm -f "$tmpdepfile" 420 exit $stat 421 fi 422 rm -f "$depfile" 423 # Each line is of the form `foo.o: dependent.h', 424 # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. 425 # Do two passes, one to just change these to 426 # `$object: dependent.h' and one to simply `dependent.h:'. 427 sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" 428 # Some versions of the HPUX 10.20 sed can't process this invocation 429 # correctly. Breaking it into two sed invocations is a workaround. 430 sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ 431 | sed -e 's/$/ :/' >> "$depfile" 432 rm -f "$tmpdepfile" 433 ;; 434 435 hp2) 436 # The "hp" stanza above does not work with aCC (C++) and HP's ia64 437 # compilers, which have integrated preprocessors. The correct option 438 # to use with these is +Maked; it writes dependencies to a file named 439 # 'foo.d', which lands next to the object file, wherever that 440 # happens to be. 441 # Much of this is similar to the tru64 case; see comments there. 442 set_dir_from "$object" 443 set_base_from "$object" 444 if test "$libtool" = yes; then 445 tmpdepfile1=$dir$base.d 446 tmpdepfile2=$dir.libs/$base.d 447 "$@" -Wc,+Maked 448 else 449 tmpdepfile1=$dir$base.d 450 tmpdepfile2=$dir$base.d 451 "$@" +Maked 452 fi 453 stat=$? 454 if test $stat -ne 0; then 455 rm -f "$tmpdepfile1" "$tmpdepfile2" 456 exit $stat 457 fi 458 459 for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" 460 do 461 test -f "$tmpdepfile" && break 462 done 463 if test -f "$tmpdepfile"; then 464 sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" 465 # Add 'dependent.h:' lines. 466 sed -ne '2,${ 467 s/^ *// 468 s/ \\*$// 469 s/$/:/ 470 p 471 }' "$tmpdepfile" >> "$depfile" 472 else 473 make_dummy_depfile 474 fi 475 rm -f "$tmpdepfile" "$tmpdepfile2" 476 ;; 477 478 tru64) 479 # The Tru64 compiler uses -MD to generate dependencies as a side 480 # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. 481 # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put 482 # dependencies in 'foo.d' instead, so we check for that too. 483 # Subdirectories are respected. 484 set_dir_from "$object" 485 set_base_from "$object" 486 487 if test "$libtool" = yes; then 488 # Libtool generates 2 separate objects for the 2 libraries. These 489 # two compilations output dependencies in $dir.libs/$base.o.d and 490 # in $dir$base.o.d. We have to check for both files, because 491 # one of the two compilations can be disabled. We should prefer 492 # $dir$base.o.d over $dir.libs/$base.o.d because the latter is 493 # automatically cleaned when .libs/ is deleted, while ignoring 494 # the former would cause a distcleancheck panic. 495 tmpdepfile1=$dir$base.o.d # libtool 1.5 496 tmpdepfile2=$dir.libs/$base.o.d # Likewise. 497 tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 498 "$@" -Wc,-MD 499 else 500 tmpdepfile1=$dir$base.d 501 tmpdepfile2=$dir$base.d 502 tmpdepfile3=$dir$base.d 503 "$@" -MD 504 fi 505 506 stat=$? 507 if test $stat -ne 0; then 508 rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" 509 exit $stat 510 fi 511 512 for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" 513 do 514 test -f "$tmpdepfile" && break 515 done 516 # Same post-processing that is required for AIX mode. 517 aix_post_process_depfile 518 ;; 519 520 msvc7) 521 if test "$libtool" = yes; then 522 showIncludes=-Wc,-showIncludes 523 else 524 showIncludes=-showIncludes 525 fi 526 "$@" $showIncludes > "$tmpdepfile" 527 stat=$? 528 grep -v '^Note: including file: ' "$tmpdepfile" 529 if test $stat -ne 0; then 530 rm -f "$tmpdepfile" 531 exit $stat 532 fi 533 rm -f "$depfile" 534 echo "$object : \\" > "$depfile" 535 # The first sed program below extracts the file names and escapes 536 # backslashes for cygpath. The second sed program outputs the file 537 # name when reading, but also accumulates all include files in the 538 # hold buffer in order to output them again at the end. This only 539 # works with sed implementations that can handle large buffers. 540 sed < "$tmpdepfile" -n ' 541 /^Note: including file: *\(.*\)/ { 542 s//\1/ 543 s/\\/\\\\/g 544 p 545 }' | $cygpath_u | sort -u | sed -n ' 546 s/ /\\ /g 547 s/\(.*\)/'"$tab"'\1 \\/p 548 s/.\(.*\) \\/\1:/ 549 H 550 $ { 551 s/.*/'"$tab"'/ 552 G 553 p 554 }' >> "$depfile" 555 echo >> "$depfile" # make sure the fragment doesn't end with a backslash 556 rm -f "$tmpdepfile" 557 ;; 558 559 msvc7msys) 560 # This case exists only to let depend.m4 do its work. It works by 561 # looking at the text of this script. This case will never be run, 562 # since it is checked for above. 563 exit 1 564 ;; 565 566 #nosideeffect) 567 # This comment above is used by automake to tell side-effect 568 # dependency tracking mechanisms from slower ones. 569 570 dashmstdout) 571 # Important note: in order to support this mode, a compiler *must* 572 # always write the preprocessed file to stdout, regardless of -o. 573 "$@" || exit $? 574 575 # Remove the call to Libtool. 576 if test "$libtool" = yes; then 577 while test "X$1" != 'X--mode=compile'; do 578 shift 579 done 580 shift 581 fi 582 583 # Remove '-o $object'. 584 IFS=" " 585 for arg 586 do 587 case $arg in 588 -o) 589 shift 590 ;; 591 $object) 592 shift 593 ;; 594 *) 595 set fnord "$@" "$arg" 596 shift # fnord 597 shift # $arg 598 ;; 599 esac 600 done 601 602 test -z "$dashmflag" && dashmflag=-M 603 # Require at least two characters before searching for ':' 604 # in the target name. This is to cope with DOS-style filenames: 605 # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. 606 "$@" $dashmflag | 607 sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" 608 rm -f "$depfile" 609 cat < "$tmpdepfile" > "$depfile" 610 # Some versions of the HPUX 10.20 sed can't process this sed invocation 611 # correctly. Breaking it into two sed invocations is a workaround. 612 tr ' ' "$nl" < "$tmpdepfile" \ 613 | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ 614 | sed -e 's/$/ :/' >> "$depfile" 615 rm -f "$tmpdepfile" 616 ;; 617 618 dashXmstdout) 619 # This case only exists to satisfy depend.m4. It is never actually 620 # run, as this mode is specially recognized in the preamble. 621 exit 1 622 ;; 623 624 makedepend) 625 "$@" || exit $? 626 # Remove any Libtool call 627 if test "$libtool" = yes; then 628 while test "X$1" != 'X--mode=compile'; do 629 shift 630 done 631 shift 632 fi 633 # X makedepend 634 shift 635 cleared=no eat=no 636 for arg 637 do 638 case $cleared in 639 no) 640 set ""; shift 641 cleared=yes ;; 642 esac 643 if test $eat = yes; then 644 eat=no 645 continue 646 fi 647 case "$arg" in 648 -D*|-I*) 649 set fnord "$@" "$arg"; shift ;; 650 # Strip any option that makedepend may not understand. Remove 651 # the object too, otherwise makedepend will parse it as a source file. 652 -arch) 653 eat=yes ;; 654 -*|$object) 655 ;; 656 *) 657 set fnord "$@" "$arg"; shift ;; 658 esac 659 done 660 obj_suffix=`echo "$object" | sed 's/^.*\././'` 661 touch "$tmpdepfile" 662 ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" 663 rm -f "$depfile" 664 # makedepend may prepend the VPATH from the source file name to the object. 665 # No need to regex-escape $object, excess matching of '.' is harmless. 666 sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" 667 # Some versions of the HPUX 10.20 sed can't process the last invocation 668 # correctly. Breaking it into two sed invocations is a workaround. 669 sed '1,2d' "$tmpdepfile" \ 670 | tr ' ' "$nl" \ 671 | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ 672 | sed -e 's/$/ :/' >> "$depfile" 673 rm -f "$tmpdepfile" "$tmpdepfile".bak 674 ;; 675 676 cpp) 677 # Important note: in order to support this mode, a compiler *must* 678 # always write the preprocessed file to stdout. 679 "$@" || exit $? 680 681 # Remove the call to Libtool. 682 if test "$libtool" = yes; then 683 while test "X$1" != 'X--mode=compile'; do 684 shift 685 done 686 shift 687 fi 688 689 # Remove '-o $object'. 690 IFS=" " 691 for arg 692 do 693 case $arg in 694 -o) 695 shift 696 ;; 697 $object) 698 shift 699 ;; 700 *) 701 set fnord "$@" "$arg" 702 shift # fnord 703 shift # $arg 704 ;; 705 esac 706 done 707 708 "$@" -E \ 709 | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ 710 -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ 711 | sed '$ s: \\$::' > "$tmpdepfile" 712 rm -f "$depfile" 713 echo "$object : \\" > "$depfile" 714 cat < "$tmpdepfile" >> "$depfile" 715 sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" 716 rm -f "$tmpdepfile" 717 ;; 718 719 msvisualcpp) 720 # Important note: in order to support this mode, a compiler *must* 721 # always write the preprocessed file to stdout. 722 "$@" || exit $? 723 724 # Remove the call to Libtool. 725 if test "$libtool" = yes; then 726 while test "X$1" != 'X--mode=compile'; do 727 shift 728 done 729 shift 730 fi 731 732 IFS=" " 733 for arg 734 do 735 case "$arg" in 736 -o) 737 shift 738 ;; 739 $object) 740 shift 741 ;; 742 "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") 743 set fnord "$@" 744 shift 745 shift 746 ;; 747 *) 748 set fnord "$@" "$arg" 749 shift 750 shift 751 ;; 752 esac 753 done 754 "$@" -E 2>/dev/null | 755 sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" 756 rm -f "$depfile" 757 echo "$object : \\" > "$depfile" 758 sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" 759 echo "$tab" >> "$depfile" 760 sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" 761 rm -f "$tmpdepfile" 762 ;; 763 764 msvcmsys) 765 # This case exists only to let depend.m4 do its work. It works by 766 # looking at the text of this script. This case will never be run, 767 # since it is checked for above. 768 exit 1 769 ;; 770 771 none) 772 exec "$@" 773 ;; 774 775 *) 776 echo "Unknown depmode $depmode" 1>&2 777 exit 1 778 ;; 779 esac 780 781 exit 0 782 783 # Local Variables: 784 # mode: shell-script 785 # sh-indentation: 2 786 # eval: (add-hook 'write-file-hooks 'time-stamp) 787 # time-stamp-start: "scriptversion=" 788 # time-stamp-format: "%:y-%02m-%02d.%02H" 789 # time-stamp-time-zone: "UTC" 790 # time-stamp-end: "; # UTC" 791 # End: 1 /usr/share/automake-1.15/depcomp -
Property mode
changed from
-
automake/install-sh
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #!/bin/sh 2 # install - install a program, script, or datafile 3 4 scriptversion=2014-09-12.12; # UTC 5 6 # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 # later released in X11R6 (xc/config/util/install.sh) with the 8 # following copyright and license. 9 # 10 # Copyright (C) 1994 X Consortium 11 # 12 # Permission is hereby granted, free of charge, to any person obtaining a copy 13 # of this software and associated documentation files (the "Software"), to 14 # deal in the Software without restriction, including without limitation the 15 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 # sell copies of the Software, and to permit persons to whom the Software is 17 # furnished to do so, subject to the following conditions: 18 # 19 # The above copyright notice and this permission notice shall be included in 20 # all copies or substantial portions of the Software. 21 # 22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 # 29 # Except as contained in this notice, the name of the X Consortium shall not 30 # be used in advertising or otherwise to promote the sale, use or other deal- 31 # ings in this Software without prior written authorization from the X Consor- 32 # tium. 33 # 34 # 35 # FSF changes to this file are in the public domain. 36 # 37 # Calling this script install-sh is preferred over install.sh, to prevent 38 # 'make' implicit rules from creating a file called install from it 39 # when there is no Makefile. 40 # 41 # This script is compatible with the BSD install script, but was written 42 # from scratch. 43 44 tab=' ' 45 nl=' 46 ' 47 IFS=" $tab$nl" 48 49 # Set DOITPROG to "echo" to test this script. 50 51 doit=${DOITPROG-} 52 doit_exec=${doit:-exec} 53 54 # Put in absolute file names if you don't have them in your path; 55 # or use environment vars. 56 57 chgrpprog=${CHGRPPROG-chgrp} 58 chmodprog=${CHMODPROG-chmod} 59 chownprog=${CHOWNPROG-chown} 60 cmpprog=${CMPPROG-cmp} 61 cpprog=${CPPROG-cp} 62 mkdirprog=${MKDIRPROG-mkdir} 63 mvprog=${MVPROG-mv} 64 rmprog=${RMPROG-rm} 65 stripprog=${STRIPPROG-strip} 66 67 posix_mkdir= 68 69 # Desired mode of installed file. 70 mode=0755 71 72 chgrpcmd= 73 chmodcmd=$chmodprog 74 chowncmd= 75 mvcmd=$mvprog 76 rmcmd="$rmprog -f" 77 stripcmd= 78 79 src= 80 dst= 81 dir_arg= 82 dst_arg= 83 84 copy_on_change=false 85 is_target_a_directory=possibly 86 87 usage="\ 88 Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89 or: $0 [OPTION]... SRCFILES... DIRECTORY 90 or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91 or: $0 [OPTION]... -d DIRECTORIES... 92 93 In the 1st form, copy SRCFILE to DSTFILE. 94 In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95 In the 4th, create DIRECTORIES. 96 97 Options: 98 --help display this help and exit. 99 --version display version info and exit. 100 101 -c (ignored) 102 -C install only if different (preserve the last data modification time) 103 -d create directories instead of installing files. 104 -g GROUP $chgrpprog installed files to GROUP. 105 -m MODE $chmodprog installed files to MODE. 106 -o USER $chownprog installed files to USER. 107 -s $stripprog installed files. 108 -t DIRECTORY install into DIRECTORY. 109 -T report an error if DSTFILE is a directory. 110 111 Environment variables override the default commands: 112 CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113 RMPROG STRIPPROG 114 " 115 116 while test $# -ne 0; do 117 case $1 in 118 -c) ;; 119 120 -C) copy_on_change=true;; 121 122 -d) dir_arg=true;; 123 124 -g) chgrpcmd="$chgrpprog $2" 125 shift;; 126 127 --help) echo "$usage"; exit $?;; 128 129 -m) mode=$2 130 case $mode in 131 *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132 echo "$0: invalid mode: $mode" >&2 133 exit 1;; 134 esac 135 shift;; 136 137 -o) chowncmd="$chownprog $2" 138 shift;; 139 140 -s) stripcmd=$stripprog;; 141 142 -t) 143 is_target_a_directory=always 144 dst_arg=$2 145 # Protect names problematic for 'test' and other utilities. 146 case $dst_arg in 147 -* | [=\(\)!]) dst_arg=./$dst_arg;; 148 esac 149 shift;; 150 151 -T) is_target_a_directory=never;; 152 153 --version) echo "$0 $scriptversion"; exit $?;; 154 155 --) shift 156 break;; 157 158 -*) echo "$0: invalid option: $1" >&2 159 exit 1;; 160 161 *) break;; 162 esac 163 shift 164 done 165 166 # We allow the use of options -d and -T together, by making -d 167 # take the precedence; this is for compatibility with GNU install. 168 169 if test -n "$dir_arg"; then 170 if test -n "$dst_arg"; then 171 echo "$0: target directory not allowed when installing a directory." >&2 172 exit 1 173 fi 174 fi 175 176 if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177 # When -d is used, all remaining arguments are directories to create. 178 # When -t is used, the destination is already specified. 179 # Otherwise, the last argument is the destination. Remove it from $@. 180 for arg 181 do 182 if test -n "$dst_arg"; then 183 # $@ is not empty: it contains at least $arg. 184 set fnord "$@" "$dst_arg" 185 shift # fnord 186 fi 187 shift # arg 188 dst_arg=$arg 189 # Protect names problematic for 'test' and other utilities. 190 case $dst_arg in 191 -* | [=\(\)!]) dst_arg=./$dst_arg;; 192 esac 193 done 194 fi 195 196 if test $# -eq 0; then 197 if test -z "$dir_arg"; then 198 echo "$0: no input file specified." >&2 199 exit 1 200 fi 201 # It's OK to call 'install-sh -d' without argument. 202 # This can happen when creating conditional directories. 203 exit 0 204 fi 205 206 if test -z "$dir_arg"; then 207 if test $# -gt 1 || test "$is_target_a_directory" = always; then 208 if test ! -d "$dst_arg"; then 209 echo "$0: $dst_arg: Is not a directory." >&2 210 exit 1 211 fi 212 fi 213 fi 214 215 if test -z "$dir_arg"; then 216 do_exit='(exit $ret); exit $ret' 217 trap "ret=129; $do_exit" 1 218 trap "ret=130; $do_exit" 2 219 trap "ret=141; $do_exit" 13 220 trap "ret=143; $do_exit" 15 221 222 # Set umask so as not to create temps with too-generous modes. 223 # However, 'strip' requires both read and write access to temps. 224 case $mode in 225 # Optimize common cases. 226 *644) cp_umask=133;; 227 *755) cp_umask=22;; 228 229 *[0-7]) 230 if test -z "$stripcmd"; then 231 u_plus_rw= 232 else 233 u_plus_rw='% 200' 234 fi 235 cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236 *) 237 if test -z "$stripcmd"; then 238 u_plus_rw= 239 else 240 u_plus_rw=,u+rw 241 fi 242 cp_umask=$mode$u_plus_rw;; 243 esac 244 fi 245 246 for src 247 do 248 # Protect names problematic for 'test' and other utilities. 249 case $src in 250 -* | [=\(\)!]) src=./$src;; 251 esac 252 253 if test -n "$dir_arg"; then 254 dst=$src 255 dstdir=$dst 256 test -d "$dstdir" 257 dstdir_status=$? 258 else 259 260 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261 # might cause directories to be created, which would be especially bad 262 # if $src (and thus $dsttmp) contains '*'. 263 if test ! -f "$src" && test ! -d "$src"; then 264 echo "$0: $src does not exist." >&2 265 exit 1 266 fi 267 268 if test -z "$dst_arg"; then 269 echo "$0: no destination specified." >&2 270 exit 1 271 fi 272 dst=$dst_arg 273 274 # If destination is a directory, append the input filename; won't work 275 # if double slashes aren't ignored. 276 if test -d "$dst"; then 277 if test "$is_target_a_directory" = never; then 278 echo "$0: $dst_arg: Is a directory" >&2 279 exit 1 280 fi 281 dstdir=$dst 282 dst=$dstdir/`basename "$src"` 283 dstdir_status=0 284 else 285 dstdir=`dirname "$dst"` 286 test -d "$dstdir" 287 dstdir_status=$? 288 fi 289 fi 290 291 obsolete_mkdir_used=false 292 293 if test $dstdir_status != 0; then 294 case $posix_mkdir in 295 '') 296 # Create intermediate dirs using mode 755 as modified by the umask. 297 # This is like FreeBSD 'install' as of 1997-10-28. 298 umask=`umask` 299 case $stripcmd.$umask in 300 # Optimize common cases. 301 *[2367][2367]) mkdir_umask=$umask;; 302 .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303 304 *[0-7]) 305 mkdir_umask=`expr $umask + 22 \ 306 - $umask % 100 % 40 + $umask % 20 \ 307 - $umask % 10 % 4 + $umask % 2 308 `;; 309 *) mkdir_umask=$umask,go-w;; 310 esac 311 312 # With -d, create the new directory with the user-specified mode. 313 # Otherwise, rely on $mkdir_umask. 314 if test -n "$dir_arg"; then 315 mkdir_mode=-m$mode 316 else 317 mkdir_mode= 318 fi 319 320 posix_mkdir=false 321 case $umask in 322 *[123567][0-7][0-7]) 323 # POSIX mkdir -p sets u+wx bits regardless of umask, which 324 # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325 ;; 326 *) 327 # $RANDOM is not portable (e.g. dash); use it when possible to 328 # lower collision chance 329 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 330 trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 331 332 # As "mkdir -p" follows symlinks and we work in /tmp possibly; so 333 # create the $tmpdir first (and fail if unsuccessful) to make sure 334 # that nobody tries to guess the $tmpdir name. 335 if (umask $mkdir_umask && 336 $mkdirprog $mkdir_mode "$tmpdir" && 337 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 338 then 339 if test -z "$dir_arg" || { 340 # Check for POSIX incompatibilities with -m. 341 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 342 # other-writable bit of parent directory when it shouldn't. 343 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 344 test_tmpdir="$tmpdir/a" 345 ls_ld_tmpdir=`ls -ld "$test_tmpdir"` 346 case $ls_ld_tmpdir in 347 d????-?r-*) different_mode=700;; 348 d????-?--*) different_mode=755;; 349 *) false;; 350 esac && 351 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { 352 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` 353 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 354 } 355 } 356 then posix_mkdir=: 357 fi 358 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 359 else 360 # Remove any dirs left behind by ancient mkdir implementations. 361 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null 362 fi 363 trap '' 0;; 364 esac;; 365 esac 366 367 if 368 $posix_mkdir && ( 369 umask $mkdir_umask && 370 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 371 ) 372 then : 373 else 374 375 # The umask is ridiculous, or mkdir does not conform to POSIX, 376 # or it failed possibly due to a race condition. Create the 377 # directory the slow way, step by step, checking for races as we go. 378 379 case $dstdir in 380 /*) prefix='/';; 381 [-=\(\)!]*) prefix='./';; 382 *) prefix='';; 383 esac 384 385 oIFS=$IFS 386 IFS=/ 387 set -f 388 set fnord $dstdir 389 shift 390 set +f 391 IFS=$oIFS 392 393 prefixes= 394 395 for d 396 do 397 test X"$d" = X && continue 398 399 prefix=$prefix$d 400 if test -d "$prefix"; then 401 prefixes= 402 else 403 if $posix_mkdir; then 404 (umask=$mkdir_umask && 405 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 406 # Don't fail if two instances are running concurrently. 407 test -d "$prefix" || exit 1 408 else 409 case $prefix in 410 *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 411 *) qprefix=$prefix;; 412 esac 413 prefixes="$prefixes '$qprefix'" 414 fi 415 fi 416 prefix=$prefix/ 417 done 418 419 if test -n "$prefixes"; then 420 # Don't fail if two instances are running concurrently. 421 (umask $mkdir_umask && 422 eval "\$doit_exec \$mkdirprog $prefixes") || 423 test -d "$dstdir" || exit 1 424 obsolete_mkdir_used=true 425 fi 426 fi 427 fi 428 429 if test -n "$dir_arg"; then 430 { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 431 { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 432 { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 433 test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 434 else 435 436 # Make a couple of temp file names in the proper directory. 437 dsttmp=$dstdir/_inst.$$_ 438 rmtmp=$dstdir/_rm.$$_ 439 440 # Trap to clean up those temp files at exit. 441 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 442 443 # Copy the file name to the temp name. 444 (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 445 446 # and set any options; do chmod last to preserve setuid bits. 447 # 448 # If any of these fail, we abort the whole thing. If we want to 449 # ignore errors from any of these, just make sure not to ignore 450 # errors from the above "$doit $cpprog $src $dsttmp" command. 451 # 452 { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 453 { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 454 { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 455 { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 456 457 # If -C, don't bother to copy if it wouldn't change the file. 458 if $copy_on_change && 459 old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 460 new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 461 set -f && 462 set X $old && old=:$2:$4:$5:$6 && 463 set X $new && new=:$2:$4:$5:$6 && 464 set +f && 465 test "$old" = "$new" && 466 $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 467 then 468 rm -f "$dsttmp" 469 else 470 # Rename the file to the real destination. 471 $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 472 473 # The rename failed, perhaps because mv can't rename something else 474 # to itself, or perhaps because mv is so ancient that it does not 475 # support -f. 476 { 477 # Now remove or move aside any old file at destination location. 478 # We try this two ways since rm can't unlink itself on some 479 # systems and the destination file might be busy for other 480 # reasons. In this case, the final cleanup might fail but the new 481 # file should still install successfully. 482 { 483 test ! -f "$dst" || 484 $doit $rmcmd -f "$dst" 2>/dev/null || 485 { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 486 { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 487 } || 488 { echo "$0: cannot unlink or rename $dst" >&2 489 (exit 1); exit 1 490 } 491 } && 492 493 # Now rename the file to the real destination. 494 $doit $mvcmd "$dsttmp" "$dst" 495 } 496 fi || exit 1 497 498 trap '' 0 499 fi 500 done 501 502 # Local variables: 503 # eval: (add-hook 'write-file-hooks 'time-stamp) 504 # time-stamp-start: "scriptversion=" 505 # time-stamp-format: "%:y-%02m-%02d.%02H" 506 # time-stamp-time-zone: "UTC" 507 # time-stamp-end: "; # UTC" 508 # End: 1 /usr/share/automake-1.15/install-sh -
Property mode
changed from
-
automake/missing
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #! /bin/sh 2 # Common wrapper for a few potentially missing GNU programs. 3 4 scriptversion=2013-10-28.13; # UTC 5 6 # Copyright (C) 1996-2014 Free Software Foundation, Inc. 7 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. 8 9 # This program is free software; you can redistribute it and/or modify 10 # it under the terms of the GNU General Public License as published by 11 # the Free Software Foundation; either version 2, or (at your option) 12 # any later version. 13 14 # This program is distributed in the hope that it will be useful, 15 # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 # GNU General Public License for more details. 18 19 # You should have received a copy of the GNU General Public License 20 # along with this program. If not, see <http://www.gnu.org/licenses/>. 21 22 # As a special exception to the GNU General Public License, if you 23 # distribute this file as part of a program that contains a 24 # configuration script generated by Autoconf, you may include it under 25 # the same distribution terms that you use for the rest of that program. 26 27 if test $# -eq 0; then 28 echo 1>&2 "Try '$0 --help' for more information" 29 exit 1 30 fi 31 32 case $1 in 33 34 --is-lightweight) 35 # Used by our autoconf macros to check whether the available missing 36 # script is modern enough. 37 exit 0 38 ;; 39 40 --run) 41 # Back-compat with the calling convention used by older automake. 42 shift 43 ;; 44 45 -h|--h|--he|--hel|--help) 46 echo "\ 47 $0 [OPTION]... PROGRAM [ARGUMENT]... 48 49 Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due 50 to PROGRAM being missing or too old. 51 52 Options: 53 -h, --help display this help and exit 54 -v, --version output version information and exit 55 56 Supported PROGRAM values: 57 aclocal autoconf autoheader autom4te automake makeinfo 58 bison yacc flex lex help2man 59 60 Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 61 'g' are ignored when checking the name. 62 63 Send bug reports to <bug-automake@gnu.org>." 64 exit $? 65 ;; 66 67 -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 68 echo "missing $scriptversion (GNU Automake)" 69 exit $? 70 ;; 71 72 -*) 73 echo 1>&2 "$0: unknown '$1' option" 74 echo 1>&2 "Try '$0 --help' for more information" 75 exit 1 76 ;; 77 78 esac 79 80 # Run the given program, remember its exit status. 81 "$@"; st=$? 82 83 # If it succeeded, we are done. 84 test $st -eq 0 && exit 0 85 86 # Also exit now if we it failed (or wasn't found), and '--version' was 87 # passed; such an option is passed most likely to detect whether the 88 # program is present and works. 89 case $2 in --version|--help) exit $st;; esac 90 91 # Exit code 63 means version mismatch. This often happens when the user 92 # tries to use an ancient version of a tool on a file that requires a 93 # minimum version. 94 if test $st -eq 63; then 95 msg="probably too old" 96 elif test $st -eq 127; then 97 # Program was missing. 98 msg="missing on your system" 99 else 100 # Program was found and executed, but failed. Give up. 101 exit $st 102 fi 103 104 perl_URL=http://www.perl.org/ 105 flex_URL=http://flex.sourceforge.net/ 106 gnu_software_URL=http://www.gnu.org/software 107 108 program_details () 109 { 110 case $1 in 111 aclocal|automake) 112 echo "The '$1' program is part of the GNU Automake package:" 113 echo "<$gnu_software_URL/automake>" 114 echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" 115 echo "<$gnu_software_URL/autoconf>" 116 echo "<$gnu_software_URL/m4/>" 117 echo "<$perl_URL>" 118 ;; 119 autoconf|autom4te|autoheader) 120 echo "The '$1' program is part of the GNU Autoconf package:" 121 echo "<$gnu_software_URL/autoconf/>" 122 echo "It also requires GNU m4 and Perl in order to run:" 123 echo "<$gnu_software_URL/m4/>" 124 echo "<$perl_URL>" 125 ;; 126 esac 127 } 128 129 give_advice () 130 { 131 # Normalize program name to check for. 132 normalized_program=`echo "$1" | sed ' 133 s/^gnu-//; t 134 s/^gnu//; t 135 s/^g//; t'` 136 137 printf '%s\n' "'$1' is $msg." 138 139 configure_deps="'configure.ac' or m4 files included by 'configure.ac'" 140 case $normalized_program in 141 autoconf*) 142 echo "You should only need it if you modified 'configure.ac'," 143 echo "or m4 files included by it." 144 program_details 'autoconf' 145 ;; 146 autoheader*) 147 echo "You should only need it if you modified 'acconfig.h' or" 148 echo "$configure_deps." 149 program_details 'autoheader' 150 ;; 151 automake*) 152 echo "You should only need it if you modified 'Makefile.am' or" 153 echo "$configure_deps." 154 program_details 'automake' 155 ;; 156 aclocal*) 157 echo "You should only need it if you modified 'acinclude.m4' or" 158 echo "$configure_deps." 159 program_details 'aclocal' 160 ;; 161 autom4te*) 162 echo "You might have modified some maintainer files that require" 163 echo "the 'autom4te' program to be rebuilt." 164 program_details 'autom4te' 165 ;; 166 bison*|yacc*) 167 echo "You should only need it if you modified a '.y' file." 168 echo "You may want to install the GNU Bison package:" 169 echo "<$gnu_software_URL/bison/>" 170 ;; 171 lex*|flex*) 172 echo "You should only need it if you modified a '.l' file." 173 echo "You may want to install the Fast Lexical Analyzer package:" 174 echo "<$flex_URL>" 175 ;; 176 help2man*) 177 echo "You should only need it if you modified a dependency" \ 178 "of a man page." 179 echo "You may want to install the GNU Help2man package:" 180 echo "<$gnu_software_URL/help2man/>" 181 ;; 182 makeinfo*) 183 echo "You should only need it if you modified a '.texi' file, or" 184 echo "any other file indirectly affecting the aspect of the manual." 185 echo "You might want to install the Texinfo package:" 186 echo "<$gnu_software_URL/texinfo/>" 187 echo "The spurious makeinfo call might also be the consequence of" 188 echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" 189 echo "want to install GNU make:" 190 echo "<$gnu_software_URL/make/>" 191 ;; 192 *) 193 echo "You might have modified some files without having the proper" 194 echo "tools for further handling them. Check the 'README' file, it" 195 echo "often tells you about the needed prerequisites for installing" 196 echo "this package. You may also peek at any GNU archive site, in" 197 echo "case some other package contains this missing '$1' program." 198 ;; 199 esac 200 } 201 202 give_advice "$1" | sed -e '1s/^/WARNING: /' \ 203 -e '2,$s/^/ /' >&2 204 205 # Propagate the correct exit status (expected to be 127 for a program 206 # not found, 63 for a program that failed due to version mismatch). 207 exit $st 208 209 # Local variables: 210 # eval: (add-hook 'write-file-hooks 'time-stamp) 211 # time-stamp-start: "scriptversion=" 212 # time-stamp-format: "%:y-%02m-%02d.%02H" 213 # time-stamp-time-zone: "UTC" 214 # time-stamp-end: "; # UTC" 215 # End: 1 /usr/share/automake-1.15/missing -
Property mode
changed from
-
automake/test-driver
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #! /bin/sh 2 # test-driver - basic testsuite driver script. 3 4 scriptversion=2013-07-13.22; # UTC 5 6 # Copyright (C) 2011-2014 Free Software Foundation, Inc. 7 # 8 # This program is free software; you can redistribute it and/or modify 9 # it under the terms of the GNU General Public License as published by 10 # the Free Software Foundation; either version 2, or (at your option) 11 # any later version. 12 # 13 # This program is distributed in the hope that it will be useful, 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 # GNU General Public License for more details. 17 # 18 # You should have received a copy of the GNU General Public License 19 # along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 # As a special exception to the GNU General Public License, if you 22 # distribute this file as part of a program that contains a 23 # configuration script generated by Autoconf, you may include it under 24 # the same distribution terms that you use for the rest of that program. 25 26 # This file is maintained in Automake, please report 27 # bugs to <bug-automake@gnu.org> or send patches to 28 # <automake-patches@gnu.org>. 29 30 # Make unconditional expansion of undefined variables an error. This 31 # helps a lot in preventing typo-related bugs. 32 set -u 33 34 usage_error () 35 { 36 echo "$0: $*" >&2 37 print_usage >&2 38 exit 2 39 } 40 41 print_usage () 42 { 43 cat <<END 44 Usage: 45 test-driver --test-name=NAME --log-file=PATH --trs-file=PATH 46 [--expect-failure={yes|no}] [--color-tests={yes|no}] 47 [--enable-hard-errors={yes|no}] [--] 48 TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] 49 The '--test-name', '--log-file' and '--trs-file' options are mandatory. 50 END 51 } 52 53 test_name= # Used for reporting. 54 log_file= # Where to save the output of the test script. 55 trs_file= # Where to save the metadata of the test run. 56 expect_failure=no 57 color_tests=no 58 enable_hard_errors=yes 59 while test $# -gt 0; do 60 case $1 in 61 --help) print_usage; exit $?;; 62 --version) echo "test-driver $scriptversion"; exit $?;; 63 --test-name) test_name=$2; shift;; 64 --log-file) log_file=$2; shift;; 65 --trs-file) trs_file=$2; shift;; 66 --color-tests) color_tests=$2; shift;; 67 --expect-failure) expect_failure=$2; shift;; 68 --enable-hard-errors) enable_hard_errors=$2; shift;; 69 --) shift; break;; 70 -*) usage_error "invalid option: '$1'";; 71 *) break;; 72 esac 73 shift 74 done 75 76 missing_opts= 77 test x"$test_name" = x && missing_opts="$missing_opts --test-name" 78 test x"$log_file" = x && missing_opts="$missing_opts --log-file" 79 test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" 80 if test x"$missing_opts" != x; then 81 usage_error "the following mandatory options are missing:$missing_opts" 82 fi 83 84 if test $# -eq 0; then 85 usage_error "missing argument" 86 fi 87 88 if test $color_tests = yes; then 89 # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. 90 red='[0;31m' # Red. 91 grn='[0;32m' # Green. 92 lgn='[1;32m' # Light green. 93 blu='[1;34m' # Blue. 94 mgn='[0;35m' # Magenta. 95 std='[m' # No color. 96 else 97 red= grn= lgn= blu= mgn= std= 98 fi 99 100 do_exit='rm -f $log_file $trs_file; (exit $st); exit $st' 101 trap "st=129; $do_exit" 1 102 trap "st=130; $do_exit" 2 103 trap "st=141; $do_exit" 13 104 trap "st=143; $do_exit" 15 105 106 # Test script is run here. 107 "$@" >$log_file 2>&1 108 estatus=$? 109 110 if test $enable_hard_errors = no && test $estatus -eq 99; then 111 tweaked_estatus=1 112 else 113 tweaked_estatus=$estatus 114 fi 115 116 case $tweaked_estatus:$expect_failure in 117 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 118 0:*) col=$grn res=PASS recheck=no gcopy=no;; 119 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 120 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; 121 *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; 122 *:*) col=$red res=FAIL recheck=yes gcopy=yes;; 123 esac 124 125 # Report the test outcome and exit status in the logs, so that one can 126 # know whether the test passed or failed simply by looking at the '.log' 127 # file, without the need of also peaking into the corresponding '.trs' 128 # file (automake bug#11814). 129 echo "$res $test_name (exit status: $estatus)" >>$log_file 130 131 # Report outcome to console. 132 echo "${col}${res}${std}: $test_name" 133 134 # Register the test result, and other relevant metadata. 135 echo ":test-result: $res" > $trs_file 136 echo ":global-test-result: $res" >> $trs_file 137 echo ":recheck: $recheck" >> $trs_file 138 echo ":copy-in-global-log: $gcopy" >> $trs_file 139 140 # Local Variables: 141 # mode: shell-script 142 # sh-indentation: 2 143 # eval: (add-hook 'write-file-hooks 'time-stamp) 144 # time-stamp-start: "scriptversion=" 145 # time-stamp-format: "%:y-%02m-%02d.%02H" 146 # time-stamp-time-zone: "UTC" 147 # time-stamp-end: "; # UTC" 148 # End: 1 /usr/share/automake-1.15/test-driver -
Property mode
changed from
-
automake/ylwrap
-
Property mode
changed from
100755to120000
r7951100 rb067d9b 1 #! /bin/sh 2 # ylwrap - wrapper for lex/yacc invocations. 3 4 scriptversion=2013-01-12.17; # UTC 5 6 # Copyright (C) 1996-2014 Free Software Foundation, Inc. 7 # 8 # Written by Tom Tromey <tromey@cygnus.com>. 9 # 10 # This program is free software; you can redistribute it and/or modify 11 # it under the terms of the GNU General Public License as published by 12 # the Free Software Foundation; either version 2, or (at your option) 13 # any later version. 14 # 15 # This program is distributed in the hope that it will be useful, 16 # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 # GNU General Public License for more details. 19 # 20 # You should have received a copy of the GNU General Public License 21 # along with this program. If not, see <http://www.gnu.org/licenses/>. 22 23 # As a special exception to the GNU General Public License, if you 24 # distribute this file as part of a program that contains a 25 # configuration script generated by Autoconf, you may include it under 26 # the same distribution terms that you use for the rest of that program. 27 28 # This file is maintained in Automake, please report 29 # bugs to <bug-automake@gnu.org> or send patches to 30 # <automake-patches@gnu.org>. 31 32 get_dirname () 33 { 34 case $1 in 35 */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; 36 # Otherwise, we want the empty string (not "."). 37 esac 38 } 39 40 # guard FILE 41 # ---------- 42 # The CPP macro used to guard inclusion of FILE. 43 guard () 44 { 45 printf '%s\n' "$1" \ 46 | sed \ 47 -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ 48 -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ 49 -e 's/__*/_/g' 50 } 51 52 # quote_for_sed [STRING] 53 # ---------------------- 54 # Return STRING (or stdin) quoted to be used as a sed pattern. 55 quote_for_sed () 56 { 57 case $# in 58 0) cat;; 59 1) printf '%s\n' "$1";; 60 esac \ 61 | sed -e 's|[][\\.*]|\\&|g' 62 } 63 64 case "$1" in 65 '') 66 echo "$0: No files given. Try '$0 --help' for more information." 1>&2 67 exit 1 68 ;; 69 --basedir) 70 basedir=$2 71 shift 2 72 ;; 73 -h|--h*) 74 cat <<\EOF 75 Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... 76 77 Wrapper for lex/yacc invocations, renaming files as desired. 78 79 INPUT is the input file 80 OUTPUT is one file PROG generates 81 DESIRED is the file we actually want instead of OUTPUT 82 PROGRAM is program to run 83 ARGS are passed to PROG 84 85 Any number of OUTPUT,DESIRED pairs may be used. 86 87 Report bugs to <bug-automake@gnu.org>. 88 EOF 89 exit $? 90 ;; 91 -v|--v*) 92 echo "ylwrap $scriptversion" 93 exit $? 94 ;; 95 esac 96 97 98 # The input. 99 input=$1 100 shift 101 # We'll later need for a correct munging of "#line" directives. 102 input_sub_rx=`get_dirname "$input" | quote_for_sed` 103 case $input in 104 [\\/]* | ?:[\\/]*) 105 # Absolute path; do nothing. 106 ;; 107 *) 108 # Relative path. Make it absolute. 109 input=`pwd`/$input 110 ;; 111 esac 112 input_rx=`get_dirname "$input" | quote_for_sed` 113 114 # Since DOS filename conventions don't allow two dots, 115 # the DOS version of Bison writes out y_tab.c instead of y.tab.c 116 # and y_tab.h instead of y.tab.h. Test to see if this is the case. 117 y_tab_nodot=false 118 if test -f y_tab.c || test -f y_tab.h; then 119 y_tab_nodot=true 120 fi 121 122 # The parser itself, the first file, is the destination of the .y.c 123 # rule in the Makefile. 124 parser=$1 125 126 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for 127 # instance, we rename #include "y.tab.h" into #include "parse.h" 128 # during the conversion from y.tab.c to parse.c. 129 sed_fix_filenames= 130 131 # Also rename header guards, as Bison 2.7 for instance uses its header 132 # guard in its implementation file. 133 sed_fix_header_guards= 134 135 while test $# -ne 0; do 136 if test x"$1" = x"--"; then 137 shift 138 break 139 fi 140 from=$1 141 # Handle y_tab.c and y_tab.h output by DOS 142 if $y_tab_nodot; then 143 case $from in 144 "y.tab.c") from=y_tab.c;; 145 "y.tab.h") from=y_tab.h;; 146 esac 147 fi 148 shift 149 to=$1 150 shift 151 sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" 152 sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" 153 done 154 155 # The program to run. 156 prog=$1 157 shift 158 # Make any relative path in $prog absolute. 159 case $prog in 160 [\\/]* | ?:[\\/]*) ;; 161 *[\\/]*) prog=`pwd`/$prog ;; 162 esac 163 164 dirname=ylwrap$$ 165 do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' 166 trap "ret=129; $do_exit" 1 167 trap "ret=130; $do_exit" 2 168 trap "ret=141; $do_exit" 13 169 trap "ret=143; $do_exit" 15 170 mkdir $dirname || exit 1 171 172 cd $dirname 173 174 case $# in 175 0) "$prog" "$input" ;; 176 *) "$prog" "$@" "$input" ;; 177 esac 178 ret=$? 179 180 if test $ret -eq 0; then 181 for from in * 182 do 183 to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` 184 if test -f "$from"; then 185 # If $2 is an absolute path name, then just use that, 186 # otherwise prepend '../'. 187 case $to in 188 [\\/]* | ?:[\\/]*) target=$to;; 189 *) target=../$to;; 190 esac 191 192 # Do not overwrite unchanged header files to avoid useless 193 # recompilations. Always update the parser itself: it is the 194 # destination of the .y.c rule in the Makefile. Divert the 195 # output of all other files to a temporary file so we can 196 # compare them to existing versions. 197 if test $from != $parser; then 198 realtarget=$target 199 target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` 200 fi 201 202 # Munge "#line" or "#" directives. Don't let the resulting 203 # debug information point at an absolute srcdir. Use the real 204 # output file name, not yy.lex.c for instance. Adjust the 205 # include guards too. 206 sed -e "/^#/!b" \ 207 -e "s|$input_rx|$input_sub_rx|" \ 208 -e "$sed_fix_filenames" \ 209 -e "$sed_fix_header_guards" \ 210 "$from" >"$target" || ret=$? 211 212 # Check whether files must be updated. 213 if test "$from" != "$parser"; then 214 if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then 215 echo "$to is unchanged" 216 rm -f "$target" 217 else 218 echo "updating $to" 219 mv -f "$target" "$realtarget" 220 fi 221 fi 222 else 223 # A missing file is only an error for the parser. This is a 224 # blatant hack to let us support using "yacc -d". If -d is not 225 # specified, don't fail when the header file is "missing". 226 if test "$from" = "$parser"; then 227 ret=1 228 fi 229 fi 230 done 231 fi 232 233 # Remove the directory. 234 cd .. 235 rm -rf $dirname 236 237 exit $ret 238 239 # Local Variables: 240 # mode: shell-script 241 # sh-indentation: 2 242 # eval: (add-hook 'write-file-hooks 'time-stamp) 243 # time-stamp-start: "scriptversion=" 244 # time-stamp-format: "%:y-%02m-%02d.%02H" 245 # time-stamp-time-zone: "UTC" 246 # time-stamp-end: "; # UTC" 247 # End: 1 /usr/share/automake-1.15/ylwrap -
Property mode
changed from
-
configure
r7951100 rb067d9b 199 199 eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && 200 200 test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 201 202 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( 203 ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' 204 ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO 205 ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO 206 PATH=/empty FPATH=/empty; export PATH FPATH 207 test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ 208 || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 201 209 test \$(( 1 + 1 )) = 2 || exit 1" 202 210 if (eval "$as_required") 2>/dev/null; then : … … 557 565 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" 558 566 567 SHELL=${CONFIG_SHELL-/bin/sh} 568 559 569 560 570 test -n "$DJDIR" || exec 7<&0 </dev/null … … 626 636 LTLIBOBJS 627 637 LIBOBJS 628 ALLOCA 638 CFA_BACKEND_CC 639 DEMANGLER 640 LIBDEMANGLE 641 WITH_LIBTCMALLOC_FALSE 642 WITH_LIBTCMALLOC_TRUE 643 WITH_LIBPROFILER_FALSE 644 WITH_LIBPROFILER_TRUE 645 WITH_LIBFIBRE_FALSE 646 WITH_LIBFIBRE_TRUE 647 CXXCPP 648 CPP 649 LT_SYS_LIBRARY_PATH 650 OTOOL64 651 OTOOL 652 LIPO 653 NMEDIT 654 DSYMUTIL 655 MANIFEST_TOOL 656 RANLIB 657 ac_ct_AR 658 AR 659 DLLTOOL 660 OBJDUMP 661 LN_S 662 NM 663 ac_ct_DUMPBIN 664 DUMPBIN 665 FGREP 629 666 EGREP 630 667 GREP 631 CPP 632 RANLIB 668 SED 669 LIBTOOL 633 670 LEXLIB 634 671 LEX_OUTPUT_ROOT … … 663 700 LDFLAGS 664 701 CXXFLAGS 665 CXX666 702 CFA_FLAGS 667 MACHINE_TYPE 703 LIBCFA_TARGET_MAKEFILES 704 LIBCFA_TARGET_DIRS 705 TARGET_HOSTS 706 HOST_FLAGS 668 707 host_os 669 708 host_vendor … … 674 713 build_cpu 675 714 build 715 BUILD_IN_TREE_FLAGS 716 CFACPP 717 CFACC_INSTALL 718 CFACC 719 DRIVER_DIR 676 720 CFA_LIBDIR 677 721 CFA_BINDIR 678 722 CFA_INCDIR 679 723 CFA_PREFIX 724 HAS_DISTCC 725 LD 726 CXX 727 ENABLE_DISTCC_FALSE 728 ENABLE_DISTCC_TRUE 680 729 DOendif 681 730 DOifskipcompile 682 BUILD_CONCURRENCY_FALSE683 BUILD_CONCURRENCY_TRUE684 BUILD_NO_LIB_FALSE685 BUILD_NO_LIB_TRUE686 BUILD_DEBUG_FALSE687 BUILD_DEBUG_TRUE688 BUILD_RELEASE_FALSE689 BUILD_RELEASE_TRUE690 CFA_BACKEND_CC691 BACKEND_CC692 731 CFA_NAME 693 MAINT694 MAINTAINER_MODE_FALSE695 MAINTAINER_MODE_TRUE696 732 am__untar 697 733 am__tar … … 764 800 enable_option_checking 765 801 enable_silent_rules 766 enable_maintainer_mode767 802 with_cfa_name 768 with_backend_compiler 769 enable_target_release 770 enable_ target_debug771 enable_ threading803 enable_distcc 804 with_target_hosts 805 enable_gprofiler 806 enable_demangler 772 807 enable_dependency_tracking 808 enable_shared 809 enable_static 810 with_pic 811 enable_fast_install 812 with_aix_soname 813 with_gnu_ld 814 with_sysroot 815 enable_libtool_lock 773 816 ' 774 817 ac_precious_vars='build_alias … … 787 830 YACC 788 831 YFLAGS 789 CPP' 832 LT_SYS_LIBRARY_PATH 833 CPP 834 CXXCPP' 790 835 791 836 … … 1419 1464 --enable-silent-rules less verbose build output (undo: "make V=1") 1420 1465 --disable-silent-rules verbose build output (undo: "make V=0") 1421 --disable-maintainer-mode 1422 disable make rules and dependencies not useful (and 1423 sometimes confusing) to the casual installer 1424 --enable-target-release Build and install the release target 1425 --enable-target-debug Build and install the debug target 1426 --enable-threading Build and install libcfa with threading support 1427 (Enabled by default) 1466 --enable-distcc whether or not to enable distributed compilation 1467 --enable-gprofiler whether or not to enable gprofiler tools (if available) 1468 --enable-demangler whether or not to build the demangler (executable and library) 1428 1469 --enable-dependency-tracking 1429 1470 do not reject slow dependency extractors 1430 1471 --disable-dependency-tracking 1431 1472 speeds up one-time build 1473 --enable-shared[=PKGS] build shared libraries [default=yes] 1474 --enable-static[=PKGS] build static libraries [default=yes] 1475 --enable-fast-install[=PKGS] 1476 optimize for fast installation [default=yes] 1477 --disable-libtool-lock avoid locking (might break parallel builds) 1432 1478 1433 1479 Optional Packages: … … 1435 1481 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) 1436 1482 --with-cfa-name=NAME NAME too which cfa will be installed 1437 --with-backend-compiler=PROGRAM PROGRAM that performs the final code compilation (must be gcc-compatible) 1483 --with-target-hosts=HOSTS HOSTS comma seperated list of hosts to build for, format ARCH:debug|nodebug|nolib 1484 --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use 1485 both] 1486 --with-aix-soname=aix|svr4|both 1487 shared library versioning (aka "SONAME") variant to 1488 provide on AIX, [default=aix]. 1489 --with-gnu-ld assume the C compiler uses GNU ld [default=no] 1490 --with-sysroot[=DIR] Search for dependent libraries within DIR (or the 1491 compiler's sysroot if not specified). 1438 1492 1439 1493 Some influential environment variables: … … 1455 1509 This script will default YFLAGS to the empty string to avoid a 1456 1510 default value of `-d' given by some make applications. 1511 LT_SYS_LIBRARY_PATH 1512 User-defined run-time library search path. 1457 1513 CPP C preprocessor 1514 CXXCPP C++ preprocessor 1458 1515 1459 1516 Use these variables to override the choices made by `configure' or to help … … 1659 1716 } # ac_fn_c_try_link 1660 1717 1661 # ac_fn_c_check_ type LINENO TYPEVAR INCLUDES1662 # ------------------------------------------- 1663 # Tests whether TYPE exists after having included INCLUDES, setting cache1664 # variable VAR accordingly.1665 ac_fn_c_check_ type ()1718 # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES 1719 # ------------------------------------------------------- 1720 # Tests whether HEADER exists and can be compiled using the include files in 1721 # INCLUDES, setting the cache variable VAR accordingly. 1722 ac_fn_c_check_header_compile () 1666 1723 { 1667 1724 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack … … 1671 1728 $as_echo_n "(cached) " >&6 1672 1729 else 1673 eval "$3=no"1674 1730 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 1675 1731 /* end confdefs.h. */ 1676 1732 $4 1677 int 1678 main () 1679 { 1680 if (sizeof ($2)) 1681 return 0; 1682 ; 1683 return 0; 1684 } 1733 #include <$2> 1685 1734 _ACEOF 1686 1735 if ac_fn_c_try_compile "$LINENO"; then : 1687 cat confdefs.h - <<_ACEOF >conftest.$ac_ext1688 /* end confdefs.h. */1689 $41690 int1691 main ()1692 {1693 if (sizeof (($2)))1694 return 0;1695 ;1696 return 0;1697 }1698 _ACEOF1699 if ac_fn_c_try_compile "$LINENO"; then :1700 1701 else1702 1736 eval "$3=yes" 1703 fi 1704 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 1737 else 1738 eval "$3=no" 1705 1739 fi 1706 1740 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext … … 1711 1745 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno 1712 1746 1713 } # ac_fn_c_check_ type1747 } # ac_fn_c_check_header_compile 1714 1748 1715 1749 # ac_fn_c_try_cpp LINENO … … 1792 1826 } # ac_fn_c_try_run 1793 1827 1794 # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES1795 # -------------------------------------------------------1796 # Tests whether HEADER exists and can be compiled using the include files in1797 # INCLUDES, setting the cache variable VAR accordingly.1798 ac_fn_c_check_header_compile ()1799 {1800 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack1801 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&51802 $as_echo_n "checking for $2... " >&6; }1803 if eval \${$3+:} false; then :1804 $as_echo_n "(cached) " >&61805 else1806 cat confdefs.h - <<_ACEOF >conftest.$ac_ext1807 /* end confdefs.h. */1808 $41809 #include <$2>1810 _ACEOF1811 if ac_fn_c_try_compile "$LINENO"; then :1812 eval "$3=yes"1813 else1814 eval "$3=no"1815 fi1816 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext1817 fi1818 eval ac_res=\$$31819 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&51820 $as_echo "$ac_res" >&6; }1821 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno1822 1823 } # ac_fn_c_check_header_compile1824 1825 1828 # ac_fn_c_check_func LINENO FUNC VAR 1826 1829 # ---------------------------------- … … 1889 1892 1890 1893 } # ac_fn_c_check_func 1894 1895 # ac_fn_cxx_try_cpp LINENO 1896 # ------------------------ 1897 # Try to preprocess conftest.$ac_ext, and return whether this succeeded. 1898 ac_fn_cxx_try_cpp () 1899 { 1900 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 1901 if { { ac_try="$ac_cpp conftest.$ac_ext" 1902 case "(($ac_try" in 1903 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; 1904 *) ac_try_echo=$ac_try;; 1905 esac 1906 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" 1907 $as_echo "$ac_try_echo"; } >&5 1908 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err 1909 ac_status=$? 1910 if test -s conftest.err; then 1911 grep -v '^ *+' conftest.err >conftest.er1 1912 cat conftest.er1 >&5 1913 mv -f conftest.er1 conftest.err 1914 fi 1915 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 1916 test $ac_status = 0; } > conftest.i && { 1917 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || 1918 test ! -s conftest.err 1919 }; then : 1920 ac_retval=0 1921 else 1922 $as_echo "$as_me: failed program was:" >&5 1923 sed 's/^/| /' conftest.$ac_ext >&5 1924 1925 ac_retval=1 1926 fi 1927 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno 1928 as_fn_set_status $ac_retval 1929 1930 } # ac_fn_cxx_try_cpp 1931 1932 # ac_fn_cxx_try_link LINENO 1933 # ------------------------- 1934 # Try to link conftest.$ac_ext, and return whether this succeeded. 1935 ac_fn_cxx_try_link () 1936 { 1937 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 1938 rm -f conftest.$ac_objext conftest$ac_exeext 1939 if { { ac_try="$ac_link" 1940 case "(($ac_try" in 1941 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; 1942 *) ac_try_echo=$ac_try;; 1943 esac 1944 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" 1945 $as_echo "$ac_try_echo"; } >&5 1946 (eval "$ac_link") 2>conftest.err 1947 ac_status=$? 1948 if test -s conftest.err; then 1949 grep -v '^ *+' conftest.err >conftest.er1 1950 cat conftest.er1 >&5 1951 mv -f conftest.er1 conftest.err 1952 fi 1953 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 1954 test $ac_status = 0; } && { 1955 test -z "$ac_cxx_werror_flag" || 1956 test ! -s conftest.err 1957 } && test -s conftest$ac_exeext && { 1958 test "$cross_compiling" = yes || 1959 test -x conftest$ac_exeext 1960 }; then : 1961 ac_retval=0 1962 else 1963 $as_echo "$as_me: failed program was:" >&5 1964 sed 's/^/| /' conftest.$ac_ext >&5 1965 1966 ac_retval=1 1967 fi 1968 # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information 1969 # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would 1970 # interfere with the next link command; also delete a directory that is 1971 # left behind by Apple's compiler. We do this before executing the actions. 1972 rm -rf conftest.dSYM conftest_ipa8_conftest.oo 1973 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno 1974 as_fn_set_status $ac_retval 1975 1976 } # ac_fn_cxx_try_link 1891 1977 1892 1978 # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES … … 1981 2067 } # ac_fn_c_check_header_mongrel 1982 2068 1983 # ac_fn_c_ find_intX_t LINENO BITS VAR1984 # ----------------------------------- 1985 # Finds a signed integer type with width BITS, setting cache variable VAR1986 # accordingly.1987 ac_fn_c_ find_intX_t()2069 # ac_fn_c_check_type LINENO TYPE VAR INCLUDES 2070 # ------------------------------------------- 2071 # Tests whether TYPE exists after having included INCLUDES, setting cache 2072 # variable VAR accordingly. 2073 ac_fn_c_check_type () 1988 2074 { 1989 2075 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 1990 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&51991 $as_echo_n "checking for int$2_t... " >&6; }2076 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 2077 $as_echo_n "checking for $2... " >&6; } 1992 2078 if eval \${$3+:} false; then : 1993 2079 $as_echo_n "(cached) " >&6 1994 2080 else 1995 2081 eval "$3=no" 1996 # Order is important - never check a type that is potentially smaller 1997 # than half of the expected target width. 1998 for ac_type in int$2_t 'int' 'long int' \ 1999 'long long int' 'short int' 'signed char'; do 2000 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 2082 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 2001 2083 /* end confdefs.h. */ 2002 $ac_includes_default 2003 enum { N = $2 / 2 - 1 }; 2084 $4 2004 2085 int 2005 2086 main () 2006 2087 { 2007 static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; 2008 test_array [0] = 0; 2009 return test_array [0]; 2010 2088 if (sizeof ($2)) 2089 return 0; 2011 2090 ; 2012 2091 return 0; … … 2016 2095 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 2017 2096 /* end confdefs.h. */ 2018 $ac_includes_default 2019 enum { N = $2 / 2 - 1 }; 2097 $4 2020 2098 int 2021 2099 main () 2022 2100 { 2023 static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) 2024 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; 2025 test_array [0] = 0; 2026 return test_array [0]; 2027 2101 if (sizeof (($2))) 2102 return 0; 2028 2103 ; 2029 2104 return 0; … … 2033 2108 2034 2109 else 2035 case $ac_type in #( 2036 int$2_t) : 2037 eval "$3=yes" ;; #( 2038 *) : 2039 eval "$3=\$ac_type" ;; 2040 esac 2110 eval "$3=yes" 2041 2111 fi 2042 2112 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 2043 2113 fi 2044 2114 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 2045 if eval test \"x\$"$3"\" = x"no"; then :2046 2047 else2048 break2049 fi2050 done2051 2115 fi 2052 2116 eval ac_res=\$$3 … … 2055 2119 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno 2056 2120 2057 } # ac_fn_c_find_intX_t 2058 2059 # ac_fn_c_find_uintX_t LINENO BITS VAR 2060 # ------------------------------------ 2061 # Finds an unsigned integer type with width BITS, setting cache variable VAR 2062 # accordingly. 2063 ac_fn_c_find_uintX_t () 2064 { 2065 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 2066 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 2067 $as_echo_n "checking for uint$2_t... " >&6; } 2068 if eval \${$3+:} false; then : 2069 $as_echo_n "(cached) " >&6 2070 else 2071 eval "$3=no" 2072 # Order is important - never check a type that is potentially smaller 2073 # than half of the expected target width. 2074 for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ 2075 'unsigned long long int' 'unsigned short int' 'unsigned char'; do 2076 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 2077 /* end confdefs.h. */ 2078 $ac_includes_default 2079 int 2080 main () 2081 { 2082 static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; 2083 test_array [0] = 0; 2084 return test_array [0]; 2085 2086 ; 2087 return 0; 2088 } 2089 _ACEOF 2090 if ac_fn_c_try_compile "$LINENO"; then : 2091 case $ac_type in #( 2092 uint$2_t) : 2093 eval "$3=yes" ;; #( 2094 *) : 2095 eval "$3=\$ac_type" ;; 2096 esac 2097 fi 2098 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 2099 if eval test \"x\$"$3"\" = x"no"; then : 2100 2101 else 2102 break 2103 fi 2104 done 2105 fi 2106 eval ac_res=\$$3 2107 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 2108 $as_echo "$ac_res" >&6; } 2109 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno 2110 2111 } # ac_fn_c_find_uintX_t 2121 } # ac_fn_c_check_type 2112 2122 cat >config.log <<_ACEOF 2113 2123 This file contains any messages produced by compilers while … … 2491 2501 2492 2502 2503 2493 2504 #AC_CONFIG_SRCDIR([src/main.cc]) 2494 ac_config_headers="$ac_config_headers config.h "2505 ac_config_headers="$ac_config_headers config.h:src/config.h.in" 2495 2506 2496 2507 # Check whether --enable-silent-rules was given. … … 2502 2513 yes) AM_DEFAULT_VERBOSITY=0;; 2503 2514 no) AM_DEFAULT_VERBOSITY=1;; 2504 *) AM_DEFAULT_VERBOSITY= 1;;2515 *) AM_DEFAULT_VERBOSITY=0;; 2505 2516 esac 2506 2517 am_make=${MAKE-make} … … 2533 2544 AM_BACKSLASH='\' 2534 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 # http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_check_compile_flag.m4 2555 2556 2557 # don't use the default CFLAGS as they unconditonnaly add -O2 2558 : ${CFLAGS=""} 2535 2559 2536 2560 am__api_version='1.15' … … 3075 3099 3076 3100 3077 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&53078 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }3079 # Check whether --enable-maintainer-mode was given.3080 if test "${enable_maintainer_mode+set}" = set; then :3081 enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval3082 else3083 USE_MAINTAINER_MODE=yes3084 fi3085 3086 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&53087 $as_echo "$USE_MAINTAINER_MODE" >&6; }3088 if test $USE_MAINTAINER_MODE = yes; then3089 MAINTAINER_MODE_TRUE=3090 MAINTAINER_MODE_FALSE='#'3091 else3092 MAINTAINER_MODE_TRUE='#'3093 MAINTAINER_MODE_FALSE=3094 fi3095 3096 MAINT=$MAINTAINER_MODE_TRUE3097 3098 # may require auto* software to be installed3099 3100 3101 # Allow program name tansformation 3101 3102 # will fill program_transform_name with appropriate sed regex 3102 3103 3103 3104 3105 #============================================================================== 3104 3106 #Trasforming cc1 will break compilation 3105 if test "${program_transform_name}" = ""; then 3106 as_fn_error $? "Program transform not supported. 3107 Use --with-cfa-name='[Desired name here]' instead" "$LINENO" 5 3108 fi 3109 3107 3108 if test "${program_transform_name}" = ""; then 3109 as_fn_error $? "Program transform not supported. 3110 Use --with-cfa-name='[Desired name here]' instead" "$LINENO" 5 3111 fi 3112 3113 #Define the new name of the installed command 3110 3114 3111 3115 # Check whether --with-cfa-name was given. … … 3117 3121 3118 3122 3119 #Define the new name of the installed command 3120 CFA_NAME=${cfa_name} 3121 3123 CFA_NAME=${cfa_name} 3124 3125 3126 3127 #============================================================================== 3128 # version information 3122 3129 3123 3130 rm -f version … … 3171 3178 3172 3179 3173 # Installation paths 3174 3175 3176 # Check whether --with-backend-compiler was given. 3177 if test "${with_backend_compiler+set}" = set; then : 3178 withval=$with_backend_compiler; backendcompiler=$withval 3179 else 3180 backendcompiler="" 3181 fi 3182 3183 if test "x$backendcompiler" != "x"; then 3184 BACKEND_CC=${backendcompiler} 3185 else 3186 # Extract the first word of "gcc", so it can be a program name with args. 3187 set dummy gcc; ac_word=$2 3188 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 3189 $as_echo_n "checking for $ac_word... " >&6; } 3190 if ${ac_cv_path_BACKEND_CC+:} false; then : 3191 $as_echo_n "(cached) " >&6 3192 else 3193 case $BACKEND_CC in 3194 [\\/]* | ?:[\\/]*) 3195 ac_cv_path_BACKEND_CC="$BACKEND_CC" # Let the user override the test with a path. 3196 ;; 3197 *) 3198 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 3199 for as_dir in $PATH 3200 do 3201 IFS=$as_save_IFS 3202 test -z "$as_dir" && as_dir=. 3203 for ac_exec_ext in '' $ac_executable_extensions; do 3204 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 3205 ac_cv_path_BACKEND_CC="$as_dir/$ac_word$ac_exec_ext" 3206 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 3207 break 2 3208 fi 3209 done 3210 done 3211 IFS=$as_save_IFS 3212 3213 ;; 3214 esac 3215 fi 3216 BACKEND_CC=$ac_cv_path_BACKEND_CC 3217 if test -n "$BACKEND_CC"; then 3218 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BACKEND_CC" >&5 3219 $as_echo "$BACKEND_CC" >&6; } 3220 else 3221 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 3222 $as_echo "no" >&6; } 3223 fi 3224 3225 # check gcc installed 3226 if test "x$BACKEND_CC" = "x"; then 3227 as_fn_error $? "some version of gcc is needed. Get it at ftp://ftp.gnu.org" "$LINENO" 5 3228 exit 1 3229 fi 3230 fi 3231 3232 cat >>confdefs.h <<_ACEOF 3233 #define CFA_BACKEND_CC "${BACKEND_CC}" 3234 _ACEOF 3235 3236 3237 3238 3239 3240 # Check whether --enable-target-release was given. 3241 if test "${enable_target_release+set}" = set; then : 3242 enableval=$enable_target_release; 3243 fi 3244 3245 # Check whether --enable-target-debug was given. 3246 if test "${enable_target_debug+set}" = set; then : 3247 enableval=$enable_target_debug; 3248 fi 3249 3250 # Check whether --enable-threading was given. 3251 if test "${enable_threading+set}" = set; then : 3252 enableval=$enable_threading; case "${enableval}" in 3253 yes) build_threading="yes" ;; 3254 no) build_threading="no" ;; 3255 *) as_fn_error $? "bad value ${enableval} for --enable-debug" "$LINENO" 5 ;; 3256 esac 3257 else 3258 build_threading="yes" 3259 fi 3260 3261 3262 case "$enable_target_release" in 3263 yes) 3264 case "$enable_target_debug" in 3265 yes) 3266 build_release="yes" 3267 build_debug="yes" 3268 ;; 3269 no) 3270 build_release="yes" 3271 build_debug="no" 3272 ;; 3273 *) 3274 build_release="yes" 3275 build_debug="no" 3276 ;; 3277 esac 3278 ;; 3279 no) 3280 case "$enable_target_debug" in 3281 yes) 3282 build_release="no" 3283 build_debug="yes" 3284 ;; 3285 no) 3286 build_release="no" 3287 build_debug="no" 3288 ;; 3289 *) 3290 build_release="no" 3291 build_debug="yes" 3292 ;; 3293 esac 3294 ;; 3295 *) 3296 case "$enable_target_debug" in 3297 yes) 3298 build_release="no" 3299 build_debug="yes" 3300 ;; 3301 no) 3302 build_release="yes" 3303 build_debug="no" 3304 ;; 3305 *) 3306 build_release="yes" 3307 build_debug="yes" 3308 ;; 3309 esac 3310 ;; 3311 esac 3312 3313 if test "x$build_release" = "xyes"; then 3314 BUILD_RELEASE_TRUE= 3315 BUILD_RELEASE_FALSE='#' 3316 else 3317 BUILD_RELEASE_TRUE='#' 3318 BUILD_RELEASE_FALSE= 3319 fi 3320 3321 if test "x$build_debug" = "xyes"; then 3322 BUILD_DEBUG_TRUE= 3323 BUILD_DEBUG_FALSE='#' 3324 else 3325 BUILD_DEBUG_TRUE='#' 3326 BUILD_DEBUG_FALSE= 3327 fi 3328 3329 if test "x$build_release$build_debug" = "xnono"; then 3330 BUILD_NO_LIB_TRUE= 3331 BUILD_NO_LIB_FALSE='#' 3332 else 3333 BUILD_NO_LIB_TRUE='#' 3334 BUILD_NO_LIB_FALSE= 3335 fi 3336 3337 if test "x$build_threading" = "xyes"; then 3338 BUILD_CONCURRENCY_TRUE= 3339 BUILD_CONCURRENCY_FALSE='#' 3340 else 3341 BUILD_CONCURRENCY_TRUE='#' 3342 BUILD_CONCURRENCY_FALSE= 3343 fi 3344 3345 3180 #============================================================================== 3181 # HACK to be able to use conditionnals inside makefiles 3346 3182 DOifskipcompile='ifeq ($(skipcompile),yes) 3347 3183 else' … … 3353 3189 3354 3190 3355 if test "x$prefix" = "xNONE"; then 3356 cfa_prefix=${ac_default_prefix} 3357 else 3358 cfa_prefix=${prefix} 3359 fi 3191 #============================================================================== 3192 # distcc support 3193 3194 # Check whether --enable-distcc was given. 3195 if test "${enable_distcc+set}" = set; then : 3196 enableval=$enable_distcc; enable_distcc=$enableval 3197 else 3198 enable_distcc=no 3199 fi 3200 3201 3202 if test x$enable_distcc = xyes; then 3203 ENABLE_DISTCC_TRUE= 3204 ENABLE_DISTCC_FALSE='#' 3205 else 3206 ENABLE_DISTCC_TRUE='#' 3207 ENABLE_DISTCC_FALSE= 3208 fi 3209 3210 HAS_DISTCC="False" 3211 3212 if test x$enable_distcc = xyes; then 3213 CXX="distcc ${CXX}" 3214 LD="distcc ${LD} -lstdc++" 3215 HAS_DISTCC="True" 3216 echo "Enabling distributed builds" 3217 fi 3218 3219 3220 3221 3222 3223 #============================================================================== 3224 # Installation paths 3225 3226 if test "x$prefix" = "xNONE"; then 3227 cfa_prefix=${ac_default_prefix} 3228 else 3229 cfa_prefix=${prefix} 3230 fi 3231 cfa_prefix="$(readlink -m ${cfa_prefix})/" 3360 3232 3361 3233 cat >>confdefs.h <<_ACEOF … … 3363 3235 _ACEOF 3364 3236 3365 CFA_PREFIX=${cfa_prefix} 3366 3367 3368 if test "$includedir" = '${prefix}/include'; then 3369 cfa_incdir="${cfa_prefix}/include/${cfa_name}" 3370 else 3371 cfa_incdir=${includedir} 3372 fi 3237 CFA_PREFIX=${cfa_prefix} 3238 3239 3240 if test "$includedir" = '${prefix}/include'; then 3241 cfa_incdir="${cfa_prefix}include/${cfa_name}" 3242 else 3243 cfa_incdir=${includedir} 3244 fi 3245 cfa_incdir="$(readlink -m ${cfa_incdir})/" 3373 3246 3374 3247 cat >>confdefs.h <<_ACEOF … … 3376 3249 _ACEOF 3377 3250 3378 CFA_INCDIR=${cfa_incdir} 3379 3380 3381 if test "$bindir" = '${exec_prefix}/bin'; then 3382 cfa_bindir="${cfa_prefix}/bin" 3383 else 3384 cfa_bindir=${bindir} 3385 fi 3251 CFA_INCDIR=${cfa_incdir} 3252 3253 3254 if test "$bindir" = '${exec_prefix}/bin'; then 3255 cfa_bindir="${cfa_prefix}bin" 3256 else 3257 cfa_bindir=${bindir} 3258 fi 3259 cfa_bindir="$(readlink -m ${cfa_bindir})/" 3386 3260 3387 3261 cat >>confdefs.h <<_ACEOF … … 3389 3263 _ACEOF 3390 3264 3391 CFA_BINDIR=${cfa_bindir} 3392 3393 3394 if test "$libdir" = '${exec_prefix}/lib'; then 3395 cfa_libdir="${cfa_prefix}/lib/${cfa_name}" 3396 else 3397 cfa_libdir=${libdir} 3398 fi 3265 CFA_BINDIR=${cfa_bindir} 3266 3267 3268 if test "$libdir" = '${exec_prefix}/lib'; then 3269 if test "${ARCHITECTURE}" != ""; then 3270 cfa_libdir="${cfa_prefix}lib/${cfa_name}/${ARCHITECTURE}-${CONFIGURATION}/" 3271 else 3272 cfa_libdir="${cfa_prefix}lib/${cfa_name}/" 3273 fi 3274 else 3275 cfa_libdir="${libdir}/${ARCHITECTURE}${CONFIGURATION}" 3276 fi 3277 cfa_libdir="$(readlink -m ${cfa_libdir})/" 3399 3278 3400 3279 cat >>confdefs.h <<_ACEOF … … 3402 3281 _ACEOF 3403 3282 3404 CFA_LIBDIR=${cfa_libdir} 3405 3406 3283 CFA_LIBDIR=${cfa_libdir} 3284 3285 3286 3287 #============================================================================== 3288 # Create variables for commonly used targets 3289 3290 TOP_SRCDIR="$(readlink -m $ac_confdir/)/" 3291 TOP_BUILDDIR="$(readlink -m $ac_pwd/)/" 3292 3293 3294 cat >>confdefs.h <<_ACEOF 3295 #define TOP_SRCDIR "$TOP_SRCDIR" 3296 _ACEOF 3297 3298 3299 cat >>confdefs.h <<_ACEOF 3300 #define TOP_BUILDDIR "$TOP_BUILDDIR" 3301 _ACEOF 3302 3303 3304 DRIVER_DIR=${TOP_BUILDDIR}driver/ 3305 CFACC=${DRIVER_DIR}cfa 3306 CFACC_INSTALL=${CFA_BINDIR}${CFA_NAME} 3307 CFACPP=${DRIVER_DIR}cfa-cpp 3308 3309 3310 3311 3312 3313 #============================================================================== 3314 # Flag variables needed to build in tree 3315 LIBCFA_SRC='${TOP_SRCDIR}/libcfa/src' 3316 BUILD_IN_TREE_FLAGS="-XCFA -t -B${DRIVER_DIR}" 3317 3318 3319 #============================================================================== 3320 # handle the list of hosts to build for 3321 for var in $ac_configure_args 3322 do 3323 #strip quotes surrouding values 3324 case $var in 3325 # skip cross compilation related arguments 3326 \'--host=*) ;; \'host_alias=*) ;; \'--build=*) ;; \'build_alias=*) ;; \'--target=*) ;; \'target_alias=*) ;; 3327 3328 # skip the target hosts 3329 \'--with-target-hosts=*) ;; 3330 3331 # skip gprofiler for libcfa 3332 \'--enable-gprofiler=*) ;; 3333 \'--disable-gprofiler) ;; 3334 3335 # append all other arguments to the sub configure arguments 3336 *) LIBCFA_GENERAL_ARGS="${LIBCFA_GENERAL_ARGS} $var";; 3337 esac 3338 done 3339 3340 #============================================================================== 3341 # handle the list of hosts to build for 3407 3342 # Make sure we can run config.sub. 3408 3343 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || … … 3476 3411 3477 3412 3478 MACHINE_TYPE=$host_cpu3479 3480 3413 3481 3414 if ! test "$host_cpu" = "$build_cpu"; then 3482 3415 case $host_cpu in 3483 3416 i386) 3484 CFLAGS+=" -m32 " 3485 CXXFLAGS+=" -m32 " 3486 CFAFLAGS+=" -m32 " 3487 LDFLAGS+=" -m32 " 3417 HOST_FLAGS="-m32" 3488 3418 ;; 3489 3419 i686) 3490 CFLAGS+=" -m32 " 3491 CXXFLAGS+=" -m32 " 3492 CFAFLAGS+=" -m32 " 3493 LDFLAGS+=" -m32 " 3420 HOST_FLAGS="-m32" 3494 3421 ;; 3495 3422 x86_64) 3496 CFLAGS+=" -m64 " 3497 CXXFLAGS+=" -m64 " 3498 CFAFLAGS+=" -m64 " 3499 LDFLAGS+=" -m64 " 3423 HOST_FLAGS="-m64" 3500 3424 ;; 3501 3425 esac 3502 3426 fi 3503 3427 3428 3429 default_target="${host_cpu}:debug, ${host_cpu}:nodebug" 3430 3431 # Check whether --with-target-hosts was given. 3432 if test "${with_target_hosts+set}" = set; then : 3433 withval=$with_target_hosts; target_hosts=$withval 3434 else 3435 target_hosts=${default_target} 3436 fi 3437 3438 3439 # Check whether --enable-gprofiler was given. 3440 if test "${enable_gprofiler+set}" = set; then : 3441 enableval=$enable_gprofiler; enable_gprofiler=$enableval 3442 else 3443 enable_gprofiler=yes 3444 fi 3445 3446 3447 # Check whether --enable-demangler was given. 3448 if test "${enable_demangler+set}" = set; then : 3449 enableval=$enable_demangler; enable_demangler=$enableval 3450 else 3451 enable_demangler=yes 3452 fi 3453 3454 3455 TARGET_HOSTS=${target_hosts} 3456 3457 3458 LIBCFA_PATHS="DRIVER_DIR=${DRIVER_DIR}" 3459 3460 for i in $(echo $target_hosts | sed "s/,/ /g") 3461 do 3462 # call your procedure/other scripts here below 3463 arch_name=$(echo $i | sed -r "s/:(.*)//g") 3464 lib_config=$(echo $i | sed -r "s/(.*)://g") 3465 3466 case $lib_config in 3467 "nodebug") ;; 3468 "debug") ;; 3469 "nolib") ;; 3470 "profile") ;; 3471 *) 3472 >&2 echo "Configuration must be 'debug', 'nodebug' or 'nolib'" 3473 exit 1 3474 ;; 3475 esac 3476 3477 3478 case ${arch_name} in 3479 "host") arch_name=${host_cpu};; 3480 *) arch_name=${arch_name};; 3481 esac 3482 3483 case $arch_name in 3484 "x64" ) cannon_arch_name="x64";; 3485 "x86-64" ) cannon_arch_name="x64";; 3486 "x86_64" ) cannon_arch_name="x64";; 3487 "aarch64" ) cannon_arch_name="arm";; 3488 "x86" ) cannon_arch_name="x86";; 3489 "i386" ) cannon_arch_name="x86";; 3490 "i486" ) cannon_arch_name="x86";; 3491 "i686" ) cannon_arch_name="x86";; 3492 "Intel 80386") cannon_arch_name="x86";; 3493 "arm" ) cannon_arch_name="arm";; 3494 "ARM" ) cannon_arch_name="arm";; 3495 "armv7l" ) cannon_arch_name="arm";; 3496 *) 3497 >&2 echo "Unknown architecture " $arch_name; 3498 exit 1 3499 ;; 3500 esac 3501 3502 lib_arch=${cannon_arch_name} 3503 lib_dir="libcfa/${lib_arch}-${lib_config}" 3504 3505 LIBCFA_TARGET_DIRS="${LIBCFA_TARGET_DIRS} ${lib_dir}" 3506 LIBCFA_TARGET_MAKEFILES="${LIBCFA_TARGET_MAKEFILES} ${lib_dir}/Makefile" 3507 3508 mkdir -p ${lib_dir} 3509 echo -n "${LIBCFA_GENERAL_ARGS} " > ${lib_dir}/config.data 3510 echo -n "${LIBCFA_PATHS} " >> ${lib_dir}/config.data 3511 echo -n "ARCHITECTURE=${lib_arch} " >> ${lib_dir}/config.data 3512 echo -n "CONFIGURATION=${lib_config} " >> ${lib_dir}/config.data 3513 echo -n "CFA_VERSION=${ver_major}:${ver_minor}:${ver_patch}" >> ${lib_dir}/config.data 3514 done 3515 3516 3517 3518 3519 3520 case ${host_cpu} in 3521 "host") arch_name=${host_cpu};; 3522 *) arch_name=${host_cpu};; 3523 esac 3524 3525 case $arch_name in 3526 "x64" ) cannon_arch_name="x64";; 3527 "x86-64" ) cannon_arch_name="x64";; 3528 "x86_64" ) cannon_arch_name="x64";; 3529 "aarch64" ) cannon_arch_name="arm";; 3530 "x86" ) cannon_arch_name="x86";; 3531 "i386" ) cannon_arch_name="x86";; 3532 "i486" ) cannon_arch_name="x86";; 3533 "i686" ) cannon_arch_name="x86";; 3534 "Intel 80386") cannon_arch_name="x86";; 3535 "arm" ) cannon_arch_name="arm";; 3536 "ARM" ) cannon_arch_name="arm";; 3537 "armv7l" ) cannon_arch_name="arm";; 3538 *) 3539 >&2 echo "Unknown architecture " $arch_name; 3540 exit 1 3541 ;; 3542 esac 3543 3544 3545 cat >>confdefs.h <<_ACEOF 3546 #define CFA_DEFAULT_CPU "$cannon_arch_name" 3547 _ACEOF 3548 3549 3550 cat >>confdefs.h <<_ACEOF 3551 #define CFA_64_CPU "x64" 3552 _ACEOF 3553 3554 3555 cat >>confdefs.h <<_ACEOF 3556 #define CFA_32_CPU "x86" 3557 _ACEOF 3558 3559 3560 #============================================================================== 3561 # CAFLAGS 3504 3562 3505 3563 cat >>confdefs.h <<_ACEOF … … 3510 3568 3511 3569 3570 #============================================================================== 3512 3571 # Checks for programs. 3513 3572 ac_ext=cpp … … 5068 5127 5069 5128 5070 # deprecated5071 5129 # These are often not installed and people miss seeing the "no", so stop the configure. 5072 5130 for ac_prog in 'bison -y' byacc … … 5275 5333 fi 5276 5334 if test "${LEX}" = "lex" ; then echo "Error: flex required." ; exit 1 ; fi 5277 5278 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 5279 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } 5280 set x ${MAKE-make} 5281 ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` 5282 if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : 5335 case `pwd` in 5336 *\ * | *\ *) 5337 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 5338 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; 5339 esac 5340 5341 5342 5343 macro_version='2.4.6' 5344 macro_revision='2.4.6' 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 ltmain=$ac_aux_dir/ltmain.sh 5359 5360 # Backslashify metacharacters that are still active within 5361 # double-quoted strings. 5362 sed_quote_subst='s/\(["`$\\]\)/\\\1/g' 5363 5364 # Same as above, but do not quote variable references. 5365 double_quote_subst='s/\(["`\\]\)/\\\1/g' 5366 5367 # Sed substitution to delay expansion of an escaped shell variable in a 5368 # double_quote_subst'ed string. 5369 delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' 5370 5371 # Sed substitution to delay expansion of an escaped single quote. 5372 delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' 5373 5374 # Sed substitution to avoid accidental globbing in evaled expressions 5375 no_glob_subst='s/\*/\\\*/g' 5376 5377 ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' 5378 ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO 5379 ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO 5380 5381 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 5382 $as_echo_n "checking how to print strings... " >&6; } 5383 # Test print first, because it will be a builtin if present. 5384 if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ 5385 test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then 5386 ECHO='print -r --' 5387 elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then 5388 ECHO='printf %s\n' 5389 else 5390 # Use this function as a fallback that always works. 5391 func_fallback_echo () 5392 { 5393 eval 'cat <<_LTECHO_EOF 5394 $1 5395 _LTECHO_EOF' 5396 } 5397 ECHO='func_fallback_echo' 5398 fi 5399 5400 # func_echo_all arg... 5401 # Invoke $ECHO with all args, space-separated. 5402 func_echo_all () 5403 { 5404 $ECHO "" 5405 } 5406 5407 case $ECHO in 5408 printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 5409 $as_echo "printf" >&6; } ;; 5410 print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 5411 $as_echo "print -r" >&6; } ;; 5412 *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 5413 $as_echo "cat" >&6; } ;; 5414 esac 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 5430 $as_echo_n "checking for a sed that does not truncate output... " >&6; } 5431 if ${ac_cv_path_SED+:} false; then : 5283 5432 $as_echo_n "(cached) " >&6 5284 5433 else 5285 cat >conftest.make <<\_ACEOF 5286 SHELL = /bin/sh 5287 all: 5288 @echo '@@@%%%=$(MAKE)=@@@%%%' 5289 _ACEOF 5290 # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. 5291 case `${MAKE-make} -f conftest.make 2>/dev/null` in 5292 *@@@%%%=?*=@@@%%%*) 5293 eval ac_cv_prog_make_${ac_make}_set=yes;; 5294 *) 5295 eval ac_cv_prog_make_${ac_make}_set=no;; 5296 esac 5297 rm -f conftest.make 5298 fi 5299 if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then 5300 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 5301 $as_echo "yes" >&6; } 5302 SET_MAKE= 5303 else 5304 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 5305 $as_echo "no" >&6; } 5306 SET_MAKE="MAKE=${MAKE-make}" 5307 fi 5308 5309 if test -n "$ac_tool_prefix"; then 5310 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. 5311 set dummy ${ac_tool_prefix}ranlib; ac_word=$2 5312 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 5313 $as_echo_n "checking for $ac_word... " >&6; } 5314 if ${ac_cv_prog_RANLIB+:} false; then : 5315 $as_echo_n "(cached) " >&6 5316 else 5317 if test -n "$RANLIB"; then 5318 ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. 5319 else 5320 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 5434 ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ 5435 for ac_i in 1 2 3 4 5 6 7; do 5436 ac_script="$ac_script$as_nl$ac_script" 5437 done 5438 echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed 5439 { ac_script=; unset ac_script;} 5440 if test -z "$SED"; then 5441 ac_path_SED_found=false 5442 # Loop through the user's path and test for each of PROGNAME-LIST 5443 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 5321 5444 for as_dir in $PATH 5322 5445 do 5323 5446 IFS=$as_save_IFS 5324 5447 test -z "$as_dir" && as_dir=. 5448 for ac_prog in sed gsed; do 5325 5449 for ac_exec_ext in '' $ac_executable_extensions; do 5326 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 5327 ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" 5328 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 5329 break 2 5330 fi 5331 done 5450 ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" 5451 as_fn_executable_p "$ac_path_SED" || continue 5452 # Check for GNU ac_path_SED and select it if it is found. 5453 # Check for GNU $ac_path_SED 5454 case `"$ac_path_SED" --version 2>&1` in 5455 *GNU*) 5456 ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; 5457 *) 5458 ac_count=0 5459 $as_echo_n 0123456789 >"conftest.in" 5460 while : 5461 do 5462 cat "conftest.in" "conftest.in" >"conftest.tmp" 5463 mv "conftest.tmp" "conftest.in" 5464 cp "conftest.in" "conftest.nl" 5465 $as_echo '' >> "conftest.nl" 5466 "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break 5467 diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break 5468 as_fn_arith $ac_count + 1 && ac_count=$as_val 5469 if test $ac_count -gt ${ac_path_SED_max-0}; then 5470 # Best one so far, save it but keep looking for a better one 5471 ac_cv_path_SED="$ac_path_SED" 5472 ac_path_SED_max=$ac_count 5473 fi 5474 # 10*(2^10) chars as input seems more than enough 5475 test $ac_count -gt 10 && break 5476 done 5477 rm -f conftest.in conftest.tmp conftest.nl conftest.out;; 5478 esac 5479 5480 $ac_path_SED_found && break 3 5481 done 5482 done 5332 5483 done 5333 5484 IFS=$as_save_IFS 5334 5335 fi 5336 fi 5337 RANLIB=$ac_cv_prog_RANLIB 5338 if test -n "$RANLIB"; then 5339 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 5340 $as_echo "$RANLIB" >&6; } 5341 else 5342 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 5343 $as_echo "no" >&6; } 5344 fi 5345 5346 5347 fi 5348 if test -z "$ac_cv_prog_RANLIB"; then 5349 ac_ct_RANLIB=$RANLIB 5350 # Extract the first word of "ranlib", so it can be a program name with args. 5351 set dummy ranlib; ac_word=$2 5352 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 5353 $as_echo_n "checking for $ac_word... " >&6; } 5354 if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : 5355 $as_echo_n "(cached) " >&6 5356 else 5357 if test -n "$ac_ct_RANLIB"; then 5358 ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. 5359 else 5360 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 5361 for as_dir in $PATH 5362 do 5363 IFS=$as_save_IFS 5364 test -z "$as_dir" && as_dir=. 5365 for ac_exec_ext in '' $ac_executable_extensions; do 5366 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 5367 ac_cv_prog_ac_ct_RANLIB="ranlib" 5368 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 5369 break 2 5485 if test -z "$ac_cv_path_SED"; then 5486 as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 5370 5487 fi 5371 done 5372 done 5373 IFS=$as_save_IFS 5374 5375 fi 5376 fi 5377 ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB 5378 if test -n "$ac_ct_RANLIB"; then 5379 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 5380 $as_echo "$ac_ct_RANLIB" >&6; } 5381 else 5382 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 5383 $as_echo "no" >&6; } 5384 fi 5385 5386 if test "x$ac_ct_RANLIB" = x; then 5387 RANLIB=":" 5388 else 5389 case $cross_compiling:$ac_tool_warned in 5390 yes:) 5391 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 5392 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 5393 ac_tool_warned=yes ;; 5394 esac 5395 RANLIB=$ac_ct_RANLIB 5396 fi 5397 else 5398 RANLIB="$ac_cv_prog_RANLIB" 5399 fi 5400 5401 5402 # Checks for libraries. 5403 5404 # Checks for header files. 5405 ac_ext=c 5406 ac_cpp='$CPP $CPPFLAGS' 5407 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 5408 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 5409 ac_compiler_gnu=$ac_cv_c_compiler_gnu 5410 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 5411 $as_echo_n "checking how to run the C preprocessor... " >&6; } 5412 # On Suns, sometimes $CPP names a directory. 5413 if test -n "$CPP" && test -d "$CPP"; then 5414 CPP= 5415 fi 5416 if test -z "$CPP"; then 5417 if ${ac_cv_prog_CPP+:} false; then : 5418 $as_echo_n "(cached) " >&6 5419 else 5420 # Double quotes because CPP needs to be expanded 5421 for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" 5422 do 5423 ac_preproc_ok=false 5424 for ac_c_preproc_warn_flag in '' yes 5425 do 5426 # Use a header file that comes with gcc, so configuring glibc 5427 # with a fresh cross-compiler works. 5428 # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since 5429 # <limits.h> exists even on freestanding compilers. 5430 # On the NeXT, cc -E runs the code through the compiler's parser, 5431 # not just through cpp. "Syntax error" is here to catch this case. 5432 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5433 /* end confdefs.h. */ 5434 #ifdef __STDC__ 5435 # include <limits.h> 5436 #else 5437 # include <assert.h> 5438 #endif 5439 Syntax error 5440 _ACEOF 5441 if ac_fn_c_try_cpp "$LINENO"; then : 5442 5443 else 5444 # Broken: fails on valid input. 5445 continue 5446 fi 5447 rm -f conftest.err conftest.i conftest.$ac_ext 5448 5449 # OK, works on sane cases. Now check whether nonexistent headers 5450 # can be detected and how. 5451 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5452 /* end confdefs.h. */ 5453 #include <ac_nonexistent.h> 5454 _ACEOF 5455 if ac_fn_c_try_cpp "$LINENO"; then : 5456 # Broken: success on invalid input. 5457 continue 5458 else 5459 # Passes both tests. 5460 ac_preproc_ok=: 5461 break 5462 fi 5463 rm -f conftest.err conftest.i conftest.$ac_ext 5464 5465 done 5466 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. 5467 rm -f conftest.i conftest.err conftest.$ac_ext 5468 if $ac_preproc_ok; then : 5469 break 5470 fi 5471 5472 done 5473 ac_cv_prog_CPP=$CPP 5474 5475 fi 5476 CPP=$ac_cv_prog_CPP 5477 else 5478 ac_cv_prog_CPP=$CPP 5479 fi 5480 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 5481 $as_echo "$CPP" >&6; } 5482 ac_preproc_ok=false 5483 for ac_c_preproc_warn_flag in '' yes 5484 do 5485 # Use a header file that comes with gcc, so configuring glibc 5486 # with a fresh cross-compiler works. 5487 # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since 5488 # <limits.h> exists even on freestanding compilers. 5489 # On the NeXT, cc -E runs the code through the compiler's parser, 5490 # not just through cpp. "Syntax error" is here to catch this case. 5491 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5492 /* end confdefs.h. */ 5493 #ifdef __STDC__ 5494 # include <limits.h> 5495 #else 5496 # include <assert.h> 5497 #endif 5498 Syntax error 5499 _ACEOF 5500 if ac_fn_c_try_cpp "$LINENO"; then : 5501 5502 else 5503 # Broken: fails on valid input. 5504 continue 5505 fi 5506 rm -f conftest.err conftest.i conftest.$ac_ext 5507 5508 # OK, works on sane cases. Now check whether nonexistent headers 5509 # can be detected and how. 5510 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5511 /* end confdefs.h. */ 5512 #include <ac_nonexistent.h> 5513 _ACEOF 5514 if ac_fn_c_try_cpp "$LINENO"; then : 5515 # Broken: success on invalid input. 5516 continue 5517 else 5518 # Passes both tests. 5519 ac_preproc_ok=: 5520 break 5521 fi 5522 rm -f conftest.err conftest.i conftest.$ac_ext 5523 5524 done 5525 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. 5526 rm -f conftest.i conftest.err conftest.$ac_ext 5527 if $ac_preproc_ok; then : 5528 5529 else 5530 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 5531 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} 5532 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check 5533 See \`config.log' for more details" "$LINENO" 5; } 5534 fi 5535 5536 ac_ext=c 5537 ac_cpp='$CPP $CPPFLAGS' 5538 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 5539 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 5540 ac_compiler_gnu=$ac_cv_c_compiler_gnu 5488 else 5489 ac_cv_path_SED=$SED 5490 fi 5491 5492 fi 5493 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 5494 $as_echo "$ac_cv_path_SED" >&6; } 5495 SED="$ac_cv_path_SED" 5496 rm -f conftest.sed 5497 5498 test -z "$SED" && SED=sed 5499 Xsed="$SED -e 1s/^X//" 5500 5501 5502 5503 5504 5505 5506 5507 5508 5541 5509 5542 5510 … … 5671 5639 5672 5640 5641 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 5642 $as_echo_n "checking for fgrep... " >&6; } 5643 if ${ac_cv_path_FGREP+:} false; then : 5644 $as_echo_n "(cached) " >&6 5645 else 5646 if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 5647 then ac_cv_path_FGREP="$GREP -F" 5648 else 5649 if test -z "$FGREP"; then 5650 ac_path_FGREP_found=false 5651 # Loop through the user's path and test for each of PROGNAME-LIST 5652 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 5653 for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin 5654 do 5655 IFS=$as_save_IFS 5656 test -z "$as_dir" && as_dir=. 5657 for ac_prog in fgrep; do 5658 for ac_exec_ext in '' $ac_executable_extensions; do 5659 ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" 5660 as_fn_executable_p "$ac_path_FGREP" || continue 5661 # Check for GNU ac_path_FGREP and select it if it is found. 5662 # Check for GNU $ac_path_FGREP 5663 case `"$ac_path_FGREP" --version 2>&1` in 5664 *GNU*) 5665 ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; 5666 *) 5667 ac_count=0 5668 $as_echo_n 0123456789 >"conftest.in" 5669 while : 5670 do 5671 cat "conftest.in" "conftest.in" >"conftest.tmp" 5672 mv "conftest.tmp" "conftest.in" 5673 cp "conftest.in" "conftest.nl" 5674 $as_echo 'FGREP' >> "conftest.nl" 5675 "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break 5676 diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break 5677 as_fn_arith $ac_count + 1 && ac_count=$as_val 5678 if test $ac_count -gt ${ac_path_FGREP_max-0}; then 5679 # Best one so far, save it but keep looking for a better one 5680 ac_cv_path_FGREP="$ac_path_FGREP" 5681 ac_path_FGREP_max=$ac_count 5682 fi 5683 # 10*(2^10) chars as input seems more than enough 5684 test $ac_count -gt 10 && break 5685 done 5686 rm -f conftest.in conftest.tmp conftest.nl conftest.out;; 5687 esac 5688 5689 $ac_path_FGREP_found && break 3 5690 done 5691 done 5692 done 5693 IFS=$as_save_IFS 5694 if test -z "$ac_cv_path_FGREP"; then 5695 as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 5696 fi 5697 else 5698 ac_cv_path_FGREP=$FGREP 5699 fi 5700 5701 fi 5702 fi 5703 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 5704 $as_echo "$ac_cv_path_FGREP" >&6; } 5705 FGREP="$ac_cv_path_FGREP" 5706 5707 5708 test -z "$GREP" && GREP=grep 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 # Check whether --with-gnu-ld was given. 5729 if test "${with_gnu_ld+set}" = set; then : 5730 withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes 5731 else 5732 with_gnu_ld=no 5733 fi 5734 5735 ac_prog=ld 5736 if test yes = "$GCC"; then 5737 # Check if gcc -print-prog-name=ld gives a path. 5738 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 5739 $as_echo_n "checking for ld used by $CC... " >&6; } 5740 case $host in 5741 *-*-mingw*) 5742 # gcc leaves a trailing carriage return, which upsets mingw 5743 ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; 5744 *) 5745 ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; 5746 esac 5747 case $ac_prog in 5748 # Accept absolute paths. 5749 [\\/]* | ?:[\\/]*) 5750 re_direlt='/[^/][^/]*/\.\./' 5751 # Canonicalize the pathname of ld 5752 ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` 5753 while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do 5754 ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` 5755 done 5756 test -z "$LD" && LD=$ac_prog 5757 ;; 5758 "") 5759 # If it fails, then pretend we aren't using GCC. 5760 ac_prog=ld 5761 ;; 5762 *) 5763 # If it is relative, then search for the first ld in PATH. 5764 with_gnu_ld=unknown 5765 ;; 5766 esac 5767 elif test yes = "$with_gnu_ld"; then 5768 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 5769 $as_echo_n "checking for GNU ld... " >&6; } 5770 else 5771 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 5772 $as_echo_n "checking for non-GNU ld... " >&6; } 5773 fi 5774 if ${lt_cv_path_LD+:} false; then : 5775 $as_echo_n "(cached) " >&6 5776 else 5777 if test -z "$LD"; then 5778 lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR 5779 for ac_dir in $PATH; do 5780 IFS=$lt_save_ifs 5781 test -z "$ac_dir" && ac_dir=. 5782 if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then 5783 lt_cv_path_LD=$ac_dir/$ac_prog 5784 # Check to see if the program is GNU ld. I'd rather use --version, 5785 # but apparently some variants of GNU ld only accept -v. 5786 # Break only if it was the GNU/non-GNU ld that we prefer. 5787 case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in 5788 *GNU* | *'with BFD'*) 5789 test no != "$with_gnu_ld" && break 5790 ;; 5791 *) 5792 test yes != "$with_gnu_ld" && break 5793 ;; 5794 esac 5795 fi 5796 done 5797 IFS=$lt_save_ifs 5798 else 5799 lt_cv_path_LD=$LD # Let the user override the test with a path. 5800 fi 5801 fi 5802 5803 LD=$lt_cv_path_LD 5804 if test -n "$LD"; then 5805 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 5806 $as_echo "$LD" >&6; } 5807 else 5808 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 5809 $as_echo "no" >&6; } 5810 fi 5811 test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 5812 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 5813 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } 5814 if ${lt_cv_prog_gnu_ld+:} false; then : 5815 $as_echo_n "(cached) " >&6 5816 else 5817 # I'd rather use --version here, but apparently some GNU lds only accept -v. 5818 case `$LD -v 2>&1 </dev/null` in 5819 *GNU* | *'with BFD'*) 5820 lt_cv_prog_gnu_ld=yes 5821 ;; 5822 *) 5823 lt_cv_prog_gnu_ld=no 5824 ;; 5825 esac 5826 fi 5827 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 5828 $as_echo "$lt_cv_prog_gnu_ld" >&6; } 5829 with_gnu_ld=$lt_cv_prog_gnu_ld 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 5840 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } 5841 if ${lt_cv_path_NM+:} false; then : 5842 $as_echo_n "(cached) " >&6 5843 else 5844 if test -n "$NM"; then 5845 # Let the user override the test. 5846 lt_cv_path_NM=$NM 5847 else 5848 lt_nm_to_check=${ac_tool_prefix}nm 5849 if test -n "$ac_tool_prefix" && test "$build" = "$host"; then 5850 lt_nm_to_check="$lt_nm_to_check nm" 5851 fi 5852 for lt_tmp_nm in $lt_nm_to_check; do 5853 lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR 5854 for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do 5855 IFS=$lt_save_ifs 5856 test -z "$ac_dir" && ac_dir=. 5857 tmp_nm=$ac_dir/$lt_tmp_nm 5858 if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then 5859 # Check to see if the nm accepts a BSD-compat flag. 5860 # Adding the 'sed 1q' prevents false positives on HP-UX, which says: 5861 # nm: unknown option "B" ignored 5862 # Tru64's nm complains that /dev/null is an invalid object file 5863 # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty 5864 case $build_os in 5865 mingw*) lt_bad_file=conftest.nm/nofile ;; 5866 *) lt_bad_file=/dev/null ;; 5867 esac 5868 case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in 5869 *$lt_bad_file* | *'Invalid file or object type'*) 5870 lt_cv_path_NM="$tmp_nm -B" 5871 break 2 5872 ;; 5873 *) 5874 case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in 5875 */dev/null*) 5876 lt_cv_path_NM="$tmp_nm -p" 5877 break 2 5878 ;; 5879 *) 5880 lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but 5881 continue # so that we can try to find one that supports BSD flags 5882 ;; 5883 esac 5884 ;; 5885 esac 5886 fi 5887 done 5888 IFS=$lt_save_ifs 5889 done 5890 : ${lt_cv_path_NM=no} 5891 fi 5892 fi 5893 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 5894 $as_echo "$lt_cv_path_NM" >&6; } 5895 if test no != "$lt_cv_path_NM"; then 5896 NM=$lt_cv_path_NM 5897 else 5898 # Didn't find any BSD compatible name lister, look for dumpbin. 5899 if test -n "$DUMPBIN"; then : 5900 # Let the user override the test. 5901 else 5902 if test -n "$ac_tool_prefix"; then 5903 for ac_prog in dumpbin "link -dump" 5904 do 5905 # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. 5906 set dummy $ac_tool_prefix$ac_prog; ac_word=$2 5907 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 5908 $as_echo_n "checking for $ac_word... " >&6; } 5909 if ${ac_cv_prog_DUMPBIN+:} false; then : 5910 $as_echo_n "(cached) " >&6 5911 else 5912 if test -n "$DUMPBIN"; then 5913 ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. 5914 else 5915 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 5916 for as_dir in $PATH 5917 do 5918 IFS=$as_save_IFS 5919 test -z "$as_dir" && as_dir=. 5920 for ac_exec_ext in '' $ac_executable_extensions; do 5921 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 5922 ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" 5923 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 5924 break 2 5925 fi 5926 done 5927 done 5928 IFS=$as_save_IFS 5929 5930 fi 5931 fi 5932 DUMPBIN=$ac_cv_prog_DUMPBIN 5933 if test -n "$DUMPBIN"; then 5934 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 5935 $as_echo "$DUMPBIN" >&6; } 5936 else 5937 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 5938 $as_echo "no" >&6; } 5939 fi 5940 5941 5942 test -n "$DUMPBIN" && break 5943 done 5944 fi 5945 if test -z "$DUMPBIN"; then 5946 ac_ct_DUMPBIN=$DUMPBIN 5947 for ac_prog in dumpbin "link -dump" 5948 do 5949 # Extract the first word of "$ac_prog", so it can be a program name with args. 5950 set dummy $ac_prog; ac_word=$2 5951 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 5952 $as_echo_n "checking for $ac_word... " >&6; } 5953 if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : 5954 $as_echo_n "(cached) " >&6 5955 else 5956 if test -n "$ac_ct_DUMPBIN"; then 5957 ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. 5958 else 5959 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 5960 for as_dir in $PATH 5961 do 5962 IFS=$as_save_IFS 5963 test -z "$as_dir" && as_dir=. 5964 for ac_exec_ext in '' $ac_executable_extensions; do 5965 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 5966 ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" 5967 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 5968 break 2 5969 fi 5970 done 5971 done 5972 IFS=$as_save_IFS 5973 5974 fi 5975 fi 5976 ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN 5977 if test -n "$ac_ct_DUMPBIN"; then 5978 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 5979 $as_echo "$ac_ct_DUMPBIN" >&6; } 5980 else 5981 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 5982 $as_echo "no" >&6; } 5983 fi 5984 5985 5986 test -n "$ac_ct_DUMPBIN" && break 5987 done 5988 5989 if test "x$ac_ct_DUMPBIN" = x; then 5990 DUMPBIN=":" 5991 else 5992 case $cross_compiling:$ac_tool_warned in 5993 yes:) 5994 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 5995 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 5996 ac_tool_warned=yes ;; 5997 esac 5998 DUMPBIN=$ac_ct_DUMPBIN 5999 fi 6000 fi 6001 6002 case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in 6003 *COFF*) 6004 DUMPBIN="$DUMPBIN -symbols -headers" 6005 ;; 6006 *) 6007 DUMPBIN=: 6008 ;; 6009 esac 6010 fi 6011 6012 if test : != "$DUMPBIN"; then 6013 NM=$DUMPBIN 6014 fi 6015 fi 6016 test -z "$NM" && NM=nm 6017 6018 6019 6020 6021 6022 6023 { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 6024 $as_echo_n "checking the name lister ($NM) interface... " >&6; } 6025 if ${lt_cv_nm_interface+:} false; then : 6026 $as_echo_n "(cached) " >&6 6027 else 6028 lt_cv_nm_interface="BSD nm" 6029 echo "int some_variable = 0;" > conftest.$ac_ext 6030 (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) 6031 (eval "$ac_compile" 2>conftest.err) 6032 cat conftest.err >&5 6033 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) 6034 (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) 6035 cat conftest.err >&5 6036 (eval echo "\"\$as_me:$LINENO: output\"" >&5) 6037 cat conftest.out >&5 6038 if $GREP 'External.*some_variable' conftest.out > /dev/null; then 6039 lt_cv_nm_interface="MS dumpbin" 6040 fi 6041 rm -f conftest* 6042 fi 6043 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 6044 $as_echo "$lt_cv_nm_interface" >&6; } 6045 6046 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 6047 $as_echo_n "checking whether ln -s works... " >&6; } 6048 LN_S=$as_ln_s 6049 if test "$LN_S" = "ln -s"; then 6050 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 6051 $as_echo "yes" >&6; } 6052 else 6053 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 6054 $as_echo "no, using $LN_S" >&6; } 6055 fi 6056 6057 # find the maximum length of command line arguments 6058 { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 6059 $as_echo_n "checking the maximum length of command line arguments... " >&6; } 6060 if ${lt_cv_sys_max_cmd_len+:} false; then : 6061 $as_echo_n "(cached) " >&6 6062 else 6063 i=0 6064 teststring=ABCD 6065 6066 case $build_os in 6067 msdosdjgpp*) 6068 # On DJGPP, this test can blow up pretty badly due to problems in libc 6069 # (any single argument exceeding 2000 bytes causes a buffer overrun 6070 # during glob expansion). Even if it were fixed, the result of this 6071 # check would be larger than it should be. 6072 lt_cv_sys_max_cmd_len=12288; # 12K is about right 6073 ;; 6074 6075 gnu*) 6076 # Under GNU Hurd, this test is not required because there is 6077 # no limit to the length of command line arguments. 6078 # Libtool will interpret -1 as no limit whatsoever 6079 lt_cv_sys_max_cmd_len=-1; 6080 ;; 6081 6082 cygwin* | mingw* | cegcc*) 6083 # On Win9x/ME, this test blows up -- it succeeds, but takes 6084 # about 5 minutes as the teststring grows exponentially. 6085 # Worse, since 9x/ME are not pre-emptively multitasking, 6086 # you end up with a "frozen" computer, even though with patience 6087 # the test eventually succeeds (with a max line length of 256k). 6088 # Instead, let's just punt: use the minimum linelength reported by 6089 # all of the supported platforms: 8192 (on NT/2K/XP). 6090 lt_cv_sys_max_cmd_len=8192; 6091 ;; 6092 6093 mint*) 6094 # On MiNT this can take a long time and run out of memory. 6095 lt_cv_sys_max_cmd_len=8192; 6096 ;; 6097 6098 amigaos*) 6099 # On AmigaOS with pdksh, this test takes hours, literally. 6100 # So we just punt and use a minimum line length of 8192. 6101 lt_cv_sys_max_cmd_len=8192; 6102 ;; 6103 6104 bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) 6105 # This has been around since 386BSD, at least. Likely further. 6106 if test -x /sbin/sysctl; then 6107 lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` 6108 elif test -x /usr/sbin/sysctl; then 6109 lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` 6110 else 6111 lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs 6112 fi 6113 # And add a safety zone 6114 lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` 6115 lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` 6116 ;; 6117 6118 interix*) 6119 # We know the value 262144 and hardcode it with a safety zone (like BSD) 6120 lt_cv_sys_max_cmd_len=196608 6121 ;; 6122 6123 os2*) 6124 # The test takes a long time on OS/2. 6125 lt_cv_sys_max_cmd_len=8192 6126 ;; 6127 6128 osf*) 6129 # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure 6130 # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not 6131 # nice to cause kernel panics so lets avoid the loop below. 6132 # First set a reasonable default. 6133 lt_cv_sys_max_cmd_len=16384 6134 # 6135 if test -x /sbin/sysconfig; then 6136 case `/sbin/sysconfig -q proc exec_disable_arg_limit` in 6137 *1*) lt_cv_sys_max_cmd_len=-1 ;; 6138 esac 6139 fi 6140 ;; 6141 sco3.2v5*) 6142 lt_cv_sys_max_cmd_len=102400 6143 ;; 6144 sysv5* | sco5v6* | sysv4.2uw2*) 6145 kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` 6146 if test -n "$kargmax"; then 6147 lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` 6148 else 6149 lt_cv_sys_max_cmd_len=32768 6150 fi 6151 ;; 6152 *) 6153 lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` 6154 if test -n "$lt_cv_sys_max_cmd_len" && \ 6155 test undefined != "$lt_cv_sys_max_cmd_len"; then 6156 lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` 6157 lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` 6158 else 6159 # Make teststring a little bigger before we do anything with it. 6160 # a 1K string should be a reasonable start. 6161 for i in 1 2 3 4 5 6 7 8; do 6162 teststring=$teststring$teststring 6163 done 6164 SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} 6165 # If test is not a shell built-in, we'll probably end up computing a 6166 # maximum length that is only half of the actual maximum length, but 6167 # we can't tell. 6168 while { test X`env echo "$teststring$teststring" 2>/dev/null` \ 6169 = "X$teststring$teststring"; } >/dev/null 2>&1 && 6170 test 17 != "$i" # 1/2 MB should be enough 6171 do 6172 i=`expr $i + 1` 6173 teststring=$teststring$teststring 6174 done 6175 # Only check the string length outside the loop. 6176 lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` 6177 teststring= 6178 # Add a significant safety factor because C++ compilers can tack on 6179 # massive amounts of additional arguments before passing them to the 6180 # linker. It appears as though 1/2 is a usable value. 6181 lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` 6182 fi 6183 ;; 6184 esac 6185 6186 fi 6187 6188 if test -n "$lt_cv_sys_max_cmd_len"; then 6189 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 6190 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } 6191 else 6192 { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 6193 $as_echo "none" >&6; } 6194 fi 6195 max_cmd_len=$lt_cv_sys_max_cmd_len 6196 6197 6198 6199 6200 6201 6202 : ${CP="cp -f"} 6203 : ${MV="mv -f"} 6204 : ${RM="rm -f"} 6205 6206 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then 6207 lt_unset=unset 6208 else 6209 lt_unset=false 6210 fi 6211 6212 6213 6214 6215 6216 # test EBCDIC or ASCII 6217 case `echo X|tr X '\101'` in 6218 A) # ASCII based system 6219 # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr 6220 lt_SP2NL='tr \040 \012' 6221 lt_NL2SP='tr \015\012 \040\040' 6222 ;; 6223 *) # EBCDIC based system 6224 lt_SP2NL='tr \100 \n' 6225 lt_NL2SP='tr \r\n \100\100' 6226 ;; 6227 esac 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 6238 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } 6239 if ${lt_cv_to_host_file_cmd+:} false; then : 6240 $as_echo_n "(cached) " >&6 6241 else 6242 case $host in 6243 *-*-mingw* ) 6244 case $build in 6245 *-*-mingw* ) # actually msys 6246 lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 6247 ;; 6248 *-*-cygwin* ) 6249 lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 6250 ;; 6251 * ) # otherwise, assume *nix 6252 lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 6253 ;; 6254 esac 6255 ;; 6256 *-*-cygwin* ) 6257 case $build in 6258 *-*-mingw* ) # actually msys 6259 lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin 6260 ;; 6261 *-*-cygwin* ) 6262 lt_cv_to_host_file_cmd=func_convert_file_noop 6263 ;; 6264 * ) # otherwise, assume *nix 6265 lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin 6266 ;; 6267 esac 6268 ;; 6269 * ) # unhandled hosts (and "normal" native builds) 6270 lt_cv_to_host_file_cmd=func_convert_file_noop 6271 ;; 6272 esac 6273 6274 fi 6275 6276 to_host_file_cmd=$lt_cv_to_host_file_cmd 6277 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 6278 $as_echo "$lt_cv_to_host_file_cmd" >&6; } 6279 6280 6281 6282 6283 6284 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 6285 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } 6286 if ${lt_cv_to_tool_file_cmd+:} false; then : 6287 $as_echo_n "(cached) " >&6 6288 else 6289 #assume ordinary cross tools, or native build. 6290 lt_cv_to_tool_file_cmd=func_convert_file_noop 6291 case $host in 6292 *-*-mingw* ) 6293 case $build in 6294 *-*-mingw* ) # actually msys 6295 lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 6296 ;; 6297 esac 6298 ;; 6299 esac 6300 6301 fi 6302 6303 to_tool_file_cmd=$lt_cv_to_tool_file_cmd 6304 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 6305 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } 6306 6307 6308 6309 6310 6311 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 6312 $as_echo_n "checking for $LD option to reload object files... " >&6; } 6313 if ${lt_cv_ld_reload_flag+:} false; then : 6314 $as_echo_n "(cached) " >&6 6315 else 6316 lt_cv_ld_reload_flag='-r' 6317 fi 6318 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 6319 $as_echo "$lt_cv_ld_reload_flag" >&6; } 6320 reload_flag=$lt_cv_ld_reload_flag 6321 case $reload_flag in 6322 "" | " "*) ;; 6323 *) reload_flag=" $reload_flag" ;; 6324 esac 6325 reload_cmds='$LD$reload_flag -o $output$reload_objs' 6326 case $host_os in 6327 cygwin* | mingw* | pw32* | cegcc*) 6328 if test yes != "$GCC"; then 6329 reload_cmds=false 6330 fi 6331 ;; 6332 darwin*) 6333 if test yes = "$GCC"; then 6334 reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' 6335 else 6336 reload_cmds='$LD$reload_flag -o $output$reload_objs' 6337 fi 6338 ;; 6339 esac 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 if test -n "$ac_tool_prefix"; then 6350 # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. 6351 set dummy ${ac_tool_prefix}objdump; ac_word=$2 6352 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 6353 $as_echo_n "checking for $ac_word... " >&6; } 6354 if ${ac_cv_prog_OBJDUMP+:} false; then : 6355 $as_echo_n "(cached) " >&6 6356 else 6357 if test -n "$OBJDUMP"; then 6358 ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. 6359 else 6360 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 6361 for as_dir in $PATH 6362 do 6363 IFS=$as_save_IFS 6364 test -z "$as_dir" && as_dir=. 6365 for ac_exec_ext in '' $ac_executable_extensions; do 6366 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 6367 ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" 6368 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 6369 break 2 6370 fi 6371 done 6372 done 6373 IFS=$as_save_IFS 6374 6375 fi 6376 fi 6377 OBJDUMP=$ac_cv_prog_OBJDUMP 6378 if test -n "$OBJDUMP"; then 6379 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 6380 $as_echo "$OBJDUMP" >&6; } 6381 else 6382 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 6383 $as_echo "no" >&6; } 6384 fi 6385 6386 6387 fi 6388 if test -z "$ac_cv_prog_OBJDUMP"; then 6389 ac_ct_OBJDUMP=$OBJDUMP 6390 # Extract the first word of "objdump", so it can be a program name with args. 6391 set dummy objdump; ac_word=$2 6392 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 6393 $as_echo_n "checking for $ac_word... " >&6; } 6394 if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : 6395 $as_echo_n "(cached) " >&6 6396 else 6397 if test -n "$ac_ct_OBJDUMP"; then 6398 ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. 6399 else 6400 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 6401 for as_dir in $PATH 6402 do 6403 IFS=$as_save_IFS 6404 test -z "$as_dir" && as_dir=. 6405 for ac_exec_ext in '' $ac_executable_extensions; do 6406 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 6407 ac_cv_prog_ac_ct_OBJDUMP="objdump" 6408 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 6409 break 2 6410 fi 6411 done 6412 done 6413 IFS=$as_save_IFS 6414 6415 fi 6416 fi 6417 ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP 6418 if test -n "$ac_ct_OBJDUMP"; then 6419 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 6420 $as_echo "$ac_ct_OBJDUMP" >&6; } 6421 else 6422 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 6423 $as_echo "no" >&6; } 6424 fi 6425 6426 if test "x$ac_ct_OBJDUMP" = x; then 6427 OBJDUMP="false" 6428 else 6429 case $cross_compiling:$ac_tool_warned in 6430 yes:) 6431 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 6432 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 6433 ac_tool_warned=yes ;; 6434 esac 6435 OBJDUMP=$ac_ct_OBJDUMP 6436 fi 6437 else 6438 OBJDUMP="$ac_cv_prog_OBJDUMP" 6439 fi 6440 6441 test -z "$OBJDUMP" && OBJDUMP=objdump 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 6452 $as_echo_n "checking how to recognize dependent libraries... " >&6; } 6453 if ${lt_cv_deplibs_check_method+:} false; then : 6454 $as_echo_n "(cached) " >&6 6455 else 6456 lt_cv_file_magic_cmd='$MAGIC_CMD' 6457 lt_cv_file_magic_test_file= 6458 lt_cv_deplibs_check_method='unknown' 6459 # Need to set the preceding variable on all platforms that support 6460 # interlibrary dependencies. 6461 # 'none' -- dependencies not supported. 6462 # 'unknown' -- same as none, but documents that we really don't know. 6463 # 'pass_all' -- all dependencies passed with no checks. 6464 # 'test_compile' -- check by making test program. 6465 # 'file_magic [[regex]]' -- check by looking for files in library path 6466 # that responds to the $file_magic_cmd with a given extended regex. 6467 # If you have 'file' or equivalent on your system and you're not sure 6468 # whether 'pass_all' will *always* work, you probably want this one. 6469 6470 case $host_os in 6471 aix[4-9]*) 6472 lt_cv_deplibs_check_method=pass_all 6473 ;; 6474 6475 beos*) 6476 lt_cv_deplibs_check_method=pass_all 6477 ;; 6478 6479 bsdi[45]*) 6480 lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' 6481 lt_cv_file_magic_cmd='/usr/bin/file -L' 6482 lt_cv_file_magic_test_file=/shlib/libc.so 6483 ;; 6484 6485 cygwin*) 6486 # func_win32_libid is a shell function defined in ltmain.sh 6487 lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' 6488 lt_cv_file_magic_cmd='func_win32_libid' 6489 ;; 6490 6491 mingw* | pw32*) 6492 # Base MSYS/MinGW do not provide the 'file' command needed by 6493 # func_win32_libid shell function, so use a weaker test based on 'objdump', 6494 # unless we find 'file', for example because we are cross-compiling. 6495 if ( file / ) >/dev/null 2>&1; then 6496 lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' 6497 lt_cv_file_magic_cmd='func_win32_libid' 6498 else 6499 # Keep this pattern in sync with the one in func_win32_libid. 6500 lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' 6501 lt_cv_file_magic_cmd='$OBJDUMP -f' 6502 fi 6503 ;; 6504 6505 cegcc*) 6506 # use the weaker test based on 'objdump'. See mingw*. 6507 lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' 6508 lt_cv_file_magic_cmd='$OBJDUMP -f' 6509 ;; 6510 6511 darwin* | rhapsody*) 6512 lt_cv_deplibs_check_method=pass_all 6513 ;; 6514 6515 freebsd* | dragonfly*) 6516 if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then 6517 case $host_cpu in 6518 i*86 ) 6519 # Not sure whether the presence of OpenBSD here was a mistake. 6520 # Let's accept both of them until this is cleared up. 6521 lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' 6522 lt_cv_file_magic_cmd=/usr/bin/file 6523 lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` 6524 ;; 6525 esac 6526 else 6527 lt_cv_deplibs_check_method=pass_all 6528 fi 6529 ;; 6530 6531 haiku*) 6532 lt_cv_deplibs_check_method=pass_all 6533 ;; 6534 6535 hpux10.20* | hpux11*) 6536 lt_cv_file_magic_cmd=/usr/bin/file 6537 case $host_cpu in 6538 ia64*) 6539 lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' 6540 lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so 6541 ;; 6542 hppa*64*) 6543 lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' 6544 lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl 6545 ;; 6546 *) 6547 lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' 6548 lt_cv_file_magic_test_file=/usr/lib/libc.sl 6549 ;; 6550 esac 6551 ;; 6552 6553 interix[3-9]*) 6554 # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here 6555 lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' 6556 ;; 6557 6558 irix5* | irix6* | nonstopux*) 6559 case $LD in 6560 *-32|*"-32 ") libmagic=32-bit;; 6561 *-n32|*"-n32 ") libmagic=N32;; 6562 *-64|*"-64 ") libmagic=64-bit;; 6563 *) libmagic=never-match;; 6564 esac 6565 lt_cv_deplibs_check_method=pass_all 6566 ;; 6567 6568 # This must be glibc/ELF. 6569 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) 6570 lt_cv_deplibs_check_method=pass_all 6571 ;; 6572 6573 netbsd* | netbsdelf*-gnu) 6574 if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then 6575 lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' 6576 else 6577 lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' 6578 fi 6579 ;; 6580 6581 newos6*) 6582 lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' 6583 lt_cv_file_magic_cmd=/usr/bin/file 6584 lt_cv_file_magic_test_file=/usr/lib/libnls.so 6585 ;; 6586 6587 *nto* | *qnx*) 6588 lt_cv_deplibs_check_method=pass_all 6589 ;; 6590 6591 openbsd* | bitrig*) 6592 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then 6593 lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' 6594 else 6595 lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' 6596 fi 6597 ;; 6598 6599 osf3* | osf4* | osf5*) 6600 lt_cv_deplibs_check_method=pass_all 6601 ;; 6602 6603 rdos*) 6604 lt_cv_deplibs_check_method=pass_all 6605 ;; 6606 6607 solaris*) 6608 lt_cv_deplibs_check_method=pass_all 6609 ;; 6610 6611 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) 6612 lt_cv_deplibs_check_method=pass_all 6613 ;; 6614 6615 sysv4 | sysv4.3*) 6616 case $host_vendor in 6617 motorola) 6618 lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' 6619 lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` 6620 ;; 6621 ncr) 6622 lt_cv_deplibs_check_method=pass_all 6623 ;; 6624 sequent) 6625 lt_cv_file_magic_cmd='/bin/file' 6626 lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' 6627 ;; 6628 sni) 6629 lt_cv_file_magic_cmd='/bin/file' 6630 lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" 6631 lt_cv_file_magic_test_file=/lib/libc.so 6632 ;; 6633 siemens) 6634 lt_cv_deplibs_check_method=pass_all 6635 ;; 6636 pc) 6637 lt_cv_deplibs_check_method=pass_all 6638 ;; 6639 esac 6640 ;; 6641 6642 tpf*) 6643 lt_cv_deplibs_check_method=pass_all 6644 ;; 6645 os2*) 6646 lt_cv_deplibs_check_method=pass_all 6647 ;; 6648 esac 6649 6650 fi 6651 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 6652 $as_echo "$lt_cv_deplibs_check_method" >&6; } 6653 6654 file_magic_glob= 6655 want_nocaseglob=no 6656 if test "$build" = "$host"; then 6657 case $host_os in 6658 mingw* | pw32*) 6659 if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then 6660 want_nocaseglob=yes 6661 else 6662 file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` 6663 fi 6664 ;; 6665 esac 6666 fi 6667 6668 file_magic_cmd=$lt_cv_file_magic_cmd 6669 deplibs_check_method=$lt_cv_deplibs_check_method 6670 test -z "$deplibs_check_method" && deplibs_check_method=unknown 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 if test -n "$ac_tool_prefix"; then 6694 # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. 6695 set dummy ${ac_tool_prefix}dlltool; ac_word=$2 6696 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 6697 $as_echo_n "checking for $ac_word... " >&6; } 6698 if ${ac_cv_prog_DLLTOOL+:} false; then : 6699 $as_echo_n "(cached) " >&6 6700 else 6701 if test -n "$DLLTOOL"; then 6702 ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. 6703 else 6704 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 6705 for as_dir in $PATH 6706 do 6707 IFS=$as_save_IFS 6708 test -z "$as_dir" && as_dir=. 6709 for ac_exec_ext in '' $ac_executable_extensions; do 6710 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 6711 ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" 6712 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 6713 break 2 6714 fi 6715 done 6716 done 6717 IFS=$as_save_IFS 6718 6719 fi 6720 fi 6721 DLLTOOL=$ac_cv_prog_DLLTOOL 6722 if test -n "$DLLTOOL"; then 6723 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 6724 $as_echo "$DLLTOOL" >&6; } 6725 else 6726 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 6727 $as_echo "no" >&6; } 6728 fi 6729 6730 6731 fi 6732 if test -z "$ac_cv_prog_DLLTOOL"; then 6733 ac_ct_DLLTOOL=$DLLTOOL 6734 # Extract the first word of "dlltool", so it can be a program name with args. 6735 set dummy dlltool; ac_word=$2 6736 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 6737 $as_echo_n "checking for $ac_word... " >&6; } 6738 if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : 6739 $as_echo_n "(cached) " >&6 6740 else 6741 if test -n "$ac_ct_DLLTOOL"; then 6742 ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. 6743 else 6744 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 6745 for as_dir in $PATH 6746 do 6747 IFS=$as_save_IFS 6748 test -z "$as_dir" && as_dir=. 6749 for ac_exec_ext in '' $ac_executable_extensions; do 6750 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 6751 ac_cv_prog_ac_ct_DLLTOOL="dlltool" 6752 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 6753 break 2 6754 fi 6755 done 6756 done 6757 IFS=$as_save_IFS 6758 6759 fi 6760 fi 6761 ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL 6762 if test -n "$ac_ct_DLLTOOL"; then 6763 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 6764 $as_echo "$ac_ct_DLLTOOL" >&6; } 6765 else 6766 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 6767 $as_echo "no" >&6; } 6768 fi 6769 6770 if test "x$ac_ct_DLLTOOL" = x; then 6771 DLLTOOL="false" 6772 else 6773 case $cross_compiling:$ac_tool_warned in 6774 yes:) 6775 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 6776 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 6777 ac_tool_warned=yes ;; 6778 esac 6779 DLLTOOL=$ac_ct_DLLTOOL 6780 fi 6781 else 6782 DLLTOOL="$ac_cv_prog_DLLTOOL" 6783 fi 6784 6785 test -z "$DLLTOOL" && DLLTOOL=dlltool 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 6797 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } 6798 if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : 6799 $as_echo_n "(cached) " >&6 6800 else 6801 lt_cv_sharedlib_from_linklib_cmd='unknown' 6802 6803 case $host_os in 6804 cygwin* | mingw* | pw32* | cegcc*) 6805 # two different shell functions defined in ltmain.sh; 6806 # decide which one to use based on capabilities of $DLLTOOL 6807 case `$DLLTOOL --help 2>&1` in 6808 *--identify-strict*) 6809 lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib 6810 ;; 6811 *) 6812 lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback 6813 ;; 6814 esac 6815 ;; 6816 *) 6817 # fallback: assume linklib IS sharedlib 6818 lt_cv_sharedlib_from_linklib_cmd=$ECHO 6819 ;; 6820 esac 6821 6822 fi 6823 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 6824 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } 6825 sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd 6826 test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO 6827 6828 6829 6830 6831 6832 6833 6834 if test -n "$ac_tool_prefix"; then 6835 for ac_prog in ar 6836 do 6837 # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. 6838 set dummy $ac_tool_prefix$ac_prog; ac_word=$2 6839 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 6840 $as_echo_n "checking for $ac_word... " >&6; } 6841 if ${ac_cv_prog_AR+:} false; then : 6842 $as_echo_n "(cached) " >&6 6843 else 6844 if test -n "$AR"; then 6845 ac_cv_prog_AR="$AR" # Let the user override the test. 6846 else 6847 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 6848 for as_dir in $PATH 6849 do 6850 IFS=$as_save_IFS 6851 test -z "$as_dir" && as_dir=. 6852 for ac_exec_ext in '' $ac_executable_extensions; do 6853 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 6854 ac_cv_prog_AR="$ac_tool_prefix$ac_prog" 6855 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 6856 break 2 6857 fi 6858 done 6859 done 6860 IFS=$as_save_IFS 6861 6862 fi 6863 fi 6864 AR=$ac_cv_prog_AR 6865 if test -n "$AR"; then 6866 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 6867 $as_echo "$AR" >&6; } 6868 else 6869 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 6870 $as_echo "no" >&6; } 6871 fi 6872 6873 6874 test -n "$AR" && break 6875 done 6876 fi 6877 if test -z "$AR"; then 6878 ac_ct_AR=$AR 6879 for ac_prog in ar 6880 do 6881 # Extract the first word of "$ac_prog", so it can be a program name with args. 6882 set dummy $ac_prog; ac_word=$2 6883 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 6884 $as_echo_n "checking for $ac_word... " >&6; } 6885 if ${ac_cv_prog_ac_ct_AR+:} false; then : 6886 $as_echo_n "(cached) " >&6 6887 else 6888 if test -n "$ac_ct_AR"; then 6889 ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. 6890 else 6891 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 6892 for as_dir in $PATH 6893 do 6894 IFS=$as_save_IFS 6895 test -z "$as_dir" && as_dir=. 6896 for ac_exec_ext in '' $ac_executable_extensions; do 6897 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 6898 ac_cv_prog_ac_ct_AR="$ac_prog" 6899 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 6900 break 2 6901 fi 6902 done 6903 done 6904 IFS=$as_save_IFS 6905 6906 fi 6907 fi 6908 ac_ct_AR=$ac_cv_prog_ac_ct_AR 6909 if test -n "$ac_ct_AR"; then 6910 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 6911 $as_echo "$ac_ct_AR" >&6; } 6912 else 6913 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 6914 $as_echo "no" >&6; } 6915 fi 6916 6917 6918 test -n "$ac_ct_AR" && break 6919 done 6920 6921 if test "x$ac_ct_AR" = x; then 6922 AR="false" 6923 else 6924 case $cross_compiling:$ac_tool_warned in 6925 yes:) 6926 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 6927 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 6928 ac_tool_warned=yes ;; 6929 esac 6930 AR=$ac_ct_AR 6931 fi 6932 fi 6933 6934 : ${AR=ar} 6935 : ${AR_FLAGS=cru} 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 6948 $as_echo_n "checking for archiver @FILE support... " >&6; } 6949 if ${lt_cv_ar_at_file+:} false; then : 6950 $as_echo_n "(cached) " >&6 6951 else 6952 lt_cv_ar_at_file=no 6953 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 6954 /* end confdefs.h. */ 6955 6956 int 6957 main () 6958 { 6959 6960 ; 6961 return 0; 6962 } 6963 _ACEOF 6964 if ac_fn_c_try_compile "$LINENO"; then : 6965 echo conftest.$ac_objext > conftest.lst 6966 lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' 6967 { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 6968 (eval $lt_ar_try) 2>&5 6969 ac_status=$? 6970 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 6971 test $ac_status = 0; } 6972 if test 0 -eq "$ac_status"; then 6973 # Ensure the archiver fails upon bogus file names. 6974 rm -f conftest.$ac_objext libconftest.a 6975 { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 6976 (eval $lt_ar_try) 2>&5 6977 ac_status=$? 6978 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 6979 test $ac_status = 0; } 6980 if test 0 -ne "$ac_status"; then 6981 lt_cv_ar_at_file=@ 6982 fi 6983 fi 6984 rm -f conftest.* libconftest.a 6985 6986 fi 6987 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 6988 6989 fi 6990 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 6991 $as_echo "$lt_cv_ar_at_file" >&6; } 6992 6993 if test no = "$lt_cv_ar_at_file"; then 6994 archiver_list_spec= 6995 else 6996 archiver_list_spec=$lt_cv_ar_at_file 6997 fi 6998 6999 7000 7001 7002 7003 7004 7005 if test -n "$ac_tool_prefix"; then 7006 # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. 7007 set dummy ${ac_tool_prefix}strip; ac_word=$2 7008 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 7009 $as_echo_n "checking for $ac_word... " >&6; } 7010 if ${ac_cv_prog_STRIP+:} false; then : 7011 $as_echo_n "(cached) " >&6 7012 else 7013 if test -n "$STRIP"; then 7014 ac_cv_prog_STRIP="$STRIP" # Let the user override the test. 7015 else 7016 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 7017 for as_dir in $PATH 7018 do 7019 IFS=$as_save_IFS 7020 test -z "$as_dir" && as_dir=. 7021 for ac_exec_ext in '' $ac_executable_extensions; do 7022 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 7023 ac_cv_prog_STRIP="${ac_tool_prefix}strip" 7024 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 7025 break 2 7026 fi 7027 done 7028 done 7029 IFS=$as_save_IFS 7030 7031 fi 7032 fi 7033 STRIP=$ac_cv_prog_STRIP 7034 if test -n "$STRIP"; then 7035 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 7036 $as_echo "$STRIP" >&6; } 7037 else 7038 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 7039 $as_echo "no" >&6; } 7040 fi 7041 7042 7043 fi 7044 if test -z "$ac_cv_prog_STRIP"; then 7045 ac_ct_STRIP=$STRIP 7046 # Extract the first word of "strip", so it can be a program name with args. 7047 set dummy strip; ac_word=$2 7048 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 7049 $as_echo_n "checking for $ac_word... " >&6; } 7050 if ${ac_cv_prog_ac_ct_STRIP+:} false; then : 7051 $as_echo_n "(cached) " >&6 7052 else 7053 if test -n "$ac_ct_STRIP"; then 7054 ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. 7055 else 7056 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 7057 for as_dir in $PATH 7058 do 7059 IFS=$as_save_IFS 7060 test -z "$as_dir" && as_dir=. 7061 for ac_exec_ext in '' $ac_executable_extensions; do 7062 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 7063 ac_cv_prog_ac_ct_STRIP="strip" 7064 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 7065 break 2 7066 fi 7067 done 7068 done 7069 IFS=$as_save_IFS 7070 7071 fi 7072 fi 7073 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP 7074 if test -n "$ac_ct_STRIP"; then 7075 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 7076 $as_echo "$ac_ct_STRIP" >&6; } 7077 else 7078 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 7079 $as_echo "no" >&6; } 7080 fi 7081 7082 if test "x$ac_ct_STRIP" = x; then 7083 STRIP=":" 7084 else 7085 case $cross_compiling:$ac_tool_warned in 7086 yes:) 7087 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 7088 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 7089 ac_tool_warned=yes ;; 7090 esac 7091 STRIP=$ac_ct_STRIP 7092 fi 7093 else 7094 STRIP="$ac_cv_prog_STRIP" 7095 fi 7096 7097 test -z "$STRIP" && STRIP=: 7098 7099 7100 7101 7102 7103 7104 if test -n "$ac_tool_prefix"; then 7105 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. 7106 set dummy ${ac_tool_prefix}ranlib; ac_word=$2 7107 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 7108 $as_echo_n "checking for $ac_word... " >&6; } 7109 if ${ac_cv_prog_RANLIB+:} false; then : 7110 $as_echo_n "(cached) " >&6 7111 else 7112 if test -n "$RANLIB"; then 7113 ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. 7114 else 7115 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 7116 for as_dir in $PATH 7117 do 7118 IFS=$as_save_IFS 7119 test -z "$as_dir" && as_dir=. 7120 for ac_exec_ext in '' $ac_executable_extensions; do 7121 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 7122 ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" 7123 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 7124 break 2 7125 fi 7126 done 7127 done 7128 IFS=$as_save_IFS 7129 7130 fi 7131 fi 7132 RANLIB=$ac_cv_prog_RANLIB 7133 if test -n "$RANLIB"; then 7134 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 7135 $as_echo "$RANLIB" >&6; } 7136 else 7137 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 7138 $as_echo "no" >&6; } 7139 fi 7140 7141 7142 fi 7143 if test -z "$ac_cv_prog_RANLIB"; then 7144 ac_ct_RANLIB=$RANLIB 7145 # Extract the first word of "ranlib", so it can be a program name with args. 7146 set dummy ranlib; ac_word=$2 7147 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 7148 $as_echo_n "checking for $ac_word... " >&6; } 7149 if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : 7150 $as_echo_n "(cached) " >&6 7151 else 7152 if test -n "$ac_ct_RANLIB"; then 7153 ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. 7154 else 7155 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 7156 for as_dir in $PATH 7157 do 7158 IFS=$as_save_IFS 7159 test -z "$as_dir" && as_dir=. 7160 for ac_exec_ext in '' $ac_executable_extensions; do 7161 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 7162 ac_cv_prog_ac_ct_RANLIB="ranlib" 7163 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 7164 break 2 7165 fi 7166 done 7167 done 7168 IFS=$as_save_IFS 7169 7170 fi 7171 fi 7172 ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB 7173 if test -n "$ac_ct_RANLIB"; then 7174 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 7175 $as_echo "$ac_ct_RANLIB" >&6; } 7176 else 7177 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 7178 $as_echo "no" >&6; } 7179 fi 7180 7181 if test "x$ac_ct_RANLIB" = x; then 7182 RANLIB=":" 7183 else 7184 case $cross_compiling:$ac_tool_warned in 7185 yes:) 7186 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 7187 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 7188 ac_tool_warned=yes ;; 7189 esac 7190 RANLIB=$ac_ct_RANLIB 7191 fi 7192 else 7193 RANLIB="$ac_cv_prog_RANLIB" 7194 fi 7195 7196 test -z "$RANLIB" && RANLIB=: 7197 7198 7199 7200 7201 7202 7203 # Determine commands to create old-style static archives. 7204 old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' 7205 old_postinstall_cmds='chmod 644 $oldlib' 7206 old_postuninstall_cmds= 7207 7208 if test -n "$RANLIB"; then 7209 case $host_os in 7210 bitrig* | openbsd*) 7211 old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" 7212 ;; 7213 *) 7214 old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" 7215 ;; 7216 esac 7217 old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" 7218 fi 7219 7220 case $host_os in 7221 darwin*) 7222 lock_old_archive_extraction=yes ;; 7223 *) 7224 lock_old_archive_extraction=no ;; 7225 esac 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 # If no C compiler was specified, use CC. 7266 LTCC=${LTCC-"$CC"} 7267 7268 # If no C compiler flags were specified, use CFLAGS. 7269 LTCFLAGS=${LTCFLAGS-"$CFLAGS"} 7270 7271 # Allow CC to be a program name with arguments. 7272 compiler=$CC 7273 7274 7275 # Check for command to grab the raw symbol name followed by C symbol from nm. 7276 { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 7277 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } 7278 if ${lt_cv_sys_global_symbol_pipe+:} false; then : 7279 $as_echo_n "(cached) " >&6 7280 else 7281 7282 # These are sane defaults that work on at least a few old systems. 7283 # [They come from Ultrix. What could be older than Ultrix?!! ;)] 7284 7285 # Character class describing NM global symbol codes. 7286 symcode='[BCDEGRST]' 7287 7288 # Regexp to match symbols that can be accessed directly from C. 7289 sympat='\([_A-Za-z][_A-Za-z0-9]*\)' 7290 7291 # Define system-specific variables. 7292 case $host_os in 7293 aix*) 7294 symcode='[BCDT]' 7295 ;; 7296 cygwin* | mingw* | pw32* | cegcc*) 7297 symcode='[ABCDGISTW]' 7298 ;; 7299 hpux*) 7300 if test ia64 = "$host_cpu"; then 7301 symcode='[ABCDEGRST]' 7302 fi 7303 ;; 7304 irix* | nonstopux*) 7305 symcode='[BCDEGRST]' 7306 ;; 7307 osf*) 7308 symcode='[BCDEGQRST]' 7309 ;; 7310 solaris*) 7311 symcode='[BDRT]' 7312 ;; 7313 sco3.2v5*) 7314 symcode='[DT]' 7315 ;; 7316 sysv4.2uw2*) 7317 symcode='[DT]' 7318 ;; 7319 sysv5* | sco5v6* | unixware* | OpenUNIX*) 7320 symcode='[ABDT]' 7321 ;; 7322 sysv4) 7323 symcode='[DFNSTU]' 7324 ;; 7325 esac 7326 7327 # If we're using GNU nm, then use its standard symbol codes. 7328 case `$NM -V 2>&1` in 7329 *GNU* | *'with BFD'*) 7330 symcode='[ABCDGIRSTW]' ;; 7331 esac 7332 7333 if test "$lt_cv_nm_interface" = "MS dumpbin"; then 7334 # Gets list of data symbols to import. 7335 lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" 7336 # Adjust the below global symbol transforms to fixup imported variables. 7337 lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" 7338 lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" 7339 lt_c_name_lib_hook="\ 7340 -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ 7341 -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" 7342 else 7343 # Disable hooks by default. 7344 lt_cv_sys_global_symbol_to_import= 7345 lt_cdecl_hook= 7346 lt_c_name_hook= 7347 lt_c_name_lib_hook= 7348 fi 7349 7350 # Transform an extracted symbol line into a proper C declaration. 7351 # Some systems (esp. on ia64) link data and code symbols differently, 7352 # so use this general approach. 7353 lt_cv_sys_global_symbol_to_cdecl="sed -n"\ 7354 $lt_cdecl_hook\ 7355 " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ 7356 " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" 7357 7358 # Transform an extracted symbol line into symbol name and symbol address 7359 lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ 7360 $lt_c_name_hook\ 7361 " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ 7362 " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" 7363 7364 # Transform an extracted symbol line into symbol name with lib prefix and 7365 # symbol address. 7366 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ 7367 $lt_c_name_lib_hook\ 7368 " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ 7369 " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ 7370 " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" 7371 7372 # Handle CRLF in mingw tool chain 7373 opt_cr= 7374 case $build_os in 7375 mingw*) 7376 opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp 7377 ;; 7378 esac 7379 7380 # Try without a prefix underscore, then with it. 7381 for ac_symprfx in "" "_"; do 7382 7383 # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. 7384 symxfrm="\\1 $ac_symprfx\\2 \\2" 7385 7386 # Write the raw and C identifiers. 7387 if test "$lt_cv_nm_interface" = "MS dumpbin"; then 7388 # Fake it for dumpbin and say T for any non-static function, 7389 # D for any global variable and I for any imported variable. 7390 # Also find C++ and __fastcall symbols from MSVC++, 7391 # which start with @ or ?. 7392 lt_cv_sys_global_symbol_pipe="$AWK '"\ 7393 " {last_section=section; section=\$ 3};"\ 7394 " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ 7395 " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ 7396 " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ 7397 " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ 7398 " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ 7399 " \$ 0!~/External *\|/{next};"\ 7400 " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ 7401 " {if(hide[section]) next};"\ 7402 " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ 7403 " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ 7404 " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ 7405 " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ 7406 " ' prfx=^$ac_symprfx" 7407 else 7408 lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" 7409 fi 7410 lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" 7411 7412 # Check to see that the pipe works correctly. 7413 pipe_works=no 7414 7415 rm -f conftest* 7416 cat > conftest.$ac_ext <<_LT_EOF 7417 #ifdef __cplusplus 7418 extern "C" { 7419 #endif 7420 char nm_test_var; 7421 void nm_test_func(void); 7422 void nm_test_func(void){} 7423 #ifdef __cplusplus 7424 } 7425 #endif 7426 int main(){nm_test_var='a';nm_test_func();return(0);} 7427 _LT_EOF 7428 7429 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 7430 (eval $ac_compile) 2>&5 7431 ac_status=$? 7432 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7433 test $ac_status = 0; }; then 7434 # Now try to grab the symbols. 7435 nlist=conftest.nm 7436 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 7437 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 7438 ac_status=$? 7439 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7440 test $ac_status = 0; } && test -s "$nlist"; then 7441 # Try sorting and uniquifying the output. 7442 if sort "$nlist" | uniq > "$nlist"T; then 7443 mv -f "$nlist"T "$nlist" 7444 else 7445 rm -f "$nlist"T 7446 fi 7447 7448 # Make sure that we snagged all the symbols we need. 7449 if $GREP ' nm_test_var$' "$nlist" >/dev/null; then 7450 if $GREP ' nm_test_func$' "$nlist" >/dev/null; then 7451 cat <<_LT_EOF > conftest.$ac_ext 7452 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ 7453 #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE 7454 /* DATA imports from DLLs on WIN32 can't be const, because runtime 7455 relocations are performed -- see ld's documentation on pseudo-relocs. */ 7456 # define LT_DLSYM_CONST 7457 #elif defined __osf__ 7458 /* This system does not cope well with relocations in const data. */ 7459 # define LT_DLSYM_CONST 7460 #else 7461 # define LT_DLSYM_CONST const 7462 #endif 7463 7464 #ifdef __cplusplus 7465 extern "C" { 7466 #endif 7467 7468 _LT_EOF 7469 # Now generate the symbol file. 7470 eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' 7471 7472 cat <<_LT_EOF >> conftest.$ac_ext 7473 7474 /* The mapping between symbol names and symbols. */ 7475 LT_DLSYM_CONST struct { 7476 const char *name; 7477 void *address; 7478 } 7479 lt__PROGRAM__LTX_preloaded_symbols[] = 7480 { 7481 { "@PROGRAM@", (void *) 0 }, 7482 _LT_EOF 7483 $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext 7484 cat <<\_LT_EOF >> conftest.$ac_ext 7485 {0, (void *) 0} 7486 }; 7487 7488 /* This works around a problem in FreeBSD linker */ 7489 #ifdef FREEBSD_WORKAROUND 7490 static const void *lt_preloaded_setup() { 7491 return lt__PROGRAM__LTX_preloaded_symbols; 7492 } 7493 #endif 7494 7495 #ifdef __cplusplus 7496 } 7497 #endif 7498 _LT_EOF 7499 # Now try linking the two files. 7500 mv conftest.$ac_objext conftstm.$ac_objext 7501 lt_globsym_save_LIBS=$LIBS 7502 lt_globsym_save_CFLAGS=$CFLAGS 7503 LIBS=conftstm.$ac_objext 7504 CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" 7505 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 7506 (eval $ac_link) 2>&5 7507 ac_status=$? 7508 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7509 test $ac_status = 0; } && test -s conftest$ac_exeext; then 7510 pipe_works=yes 7511 fi 7512 LIBS=$lt_globsym_save_LIBS 7513 CFLAGS=$lt_globsym_save_CFLAGS 7514 else 7515 echo "cannot find nm_test_func in $nlist" >&5 7516 fi 7517 else 7518 echo "cannot find nm_test_var in $nlist" >&5 7519 fi 7520 else 7521 echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 7522 fi 7523 else 7524 echo "$progname: failed program was:" >&5 7525 cat conftest.$ac_ext >&5 7526 fi 7527 rm -rf conftest* conftst* 7528 7529 # Do not use the global_symbol_pipe unless it works. 7530 if test yes = "$pipe_works"; then 7531 break 7532 else 7533 lt_cv_sys_global_symbol_pipe= 7534 fi 7535 done 7536 7537 fi 7538 7539 if test -z "$lt_cv_sys_global_symbol_pipe"; then 7540 lt_cv_sys_global_symbol_to_cdecl= 7541 fi 7542 if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then 7543 { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 7544 $as_echo "failed" >&6; } 7545 else 7546 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 7547 $as_echo "ok" >&6; } 7548 fi 7549 7550 # Response file support. 7551 if test "$lt_cv_nm_interface" = "MS dumpbin"; then 7552 nm_file_list_spec='@' 7553 elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then 7554 nm_file_list_spec='@' 7555 fi 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 7594 $as_echo_n "checking for sysroot... " >&6; } 7595 7596 # Check whether --with-sysroot was given. 7597 if test "${with_sysroot+set}" = set; then : 7598 withval=$with_sysroot; 7599 else 7600 with_sysroot=no 7601 fi 7602 7603 7604 lt_sysroot= 7605 case $with_sysroot in #( 7606 yes) 7607 if test yes = "$GCC"; then 7608 lt_sysroot=`$CC --print-sysroot 2>/dev/null` 7609 fi 7610 ;; #( 7611 /*) 7612 lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` 7613 ;; #( 7614 no|'') 7615 ;; #( 7616 *) 7617 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 7618 $as_echo "$with_sysroot" >&6; } 7619 as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 7620 ;; 7621 esac 7622 7623 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 7624 $as_echo "${lt_sysroot:-no}" >&6; } 7625 7626 7627 7628 7629 7630 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 7631 $as_echo_n "checking for a working dd... " >&6; } 7632 if ${ac_cv_path_lt_DD+:} false; then : 7633 $as_echo_n "(cached) " >&6 7634 else 7635 printf 0123456789abcdef0123456789abcdef >conftest.i 7636 cat conftest.i conftest.i >conftest2.i 7637 : ${lt_DD:=$DD} 7638 if test -z "$lt_DD"; then 7639 ac_path_lt_DD_found=false 7640 # Loop through the user's path and test for each of PROGNAME-LIST 7641 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 7642 for as_dir in $PATH 7643 do 7644 IFS=$as_save_IFS 7645 test -z "$as_dir" && as_dir=. 7646 for ac_prog in dd; do 7647 for ac_exec_ext in '' $ac_executable_extensions; do 7648 ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" 7649 as_fn_executable_p "$ac_path_lt_DD" || continue 7650 if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then 7651 cmp -s conftest.i conftest.out \ 7652 && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: 7653 fi 7654 $ac_path_lt_DD_found && break 3 7655 done 7656 done 7657 done 7658 IFS=$as_save_IFS 7659 if test -z "$ac_cv_path_lt_DD"; then 7660 : 7661 fi 7662 else 7663 ac_cv_path_lt_DD=$lt_DD 7664 fi 7665 7666 rm -f conftest.i conftest2.i conftest.out 7667 fi 7668 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 7669 $as_echo "$ac_cv_path_lt_DD" >&6; } 7670 7671 7672 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 7673 $as_echo_n "checking how to truncate binary pipes... " >&6; } 7674 if ${lt_cv_truncate_bin+:} false; then : 7675 $as_echo_n "(cached) " >&6 7676 else 7677 printf 0123456789abcdef0123456789abcdef >conftest.i 7678 cat conftest.i conftest.i >conftest2.i 7679 lt_cv_truncate_bin= 7680 if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then 7681 cmp -s conftest.i conftest.out \ 7682 && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" 7683 fi 7684 rm -f conftest.i conftest2.i conftest.out 7685 test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" 7686 fi 7687 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 7688 $as_echo "$lt_cv_truncate_bin" >&6; } 7689 7690 7691 7692 7693 7694 7695 7696 # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. 7697 func_cc_basename () 7698 { 7699 for cc_temp in $*""; do 7700 case $cc_temp in 7701 compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; 7702 distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; 7703 \-*) ;; 7704 *) break;; 7705 esac 7706 done 7707 func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` 7708 } 7709 7710 # Check whether --enable-libtool-lock was given. 7711 if test "${enable_libtool_lock+set}" = set; then : 7712 enableval=$enable_libtool_lock; 7713 fi 7714 7715 test no = "$enable_libtool_lock" || enable_libtool_lock=yes 7716 7717 # Some flags need to be propagated to the compiler or linker for good 7718 # libtool support. 7719 case $host in 7720 ia64-*-hpux*) 7721 # Find out what ABI is being produced by ac_compile, and set mode 7722 # options accordingly. 7723 echo 'int i;' > conftest.$ac_ext 7724 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 7725 (eval $ac_compile) 2>&5 7726 ac_status=$? 7727 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7728 test $ac_status = 0; }; then 7729 case `/usr/bin/file conftest.$ac_objext` in 7730 *ELF-32*) 7731 HPUX_IA64_MODE=32 7732 ;; 7733 *ELF-64*) 7734 HPUX_IA64_MODE=64 7735 ;; 7736 esac 7737 fi 7738 rm -rf conftest* 7739 ;; 7740 *-*-irix6*) 7741 # Find out what ABI is being produced by ac_compile, and set linker 7742 # options accordingly. 7743 echo '#line '$LINENO' "configure"' > conftest.$ac_ext 7744 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 7745 (eval $ac_compile) 2>&5 7746 ac_status=$? 7747 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7748 test $ac_status = 0; }; then 7749 if test yes = "$lt_cv_prog_gnu_ld"; then 7750 case `/usr/bin/file conftest.$ac_objext` in 7751 *32-bit*) 7752 LD="${LD-ld} -melf32bsmip" 7753 ;; 7754 *N32*) 7755 LD="${LD-ld} -melf32bmipn32" 7756 ;; 7757 *64-bit*) 7758 LD="${LD-ld} -melf64bmip" 7759 ;; 7760 esac 7761 else 7762 case `/usr/bin/file conftest.$ac_objext` in 7763 *32-bit*) 7764 LD="${LD-ld} -32" 7765 ;; 7766 *N32*) 7767 LD="${LD-ld} -n32" 7768 ;; 7769 *64-bit*) 7770 LD="${LD-ld} -64" 7771 ;; 7772 esac 7773 fi 7774 fi 7775 rm -rf conftest* 7776 ;; 7777 7778 mips64*-*linux*) 7779 # Find out what ABI is being produced by ac_compile, and set linker 7780 # options accordingly. 7781 echo '#line '$LINENO' "configure"' > conftest.$ac_ext 7782 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 7783 (eval $ac_compile) 2>&5 7784 ac_status=$? 7785 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7786 test $ac_status = 0; }; then 7787 emul=elf 7788 case `/usr/bin/file conftest.$ac_objext` in 7789 *32-bit*) 7790 emul="${emul}32" 7791 ;; 7792 *64-bit*) 7793 emul="${emul}64" 7794 ;; 7795 esac 7796 case `/usr/bin/file conftest.$ac_objext` in 7797 *MSB*) 7798 emul="${emul}btsmip" 7799 ;; 7800 *LSB*) 7801 emul="${emul}ltsmip" 7802 ;; 7803 esac 7804 case `/usr/bin/file conftest.$ac_objext` in 7805 *N32*) 7806 emul="${emul}n32" 7807 ;; 7808 esac 7809 LD="${LD-ld} -m $emul" 7810 fi 7811 rm -rf conftest* 7812 ;; 7813 7814 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ 7815 s390*-*linux*|s390*-*tpf*|sparc*-*linux*) 7816 # Find out what ABI is being produced by ac_compile, and set linker 7817 # options accordingly. Note that the listed cases only cover the 7818 # situations where additional linker options are needed (such as when 7819 # doing 32-bit compilation for a host where ld defaults to 64-bit, or 7820 # vice versa); the common cases where no linker options are needed do 7821 # not appear in the list. 7822 echo 'int i;' > conftest.$ac_ext 7823 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 7824 (eval $ac_compile) 2>&5 7825 ac_status=$? 7826 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7827 test $ac_status = 0; }; then 7828 case `/usr/bin/file conftest.o` in 7829 *32-bit*) 7830 case $host in 7831 x86_64-*kfreebsd*-gnu) 7832 LD="${LD-ld} -m elf_i386_fbsd" 7833 ;; 7834 x86_64-*linux*) 7835 case `/usr/bin/file conftest.o` in 7836 *x86-64*) 7837 LD="${LD-ld} -m elf32_x86_64" 7838 ;; 7839 *) 7840 LD="${LD-ld} -m elf_i386" 7841 ;; 7842 esac 7843 ;; 7844 powerpc64le-*linux*) 7845 LD="${LD-ld} -m elf32lppclinux" 7846 ;; 7847 powerpc64-*linux*) 7848 LD="${LD-ld} -m elf32ppclinux" 7849 ;; 7850 s390x-*linux*) 7851 LD="${LD-ld} -m elf_s390" 7852 ;; 7853 sparc64-*linux*) 7854 LD="${LD-ld} -m elf32_sparc" 7855 ;; 7856 esac 7857 ;; 7858 *64-bit*) 7859 case $host in 7860 x86_64-*kfreebsd*-gnu) 7861 LD="${LD-ld} -m elf_x86_64_fbsd" 7862 ;; 7863 x86_64-*linux*) 7864 LD="${LD-ld} -m elf_x86_64" 7865 ;; 7866 powerpcle-*linux*) 7867 LD="${LD-ld} -m elf64lppc" 7868 ;; 7869 powerpc-*linux*) 7870 LD="${LD-ld} -m elf64ppc" 7871 ;; 7872 s390*-*linux*|s390*-*tpf*) 7873 LD="${LD-ld} -m elf64_s390" 7874 ;; 7875 sparc*-*linux*) 7876 LD="${LD-ld} -m elf64_sparc" 7877 ;; 7878 esac 7879 ;; 7880 esac 7881 fi 7882 rm -rf conftest* 7883 ;; 7884 7885 *-*-sco3.2v5*) 7886 # On SCO OpenServer 5, we need -belf to get full-featured binaries. 7887 SAVE_CFLAGS=$CFLAGS 7888 CFLAGS="$CFLAGS -belf" 7889 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 7890 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } 7891 if ${lt_cv_cc_needs_belf+:} false; then : 7892 $as_echo_n "(cached) " >&6 7893 else 7894 ac_ext=c 7895 ac_cpp='$CPP $CPPFLAGS' 7896 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 7897 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 7898 ac_compiler_gnu=$ac_cv_c_compiler_gnu 7899 7900 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 7901 /* end confdefs.h. */ 7902 7903 int 7904 main () 7905 { 7906 7907 ; 7908 return 0; 7909 } 7910 _ACEOF 7911 if ac_fn_c_try_link "$LINENO"; then : 7912 lt_cv_cc_needs_belf=yes 7913 else 7914 lt_cv_cc_needs_belf=no 7915 fi 7916 rm -f core conftest.err conftest.$ac_objext \ 7917 conftest$ac_exeext conftest.$ac_ext 7918 ac_ext=c 7919 ac_cpp='$CPP $CPPFLAGS' 7920 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 7921 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 7922 ac_compiler_gnu=$ac_cv_c_compiler_gnu 7923 7924 fi 7925 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 7926 $as_echo "$lt_cv_cc_needs_belf" >&6; } 7927 if test yes != "$lt_cv_cc_needs_belf"; then 7928 # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf 7929 CFLAGS=$SAVE_CFLAGS 7930 fi 7931 ;; 7932 *-*solaris*) 7933 # Find out what ABI is being produced by ac_compile, and set linker 7934 # options accordingly. 7935 echo 'int i;' > conftest.$ac_ext 7936 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 7937 (eval $ac_compile) 2>&5 7938 ac_status=$? 7939 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 7940 test $ac_status = 0; }; then 7941 case `/usr/bin/file conftest.o` in 7942 *64-bit*) 7943 case $lt_cv_prog_gnu_ld in 7944 yes*) 7945 case $host in 7946 i?86-*-solaris*|x86_64-*-solaris*) 7947 LD="${LD-ld} -m elf_x86_64" 7948 ;; 7949 sparc*-*-solaris*) 7950 LD="${LD-ld} -m elf64_sparc" 7951 ;; 7952 esac 7953 # GNU ld 2.21 introduced _sol2 emulations. Use them if available. 7954 if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then 7955 LD=${LD-ld}_sol2 7956 fi 7957 ;; 7958 *) 7959 if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then 7960 LD="${LD-ld} -64" 7961 fi 7962 ;; 7963 esac 7964 ;; 7965 esac 7966 fi 7967 rm -rf conftest* 7968 ;; 7969 esac 7970 7971 need_locks=$enable_libtool_lock 7972 7973 if test -n "$ac_tool_prefix"; then 7974 # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. 7975 set dummy ${ac_tool_prefix}mt; ac_word=$2 7976 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 7977 $as_echo_n "checking for $ac_word... " >&6; } 7978 if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : 7979 $as_echo_n "(cached) " >&6 7980 else 7981 if test -n "$MANIFEST_TOOL"; then 7982 ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. 7983 else 7984 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 7985 for as_dir in $PATH 7986 do 7987 IFS=$as_save_IFS 7988 test -z "$as_dir" && as_dir=. 7989 for ac_exec_ext in '' $ac_executable_extensions; do 7990 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 7991 ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" 7992 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 7993 break 2 7994 fi 7995 done 7996 done 7997 IFS=$as_save_IFS 7998 7999 fi 8000 fi 8001 MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL 8002 if test -n "$MANIFEST_TOOL"; then 8003 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 8004 $as_echo "$MANIFEST_TOOL" >&6; } 8005 else 8006 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8007 $as_echo "no" >&6; } 8008 fi 8009 8010 8011 fi 8012 if test -z "$ac_cv_prog_MANIFEST_TOOL"; then 8013 ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL 8014 # Extract the first word of "mt", so it can be a program name with args. 8015 set dummy mt; ac_word=$2 8016 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8017 $as_echo_n "checking for $ac_word... " >&6; } 8018 if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : 8019 $as_echo_n "(cached) " >&6 8020 else 8021 if test -n "$ac_ct_MANIFEST_TOOL"; then 8022 ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. 8023 else 8024 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8025 for as_dir in $PATH 8026 do 8027 IFS=$as_save_IFS 8028 test -z "$as_dir" && as_dir=. 8029 for ac_exec_ext in '' $ac_executable_extensions; do 8030 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8031 ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" 8032 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8033 break 2 8034 fi 8035 done 8036 done 8037 IFS=$as_save_IFS 8038 8039 fi 8040 fi 8041 ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL 8042 if test -n "$ac_ct_MANIFEST_TOOL"; then 8043 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 8044 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } 8045 else 8046 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8047 $as_echo "no" >&6; } 8048 fi 8049 8050 if test "x$ac_ct_MANIFEST_TOOL" = x; then 8051 MANIFEST_TOOL=":" 8052 else 8053 case $cross_compiling:$ac_tool_warned in 8054 yes:) 8055 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 8056 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 8057 ac_tool_warned=yes ;; 8058 esac 8059 MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL 8060 fi 8061 else 8062 MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" 8063 fi 8064 8065 test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt 8066 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 8067 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } 8068 if ${lt_cv_path_mainfest_tool+:} false; then : 8069 $as_echo_n "(cached) " >&6 8070 else 8071 lt_cv_path_mainfest_tool=no 8072 echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 8073 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out 8074 cat conftest.err >&5 8075 if $GREP 'Manifest Tool' conftest.out > /dev/null; then 8076 lt_cv_path_mainfest_tool=yes 8077 fi 8078 rm -f conftest* 8079 fi 8080 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 8081 $as_echo "$lt_cv_path_mainfest_tool" >&6; } 8082 if test yes != "$lt_cv_path_mainfest_tool"; then 8083 MANIFEST_TOOL=: 8084 fi 8085 8086 8087 8088 8089 8090 8091 case $host_os in 8092 rhapsody* | darwin*) 8093 if test -n "$ac_tool_prefix"; then 8094 # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. 8095 set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 8096 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8097 $as_echo_n "checking for $ac_word... " >&6; } 8098 if ${ac_cv_prog_DSYMUTIL+:} false; then : 8099 $as_echo_n "(cached) " >&6 8100 else 8101 if test -n "$DSYMUTIL"; then 8102 ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. 8103 else 8104 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8105 for as_dir in $PATH 8106 do 8107 IFS=$as_save_IFS 8108 test -z "$as_dir" && as_dir=. 8109 for ac_exec_ext in '' $ac_executable_extensions; do 8110 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8111 ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" 8112 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8113 break 2 8114 fi 8115 done 8116 done 8117 IFS=$as_save_IFS 8118 8119 fi 8120 fi 8121 DSYMUTIL=$ac_cv_prog_DSYMUTIL 8122 if test -n "$DSYMUTIL"; then 8123 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 8124 $as_echo "$DSYMUTIL" >&6; } 8125 else 8126 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8127 $as_echo "no" >&6; } 8128 fi 8129 8130 8131 fi 8132 if test -z "$ac_cv_prog_DSYMUTIL"; then 8133 ac_ct_DSYMUTIL=$DSYMUTIL 8134 # Extract the first word of "dsymutil", so it can be a program name with args. 8135 set dummy dsymutil; ac_word=$2 8136 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8137 $as_echo_n "checking for $ac_word... " >&6; } 8138 if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : 8139 $as_echo_n "(cached) " >&6 8140 else 8141 if test -n "$ac_ct_DSYMUTIL"; then 8142 ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. 8143 else 8144 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8145 for as_dir in $PATH 8146 do 8147 IFS=$as_save_IFS 8148 test -z "$as_dir" && as_dir=. 8149 for ac_exec_ext in '' $ac_executable_extensions; do 8150 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8151 ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" 8152 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8153 break 2 8154 fi 8155 done 8156 done 8157 IFS=$as_save_IFS 8158 8159 fi 8160 fi 8161 ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL 8162 if test -n "$ac_ct_DSYMUTIL"; then 8163 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 8164 $as_echo "$ac_ct_DSYMUTIL" >&6; } 8165 else 8166 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8167 $as_echo "no" >&6; } 8168 fi 8169 8170 if test "x$ac_ct_DSYMUTIL" = x; then 8171 DSYMUTIL=":" 8172 else 8173 case $cross_compiling:$ac_tool_warned in 8174 yes:) 8175 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 8176 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 8177 ac_tool_warned=yes ;; 8178 esac 8179 DSYMUTIL=$ac_ct_DSYMUTIL 8180 fi 8181 else 8182 DSYMUTIL="$ac_cv_prog_DSYMUTIL" 8183 fi 8184 8185 if test -n "$ac_tool_prefix"; then 8186 # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. 8187 set dummy ${ac_tool_prefix}nmedit; ac_word=$2 8188 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8189 $as_echo_n "checking for $ac_word... " >&6; } 8190 if ${ac_cv_prog_NMEDIT+:} false; then : 8191 $as_echo_n "(cached) " >&6 8192 else 8193 if test -n "$NMEDIT"; then 8194 ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. 8195 else 8196 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8197 for as_dir in $PATH 8198 do 8199 IFS=$as_save_IFS 8200 test -z "$as_dir" && as_dir=. 8201 for ac_exec_ext in '' $ac_executable_extensions; do 8202 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8203 ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" 8204 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8205 break 2 8206 fi 8207 done 8208 done 8209 IFS=$as_save_IFS 8210 8211 fi 8212 fi 8213 NMEDIT=$ac_cv_prog_NMEDIT 8214 if test -n "$NMEDIT"; then 8215 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 8216 $as_echo "$NMEDIT" >&6; } 8217 else 8218 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8219 $as_echo "no" >&6; } 8220 fi 8221 8222 8223 fi 8224 if test -z "$ac_cv_prog_NMEDIT"; then 8225 ac_ct_NMEDIT=$NMEDIT 8226 # Extract the first word of "nmedit", so it can be a program name with args. 8227 set dummy nmedit; ac_word=$2 8228 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8229 $as_echo_n "checking for $ac_word... " >&6; } 8230 if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : 8231 $as_echo_n "(cached) " >&6 8232 else 8233 if test -n "$ac_ct_NMEDIT"; then 8234 ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. 8235 else 8236 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8237 for as_dir in $PATH 8238 do 8239 IFS=$as_save_IFS 8240 test -z "$as_dir" && as_dir=. 8241 for ac_exec_ext in '' $ac_executable_extensions; do 8242 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8243 ac_cv_prog_ac_ct_NMEDIT="nmedit" 8244 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8245 break 2 8246 fi 8247 done 8248 done 8249 IFS=$as_save_IFS 8250 8251 fi 8252 fi 8253 ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT 8254 if test -n "$ac_ct_NMEDIT"; then 8255 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 8256 $as_echo "$ac_ct_NMEDIT" >&6; } 8257 else 8258 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8259 $as_echo "no" >&6; } 8260 fi 8261 8262 if test "x$ac_ct_NMEDIT" = x; then 8263 NMEDIT=":" 8264 else 8265 case $cross_compiling:$ac_tool_warned in 8266 yes:) 8267 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 8268 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 8269 ac_tool_warned=yes ;; 8270 esac 8271 NMEDIT=$ac_ct_NMEDIT 8272 fi 8273 else 8274 NMEDIT="$ac_cv_prog_NMEDIT" 8275 fi 8276 8277 if test -n "$ac_tool_prefix"; then 8278 # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. 8279 set dummy ${ac_tool_prefix}lipo; ac_word=$2 8280 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8281 $as_echo_n "checking for $ac_word... " >&6; } 8282 if ${ac_cv_prog_LIPO+:} false; then : 8283 $as_echo_n "(cached) " >&6 8284 else 8285 if test -n "$LIPO"; then 8286 ac_cv_prog_LIPO="$LIPO" # Let the user override the test. 8287 else 8288 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8289 for as_dir in $PATH 8290 do 8291 IFS=$as_save_IFS 8292 test -z "$as_dir" && as_dir=. 8293 for ac_exec_ext in '' $ac_executable_extensions; do 8294 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8295 ac_cv_prog_LIPO="${ac_tool_prefix}lipo" 8296 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8297 break 2 8298 fi 8299 done 8300 done 8301 IFS=$as_save_IFS 8302 8303 fi 8304 fi 8305 LIPO=$ac_cv_prog_LIPO 8306 if test -n "$LIPO"; then 8307 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 8308 $as_echo "$LIPO" >&6; } 8309 else 8310 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8311 $as_echo "no" >&6; } 8312 fi 8313 8314 8315 fi 8316 if test -z "$ac_cv_prog_LIPO"; then 8317 ac_ct_LIPO=$LIPO 8318 # Extract the first word of "lipo", so it can be a program name with args. 8319 set dummy lipo; ac_word=$2 8320 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8321 $as_echo_n "checking for $ac_word... " >&6; } 8322 if ${ac_cv_prog_ac_ct_LIPO+:} false; then : 8323 $as_echo_n "(cached) " >&6 8324 else 8325 if test -n "$ac_ct_LIPO"; then 8326 ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. 8327 else 8328 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8329 for as_dir in $PATH 8330 do 8331 IFS=$as_save_IFS 8332 test -z "$as_dir" && as_dir=. 8333 for ac_exec_ext in '' $ac_executable_extensions; do 8334 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8335 ac_cv_prog_ac_ct_LIPO="lipo" 8336 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8337 break 2 8338 fi 8339 done 8340 done 8341 IFS=$as_save_IFS 8342 8343 fi 8344 fi 8345 ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO 8346 if test -n "$ac_ct_LIPO"; then 8347 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 8348 $as_echo "$ac_ct_LIPO" >&6; } 8349 else 8350 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8351 $as_echo "no" >&6; } 8352 fi 8353 8354 if test "x$ac_ct_LIPO" = x; then 8355 LIPO=":" 8356 else 8357 case $cross_compiling:$ac_tool_warned in 8358 yes:) 8359 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 8360 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 8361 ac_tool_warned=yes ;; 8362 esac 8363 LIPO=$ac_ct_LIPO 8364 fi 8365 else 8366 LIPO="$ac_cv_prog_LIPO" 8367 fi 8368 8369 if test -n "$ac_tool_prefix"; then 8370 # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. 8371 set dummy ${ac_tool_prefix}otool; ac_word=$2 8372 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8373 $as_echo_n "checking for $ac_word... " >&6; } 8374 if ${ac_cv_prog_OTOOL+:} false; then : 8375 $as_echo_n "(cached) " >&6 8376 else 8377 if test -n "$OTOOL"; then 8378 ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. 8379 else 8380 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8381 for as_dir in $PATH 8382 do 8383 IFS=$as_save_IFS 8384 test -z "$as_dir" && as_dir=. 8385 for ac_exec_ext in '' $ac_executable_extensions; do 8386 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8387 ac_cv_prog_OTOOL="${ac_tool_prefix}otool" 8388 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8389 break 2 8390 fi 8391 done 8392 done 8393 IFS=$as_save_IFS 8394 8395 fi 8396 fi 8397 OTOOL=$ac_cv_prog_OTOOL 8398 if test -n "$OTOOL"; then 8399 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 8400 $as_echo "$OTOOL" >&6; } 8401 else 8402 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8403 $as_echo "no" >&6; } 8404 fi 8405 8406 8407 fi 8408 if test -z "$ac_cv_prog_OTOOL"; then 8409 ac_ct_OTOOL=$OTOOL 8410 # Extract the first word of "otool", so it can be a program name with args. 8411 set dummy otool; ac_word=$2 8412 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8413 $as_echo_n "checking for $ac_word... " >&6; } 8414 if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : 8415 $as_echo_n "(cached) " >&6 8416 else 8417 if test -n "$ac_ct_OTOOL"; then 8418 ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. 8419 else 8420 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8421 for as_dir in $PATH 8422 do 8423 IFS=$as_save_IFS 8424 test -z "$as_dir" && as_dir=. 8425 for ac_exec_ext in '' $ac_executable_extensions; do 8426 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8427 ac_cv_prog_ac_ct_OTOOL="otool" 8428 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8429 break 2 8430 fi 8431 done 8432 done 8433 IFS=$as_save_IFS 8434 8435 fi 8436 fi 8437 ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL 8438 if test -n "$ac_ct_OTOOL"; then 8439 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 8440 $as_echo "$ac_ct_OTOOL" >&6; } 8441 else 8442 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8443 $as_echo "no" >&6; } 8444 fi 8445 8446 if test "x$ac_ct_OTOOL" = x; then 8447 OTOOL=":" 8448 else 8449 case $cross_compiling:$ac_tool_warned in 8450 yes:) 8451 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 8452 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 8453 ac_tool_warned=yes ;; 8454 esac 8455 OTOOL=$ac_ct_OTOOL 8456 fi 8457 else 8458 OTOOL="$ac_cv_prog_OTOOL" 8459 fi 8460 8461 if test -n "$ac_tool_prefix"; then 8462 # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. 8463 set dummy ${ac_tool_prefix}otool64; ac_word=$2 8464 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8465 $as_echo_n "checking for $ac_word... " >&6; } 8466 if ${ac_cv_prog_OTOOL64+:} false; then : 8467 $as_echo_n "(cached) " >&6 8468 else 8469 if test -n "$OTOOL64"; then 8470 ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. 8471 else 8472 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8473 for as_dir in $PATH 8474 do 8475 IFS=$as_save_IFS 8476 test -z "$as_dir" && as_dir=. 8477 for ac_exec_ext in '' $ac_executable_extensions; do 8478 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8479 ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" 8480 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8481 break 2 8482 fi 8483 done 8484 done 8485 IFS=$as_save_IFS 8486 8487 fi 8488 fi 8489 OTOOL64=$ac_cv_prog_OTOOL64 8490 if test -n "$OTOOL64"; then 8491 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 8492 $as_echo "$OTOOL64" >&6; } 8493 else 8494 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8495 $as_echo "no" >&6; } 8496 fi 8497 8498 8499 fi 8500 if test -z "$ac_cv_prog_OTOOL64"; then 8501 ac_ct_OTOOL64=$OTOOL64 8502 # Extract the first word of "otool64", so it can be a program name with args. 8503 set dummy otool64; ac_word=$2 8504 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 8505 $as_echo_n "checking for $ac_word... " >&6; } 8506 if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : 8507 $as_echo_n "(cached) " >&6 8508 else 8509 if test -n "$ac_ct_OTOOL64"; then 8510 ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. 8511 else 8512 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR 8513 for as_dir in $PATH 8514 do 8515 IFS=$as_save_IFS 8516 test -z "$as_dir" && as_dir=. 8517 for ac_exec_ext in '' $ac_executable_extensions; do 8518 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 8519 ac_cv_prog_ac_ct_OTOOL64="otool64" 8520 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 8521 break 2 8522 fi 8523 done 8524 done 8525 IFS=$as_save_IFS 8526 8527 fi 8528 fi 8529 ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 8530 if test -n "$ac_ct_OTOOL64"; then 8531 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 8532 $as_echo "$ac_ct_OTOOL64" >&6; } 8533 else 8534 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 8535 $as_echo "no" >&6; } 8536 fi 8537 8538 if test "x$ac_ct_OTOOL64" = x; then 8539 OTOOL64=":" 8540 else 8541 case $cross_compiling:$ac_tool_warned in 8542 yes:) 8543 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 8544 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} 8545 ac_tool_warned=yes ;; 8546 esac 8547 OTOOL64=$ac_ct_OTOOL64 8548 fi 8549 else 8550 OTOOL64="$ac_cv_prog_OTOOL64" 8551 fi 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 8580 $as_echo_n "checking for -single_module linker flag... " >&6; } 8581 if ${lt_cv_apple_cc_single_mod+:} false; then : 8582 $as_echo_n "(cached) " >&6 8583 else 8584 lt_cv_apple_cc_single_mod=no 8585 if test -z "$LT_MULTI_MODULE"; then 8586 # By default we will add the -single_module flag. You can override 8587 # by either setting the environment variable LT_MULTI_MODULE 8588 # non-empty at configure time, or by adding -multi_module to the 8589 # link flags. 8590 rm -rf libconftest.dylib* 8591 echo "int foo(void){return 1;}" > conftest.c 8592 echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ 8593 -dynamiclib -Wl,-single_module conftest.c" >&5 8594 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ 8595 -dynamiclib -Wl,-single_module conftest.c 2>conftest.err 8596 _lt_result=$? 8597 # If there is a non-empty error log, and "single_module" 8598 # appears in it, assume the flag caused a linker warning 8599 if test -s conftest.err && $GREP single_module conftest.err; then 8600 cat conftest.err >&5 8601 # Otherwise, if the output was created with a 0 exit code from 8602 # the compiler, it worked. 8603 elif test -f libconftest.dylib && test 0 = "$_lt_result"; then 8604 lt_cv_apple_cc_single_mod=yes 8605 else 8606 cat conftest.err >&5 8607 fi 8608 rm -rf libconftest.dylib* 8609 rm -f conftest.* 8610 fi 8611 fi 8612 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 8613 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } 8614 8615 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 8616 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } 8617 if ${lt_cv_ld_exported_symbols_list+:} false; then : 8618 $as_echo_n "(cached) " >&6 8619 else 8620 lt_cv_ld_exported_symbols_list=no 8621 save_LDFLAGS=$LDFLAGS 8622 echo "_main" > conftest.sym 8623 LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" 8624 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 8625 /* end confdefs.h. */ 8626 8627 int 8628 main () 8629 { 8630 8631 ; 8632 return 0; 8633 } 8634 _ACEOF 8635 if ac_fn_c_try_link "$LINENO"; then : 8636 lt_cv_ld_exported_symbols_list=yes 8637 else 8638 lt_cv_ld_exported_symbols_list=no 8639 fi 8640 rm -f core conftest.err conftest.$ac_objext \ 8641 conftest$ac_exeext conftest.$ac_ext 8642 LDFLAGS=$save_LDFLAGS 8643 8644 fi 8645 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 8646 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } 8647 8648 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 8649 $as_echo_n "checking for -force_load linker flag... " >&6; } 8650 if ${lt_cv_ld_force_load+:} false; then : 8651 $as_echo_n "(cached) " >&6 8652 else 8653 lt_cv_ld_force_load=no 8654 cat > conftest.c << _LT_EOF 8655 int forced_loaded() { return 2;} 8656 _LT_EOF 8657 echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 8658 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 8659 echo "$AR cru libconftest.a conftest.o" >&5 8660 $AR cru libconftest.a conftest.o 2>&5 8661 echo "$RANLIB libconftest.a" >&5 8662 $RANLIB libconftest.a 2>&5 8663 cat > conftest.c << _LT_EOF 8664 int main() { return 0;} 8665 _LT_EOF 8666 echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 8667 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err 8668 _lt_result=$? 8669 if test -s conftest.err && $GREP force_load conftest.err; then 8670 cat conftest.err >&5 8671 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then 8672 lt_cv_ld_force_load=yes 8673 else 8674 cat conftest.err >&5 8675 fi 8676 rm -f conftest.err libconftest.a conftest conftest.c 8677 rm -rf conftest.dSYM 8678 8679 fi 8680 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 8681 $as_echo "$lt_cv_ld_force_load" >&6; } 8682 case $host_os in 8683 rhapsody* | darwin1.[012]) 8684 _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; 8685 darwin1.*) 8686 _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 8687 darwin*) # darwin 5.x on 8688 # if running on 10.5 or later, the deployment target defaults 8689 # to the OS version, if on x86, and 10.4, the deployment 8690 # target defaults to 10.4. Don't you love it? 8691 case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 8692 10.0,*86*-darwin8*|10.0,*-darwin[91]*) 8693 _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 8694 10.[012][,.]*) 8695 _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 8696 10.*) 8697 _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 8698 esac 8699 ;; 8700 esac 8701 if test yes = "$lt_cv_apple_cc_single_mod"; then 8702 _lt_dar_single_mod='$single_module' 8703 fi 8704 if test yes = "$lt_cv_ld_exported_symbols_list"; then 8705 _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' 8706 else 8707 _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' 8708 fi 8709 if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then 8710 _lt_dsymutil='~$DSYMUTIL $lib || :' 8711 else 8712 _lt_dsymutil= 8713 fi 8714 ;; 8715 esac 8716 8717 # func_munge_path_list VARIABLE PATH 8718 # ----------------------------------- 8719 # VARIABLE is name of variable containing _space_ separated list of 8720 # directories to be munged by the contents of PATH, which is string 8721 # having a format: 8722 # "DIR[:DIR]:" 8723 # string "DIR[ DIR]" will be prepended to VARIABLE 8724 # ":DIR[:DIR]" 8725 # string "DIR[ DIR]" will be appended to VARIABLE 8726 # "DIRP[:DIRP]::[DIRA:]DIRA" 8727 # string "DIRP[ DIRP]" will be prepended to VARIABLE and string 8728 # "DIRA[ DIRA]" will be appended to VARIABLE 8729 # "DIR[:DIR]" 8730 # VARIABLE will be replaced by "DIR[ DIR]" 8731 func_munge_path_list () 8732 { 8733 case x$2 in 8734 x) 8735 ;; 8736 *:) 8737 eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" 8738 ;; 8739 x:*) 8740 eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" 8741 ;; 8742 *::*) 8743 eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" 8744 eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" 8745 ;; 8746 *) 8747 eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" 8748 ;; 8749 esac 8750 } 8751 8752 ac_ext=c 8753 ac_cpp='$CPP $CPPFLAGS' 8754 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 8755 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 8756 ac_compiler_gnu=$ac_cv_c_compiler_gnu 8757 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 8758 $as_echo_n "checking how to run the C preprocessor... " >&6; } 8759 # On Suns, sometimes $CPP names a directory. 8760 if test -n "$CPP" && test -d "$CPP"; then 8761 CPP= 8762 fi 8763 if test -z "$CPP"; then 8764 if ${ac_cv_prog_CPP+:} false; then : 8765 $as_echo_n "(cached) " >&6 8766 else 8767 # Double quotes because CPP needs to be expanded 8768 for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" 8769 do 8770 ac_preproc_ok=false 8771 for ac_c_preproc_warn_flag in '' yes 8772 do 8773 # Use a header file that comes with gcc, so configuring glibc 8774 # with a fresh cross-compiler works. 8775 # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since 8776 # <limits.h> exists even on freestanding compilers. 8777 # On the NeXT, cc -E runs the code through the compiler's parser, 8778 # not just through cpp. "Syntax error" is here to catch this case. 8779 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 8780 /* end confdefs.h. */ 8781 #ifdef __STDC__ 8782 # include <limits.h> 8783 #else 8784 # include <assert.h> 8785 #endif 8786 Syntax error 8787 _ACEOF 8788 if ac_fn_c_try_cpp "$LINENO"; then : 8789 8790 else 8791 # Broken: fails on valid input. 8792 continue 8793 fi 8794 rm -f conftest.err conftest.i conftest.$ac_ext 8795 8796 # OK, works on sane cases. Now check whether nonexistent headers 8797 # can be detected and how. 8798 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 8799 /* end confdefs.h. */ 8800 #include <ac_nonexistent.h> 8801 _ACEOF 8802 if ac_fn_c_try_cpp "$LINENO"; then : 8803 # Broken: success on invalid input. 8804 continue 8805 else 8806 # Passes both tests. 8807 ac_preproc_ok=: 8808 break 8809 fi 8810 rm -f conftest.err conftest.i conftest.$ac_ext 8811 8812 done 8813 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. 8814 rm -f conftest.i conftest.err conftest.$ac_ext 8815 if $ac_preproc_ok; then : 8816 break 8817 fi 8818 8819 done 8820 ac_cv_prog_CPP=$CPP 8821 8822 fi 8823 CPP=$ac_cv_prog_CPP 8824 else 8825 ac_cv_prog_CPP=$CPP 8826 fi 8827 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 8828 $as_echo "$CPP" >&6; } 8829 ac_preproc_ok=false 8830 for ac_c_preproc_warn_flag in '' yes 8831 do 8832 # Use a header file that comes with gcc, so configuring glibc 8833 # with a fresh cross-compiler works. 8834 # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since 8835 # <limits.h> exists even on freestanding compilers. 8836 # On the NeXT, cc -E runs the code through the compiler's parser, 8837 # not just through cpp. "Syntax error" is here to catch this case. 8838 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 8839 /* end confdefs.h. */ 8840 #ifdef __STDC__ 8841 # include <limits.h> 8842 #else 8843 # include <assert.h> 8844 #endif 8845 Syntax error 8846 _ACEOF 8847 if ac_fn_c_try_cpp "$LINENO"; then : 8848 8849 else 8850 # Broken: fails on valid input. 8851 continue 8852 fi 8853 rm -f conftest.err conftest.i conftest.$ac_ext 8854 8855 # OK, works on sane cases. Now check whether nonexistent headers 8856 # can be detected and how. 8857 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 8858 /* end confdefs.h. */ 8859 #include <ac_nonexistent.h> 8860 _ACEOF 8861 if ac_fn_c_try_cpp "$LINENO"; then : 8862 # Broken: success on invalid input. 8863 continue 8864 else 8865 # Passes both tests. 8866 ac_preproc_ok=: 8867 break 8868 fi 8869 rm -f conftest.err conftest.i conftest.$ac_ext 8870 8871 done 8872 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. 8873 rm -f conftest.i conftest.err conftest.$ac_ext 8874 if $ac_preproc_ok; then : 8875 8876 else 8877 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 8878 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} 8879 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check 8880 See \`config.log' for more details" "$LINENO" 5; } 8881 fi 8882 8883 ac_ext=c 8884 ac_cpp='$CPP $CPPFLAGS' 8885 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 8886 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 8887 ac_compiler_gnu=$ac_cv_c_compiler_gnu 8888 8889 5673 8890 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 5674 8891 $as_echo_n "checking for ANSI C header files... " >&6; } … … 5800 9017 5801 9018 5802 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" 5803 if test "x$ac_cv_type_size_t" = xyes; then : 5804 5805 else 9019 for ac_header in dlfcn.h 9020 do : 9021 ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default 9022 " 9023 if test "x$ac_cv_header_dlfcn_h" = xyes; then : 9024 cat >>confdefs.h <<_ACEOF 9025 #define HAVE_DLFCN_H 1 9026 _ACEOF 9027 9028 fi 9029 9030 done 9031 9032 9033 9034 9035 func_stripname_cnf () 9036 { 9037 case $2 in 9038 .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; 9039 *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; 9040 esac 9041 } # func_stripname_cnf 9042 9043 9044 9045 9046 9047 # Set options 9048 9049 9050 9051 enable_dlopen=no 9052 9053 9054 enable_win32_dll=no 9055 9056 9057 # Check whether --enable-shared was given. 9058 if test "${enable_shared+set}" = set; then : 9059 enableval=$enable_shared; p=${PACKAGE-default} 9060 case $enableval in 9061 yes) enable_shared=yes ;; 9062 no) enable_shared=no ;; 9063 *) 9064 enable_shared=no 9065 # Look at the argument we got. We use all the common list separators. 9066 lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, 9067 for pkg in $enableval; do 9068 IFS=$lt_save_ifs 9069 if test "X$pkg" = "X$p"; then 9070 enable_shared=yes 9071 fi 9072 done 9073 IFS=$lt_save_ifs 9074 ;; 9075 esac 9076 else 9077 enable_shared=yes 9078 fi 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 # Check whether --enable-static was given. 9089 if test "${enable_static+set}" = set; then : 9090 enableval=$enable_static; p=${PACKAGE-default} 9091 case $enableval in 9092 yes) enable_static=yes ;; 9093 no) enable_static=no ;; 9094 *) 9095 enable_static=no 9096 # Look at the argument we got. We use all the common list separators. 9097 lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, 9098 for pkg in $enableval; do 9099 IFS=$lt_save_ifs 9100 if test "X$pkg" = "X$p"; then 9101 enable_static=yes 9102 fi 9103 done 9104 IFS=$lt_save_ifs 9105 ;; 9106 esac 9107 else 9108 enable_static=yes 9109 fi 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 # Check whether --with-pic was given. 9121 if test "${with_pic+set}" = set; then : 9122 withval=$with_pic; lt_p=${PACKAGE-default} 9123 case $withval in 9124 yes|no) pic_mode=$withval ;; 9125 *) 9126 pic_mode=default 9127 # Look at the argument we got. We use all the common list separators. 9128 lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, 9129 for lt_pkg in $withval; do 9130 IFS=$lt_save_ifs 9131 if test "X$lt_pkg" = "X$lt_p"; then 9132 pic_mode=yes 9133 fi 9134 done 9135 IFS=$lt_save_ifs 9136 ;; 9137 esac 9138 else 9139 pic_mode=default 9140 fi 9141 9142 9143 9144 9145 9146 9147 9148 9149 # Check whether --enable-fast-install was given. 9150 if test "${enable_fast_install+set}" = set; then : 9151 enableval=$enable_fast_install; p=${PACKAGE-default} 9152 case $enableval in 9153 yes) enable_fast_install=yes ;; 9154 no) enable_fast_install=no ;; 9155 *) 9156 enable_fast_install=no 9157 # Look at the argument we got. We use all the common list separators. 9158 lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, 9159 for pkg in $enableval; do 9160 IFS=$lt_save_ifs 9161 if test "X$pkg" = "X$p"; then 9162 enable_fast_install=yes 9163 fi 9164 done 9165 IFS=$lt_save_ifs 9166 ;; 9167 esac 9168 else 9169 enable_fast_install=yes 9170 fi 9171 9172 9173 9174 9175 9176 9177 9178 9179 shared_archive_member_spec= 9180 case $host,$enable_shared in 9181 power*-*-aix[5-9]*,yes) 9182 { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 9183 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } 9184 9185 # Check whether --with-aix-soname was given. 9186 if test "${with_aix_soname+set}" = set; then : 9187 withval=$with_aix_soname; case $withval in 9188 aix|svr4|both) 9189 ;; 9190 *) 9191 as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 9192 ;; 9193 esac 9194 lt_cv_with_aix_soname=$with_aix_soname 9195 else 9196 if ${lt_cv_with_aix_soname+:} false; then : 9197 $as_echo_n "(cached) " >&6 9198 else 9199 lt_cv_with_aix_soname=aix 9200 fi 9201 9202 with_aix_soname=$lt_cv_with_aix_soname 9203 fi 9204 9205 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 9206 $as_echo "$with_aix_soname" >&6; } 9207 if test aix != "$with_aix_soname"; then 9208 # For the AIX way of multilib, we name the shared archive member 9209 # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', 9210 # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. 9211 # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, 9212 # the AIX toolchain works better with OBJECT_MODE set (default 32). 9213 if test 64 = "${OBJECT_MODE-32}"; then 9214 shared_archive_member_spec=shr_64 9215 else 9216 shared_archive_member_spec=shr 9217 fi 9218 fi 9219 ;; 9220 *) 9221 with_aix_soname=aix 9222 ;; 9223 esac 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 # This can be used to rebuild libtool when needed 9235 LIBTOOL_DEPS=$ltmain 9236 9237 # Always use our own libtool. 9238 LIBTOOL='$(SHELL) $(top_builddir)/libtool' 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 test -z "$LN_S" && LN_S="ln -s" 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 if test -n "${ZSH_VERSION+set}"; then 9285 setopt NO_GLOB_SUBST 9286 fi 9287 9288 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 9289 $as_echo_n "checking for objdir... " >&6; } 9290 if ${lt_cv_objdir+:} false; then : 9291 $as_echo_n "(cached) " >&6 9292 else 9293 rm -f .libs 2>/dev/null 9294 mkdir .libs 2>/dev/null 9295 if test -d .libs; then 9296 lt_cv_objdir=.libs 9297 else 9298 # MS-DOS does not allow filenames that begin with a dot. 9299 lt_cv_objdir=_libs 9300 fi 9301 rmdir .libs 2>/dev/null 9302 fi 9303 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 9304 $as_echo "$lt_cv_objdir" >&6; } 9305 objdir=$lt_cv_objdir 9306 9307 9308 9309 5806 9310 5807 9311 cat >>confdefs.h <<_ACEOF 5808 #define size_t unsigned int9312 #define LT_OBJDIR "$lt_cv_objdir/" 5809 9313 _ACEOF 5810 9314 5811 fi 5812 5813 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works 5814 # for constant arguments. Useless! 5815 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 5816 $as_echo_n "checking for working alloca.h... " >&6; } 5817 if ${ac_cv_working_alloca_h+:} false; then : 9315 9316 9317 9318 case $host_os in 9319 aix3*) 9320 # AIX sometimes has problems with the GCC collect2 program. For some 9321 # reason, if we set the COLLECT_NAMES environment variable, the problems 9322 # vanish in a puff of smoke. 9323 if test set != "${COLLECT_NAMES+set}"; then 9324 COLLECT_NAMES= 9325 export COLLECT_NAMES 9326 fi 9327 ;; 9328 esac 9329 9330 # Global variables: 9331 ofile=libtool 9332 can_build_shared=yes 9333 9334 # All known linkers require a '.a' archive for static linking (except MSVC, 9335 # which needs '.lib'). 9336 libext=a 9337 9338 with_gnu_ld=$lt_cv_prog_gnu_ld 9339 9340 old_CC=$CC 9341 old_CFLAGS=$CFLAGS 9342 9343 # Set sane defaults for various variables 9344 test -z "$CC" && CC=cc 9345 test -z "$LTCC" && LTCC=$CC 9346 test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS 9347 test -z "$LD" && LD=ld 9348 test -z "$ac_objext" && ac_objext=o 9349 9350 func_cc_basename $compiler 9351 cc_basename=$func_cc_basename_result 9352 9353 9354 # Only perform the check for file, if the check method requires it 9355 test -z "$MAGIC_CMD" && MAGIC_CMD=file 9356 case $deplibs_check_method in 9357 file_magic*) 9358 if test "$file_magic_cmd" = '$MAGIC_CMD'; then 9359 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 9360 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } 9361 if ${lt_cv_path_MAGIC_CMD+:} false; then : 9362 $as_echo_n "(cached) " >&6 9363 else 9364 case $MAGIC_CMD in 9365 [\\/*] | ?:[\\/]*) 9366 lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. 9367 ;; 9368 *) 9369 lt_save_MAGIC_CMD=$MAGIC_CMD 9370 lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR 9371 ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" 9372 for ac_dir in $ac_dummy; do 9373 IFS=$lt_save_ifs 9374 test -z "$ac_dir" && ac_dir=. 9375 if test -f "$ac_dir/${ac_tool_prefix}file"; then 9376 lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" 9377 if test -n "$file_magic_test_file"; then 9378 case $deplibs_check_method in 9379 "file_magic "*) 9380 file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` 9381 MAGIC_CMD=$lt_cv_path_MAGIC_CMD 9382 if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | 9383 $EGREP "$file_magic_regex" > /dev/null; then 9384 : 9385 else 9386 cat <<_LT_EOF 1>&2 9387 9388 *** Warning: the command libtool uses to detect shared libraries, 9389 *** $file_magic_cmd, produces output that libtool cannot recognize. 9390 *** The result is that libtool may fail to recognize shared libraries 9391 *** as such. This will affect the creation of libtool libraries that 9392 *** depend on shared libraries, but programs linked with such libtool 9393 *** libraries will work regardless of this problem. Nevertheless, you 9394 *** may want to report the problem to your system manager and/or to 9395 *** bug-libtool@gnu.org 9396 9397 _LT_EOF 9398 fi ;; 9399 esac 9400 fi 9401 break 9402 fi 9403 done 9404 IFS=$lt_save_ifs 9405 MAGIC_CMD=$lt_save_MAGIC_CMD 9406 ;; 9407 esac 9408 fi 9409 9410 MAGIC_CMD=$lt_cv_path_MAGIC_CMD 9411 if test -n "$MAGIC_CMD"; then 9412 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 9413 $as_echo "$MAGIC_CMD" >&6; } 9414 else 9415 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 9416 $as_echo "no" >&6; } 9417 fi 9418 9419 9420 9421 9422 9423 if test -z "$lt_cv_path_MAGIC_CMD"; then 9424 if test -n "$ac_tool_prefix"; then 9425 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 9426 $as_echo_n "checking for file... " >&6; } 9427 if ${lt_cv_path_MAGIC_CMD+:} false; then : 9428 $as_echo_n "(cached) " >&6 9429 else 9430 case $MAGIC_CMD in 9431 [\\/*] | ?:[\\/]*) 9432 lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. 9433 ;; 9434 *) 9435 lt_save_MAGIC_CMD=$MAGIC_CMD 9436 lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR 9437 ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" 9438 for ac_dir in $ac_dummy; do 9439 IFS=$lt_save_ifs 9440 test -z "$ac_dir" && ac_dir=. 9441 if test -f "$ac_dir/file"; then 9442 lt_cv_path_MAGIC_CMD=$ac_dir/"file" 9443 if test -n "$file_magic_test_file"; then 9444 case $deplibs_check_method in 9445 "file_magic "*) 9446 file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` 9447 MAGIC_CMD=$lt_cv_path_MAGIC_CMD 9448 if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | 9449 $EGREP "$file_magic_regex" > /dev/null; then 9450 : 9451 else 9452 cat <<_LT_EOF 1>&2 9453 9454 *** Warning: the command libtool uses to detect shared libraries, 9455 *** $file_magic_cmd, produces output that libtool cannot recognize. 9456 *** The result is that libtool may fail to recognize shared libraries 9457 *** as such. This will affect the creation of libtool libraries that 9458 *** depend on shared libraries, but programs linked with such libtool 9459 *** libraries will work regardless of this problem. Nevertheless, you 9460 *** may want to report the problem to your system manager and/or to 9461 *** bug-libtool@gnu.org 9462 9463 _LT_EOF 9464 fi ;; 9465 esac 9466 fi 9467 break 9468 fi 9469 done 9470 IFS=$lt_save_ifs 9471 MAGIC_CMD=$lt_save_MAGIC_CMD 9472 ;; 9473 esac 9474 fi 9475 9476 MAGIC_CMD=$lt_cv_path_MAGIC_CMD 9477 if test -n "$MAGIC_CMD"; then 9478 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 9479 $as_echo "$MAGIC_CMD" >&6; } 9480 else 9481 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 9482 $as_echo "no" >&6; } 9483 fi 9484 9485 9486 else 9487 MAGIC_CMD=: 9488 fi 9489 fi 9490 9491 fi 9492 ;; 9493 esac 9494 9495 # Use C for the default configuration in the libtool script 9496 9497 lt_save_CC=$CC 9498 ac_ext=c 9499 ac_cpp='$CPP $CPPFLAGS' 9500 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 9501 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 9502 ac_compiler_gnu=$ac_cv_c_compiler_gnu 9503 9504 9505 # Source file extension for C test sources. 9506 ac_ext=c 9507 9508 # Object file extension for compiled C test sources. 9509 objext=o 9510 objext=$objext 9511 9512 # Code to be used in simple compile tests 9513 lt_simple_compile_test_code="int some_variable = 0;" 9514 9515 # Code to be used in simple link tests 9516 lt_simple_link_test_code='int main(){return(0);}' 9517 9518 9519 9520 9521 9522 9523 9524 # If no C compiler was specified, use CC. 9525 LTCC=${LTCC-"$CC"} 9526 9527 # If no C compiler flags were specified, use CFLAGS. 9528 LTCFLAGS=${LTCFLAGS-"$CFLAGS"} 9529 9530 # Allow CC to be a program name with arguments. 9531 compiler=$CC 9532 9533 # Save the default compiler, since it gets overwritten when the other 9534 # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. 9535 compiler_DEFAULT=$CC 9536 9537 # save warnings/boilerplate of simple test code 9538 ac_outfile=conftest.$ac_objext 9539 echo "$lt_simple_compile_test_code" >conftest.$ac_ext 9540 eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err 9541 _lt_compiler_boilerplate=`cat conftest.err` 9542 $RM conftest* 9543 9544 ac_outfile=conftest.$ac_objext 9545 echo "$lt_simple_link_test_code" >conftest.$ac_ext 9546 eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err 9547 _lt_linker_boilerplate=`cat conftest.err` 9548 $RM -r conftest* 9549 9550 9551 ## CAVEAT EMPTOR: 9552 ## There is no encapsulation within the following macros, do not change 9553 ## the running order or otherwise move them around unless you know exactly 9554 ## what you are doing... 9555 if test -n "$compiler"; then 9556 9557 lt_prog_compiler_no_builtin_flag= 9558 9559 if test yes = "$GCC"; then 9560 case $cc_basename in 9561 nvcc*) 9562 lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; 9563 *) 9564 lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; 9565 esac 9566 9567 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 9568 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } 9569 if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : 9570 $as_echo_n "(cached) " >&6 9571 else 9572 lt_cv_prog_compiler_rtti_exceptions=no 9573 ac_outfile=conftest.$ac_objext 9574 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 9575 lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment 9576 # Insert the option either (1) after the last *FLAGS variable, or 9577 # (2) before a word containing "conftest.", or (3) at the end. 9578 # Note that $ac_compile itself does not contain backslashes and begins 9579 # with a dollar sign (not a hyphen), so the echo should work correctly. 9580 # The option is referenced via a variable to avoid confusing sed. 9581 lt_compile=`echo "$ac_compile" | $SED \ 9582 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ 9583 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ 9584 -e 's:$: $lt_compiler_flag:'` 9585 (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) 9586 (eval "$lt_compile" 2>conftest.err) 9587 ac_status=$? 9588 cat conftest.err >&5 9589 echo "$as_me:$LINENO: \$? = $ac_status" >&5 9590 if (exit $ac_status) && test -s "$ac_outfile"; then 9591 # The compiler can only warn and ignore the option if not recognized 9592 # So say no if there are warnings other than the usual output. 9593 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp 9594 $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 9595 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then 9596 lt_cv_prog_compiler_rtti_exceptions=yes 9597 fi 9598 fi 9599 $RM conftest* 9600 9601 fi 9602 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 9603 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } 9604 9605 if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then 9606 lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" 9607 else 9608 : 9609 fi 9610 9611 fi 9612 9613 9614 9615 9616 9617 9618 lt_prog_compiler_wl= 9619 lt_prog_compiler_pic= 9620 lt_prog_compiler_static= 9621 9622 9623 if test yes = "$GCC"; then 9624 lt_prog_compiler_wl='-Wl,' 9625 lt_prog_compiler_static='-static' 9626 9627 case $host_os in 9628 aix*) 9629 # All AIX code is PIC. 9630 if test ia64 = "$host_cpu"; then 9631 # AIX 5 now supports IA64 processor 9632 lt_prog_compiler_static='-Bstatic' 9633 fi 9634 lt_prog_compiler_pic='-fPIC' 9635 ;; 9636 9637 amigaos*) 9638 case $host_cpu in 9639 powerpc) 9640 # see comment about AmigaOS4 .so support 9641 lt_prog_compiler_pic='-fPIC' 9642 ;; 9643 m68k) 9644 # FIXME: we need at least 68020 code to build shared libraries, but 9645 # adding the '-m68020' flag to GCC prevents building anything better, 9646 # like '-m68040'. 9647 lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' 9648 ;; 9649 esac 9650 ;; 9651 9652 beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) 9653 # PIC is the default for these OSes. 9654 ;; 9655 9656 mingw* | cygwin* | pw32* | os2* | cegcc*) 9657 # This hack is so that the source file can tell whether it is being 9658 # built for inclusion in a dll (and should export symbols for example). 9659 # Although the cygwin gcc ignores -fPIC, still need this for old-style 9660 # (--disable-auto-import) libraries 9661 lt_prog_compiler_pic='-DDLL_EXPORT' 9662 case $host_os in 9663 os2*) 9664 lt_prog_compiler_static='$wl-static' 9665 ;; 9666 esac 9667 ;; 9668 9669 darwin* | rhapsody*) 9670 # PIC is the default on this platform 9671 # Common symbols not allowed in MH_DYLIB files 9672 lt_prog_compiler_pic='-fno-common' 9673 ;; 9674 9675 haiku*) 9676 # PIC is the default for Haiku. 9677 # The "-static" flag exists, but is broken. 9678 lt_prog_compiler_static= 9679 ;; 9680 9681 hpux*) 9682 # PIC is the default for 64-bit PA HP-UX, but not for 32-bit 9683 # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag 9684 # sets the default TLS model and affects inlining. 9685 case $host_cpu in 9686 hppa*64*) 9687 # +Z the default 9688 ;; 9689 *) 9690 lt_prog_compiler_pic='-fPIC' 9691 ;; 9692 esac 9693 ;; 9694 9695 interix[3-9]*) 9696 # Interix 3.x gcc -fpic/-fPIC options generate broken code. 9697 # Instead, we relocate shared libraries at runtime. 9698 ;; 9699 9700 msdosdjgpp*) 9701 # Just because we use GCC doesn't mean we suddenly get shared libraries 9702 # on systems that don't support them. 9703 lt_prog_compiler_can_build_shared=no 9704 enable_shared=no 9705 ;; 9706 9707 *nto* | *qnx*) 9708 # QNX uses GNU C++, but need to define -shared option too, otherwise 9709 # it will coredump. 9710 lt_prog_compiler_pic='-fPIC -shared' 9711 ;; 9712 9713 sysv4*MP*) 9714 if test -d /usr/nec; then 9715 lt_prog_compiler_pic=-Kconform_pic 9716 fi 9717 ;; 9718 9719 *) 9720 lt_prog_compiler_pic='-fPIC' 9721 ;; 9722 esac 9723 9724 case $cc_basename in 9725 nvcc*) # Cuda Compiler Driver 2.2 9726 lt_prog_compiler_wl='-Xlinker ' 9727 if test -n "$lt_prog_compiler_pic"; then 9728 lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" 9729 fi 9730 ;; 9731 esac 9732 else 9733 # PORTME Check for flag to pass linker flags through the system compiler. 9734 case $host_os in 9735 aix*) 9736 lt_prog_compiler_wl='-Wl,' 9737 if test ia64 = "$host_cpu"; then 9738 # AIX 5 now supports IA64 processor 9739 lt_prog_compiler_static='-Bstatic' 9740 else 9741 lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' 9742 fi 9743 ;; 9744 9745 darwin* | rhapsody*) 9746 # PIC is the default on this platform 9747 # Common symbols not allowed in MH_DYLIB files 9748 lt_prog_compiler_pic='-fno-common' 9749 case $cc_basename in 9750 nagfor*) 9751 # NAG Fortran compiler 9752 lt_prog_compiler_wl='-Wl,-Wl,,' 9753 lt_prog_compiler_pic='-PIC' 9754 lt_prog_compiler_static='-Bstatic' 9755 ;; 9756 esac 9757 ;; 9758 9759 mingw* | cygwin* | pw32* | os2* | cegcc*) 9760 # This hack is so that the source file can tell whether it is being 9761 # built for inclusion in a dll (and should export symbols for example). 9762 lt_prog_compiler_pic='-DDLL_EXPORT' 9763 case $host_os in 9764 os2*) 9765 lt_prog_compiler_static='$wl-static' 9766 ;; 9767 esac 9768 ;; 9769 9770 hpux9* | hpux10* | hpux11*) 9771 lt_prog_compiler_wl='-Wl,' 9772 # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but 9773 # not for PA HP-UX. 9774 case $host_cpu in 9775 hppa*64*|ia64*) 9776 # +Z the default 9777 ;; 9778 *) 9779 lt_prog_compiler_pic='+Z' 9780 ;; 9781 esac 9782 # Is there a better lt_prog_compiler_static that works with the bundled CC? 9783 lt_prog_compiler_static='$wl-a ${wl}archive' 9784 ;; 9785 9786 irix5* | irix6* | nonstopux*) 9787 lt_prog_compiler_wl='-Wl,' 9788 # PIC (with -KPIC) is the default. 9789 lt_prog_compiler_static='-non_shared' 9790 ;; 9791 9792 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) 9793 case $cc_basename in 9794 # old Intel for x86_64, which still supported -KPIC. 9795 ecc*) 9796 lt_prog_compiler_wl='-Wl,' 9797 lt_prog_compiler_pic='-KPIC' 9798 lt_prog_compiler_static='-static' 9799 ;; 9800 # icc used to be incompatible with GCC. 9801 # ICC 10 doesn't accept -KPIC any more. 9802 icc* | ifort*) 9803 lt_prog_compiler_wl='-Wl,' 9804 lt_prog_compiler_pic='-fPIC' 9805 lt_prog_compiler_static='-static' 9806 ;; 9807 # Lahey Fortran 8.1. 9808 lf95*) 9809 lt_prog_compiler_wl='-Wl,' 9810 lt_prog_compiler_pic='--shared' 9811 lt_prog_compiler_static='--static' 9812 ;; 9813 nagfor*) 9814 # NAG Fortran compiler 9815 lt_prog_compiler_wl='-Wl,-Wl,,' 9816 lt_prog_compiler_pic='-PIC' 9817 lt_prog_compiler_static='-Bstatic' 9818 ;; 9819 tcc*) 9820 # Fabrice Bellard et al's Tiny C Compiler 9821 lt_prog_compiler_wl='-Wl,' 9822 lt_prog_compiler_pic='-fPIC' 9823 lt_prog_compiler_static='-static' 9824 ;; 9825 pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) 9826 # Portland Group compilers (*not* the Pentium gcc compiler, 9827 # which looks to be a dead project) 9828 lt_prog_compiler_wl='-Wl,' 9829 lt_prog_compiler_pic='-fpic' 9830 lt_prog_compiler_static='-Bstatic' 9831 ;; 9832 ccc*) 9833 lt_prog_compiler_wl='-Wl,' 9834 # All Alpha code is PIC. 9835 lt_prog_compiler_static='-non_shared' 9836 ;; 9837 xl* | bgxl* | bgf* | mpixl*) 9838 # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene 9839 lt_prog_compiler_wl='-Wl,' 9840 lt_prog_compiler_pic='-qpic' 9841 lt_prog_compiler_static='-qstaticlink' 9842 ;; 9843 *) 9844 case `$CC -V 2>&1 | sed 5q` in 9845 *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) 9846 # Sun Fortran 8.3 passes all unrecognized flags to the linker 9847 lt_prog_compiler_pic='-KPIC' 9848 lt_prog_compiler_static='-Bstatic' 9849 lt_prog_compiler_wl='' 9850 ;; 9851 *Sun\ F* | *Sun*Fortran*) 9852 lt_prog_compiler_pic='-KPIC' 9853 lt_prog_compiler_static='-Bstatic' 9854 lt_prog_compiler_wl='-Qoption ld ' 9855 ;; 9856 *Sun\ C*) 9857 # Sun C 5.9 9858 lt_prog_compiler_pic='-KPIC' 9859 lt_prog_compiler_static='-Bstatic' 9860 lt_prog_compiler_wl='-Wl,' 9861 ;; 9862 *Intel*\ [CF]*Compiler*) 9863 lt_prog_compiler_wl='-Wl,' 9864 lt_prog_compiler_pic='-fPIC' 9865 lt_prog_compiler_static='-static' 9866 ;; 9867 *Portland\ Group*) 9868 lt_prog_compiler_wl='-Wl,' 9869 lt_prog_compiler_pic='-fpic' 9870 lt_prog_compiler_static='-Bstatic' 9871 ;; 9872 esac 9873 ;; 9874 esac 9875 ;; 9876 9877 newsos6) 9878 lt_prog_compiler_pic='-KPIC' 9879 lt_prog_compiler_static='-Bstatic' 9880 ;; 9881 9882 *nto* | *qnx*) 9883 # QNX uses GNU C++, but need to define -shared option too, otherwise 9884 # it will coredump. 9885 lt_prog_compiler_pic='-fPIC -shared' 9886 ;; 9887 9888 osf3* | osf4* | osf5*) 9889 lt_prog_compiler_wl='-Wl,' 9890 # All OSF/1 code is PIC. 9891 lt_prog_compiler_static='-non_shared' 9892 ;; 9893 9894 rdos*) 9895 lt_prog_compiler_static='-non_shared' 9896 ;; 9897 9898 solaris*) 9899 lt_prog_compiler_pic='-KPIC' 9900 lt_prog_compiler_static='-Bstatic' 9901 case $cc_basename in 9902 f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) 9903 lt_prog_compiler_wl='-Qoption ld ';; 9904 *) 9905 lt_prog_compiler_wl='-Wl,';; 9906 esac 9907 ;; 9908 9909 sunos4*) 9910 lt_prog_compiler_wl='-Qoption ld ' 9911 lt_prog_compiler_pic='-PIC' 9912 lt_prog_compiler_static='-Bstatic' 9913 ;; 9914 9915 sysv4 | sysv4.2uw2* | sysv4.3*) 9916 lt_prog_compiler_wl='-Wl,' 9917 lt_prog_compiler_pic='-KPIC' 9918 lt_prog_compiler_static='-Bstatic' 9919 ;; 9920 9921 sysv4*MP*) 9922 if test -d /usr/nec; then 9923 lt_prog_compiler_pic='-Kconform_pic' 9924 lt_prog_compiler_static='-Bstatic' 9925 fi 9926 ;; 9927 9928 sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) 9929 lt_prog_compiler_wl='-Wl,' 9930 lt_prog_compiler_pic='-KPIC' 9931 lt_prog_compiler_static='-Bstatic' 9932 ;; 9933 9934 unicos*) 9935 lt_prog_compiler_wl='-Wl,' 9936 lt_prog_compiler_can_build_shared=no 9937 ;; 9938 9939 uts4*) 9940 lt_prog_compiler_pic='-pic' 9941 lt_prog_compiler_static='-Bstatic' 9942 ;; 9943 9944 *) 9945 lt_prog_compiler_can_build_shared=no 9946 ;; 9947 esac 9948 fi 9949 9950 case $host_os in 9951 # For platforms that do not support PIC, -DPIC is meaningless: 9952 *djgpp*) 9953 lt_prog_compiler_pic= 9954 ;; 9955 *) 9956 lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" 9957 ;; 9958 esac 9959 9960 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 9961 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } 9962 if ${lt_cv_prog_compiler_pic+:} false; then : 9963 $as_echo_n "(cached) " >&6 9964 else 9965 lt_cv_prog_compiler_pic=$lt_prog_compiler_pic 9966 fi 9967 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 9968 $as_echo "$lt_cv_prog_compiler_pic" >&6; } 9969 lt_prog_compiler_pic=$lt_cv_prog_compiler_pic 9970 9971 # 9972 # Check to make sure the PIC flag actually works. 9973 # 9974 if test -n "$lt_prog_compiler_pic"; then 9975 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 9976 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } 9977 if ${lt_cv_prog_compiler_pic_works+:} false; then : 9978 $as_echo_n "(cached) " >&6 9979 else 9980 lt_cv_prog_compiler_pic_works=no 9981 ac_outfile=conftest.$ac_objext 9982 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 9983 lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment 9984 # Insert the option either (1) after the last *FLAGS variable, or 9985 # (2) before a word containing "conftest.", or (3) at the end. 9986 # Note that $ac_compile itself does not contain backslashes and begins 9987 # with a dollar sign (not a hyphen), so the echo should work correctly. 9988 # The option is referenced via a variable to avoid confusing sed. 9989 lt_compile=`echo "$ac_compile" | $SED \ 9990 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ 9991 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ 9992 -e 's:$: $lt_compiler_flag:'` 9993 (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) 9994 (eval "$lt_compile" 2>conftest.err) 9995 ac_status=$? 9996 cat conftest.err >&5 9997 echo "$as_me:$LINENO: \$? = $ac_status" >&5 9998 if (exit $ac_status) && test -s "$ac_outfile"; then 9999 # The compiler can only warn and ignore the option if not recognized 10000 # So say no if there are warnings other than the usual output. 10001 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp 10002 $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 10003 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then 10004 lt_cv_prog_compiler_pic_works=yes 10005 fi 10006 fi 10007 $RM conftest* 10008 10009 fi 10010 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 10011 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } 10012 10013 if test yes = "$lt_cv_prog_compiler_pic_works"; then 10014 case $lt_prog_compiler_pic in 10015 "" | " "*) ;; 10016 *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; 10017 esac 10018 else 10019 lt_prog_compiler_pic= 10020 lt_prog_compiler_can_build_shared=no 10021 fi 10022 10023 fi 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 # 10036 # Check to make sure the static flag actually works. 10037 # 10038 wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" 10039 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 10040 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } 10041 if ${lt_cv_prog_compiler_static_works+:} false; then : 10042 $as_echo_n "(cached) " >&6 10043 else 10044 lt_cv_prog_compiler_static_works=no 10045 save_LDFLAGS=$LDFLAGS 10046 LDFLAGS="$LDFLAGS $lt_tmp_static_flag" 10047 echo "$lt_simple_link_test_code" > conftest.$ac_ext 10048 if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then 10049 # The linker can only warn and ignore the option if not recognized 10050 # So say no if there are warnings 10051 if test -s conftest.err; then 10052 # Append any errors to the config.log. 10053 cat conftest.err 1>&5 10054 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp 10055 $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 10056 if diff conftest.exp conftest.er2 >/dev/null; then 10057 lt_cv_prog_compiler_static_works=yes 10058 fi 10059 else 10060 lt_cv_prog_compiler_static_works=yes 10061 fi 10062 fi 10063 $RM -r conftest* 10064 LDFLAGS=$save_LDFLAGS 10065 10066 fi 10067 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 10068 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } 10069 10070 if test yes = "$lt_cv_prog_compiler_static_works"; then 10071 : 10072 else 10073 lt_prog_compiler_static= 10074 fi 10075 10076 10077 10078 10079 10080 10081 10082 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 10083 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } 10084 if ${lt_cv_prog_compiler_c_o+:} false; then : 10085 $as_echo_n "(cached) " >&6 10086 else 10087 lt_cv_prog_compiler_c_o=no 10088 $RM -r conftest 2>/dev/null 10089 mkdir conftest 10090 cd conftest 10091 mkdir out 10092 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 10093 10094 lt_compiler_flag="-o out/conftest2.$ac_objext" 10095 # Insert the option either (1) after the last *FLAGS variable, or 10096 # (2) before a word containing "conftest.", or (3) at the end. 10097 # Note that $ac_compile itself does not contain backslashes and begins 10098 # with a dollar sign (not a hyphen), so the echo should work correctly. 10099 lt_compile=`echo "$ac_compile" | $SED \ 10100 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ 10101 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ 10102 -e 's:$: $lt_compiler_flag:'` 10103 (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) 10104 (eval "$lt_compile" 2>out/conftest.err) 10105 ac_status=$? 10106 cat out/conftest.err >&5 10107 echo "$as_me:$LINENO: \$? = $ac_status" >&5 10108 if (exit $ac_status) && test -s out/conftest2.$ac_objext 10109 then 10110 # The compiler can only warn and ignore the option if not recognized 10111 # So say no if there are warnings 10112 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp 10113 $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 10114 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then 10115 lt_cv_prog_compiler_c_o=yes 10116 fi 10117 fi 10118 chmod u+w . 2>&5 10119 $RM conftest* 10120 # SGI C++ compiler will create directory out/ii_files/ for 10121 # template instantiation 10122 test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files 10123 $RM out/* && rmdir out 10124 cd .. 10125 $RM -r conftest 10126 $RM conftest* 10127 10128 fi 10129 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 10130 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } 10131 10132 10133 10134 10135 10136 10137 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 10138 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } 10139 if ${lt_cv_prog_compiler_c_o+:} false; then : 10140 $as_echo_n "(cached) " >&6 10141 else 10142 lt_cv_prog_compiler_c_o=no 10143 $RM -r conftest 2>/dev/null 10144 mkdir conftest 10145 cd conftest 10146 mkdir out 10147 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 10148 10149 lt_compiler_flag="-o out/conftest2.$ac_objext" 10150 # Insert the option either (1) after the last *FLAGS variable, or 10151 # (2) before a word containing "conftest.", or (3) at the end. 10152 # Note that $ac_compile itself does not contain backslashes and begins 10153 # with a dollar sign (not a hyphen), so the echo should work correctly. 10154 lt_compile=`echo "$ac_compile" | $SED \ 10155 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ 10156 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ 10157 -e 's:$: $lt_compiler_flag:'` 10158 (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) 10159 (eval "$lt_compile" 2>out/conftest.err) 10160 ac_status=$? 10161 cat out/conftest.err >&5 10162 echo "$as_me:$LINENO: \$? = $ac_status" >&5 10163 if (exit $ac_status) && test -s out/conftest2.$ac_objext 10164 then 10165 # The compiler can only warn and ignore the option if not recognized 10166 # So say no if there are warnings 10167 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp 10168 $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 10169 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then 10170 lt_cv_prog_compiler_c_o=yes 10171 fi 10172 fi 10173 chmod u+w . 2>&5 10174 $RM conftest* 10175 # SGI C++ compiler will create directory out/ii_files/ for 10176 # template instantiation 10177 test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files 10178 $RM out/* && rmdir out 10179 cd .. 10180 $RM -r conftest 10181 $RM conftest* 10182 10183 fi 10184 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 10185 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } 10186 10187 10188 10189 10190 hard_links=nottested 10191 if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then 10192 # do not overwrite the value of need_locks provided by the user 10193 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 10194 $as_echo_n "checking if we can lock with hard links... " >&6; } 10195 hard_links=yes 10196 $RM conftest* 10197 ln conftest.a conftest.b 2>/dev/null && hard_links=no 10198 touch conftest.a 10199 ln conftest.a conftest.b 2>&5 || hard_links=no 10200 ln conftest.a conftest.b 2>/dev/null && hard_links=no 10201 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 10202 $as_echo "$hard_links" >&6; } 10203 if test no = "$hard_links"; then 10204 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 10205 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} 10206 need_locks=warn 10207 fi 10208 else 10209 need_locks=no 10210 fi 10211 10212 10213 10214 10215 10216 10217 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 10218 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } 10219 10220 runpath_var= 10221 allow_undefined_flag= 10222 always_export_symbols=no 10223 archive_cmds= 10224 archive_expsym_cmds= 10225 compiler_needs_object=no 10226 enable_shared_with_static_runtimes=no 10227 export_dynamic_flag_spec= 10228 export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' 10229 hardcode_automatic=no 10230 hardcode_direct=no 10231 hardcode_direct_absolute=no 10232 hardcode_libdir_flag_spec= 10233 hardcode_libdir_separator= 10234 hardcode_minus_L=no 10235 hardcode_shlibpath_var=unsupported 10236 inherit_rpath=no 10237 link_all_deplibs=unknown 10238 module_cmds= 10239 module_expsym_cmds= 10240 old_archive_from_new_cmds= 10241 old_archive_from_expsyms_cmds= 10242 thread_safe_flag_spec= 10243 whole_archive_flag_spec= 10244 # include_expsyms should be a list of space-separated symbols to be *always* 10245 # included in the symbol list 10246 include_expsyms= 10247 # exclude_expsyms can be an extended regexp of symbols to exclude 10248 # it will be wrapped by ' (' and ')$', so one must not match beginning or 10249 # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', 10250 # as well as any symbol that contains 'd'. 10251 exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' 10252 # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out 10253 # platforms (ab)use it in PIC code, but their linkers get confused if 10254 # the symbol is explicitly referenced. Since portable code cannot 10255 # rely on this symbol name, it's probably fine to never include it in 10256 # preloaded symbol tables. 10257 # Exclude shared library initialization/finalization symbols. 10258 extract_expsyms_cmds= 10259 10260 case $host_os in 10261 cygwin* | mingw* | pw32* | cegcc*) 10262 # FIXME: the MSVC++ port hasn't been tested in a loooong time 10263 # When not using gcc, we currently assume that we are using 10264 # Microsoft Visual C++. 10265 if test yes != "$GCC"; then 10266 with_gnu_ld=no 10267 fi 10268 ;; 10269 interix*) 10270 # we just hope/assume this is gcc and not c89 (= MSVC++) 10271 with_gnu_ld=yes 10272 ;; 10273 openbsd* | bitrig*) 10274 with_gnu_ld=no 10275 ;; 10276 linux* | k*bsd*-gnu | gnu*) 10277 link_all_deplibs=no 10278 ;; 10279 esac 10280 10281 ld_shlibs=yes 10282 10283 # On some targets, GNU ld is compatible enough with the native linker 10284 # that we're better off using the native interface for both. 10285 lt_use_gnu_ld_interface=no 10286 if test yes = "$with_gnu_ld"; then 10287 case $host_os in 10288 aix*) 10289 # The AIX port of GNU ld has always aspired to compatibility 10290 # with the native linker. However, as the warning in the GNU ld 10291 # block says, versions before 2.19.5* couldn't really create working 10292 # shared libraries, regardless of the interface used. 10293 case `$LD -v 2>&1` in 10294 *\ \(GNU\ Binutils\)\ 2.19.5*) ;; 10295 *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; 10296 *\ \(GNU\ Binutils\)\ [3-9]*) ;; 10297 *) 10298 lt_use_gnu_ld_interface=yes 10299 ;; 10300 esac 10301 ;; 10302 *) 10303 lt_use_gnu_ld_interface=yes 10304 ;; 10305 esac 10306 fi 10307 10308 if test yes = "$lt_use_gnu_ld_interface"; then 10309 # If archive_cmds runs LD, not CC, wlarc should be empty 10310 wlarc='$wl' 10311 10312 # Set some defaults for GNU ld with shared library support. These 10313 # are reset later if shared libraries are not supported. Putting them 10314 # here allows them to be overridden if necessary. 10315 runpath_var=LD_RUN_PATH 10316 hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 10317 export_dynamic_flag_spec='$wl--export-dynamic' 10318 # ancient GNU ld didn't support --whole-archive et. al. 10319 if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then 10320 whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' 10321 else 10322 whole_archive_flag_spec= 10323 fi 10324 supports_anon_versioning=no 10325 case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in 10326 *GNU\ gold*) supports_anon_versioning=yes ;; 10327 *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 10328 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... 10329 *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... 10330 *\ 2.11.*) ;; # other 2.11 versions 10331 *) supports_anon_versioning=yes ;; 10332 esac 10333 10334 # See if GNU ld supports shared libraries. 10335 case $host_os in 10336 aix[3-9]*) 10337 # On AIX/PPC, the GNU linker is very broken 10338 if test ia64 != "$host_cpu"; then 10339 ld_shlibs=no 10340 cat <<_LT_EOF 1>&2 10341 10342 *** Warning: the GNU linker, at least up to release 2.19, is reported 10343 *** to be unable to reliably create shared libraries on AIX. 10344 *** Therefore, libtool is disabling shared libraries support. If you 10345 *** really care for shared libraries, you may want to install binutils 10346 *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. 10347 *** You will then need to restart the configuration process. 10348 10349 _LT_EOF 10350 fi 10351 ;; 10352 10353 amigaos*) 10354 case $host_cpu in 10355 powerpc) 10356 # see comment about AmigaOS4 .so support 10357 archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10358 archive_expsym_cmds='' 10359 ;; 10360 m68k) 10361 archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' 10362 hardcode_libdir_flag_spec='-L$libdir' 10363 hardcode_minus_L=yes 10364 ;; 10365 esac 10366 ;; 10367 10368 beos*) 10369 if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then 10370 allow_undefined_flag=unsupported 10371 # Joseph Beckenbach <jrb3@best.com> says some releases of gcc 10372 # support --undefined. This deserves some investigation. FIXME 10373 archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10374 else 10375 ld_shlibs=no 10376 fi 10377 ;; 10378 10379 cygwin* | mingw* | pw32* | cegcc*) 10380 # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, 10381 # as there is no search path for DLLs. 10382 hardcode_libdir_flag_spec='-L$libdir' 10383 export_dynamic_flag_spec='$wl--export-all-symbols' 10384 allow_undefined_flag=unsupported 10385 always_export_symbols=no 10386 enable_shared_with_static_runtimes=yes 10387 export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' 10388 exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' 10389 10390 if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then 10391 archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' 10392 # If the export-symbols file already is a .def file, use it as 10393 # is; otherwise, prepend EXPORTS... 10394 archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then 10395 cp $export_symbols $output_objdir/$soname.def; 10396 else 10397 echo EXPORTS > $output_objdir/$soname.def; 10398 cat $export_symbols >> $output_objdir/$soname.def; 10399 fi~ 10400 $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' 10401 else 10402 ld_shlibs=no 10403 fi 10404 ;; 10405 10406 haiku*) 10407 archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10408 link_all_deplibs=yes 10409 ;; 10410 10411 os2*) 10412 hardcode_libdir_flag_spec='-L$libdir' 10413 hardcode_minus_L=yes 10414 allow_undefined_flag=unsupported 10415 shrext_cmds=.dll 10416 archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ 10417 $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ 10418 $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ 10419 $ECHO EXPORTS >> $output_objdir/$libname.def~ 10420 emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ 10421 $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ 10422 emximp -o $lib $output_objdir/$libname.def' 10423 archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ 10424 $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ 10425 $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ 10426 $ECHO EXPORTS >> $output_objdir/$libname.def~ 10427 prefix_cmds="$SED"~ 10428 if test EXPORTS = "`$SED 1q $export_symbols`"; then 10429 prefix_cmds="$prefix_cmds -e 1d"; 10430 fi~ 10431 prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ 10432 cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ 10433 $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ 10434 emximp -o $lib $output_objdir/$libname.def' 10435 old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' 10436 enable_shared_with_static_runtimes=yes 10437 ;; 10438 10439 interix[3-9]*) 10440 hardcode_direct=no 10441 hardcode_shlibpath_var=no 10442 hardcode_libdir_flag_spec='$wl-rpath,$libdir' 10443 export_dynamic_flag_spec='$wl-E' 10444 # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. 10445 # Instead, shared libraries are loaded at an image base (0x10000000 by 10446 # default) and relocated if they conflict, which is a slow very memory 10447 # consuming and fragmenting process. To avoid this, we pick a random, 10448 # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link 10449 # time. Moving up from 0x10000000 also allows more sbrk(2) space. 10450 archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' 10451 archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' 10452 ;; 10453 10454 gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) 10455 tmp_diet=no 10456 if test linux-dietlibc = "$host_os"; then 10457 case $cc_basename in 10458 diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) 10459 esac 10460 fi 10461 if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ 10462 && test no = "$tmp_diet" 10463 then 10464 tmp_addflag=' $pic_flag' 10465 tmp_sharedflag='-shared' 10466 case $cc_basename,$host_cpu in 10467 pgcc*) # Portland Group C compiler 10468 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' 10469 tmp_addflag=' $pic_flag' 10470 ;; 10471 pgf77* | pgf90* | pgf95* | pgfortran*) 10472 # Portland Group f77 and f90 compilers 10473 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' 10474 tmp_addflag=' $pic_flag -Mnomain' ;; 10475 ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 10476 tmp_addflag=' -i_dynamic' ;; 10477 efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 10478 tmp_addflag=' -i_dynamic -nofor_main' ;; 10479 ifc* | ifort*) # Intel Fortran compiler 10480 tmp_addflag=' -nofor_main' ;; 10481 lf95*) # Lahey Fortran 8.1 10482 whole_archive_flag_spec= 10483 tmp_sharedflag='--shared' ;; 10484 nagfor*) # NAGFOR 5.3 10485 tmp_sharedflag='-Wl,-shared' ;; 10486 xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) 10487 tmp_sharedflag='-qmkshrobj' 10488 tmp_addflag= ;; 10489 nvcc*) # Cuda Compiler Driver 2.2 10490 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' 10491 compiler_needs_object=yes 10492 ;; 10493 esac 10494 case `$CC -V 2>&1 | sed 5q` in 10495 *Sun\ C*) # Sun C 5.9 10496 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' 10497 compiler_needs_object=yes 10498 tmp_sharedflag='-G' ;; 10499 *Sun\ F*) # Sun Fortran 8.3 10500 tmp_sharedflag='-G' ;; 10501 esac 10502 archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10503 10504 if test yes = "$supports_anon_versioning"; then 10505 archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ 10506 cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ 10507 echo "local: *; };" >> $output_objdir/$libname.ver~ 10508 $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' 10509 fi 10510 10511 case $cc_basename in 10512 tcc*) 10513 export_dynamic_flag_spec='-rdynamic' 10514 ;; 10515 xlf* | bgf* | bgxlf* | mpixlf*) 10516 # IBM XL Fortran 10.1 on PPC cannot create shared libs itself 10517 whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' 10518 hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 10519 archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' 10520 if test yes = "$supports_anon_versioning"; then 10521 archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ 10522 cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ 10523 echo "local: *; };" >> $output_objdir/$libname.ver~ 10524 $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' 10525 fi 10526 ;; 10527 esac 10528 else 10529 ld_shlibs=no 10530 fi 10531 ;; 10532 10533 netbsd* | netbsdelf*-gnu) 10534 if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then 10535 archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' 10536 wlarc= 10537 else 10538 archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10539 archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 10540 fi 10541 ;; 10542 10543 solaris*) 10544 if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then 10545 ld_shlibs=no 10546 cat <<_LT_EOF 1>&2 10547 10548 *** Warning: The releases 2.8.* of the GNU linker cannot reliably 10549 *** create shared libraries on Solaris systems. Therefore, libtool 10550 *** is disabling shared libraries support. We urge you to upgrade GNU 10551 *** binutils to release 2.9.1 or newer. Another option is to modify 10552 *** your PATH or compiler configuration so that the native linker is 10553 *** used, and then restart. 10554 10555 _LT_EOF 10556 elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then 10557 archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10558 archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 10559 else 10560 ld_shlibs=no 10561 fi 10562 ;; 10563 10564 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) 10565 case `$LD -v 2>&1` in 10566 *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) 10567 ld_shlibs=no 10568 cat <<_LT_EOF 1>&2 10569 10570 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot 10571 *** reliably create shared libraries on SCO systems. Therefore, libtool 10572 *** is disabling shared libraries support. We urge you to upgrade GNU 10573 *** binutils to release 2.16.91.0.3 or newer. Another option is to modify 10574 *** your PATH or compiler configuration so that the native linker is 10575 *** used, and then restart. 10576 10577 _LT_EOF 10578 ;; 10579 *) 10580 # For security reasons, it is highly recommended that you always 10581 # use absolute paths for naming shared libraries, and exclude the 10582 # DT_RUNPATH tag from executables and libraries. But doing so 10583 # requires that you compile everything twice, which is a pain. 10584 if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then 10585 hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 10586 archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10587 archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 10588 else 10589 ld_shlibs=no 10590 fi 10591 ;; 10592 esac 10593 ;; 10594 10595 sunos4*) 10596 archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' 10597 wlarc= 10598 hardcode_direct=yes 10599 hardcode_shlibpath_var=no 10600 ;; 10601 10602 *) 10603 if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then 10604 archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10605 archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 10606 else 10607 ld_shlibs=no 10608 fi 10609 ;; 10610 esac 10611 10612 if test no = "$ld_shlibs"; then 10613 runpath_var= 10614 hardcode_libdir_flag_spec= 10615 export_dynamic_flag_spec= 10616 whole_archive_flag_spec= 10617 fi 10618 else 10619 # PORTME fill in a description of your system's linker (not GNU ld) 10620 case $host_os in 10621 aix3*) 10622 allow_undefined_flag=unsupported 10623 always_export_symbols=yes 10624 archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' 10625 # Note: this linker hardcodes the directories in LIBPATH if there 10626 # are no directories specified by -L. 10627 hardcode_minus_L=yes 10628 if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then 10629 # Neither direct hardcoding nor static linking is supported with a 10630 # broken collect2. 10631 hardcode_direct=unsupported 10632 fi 10633 ;; 10634 10635 aix[4-9]*) 10636 if test ia64 = "$host_cpu"; then 10637 # On IA64, the linker does run time linking by default, so we don't 10638 # have to do anything special. 10639 aix_use_runtimelinking=no 10640 exp_sym_flag='-Bexport' 10641 no_entry_flag= 10642 else 10643 # If we're using GNU nm, then we don't want the "-C" option. 10644 # -C means demangle to GNU nm, but means don't demangle to AIX nm. 10645 # Without the "-l" option, or with the "-B" option, AIX nm treats 10646 # weak defined symbols like other global defined symbols, whereas 10647 # GNU nm marks them as "W". 10648 # While the 'weak' keyword is ignored in the Export File, we need 10649 # it in the Import File for the 'aix-soname' feature, so we have 10650 # to replace the "-B" option with "-P" for AIX nm. 10651 if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then 10652 export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' 10653 else 10654 export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' 10655 fi 10656 aix_use_runtimelinking=no 10657 10658 # Test if we are trying to use run time linking or normal 10659 # AIX style linking. If -brtl is somewhere in LDFLAGS, we 10660 # have runtime linking enabled, and use it for executables. 10661 # For shared libraries, we enable/disable runtime linking 10662 # depending on the kind of the shared library created - 10663 # when "with_aix_soname,aix_use_runtimelinking" is: 10664 # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables 10665 # "aix,yes" lib.so shared, rtl:yes, for executables 10666 # lib.a static archive 10667 # "both,no" lib.so.V(shr.o) shared, rtl:yes 10668 # lib.a(lib.so.V) shared, rtl:no, for executables 10669 # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables 10670 # lib.a(lib.so.V) shared, rtl:no 10671 # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables 10672 # lib.a static archive 10673 case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) 10674 for ld_flag in $LDFLAGS; do 10675 if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then 10676 aix_use_runtimelinking=yes 10677 break 10678 fi 10679 done 10680 if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then 10681 # With aix-soname=svr4, we create the lib.so.V shared archives only, 10682 # so we don't have lib.a shared libs to link our executables. 10683 # We have to force runtime linking in this case. 10684 aix_use_runtimelinking=yes 10685 LDFLAGS="$LDFLAGS -Wl,-brtl" 10686 fi 10687 ;; 10688 esac 10689 10690 exp_sym_flag='-bexport' 10691 no_entry_flag='-bnoentry' 10692 fi 10693 10694 # When large executables or shared objects are built, AIX ld can 10695 # have problems creating the table of contents. If linking a library 10696 # or program results in "error TOC overflow" add -mminimal-toc to 10697 # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not 10698 # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. 10699 10700 archive_cmds='' 10701 hardcode_direct=yes 10702 hardcode_direct_absolute=yes 10703 hardcode_libdir_separator=':' 10704 link_all_deplibs=yes 10705 file_list_spec='$wl-f,' 10706 case $with_aix_soname,$aix_use_runtimelinking in 10707 aix,*) ;; # traditional, no import file 10708 svr4,* | *,yes) # use import file 10709 # The Import File defines what to hardcode. 10710 hardcode_direct=no 10711 hardcode_direct_absolute=no 10712 ;; 10713 esac 10714 10715 if test yes = "$GCC"; then 10716 case $host_os in aix4.[012]|aix4.[012].*) 10717 # We only want to do this on AIX 4.2 and lower, the check 10718 # below for broken collect2 doesn't work under 4.3+ 10719 collect2name=`$CC -print-prog-name=collect2` 10720 if test -f "$collect2name" && 10721 strings "$collect2name" | $GREP resolve_lib_name >/dev/null 10722 then 10723 # We have reworked collect2 10724 : 10725 else 10726 # We have old collect2 10727 hardcode_direct=unsupported 10728 # It fails to find uninstalled libraries when the uninstalled 10729 # path is not listed in the libpath. Setting hardcode_minus_L 10730 # to unsupported forces relinking 10731 hardcode_minus_L=yes 10732 hardcode_libdir_flag_spec='-L$libdir' 10733 hardcode_libdir_separator= 10734 fi 10735 ;; 10736 esac 10737 shared_flag='-shared' 10738 if test yes = "$aix_use_runtimelinking"; then 10739 shared_flag="$shared_flag "'$wl-G' 10740 fi 10741 # Need to ensure runtime linking is disabled for the traditional 10742 # shared library, or the linker may eventually find shared libraries 10743 # /with/ Import File - we do not want to mix them. 10744 shared_flag_aix='-shared' 10745 shared_flag_svr4='-shared $wl-G' 10746 else 10747 # not using gcc 10748 if test ia64 = "$host_cpu"; then 10749 # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release 10750 # chokes on -Wl,-G. The following line is correct: 10751 shared_flag='-G' 10752 else 10753 if test yes = "$aix_use_runtimelinking"; then 10754 shared_flag='$wl-G' 10755 else 10756 shared_flag='$wl-bM:SRE' 10757 fi 10758 shared_flag_aix='$wl-bM:SRE' 10759 shared_flag_svr4='$wl-G' 10760 fi 10761 fi 10762 10763 export_dynamic_flag_spec='$wl-bexpall' 10764 # It seems that -bexpall does not export symbols beginning with 10765 # underscore (_), so it is better to generate a list of symbols to export. 10766 always_export_symbols=yes 10767 if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then 10768 # Warning - without using the other runtime loading flags (-brtl), 10769 # -berok will link without error, but may produce a broken library. 10770 allow_undefined_flag='-berok' 10771 # Determine the default libpath from the value encoded in an 10772 # empty executable. 10773 if test set = "${lt_cv_aix_libpath+set}"; then 10774 aix_libpath=$lt_cv_aix_libpath 10775 else 10776 if ${lt_cv_aix_libpath_+:} false; then : 5818 10777 $as_echo_n "(cached) " >&6 5819 10778 else 5820 10779 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5821 10780 /* end confdefs.h. */ 5822 #include <alloca.h> 10781 5823 10782 int 5824 10783 main () 5825 10784 { 5826 char *p = (char *) alloca (2 * sizeof (int)); 5827 if (p) return 0; 10785 5828 10786 ; 5829 10787 return 0; … … 5831 10789 _ACEOF 5832 10790 if ac_fn_c_try_link "$LINENO"; then : 5833 ac_cv_working_alloca_h=yes 5834 else 5835 ac_cv_working_alloca_h=no 10791 10792 lt_aix_libpath_sed=' 10793 /Import File Strings/,/^$/ { 10794 /^0/ { 10795 s/^0 *\([^ ]*\) *$/\1/ 10796 p 10797 } 10798 }' 10799 lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 10800 # Check for a 64-bit object if we didn't find anything. 10801 if test -z "$lt_cv_aix_libpath_"; then 10802 lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 10803 fi 5836 10804 fi 5837 10805 rm -f core conftest.err conftest.$ac_objext \ 5838 10806 conftest$ac_exeext conftest.$ac_ext 5839 fi 5840 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 5841 $as_echo "$ac_cv_working_alloca_h" >&6; } 5842 if test $ac_cv_working_alloca_h = yes; then 5843 5844 $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h 5845 5846 fi 5847 5848 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 5849 $as_echo_n "checking for alloca... " >&6; } 5850 if ${ac_cv_func_alloca_works+:} false; then : 10807 if test -z "$lt_cv_aix_libpath_"; then 10808 lt_cv_aix_libpath_=/usr/lib:/lib 10809 fi 10810 10811 fi 10812 10813 aix_libpath=$lt_cv_aix_libpath_ 10814 fi 10815 10816 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" 10817 archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag 10818 else 10819 if test ia64 = "$host_cpu"; then 10820 hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' 10821 allow_undefined_flag="-z nodefs" 10822 archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" 10823 else 10824 # Determine the default libpath from the value encoded in an 10825 # empty executable. 10826 if test set = "${lt_cv_aix_libpath+set}"; then 10827 aix_libpath=$lt_cv_aix_libpath 10828 else 10829 if ${lt_cv_aix_libpath_+:} false; then : 5851 10830 $as_echo_n "(cached) " >&6 5852 10831 else 5853 10832 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5854 10833 /* end confdefs.h. */ 5855 #ifdef __GNUC__5856 # define alloca __builtin_alloca5857 #else5858 # ifdef _MSC_VER5859 # include <malloc.h>5860 # define alloca _alloca5861 # else5862 # ifdef HAVE_ALLOCA_H5863 # include <alloca.h>5864 # else5865 # ifdef _AIX5866 #pragma alloca5867 # else5868 # ifndef alloca /* predefined by HP cc +Olibcalls */5869 void *alloca (size_t);5870 # endif5871 # endif5872 # endif5873 # endif5874 #endif5875 10834 5876 10835 int 5877 10836 main () 5878 10837 { 5879 char *p = (char *) alloca (1); 5880 if (p) return 0; 10838 5881 10839 ; 5882 10840 return 0; … … 5884 10842 _ACEOF 5885 10843 if ac_fn_c_try_link "$LINENO"; then : 5886 ac_cv_func_alloca_works=yes 5887 else 5888 ac_cv_func_alloca_works=no 10844 10845 lt_aix_libpath_sed=' 10846 /Import File Strings/,/^$/ { 10847 /^0/ { 10848 s/^0 *\([^ ]*\) *$/\1/ 10849 p 10850 } 10851 }' 10852 lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 10853 # Check for a 64-bit object if we didn't find anything. 10854 if test -z "$lt_cv_aix_libpath_"; then 10855 lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 10856 fi 5889 10857 fi 5890 10858 rm -f core conftest.err conftest.$ac_objext \ 5891 10859 conftest$ac_exeext conftest.$ac_ext 5892 fi 5893 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 5894 $as_echo "$ac_cv_func_alloca_works" >&6; } 5895 5896 if test $ac_cv_func_alloca_works = yes; then 5897 5898 $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h 5899 5900 else 5901 # The SVR3 libPW and SVR4 libucb both contain incompatible functions 5902 # that cause trouble. Some versions do not even contain alloca or 5903 # contain a buggy version. If you still want to use their alloca, 5904 # use ar to extract alloca.o from them instead of compiling alloca.c. 5905 5906 ALLOCA=\${LIBOBJDIR}alloca.$ac_objext 5907 5908 $as_echo "#define C_ALLOCA 1" >>confdefs.h 5909 5910 5911 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 5912 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } 5913 if ${ac_cv_os_cray+:} false; then : 10860 if test -z "$lt_cv_aix_libpath_"; then 10861 lt_cv_aix_libpath_=/usr/lib:/lib 10862 fi 10863 10864 fi 10865 10866 aix_libpath=$lt_cv_aix_libpath_ 10867 fi 10868 10869 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" 10870 # Warning - without using the other run time loading flags, 10871 # -berok will link without error, but may produce a broken library. 10872 no_undefined_flag=' $wl-bernotok' 10873 allow_undefined_flag=' $wl-berok' 10874 if test yes = "$with_gnu_ld"; then 10875 # We only use this code for GNU lds that support --whole-archive. 10876 whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' 10877 else 10878 # Exported symbols can be pulled into shared objects from archives 10879 whole_archive_flag_spec='$convenience' 10880 fi 10881 archive_cmds_need_lc=yes 10882 archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' 10883 # -brtl affects multiple linker settings, -berok does not and is overridden later 10884 compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' 10885 if test svr4 != "$with_aix_soname"; then 10886 # This is similar to how AIX traditionally builds its shared libraries. 10887 archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' 10888 fi 10889 if test aix != "$with_aix_soname"; then 10890 archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' 10891 else 10892 # used by -dlpreopen to get the symbols 10893 archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' 10894 fi 10895 archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' 10896 fi 10897 fi 10898 ;; 10899 10900 amigaos*) 10901 case $host_cpu in 10902 powerpc) 10903 # see comment about AmigaOS4 .so support 10904 archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 10905 archive_expsym_cmds='' 10906 ;; 10907 m68k) 10908 archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' 10909 hardcode_libdir_flag_spec='-L$libdir' 10910 hardcode_minus_L=yes 10911 ;; 10912 esac 10913 ;; 10914 10915 bsdi[45]*) 10916 export_dynamic_flag_spec=-rdynamic 10917 ;; 10918 10919 cygwin* | mingw* | pw32* | cegcc*) 10920 # When not using gcc, we currently assume that we are using 10921 # Microsoft Visual C++. 10922 # hardcode_libdir_flag_spec is actually meaningless, as there is 10923 # no search path for DLLs. 10924 case $cc_basename in 10925 cl*) 10926 # Native MSVC 10927 hardcode_libdir_flag_spec=' ' 10928 allow_undefined_flag=unsupported 10929 always_export_symbols=yes 10930 file_list_spec='@' 10931 # Tell ltmain to make .lib files, not .a files. 10932 libext=lib 10933 # Tell ltmain to make .dll files, not .so files. 10934 shrext_cmds=.dll 10935 # FIXME: Setting linknames here is a bad hack. 10936 archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' 10937 archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then 10938 cp "$export_symbols" "$output_objdir/$soname.def"; 10939 echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; 10940 else 10941 $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; 10942 fi~ 10943 $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ 10944 linknames=' 10945 # The linker will not automatically build a static lib if we build a DLL. 10946 # _LT_TAGVAR(old_archive_from_new_cmds, )='true' 10947 enable_shared_with_static_runtimes=yes 10948 exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' 10949 export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' 10950 # Don't use ranlib 10951 old_postinstall_cmds='chmod 644 $oldlib' 10952 postlink_cmds='lt_outputfile="@OUTPUT@"~ 10953 lt_tool_outputfile="@TOOL_OUTPUT@"~ 10954 case $lt_outputfile in 10955 *.exe|*.EXE) ;; 10956 *) 10957 lt_outputfile=$lt_outputfile.exe 10958 lt_tool_outputfile=$lt_tool_outputfile.exe 10959 ;; 10960 esac~ 10961 if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then 10962 $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; 10963 $RM "$lt_outputfile.manifest"; 10964 fi' 10965 ;; 10966 *) 10967 # Assume MSVC wrapper 10968 hardcode_libdir_flag_spec=' ' 10969 allow_undefined_flag=unsupported 10970 # Tell ltmain to make .lib files, not .a files. 10971 libext=lib 10972 # Tell ltmain to make .dll files, not .so files. 10973 shrext_cmds=.dll 10974 # FIXME: Setting linknames here is a bad hack. 10975 archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' 10976 # The linker will automatically build a .lib file if we build a DLL. 10977 old_archive_from_new_cmds='true' 10978 # FIXME: Should let the user specify the lib program. 10979 old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' 10980 enable_shared_with_static_runtimes=yes 10981 ;; 10982 esac 10983 ;; 10984 10985 darwin* | rhapsody*) 10986 10987 10988 archive_cmds_need_lc=no 10989 hardcode_direct=no 10990 hardcode_automatic=yes 10991 hardcode_shlibpath_var=unsupported 10992 if test yes = "$lt_cv_ld_force_load"; then 10993 whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' 10994 10995 else 10996 whole_archive_flag_spec='' 10997 fi 10998 link_all_deplibs=yes 10999 allow_undefined_flag=$_lt_dar_allow_undefined 11000 case $cc_basename in 11001 ifort*|nagfor*) _lt_dar_can_shared=yes ;; 11002 *) _lt_dar_can_shared=$GCC ;; 11003 esac 11004 if test yes = "$_lt_dar_can_shared"; then 11005 output_verbose_link_cmd=func_echo_all 11006 archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" 11007 module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" 11008 archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" 11009 module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" 11010 11011 else 11012 ld_shlibs=no 11013 fi 11014 11015 ;; 11016 11017 dgux*) 11018 archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' 11019 hardcode_libdir_flag_spec='-L$libdir' 11020 hardcode_shlibpath_var=no 11021 ;; 11022 11023 # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor 11024 # support. Future versions do this automatically, but an explicit c++rt0.o 11025 # does not break anything, and helps significantly (at the cost of a little 11026 # extra space). 11027 freebsd2.2*) 11028 archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' 11029 hardcode_libdir_flag_spec='-R$libdir' 11030 hardcode_direct=yes 11031 hardcode_shlibpath_var=no 11032 ;; 11033 11034 # Unfortunately, older versions of FreeBSD 2 do not have this feature. 11035 freebsd2.*) 11036 archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' 11037 hardcode_direct=yes 11038 hardcode_minus_L=yes 11039 hardcode_shlibpath_var=no 11040 ;; 11041 11042 # FreeBSD 3 and greater uses gcc -shared to do shared libraries. 11043 freebsd* | dragonfly*) 11044 archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' 11045 hardcode_libdir_flag_spec='-R$libdir' 11046 hardcode_direct=yes 11047 hardcode_shlibpath_var=no 11048 ;; 11049 11050 hpux9*) 11051 if test yes = "$GCC"; then 11052 archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' 11053 else 11054 archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' 11055 fi 11056 hardcode_libdir_flag_spec='$wl+b $wl$libdir' 11057 hardcode_libdir_separator=: 11058 hardcode_direct=yes 11059 11060 # hardcode_minus_L: Not really in the search PATH, 11061 # but as the default location of the library. 11062 hardcode_minus_L=yes 11063 export_dynamic_flag_spec='$wl-E' 11064 ;; 11065 11066 hpux10*) 11067 if test yes,no = "$GCC,$with_gnu_ld"; then 11068 archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' 11069 else 11070 archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' 11071 fi 11072 if test no = "$with_gnu_ld"; then 11073 hardcode_libdir_flag_spec='$wl+b $wl$libdir' 11074 hardcode_libdir_separator=: 11075 hardcode_direct=yes 11076 hardcode_direct_absolute=yes 11077 export_dynamic_flag_spec='$wl-E' 11078 # hardcode_minus_L: Not really in the search PATH, 11079 # but as the default location of the library. 11080 hardcode_minus_L=yes 11081 fi 11082 ;; 11083 11084 hpux11*) 11085 if test yes,no = "$GCC,$with_gnu_ld"; then 11086 case $host_cpu in 11087 hppa*64*) 11088 archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' 11089 ;; 11090 ia64*) 11091 archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' 11092 ;; 11093 *) 11094 archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' 11095 ;; 11096 esac 11097 else 11098 case $host_cpu in 11099 hppa*64*) 11100 archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' 11101 ;; 11102 ia64*) 11103 archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' 11104 ;; 11105 *) 11106 11107 # Older versions of the 11.00 compiler do not understand -b yet 11108 # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) 11109 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 11110 $as_echo_n "checking if $CC understands -b... " >&6; } 11111 if ${lt_cv_prog_compiler__b+:} false; then : 5914 11112 $as_echo_n "(cached) " >&6 5915 11113 else 11114 lt_cv_prog_compiler__b=no 11115 save_LDFLAGS=$LDFLAGS 11116 LDFLAGS="$LDFLAGS -b" 11117 echo "$lt_simple_link_test_code" > conftest.$ac_ext 11118 if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then 11119 # The linker can only warn and ignore the option if not recognized 11120 # So say no if there are warnings 11121 if test -s conftest.err; then 11122 # Append any errors to the config.log. 11123 cat conftest.err 1>&5 11124 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp 11125 $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 11126 if diff conftest.exp conftest.er2 >/dev/null; then 11127 lt_cv_prog_compiler__b=yes 11128 fi 11129 else 11130 lt_cv_prog_compiler__b=yes 11131 fi 11132 fi 11133 $RM -r conftest* 11134 LDFLAGS=$save_LDFLAGS 11135 11136 fi 11137 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 11138 $as_echo "$lt_cv_prog_compiler__b" >&6; } 11139 11140 if test yes = "$lt_cv_prog_compiler__b"; then 11141 archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' 11142 else 11143 archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' 11144 fi 11145 11146 ;; 11147 esac 11148 fi 11149 if test no = "$with_gnu_ld"; then 11150 hardcode_libdir_flag_spec='$wl+b $wl$libdir' 11151 hardcode_libdir_separator=: 11152 11153 case $host_cpu in 11154 hppa*64*|ia64*) 11155 hardcode_direct=no 11156 hardcode_shlibpath_var=no 11157 ;; 11158 *) 11159 hardcode_direct=yes 11160 hardcode_direct_absolute=yes 11161 export_dynamic_flag_spec='$wl-E' 11162 11163 # hardcode_minus_L: Not really in the search PATH, 11164 # but as the default location of the library. 11165 hardcode_minus_L=yes 11166 ;; 11167 esac 11168 fi 11169 ;; 11170 11171 irix5* | irix6* | nonstopux*) 11172 if test yes = "$GCC"; then 11173 archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' 11174 # Try to use the -exported_symbol ld option, if it does not 11175 # work, assume that -exports_file does not work either and 11176 # implicitly export all symbols. 11177 # This should be the same for all languages, so no per-tag cache variable. 11178 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 11179 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } 11180 if ${lt_cv_irix_exported_symbol+:} false; then : 11181 $as_echo_n "(cached) " >&6 11182 else 11183 save_LDFLAGS=$LDFLAGS 11184 LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" 11185 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 11186 /* end confdefs.h. */ 11187 int foo (void) { return 0; } 11188 _ACEOF 11189 if ac_fn_c_try_link "$LINENO"; then : 11190 lt_cv_irix_exported_symbol=yes 11191 else 11192 lt_cv_irix_exported_symbol=no 11193 fi 11194 rm -f core conftest.err conftest.$ac_objext \ 11195 conftest$ac_exeext conftest.$ac_ext 11196 LDFLAGS=$save_LDFLAGS 11197 fi 11198 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 11199 $as_echo "$lt_cv_irix_exported_symbol" >&6; } 11200 if test yes = "$lt_cv_irix_exported_symbol"; then 11201 archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' 11202 fi 11203 link_all_deplibs=no 11204 else 11205 archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' 11206 archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' 11207 fi 11208 archive_cmds_need_lc='no' 11209 hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 11210 hardcode_libdir_separator=: 11211 inherit_rpath=yes 11212 link_all_deplibs=yes 11213 ;; 11214 11215 linux*) 11216 case $cc_basename in 11217 tcc*) 11218 # Fabrice Bellard et al's Tiny C Compiler 11219 ld_shlibs=yes 11220 archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' 11221 ;; 11222 esac 11223 ;; 11224 11225 netbsd* | netbsdelf*-gnu) 11226 if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then 11227 archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out 11228 else 11229 archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF 11230 fi 11231 hardcode_libdir_flag_spec='-R$libdir' 11232 hardcode_direct=yes 11233 hardcode_shlibpath_var=no 11234 ;; 11235 11236 newsos6) 11237 archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' 11238 hardcode_direct=yes 11239 hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 11240 hardcode_libdir_separator=: 11241 hardcode_shlibpath_var=no 11242 ;; 11243 11244 *nto* | *qnx*) 11245 ;; 11246 11247 openbsd* | bitrig*) 11248 if test -f /usr/libexec/ld.so; then 11249 hardcode_direct=yes 11250 hardcode_shlibpath_var=no 11251 hardcode_direct_absolute=yes 11252 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then 11253 archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' 11254 archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' 11255 hardcode_libdir_flag_spec='$wl-rpath,$libdir' 11256 export_dynamic_flag_spec='$wl-E' 11257 else 11258 archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' 11259 hardcode_libdir_flag_spec='$wl-rpath,$libdir' 11260 fi 11261 else 11262 ld_shlibs=no 11263 fi 11264 ;; 11265 11266 os2*) 11267 hardcode_libdir_flag_spec='-L$libdir' 11268 hardcode_minus_L=yes 11269 allow_undefined_flag=unsupported 11270 shrext_cmds=.dll 11271 archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ 11272 $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ 11273 $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ 11274 $ECHO EXPORTS >> $output_objdir/$libname.def~ 11275 emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ 11276 $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ 11277 emximp -o $lib $output_objdir/$libname.def' 11278 archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ 11279 $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ 11280 $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ 11281 $ECHO EXPORTS >> $output_objdir/$libname.def~ 11282 prefix_cmds="$SED"~ 11283 if test EXPORTS = "`$SED 1q $export_symbols`"; then 11284 prefix_cmds="$prefix_cmds -e 1d"; 11285 fi~ 11286 prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ 11287 cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ 11288 $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ 11289 emximp -o $lib $output_objdir/$libname.def' 11290 old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' 11291 enable_shared_with_static_runtimes=yes 11292 ;; 11293 11294 osf3*) 11295 if test yes = "$GCC"; then 11296 allow_undefined_flag=' $wl-expect_unresolved $wl\*' 11297 archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' 11298 else 11299 allow_undefined_flag=' -expect_unresolved \*' 11300 archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' 11301 fi 11302 archive_cmds_need_lc='no' 11303 hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 11304 hardcode_libdir_separator=: 11305 ;; 11306 11307 osf4* | osf5*) # as osf3* with the addition of -msym flag 11308 if test yes = "$GCC"; then 11309 allow_undefined_flag=' $wl-expect_unresolved $wl\*' 11310 archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' 11311 hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' 11312 else 11313 allow_undefined_flag=' -expect_unresolved \*' 11314 archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' 11315 archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ 11316 $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' 11317 11318 # Both c and cxx compiler support -rpath directly 11319 hardcode_libdir_flag_spec='-rpath $libdir' 11320 fi 11321 archive_cmds_need_lc='no' 11322 hardcode_libdir_separator=: 11323 ;; 11324 11325 solaris*) 11326 no_undefined_flag=' -z defs' 11327 if test yes = "$GCC"; then 11328 wlarc='$wl' 11329 archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' 11330 archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ 11331 $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' 11332 else 11333 case `$CC -V 2>&1` in 11334 *"Compilers 5.0"*) 11335 wlarc='' 11336 archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' 11337 archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ 11338 $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' 11339 ;; 11340 *) 11341 wlarc='$wl' 11342 archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' 11343 archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ 11344 $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' 11345 ;; 11346 esac 11347 fi 11348 hardcode_libdir_flag_spec='-R$libdir' 11349 hardcode_shlibpath_var=no 11350 case $host_os in 11351 solaris2.[0-5] | solaris2.[0-5].*) ;; 11352 *) 11353 # The compiler driver will combine and reorder linker options, 11354 # but understands '-z linker_flag'. GCC discards it without '$wl', 11355 # but is careful enough not to reorder. 11356 # Supported since Solaris 2.6 (maybe 2.5.1?) 11357 if test yes = "$GCC"; then 11358 whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' 11359 else 11360 whole_archive_flag_spec='-z allextract$convenience -z defaultextract' 11361 fi 11362 ;; 11363 esac 11364 link_all_deplibs=yes 11365 ;; 11366 11367 sunos4*) 11368 if test sequent = "$host_vendor"; then 11369 # Use $CC to link under sequent, because it throws in some extra .o 11370 # files that make .init and .fini sections work. 11371 archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' 11372 else 11373 archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' 11374 fi 11375 hardcode_libdir_flag_spec='-L$libdir' 11376 hardcode_direct=yes 11377 hardcode_minus_L=yes 11378 hardcode_shlibpath_var=no 11379 ;; 11380 11381 sysv4) 11382 case $host_vendor in 11383 sni) 11384 archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' 11385 hardcode_direct=yes # is this really true??? 11386 ;; 11387 siemens) 11388 ## LD is ld it makes a PLAMLIB 11389 ## CC just makes a GrossModule. 11390 archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' 11391 reload_cmds='$CC -r -o $output$reload_objs' 11392 hardcode_direct=no 11393 ;; 11394 motorola) 11395 archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' 11396 hardcode_direct=no #Motorola manual says yes, but my tests say they lie 11397 ;; 11398 esac 11399 runpath_var='LD_RUN_PATH' 11400 hardcode_shlibpath_var=no 11401 ;; 11402 11403 sysv4.3*) 11404 archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' 11405 hardcode_shlibpath_var=no 11406 export_dynamic_flag_spec='-Bexport' 11407 ;; 11408 11409 sysv4*MP*) 11410 if test -d /usr/nec; then 11411 archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' 11412 hardcode_shlibpath_var=no 11413 runpath_var=LD_RUN_PATH 11414 hardcode_runpath_var=yes 11415 ld_shlibs=yes 11416 fi 11417 ;; 11418 11419 sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) 11420 no_undefined_flag='$wl-z,text' 11421 archive_cmds_need_lc=no 11422 hardcode_shlibpath_var=no 11423 runpath_var='LD_RUN_PATH' 11424 11425 if test yes = "$GCC"; then 11426 archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11427 archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11428 else 11429 archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11430 archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11431 fi 11432 ;; 11433 11434 sysv5* | sco3.2v5* | sco5v6*) 11435 # Note: We CANNOT use -z defs as we might desire, because we do not 11436 # link with -lc, and that would cause any symbols used from libc to 11437 # always be unresolved, which means just about no library would 11438 # ever link correctly. If we're not using GNU ld we use -z text 11439 # though, which does catch some bad symbols but isn't as heavy-handed 11440 # as -z defs. 11441 no_undefined_flag='$wl-z,text' 11442 allow_undefined_flag='$wl-z,nodefs' 11443 archive_cmds_need_lc=no 11444 hardcode_shlibpath_var=no 11445 hardcode_libdir_flag_spec='$wl-R,$libdir' 11446 hardcode_libdir_separator=':' 11447 link_all_deplibs=yes 11448 export_dynamic_flag_spec='$wl-Bexport' 11449 runpath_var='LD_RUN_PATH' 11450 11451 if test yes = "$GCC"; then 11452 archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11453 archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11454 else 11455 archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11456 archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 11457 fi 11458 ;; 11459 11460 uts4*) 11461 archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' 11462 hardcode_libdir_flag_spec='-L$libdir' 11463 hardcode_shlibpath_var=no 11464 ;; 11465 11466 *) 11467 ld_shlibs=no 11468 ;; 11469 esac 11470 11471 if test sni = "$host_vendor"; then 11472 case $host in 11473 sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) 11474 export_dynamic_flag_spec='$wl-Blargedynsym' 11475 ;; 11476 esac 11477 fi 11478 fi 11479 11480 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 11481 $as_echo "$ld_shlibs" >&6; } 11482 test no = "$ld_shlibs" && can_build_shared=no 11483 11484 with_gnu_ld=$with_gnu_ld 11485 11486 11487 11488 11489 11490 11491 11492 11493 11494 11495 11496 11497 11498 11499 11500 # 11501 # Do we need to explicitly link libc? 11502 # 11503 case "x$archive_cmds_need_lc" in 11504 x|xyes) 11505 # Assume -lc should be added 11506 archive_cmds_need_lc=yes 11507 11508 if test yes,yes = "$GCC,$enable_shared"; then 11509 case $archive_cmds in 11510 *'~'*) 11511 # FIXME: we may have to deal with multi-command sequences. 11512 ;; 11513 '$CC '*) 11514 # Test whether the compiler implicitly links with -lc since on some 11515 # systems, -lgcc has to come before -lc. If gcc already passes -lc 11516 # to ld, don't add -lc before -lgcc. 11517 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 11518 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } 11519 if ${lt_cv_archive_cmds_need_lc+:} false; then : 11520 $as_echo_n "(cached) " >&6 11521 else 11522 $RM conftest* 11523 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 11524 11525 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 11526 (eval $ac_compile) 2>&5 11527 ac_status=$? 11528 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 11529 test $ac_status = 0; } 2>conftest.err; then 11530 soname=conftest 11531 lib=conftest 11532 libobjs=conftest.$ac_objext 11533 deplibs= 11534 wl=$lt_prog_compiler_wl 11535 pic_flag=$lt_prog_compiler_pic 11536 compiler_flags=-v 11537 linker_flags=-v 11538 verstring= 11539 output_objdir=. 11540 libname=conftest 11541 lt_save_allow_undefined_flag=$allow_undefined_flag 11542 allow_undefined_flag= 11543 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 11544 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 11545 ac_status=$? 11546 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 11547 test $ac_status = 0; } 11548 then 11549 lt_cv_archive_cmds_need_lc=no 11550 else 11551 lt_cv_archive_cmds_need_lc=yes 11552 fi 11553 allow_undefined_flag=$lt_save_allow_undefined_flag 11554 else 11555 cat conftest.err 1>&5 11556 fi 11557 $RM conftest* 11558 11559 fi 11560 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 11561 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } 11562 archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc 11563 ;; 11564 esac 11565 fi 11566 ;; 11567 esac 11568 11569 11570 11571 11572 11573 11574 11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599 11600 11601 11602 11603 11604 11605 11606 11607 11608 11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 11721 $as_echo_n "checking dynamic linker characteristics... " >&6; } 11722 11723 if test yes = "$GCC"; then 11724 case $host_os in 11725 darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; 11726 *) lt_awk_arg='/^libraries:/' ;; 11727 esac 11728 case $host_os in 11729 mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; 11730 *) lt_sed_strip_eq='s|=/|/|g' ;; 11731 esac 11732 lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` 11733 case $lt_search_path_spec in 11734 *\;*) 11735 # if the path contains ";" then we assume it to be the separator 11736 # otherwise default to the standard path separator (i.e. ":") - it is 11737 # assumed that no part of a normal pathname contains ";" but that should 11738 # okay in the real world where ";" in dirpaths is itself problematic. 11739 lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` 11740 ;; 11741 *) 11742 lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` 11743 ;; 11744 esac 11745 # Ok, now we have the path, separated by spaces, we can step through it 11746 # and add multilib dir if necessary... 11747 lt_tmp_lt_search_path_spec= 11748 lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` 11749 # ...but if some path component already ends with the multilib dir we assume 11750 # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). 11751 case "$lt_multi_os_dir; $lt_search_path_spec " in 11752 "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) 11753 lt_multi_os_dir= 11754 ;; 11755 esac 11756 for lt_sys_path in $lt_search_path_spec; do 11757 if test -d "$lt_sys_path$lt_multi_os_dir"; then 11758 lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" 11759 elif test -n "$lt_multi_os_dir"; then 11760 test -d "$lt_sys_path" && \ 11761 lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" 11762 fi 11763 done 11764 lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' 11765 BEGIN {RS = " "; FS = "/|\n";} { 11766 lt_foo = ""; 11767 lt_count = 0; 11768 for (lt_i = NF; lt_i > 0; lt_i--) { 11769 if ($lt_i != "" && $lt_i != ".") { 11770 if ($lt_i == "..") { 11771 lt_count++; 11772 } else { 11773 if (lt_count == 0) { 11774 lt_foo = "/" $lt_i lt_foo; 11775 } else { 11776 lt_count--; 11777 } 11778 } 11779 } 11780 } 11781 if (lt_foo != "") { lt_freq[lt_foo]++; } 11782 if (lt_freq[lt_foo] == 1) { print lt_foo; } 11783 }'` 11784 # AWK program above erroneously prepends '/' to C:/dos/paths 11785 # for these hosts. 11786 case $host_os in 11787 mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ 11788 $SED 's|/\([A-Za-z]:\)|\1|g'` ;; 11789 esac 11790 sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` 11791 else 11792 sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" 11793 fi 11794 library_names_spec= 11795 libname_spec='lib$name' 11796 soname_spec= 11797 shrext_cmds=.so 11798 postinstall_cmds= 11799 postuninstall_cmds= 11800 finish_cmds= 11801 finish_eval= 11802 shlibpath_var= 11803 shlibpath_overrides_runpath=unknown 11804 version_type=none 11805 dynamic_linker="$host_os ld.so" 11806 sys_lib_dlsearch_path_spec="/lib /usr/lib" 11807 need_lib_prefix=unknown 11808 hardcode_into_libs=no 11809 11810 # when you set need_version to no, make sure it does not cause -set_version 11811 # flags to be left without arguments 11812 need_version=unknown 11813 11814 11815 11816 case $host_os in 11817 aix3*) 11818 version_type=linux # correct to gnu/linux during the next big refactor 11819 library_names_spec='$libname$release$shared_ext$versuffix $libname.a' 11820 shlibpath_var=LIBPATH 11821 11822 # AIX 3 has no versioning support, so we append a major version to the name. 11823 soname_spec='$libname$release$shared_ext$major' 11824 ;; 11825 11826 aix[4-9]*) 11827 version_type=linux # correct to gnu/linux during the next big refactor 11828 need_lib_prefix=no 11829 need_version=no 11830 hardcode_into_libs=yes 11831 if test ia64 = "$host_cpu"; then 11832 # AIX 5 supports IA64 11833 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' 11834 shlibpath_var=LD_LIBRARY_PATH 11835 else 11836 # With GCC up to 2.95.x, collect2 would create an import file 11837 # for dependence libraries. The import file would start with 11838 # the line '#! .'. This would cause the generated library to 11839 # depend on '.', always an invalid library. This was fixed in 11840 # development snapshots of GCC prior to 3.0. 11841 case $host_os in 11842 aix4 | aix4.[01] | aix4.[01].*) 11843 if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' 11844 echo ' yes ' 11845 echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then 11846 : 11847 else 11848 can_build_shared=no 11849 fi 11850 ;; 11851 esac 11852 # Using Import Files as archive members, it is possible to support 11853 # filename-based versioning of shared library archives on AIX. While 11854 # this would work for both with and without runtime linking, it will 11855 # prevent static linking of such archives. So we do filename-based 11856 # shared library versioning with .so extension only, which is used 11857 # when both runtime linking and shared linking is enabled. 11858 # Unfortunately, runtime linking may impact performance, so we do 11859 # not want this to be the default eventually. Also, we use the 11860 # versioned .so libs for executables only if there is the -brtl 11861 # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. 11862 # To allow for filename-based versioning support, we need to create 11863 # libNAME.so.V as an archive file, containing: 11864 # *) an Import File, referring to the versioned filename of the 11865 # archive as well as the shared archive member, telling the 11866 # bitwidth (32 or 64) of that shared object, and providing the 11867 # list of exported symbols of that shared object, eventually 11868 # decorated with the 'weak' keyword 11869 # *) the shared object with the F_LOADONLY flag set, to really avoid 11870 # it being seen by the linker. 11871 # At run time we better use the real file rather than another symlink, 11872 # but for link time we create the symlink libNAME.so -> libNAME.so.V 11873 11874 case $with_aix_soname,$aix_use_runtimelinking in 11875 # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct 11876 # soname into executable. Probably we can add versioning support to 11877 # collect2, so additional links can be useful in future. 11878 aix,yes) # traditional libtool 11879 dynamic_linker='AIX unversionable lib.so' 11880 # If using run time linking (on AIX 4.2 or later) use lib<name>.so 11881 # instead of lib<name>.a to let people know that these are not 11882 # typical AIX shared libraries. 11883 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 11884 ;; 11885 aix,no) # traditional AIX only 11886 dynamic_linker='AIX lib.a(lib.so.V)' 11887 # We preserve .a as extension for shared libraries through AIX4.2 11888 # and later when we are not doing run time linking. 11889 library_names_spec='$libname$release.a $libname.a' 11890 soname_spec='$libname$release$shared_ext$major' 11891 ;; 11892 svr4,*) # full svr4 only 11893 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" 11894 library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' 11895 # We do not specify a path in Import Files, so LIBPATH fires. 11896 shlibpath_overrides_runpath=yes 11897 ;; 11898 *,yes) # both, prefer svr4 11899 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" 11900 library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' 11901 # unpreferred sharedlib libNAME.a needs extra handling 11902 postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' 11903 postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' 11904 # We do not specify a path in Import Files, so LIBPATH fires. 11905 shlibpath_overrides_runpath=yes 11906 ;; 11907 *,no) # both, prefer aix 11908 dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" 11909 library_names_spec='$libname$release.a $libname.a' 11910 soname_spec='$libname$release$shared_ext$major' 11911 # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling 11912 postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' 11913 postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' 11914 ;; 11915 esac 11916 shlibpath_var=LIBPATH 11917 fi 11918 ;; 11919 11920 amigaos*) 11921 case $host_cpu in 11922 powerpc) 11923 # Since July 2007 AmigaOS4 officially supports .so libraries. 11924 # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. 11925 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 11926 ;; 11927 m68k) 11928 library_names_spec='$libname.ixlibrary $libname.a' 11929 # Create ${libname}_ixlibrary.a entries in /sys/libs. 11930 finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' 11931 ;; 11932 esac 11933 ;; 11934 11935 beos*) 11936 library_names_spec='$libname$shared_ext' 11937 dynamic_linker="$host_os ld.so" 11938 shlibpath_var=LIBRARY_PATH 11939 ;; 11940 11941 bsdi[45]*) 11942 version_type=linux # correct to gnu/linux during the next big refactor 11943 need_version=no 11944 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 11945 soname_spec='$libname$release$shared_ext$major' 11946 finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' 11947 shlibpath_var=LD_LIBRARY_PATH 11948 sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" 11949 sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" 11950 # the default ld.so.conf also contains /usr/contrib/lib and 11951 # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow 11952 # libtool to hard-code these into programs 11953 ;; 11954 11955 cygwin* | mingw* | pw32* | cegcc*) 11956 version_type=windows 11957 shrext_cmds=.dll 11958 need_version=no 11959 need_lib_prefix=no 11960 11961 case $GCC,$cc_basename in 11962 yes,*) 11963 # gcc 11964 library_names_spec='$libname.dll.a' 11965 # DLL is installed to $(libdir)/../bin by postinstall_cmds 11966 postinstall_cmds='base_file=`basename \$file`~ 11967 dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ 11968 dldir=$destdir/`dirname \$dlpath`~ 11969 test -d \$dldir || mkdir -p \$dldir~ 11970 $install_prog $dir/$dlname \$dldir/$dlname~ 11971 chmod a+x \$dldir/$dlname~ 11972 if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then 11973 eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; 11974 fi' 11975 postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ 11976 dlpath=$dir/\$dldll~ 11977 $RM \$dlpath' 11978 shlibpath_overrides_runpath=yes 11979 11980 case $host_os in 11981 cygwin*) 11982 # Cygwin DLLs use 'cyg' prefix rather than 'lib' 11983 soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 11984 11985 sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" 11986 ;; 11987 mingw* | cegcc*) 11988 # MinGW DLLs use traditional 'lib' prefix 11989 soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 11990 ;; 11991 pw32*) 11992 # pw32 DLLs use 'pw' prefix rather than 'lib' 11993 library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 11994 ;; 11995 esac 11996 dynamic_linker='Win32 ld.exe' 11997 ;; 11998 11999 *,cl*) 12000 # Native MSVC 12001 libname_spec='$name' 12002 soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 12003 library_names_spec='$libname.dll.lib' 12004 12005 case $build_os in 12006 mingw*) 12007 sys_lib_search_path_spec= 12008 lt_save_ifs=$IFS 12009 IFS=';' 12010 for lt_path in $LIB 12011 do 12012 IFS=$lt_save_ifs 12013 # Let DOS variable expansion print the short 8.3 style file name. 12014 lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` 12015 sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" 12016 done 12017 IFS=$lt_save_ifs 12018 # Convert to MSYS style. 12019 sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` 12020 ;; 12021 cygwin*) 12022 # Convert to unix form, then to dos form, then back to unix form 12023 # but this time dos style (no spaces!) so that the unix form looks 12024 # like /cygdrive/c/PROGRA~1:/cygdr... 12025 sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` 12026 sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` 12027 sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` 12028 ;; 12029 *) 12030 sys_lib_search_path_spec=$LIB 12031 if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then 12032 # It is most probably a Windows format PATH. 12033 sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` 12034 else 12035 sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` 12036 fi 12037 # FIXME: find the short name or the path components, as spaces are 12038 # common. (e.g. "Program Files" -> "PROGRA~1") 12039 ;; 12040 esac 12041 12042 # DLL is installed to $(libdir)/../bin by postinstall_cmds 12043 postinstall_cmds='base_file=`basename \$file`~ 12044 dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ 12045 dldir=$destdir/`dirname \$dlpath`~ 12046 test -d \$dldir || mkdir -p \$dldir~ 12047 $install_prog $dir/$dlname \$dldir/$dlname' 12048 postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ 12049 dlpath=$dir/\$dldll~ 12050 $RM \$dlpath' 12051 shlibpath_overrides_runpath=yes 12052 dynamic_linker='Win32 link.exe' 12053 ;; 12054 12055 *) 12056 # Assume MSVC wrapper 12057 library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' 12058 dynamic_linker='Win32 ld.exe' 12059 ;; 12060 esac 12061 # FIXME: first we should search . and the directory the executable is in 12062 shlibpath_var=PATH 12063 ;; 12064 12065 darwin* | rhapsody*) 12066 dynamic_linker="$host_os dyld" 12067 version_type=darwin 12068 need_lib_prefix=no 12069 need_version=no 12070 library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' 12071 soname_spec='$libname$release$major$shared_ext' 12072 shlibpath_overrides_runpath=yes 12073 shlibpath_var=DYLD_LIBRARY_PATH 12074 shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' 12075 12076 sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" 12077 sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' 12078 ;; 12079 12080 dgux*) 12081 version_type=linux # correct to gnu/linux during the next big refactor 12082 need_lib_prefix=no 12083 need_version=no 12084 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12085 soname_spec='$libname$release$shared_ext$major' 12086 shlibpath_var=LD_LIBRARY_PATH 12087 ;; 12088 12089 freebsd* | dragonfly*) 12090 # DragonFly does not have aout. When/if they implement a new 12091 # versioning mechanism, adjust this. 12092 if test -x /usr/bin/objformat; then 12093 objformat=`/usr/bin/objformat` 12094 else 12095 case $host_os in 12096 freebsd[23].*) objformat=aout ;; 12097 *) objformat=elf ;; 12098 esac 12099 fi 12100 version_type=freebsd-$objformat 12101 case $version_type in 12102 freebsd-elf*) 12103 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12104 soname_spec='$libname$release$shared_ext$major' 12105 need_version=no 12106 need_lib_prefix=no 12107 ;; 12108 freebsd-*) 12109 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 12110 need_version=yes 12111 ;; 12112 esac 12113 shlibpath_var=LD_LIBRARY_PATH 12114 case $host_os in 12115 freebsd2.*) 12116 shlibpath_overrides_runpath=yes 12117 ;; 12118 freebsd3.[01]* | freebsdelf3.[01]*) 12119 shlibpath_overrides_runpath=yes 12120 hardcode_into_libs=yes 12121 ;; 12122 freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ 12123 freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) 12124 shlibpath_overrides_runpath=no 12125 hardcode_into_libs=yes 12126 ;; 12127 *) # from 4.6 on, and DragonFly 12128 shlibpath_overrides_runpath=yes 12129 hardcode_into_libs=yes 12130 ;; 12131 esac 12132 ;; 12133 12134 haiku*) 12135 version_type=linux # correct to gnu/linux during the next big refactor 12136 need_lib_prefix=no 12137 need_version=no 12138 dynamic_linker="$host_os runtime_loader" 12139 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12140 soname_spec='$libname$release$shared_ext$major' 12141 shlibpath_var=LIBRARY_PATH 12142 shlibpath_overrides_runpath=no 12143 sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' 12144 hardcode_into_libs=yes 12145 ;; 12146 12147 hpux9* | hpux10* | hpux11*) 12148 # Give a soname corresponding to the major version so that dld.sl refuses to 12149 # link against other versions. 12150 version_type=sunos 12151 need_lib_prefix=no 12152 need_version=no 12153 case $host_cpu in 12154 ia64*) 12155 shrext_cmds='.so' 12156 hardcode_into_libs=yes 12157 dynamic_linker="$host_os dld.so" 12158 shlibpath_var=LD_LIBRARY_PATH 12159 shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. 12160 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12161 soname_spec='$libname$release$shared_ext$major' 12162 if test 32 = "$HPUX_IA64_MODE"; then 12163 sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" 12164 sys_lib_dlsearch_path_spec=/usr/lib/hpux32 12165 else 12166 sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" 12167 sys_lib_dlsearch_path_spec=/usr/lib/hpux64 12168 fi 12169 ;; 12170 hppa*64*) 12171 shrext_cmds='.sl' 12172 hardcode_into_libs=yes 12173 dynamic_linker="$host_os dld.sl" 12174 shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH 12175 shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. 12176 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12177 soname_spec='$libname$release$shared_ext$major' 12178 sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" 12179 sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 12180 ;; 12181 *) 12182 shrext_cmds='.sl' 12183 dynamic_linker="$host_os dld.sl" 12184 shlibpath_var=SHLIB_PATH 12185 shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH 12186 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12187 soname_spec='$libname$release$shared_ext$major' 12188 ;; 12189 esac 12190 # HP-UX runs *really* slowly unless shared libraries are mode 555, ... 12191 postinstall_cmds='chmod 555 $lib' 12192 # or fails outright, so override atomically: 12193 install_override_mode=555 12194 ;; 12195 12196 interix[3-9]*) 12197 version_type=linux # correct to gnu/linux during the next big refactor 12198 need_lib_prefix=no 12199 need_version=no 12200 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12201 soname_spec='$libname$release$shared_ext$major' 12202 dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' 12203 shlibpath_var=LD_LIBRARY_PATH 12204 shlibpath_overrides_runpath=no 12205 hardcode_into_libs=yes 12206 ;; 12207 12208 irix5* | irix6* | nonstopux*) 12209 case $host_os in 12210 nonstopux*) version_type=nonstopux ;; 12211 *) 12212 if test yes = "$lt_cv_prog_gnu_ld"; then 12213 version_type=linux # correct to gnu/linux during the next big refactor 12214 else 12215 version_type=irix 12216 fi ;; 12217 esac 12218 need_lib_prefix=no 12219 need_version=no 12220 soname_spec='$libname$release$shared_ext$major' 12221 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' 12222 case $host_os in 12223 irix5* | nonstopux*) 12224 libsuff= shlibsuff= 12225 ;; 12226 *) 12227 case $LD in # libtool.m4 will add one of these switches to LD 12228 *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") 12229 libsuff= shlibsuff= libmagic=32-bit;; 12230 *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") 12231 libsuff=32 shlibsuff=N32 libmagic=N32;; 12232 *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") 12233 libsuff=64 shlibsuff=64 libmagic=64-bit;; 12234 *) libsuff= shlibsuff= libmagic=never-match;; 12235 esac 12236 ;; 12237 esac 12238 shlibpath_var=LD_LIBRARY${shlibsuff}_PATH 12239 shlibpath_overrides_runpath=no 12240 sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" 12241 sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" 12242 hardcode_into_libs=yes 12243 ;; 12244 12245 # No shared lib support for Linux oldld, aout, or coff. 12246 linux*oldld* | linux*aout* | linux*coff*) 12247 dynamic_linker=no 12248 ;; 12249 12250 linux*android*) 12251 version_type=none # Android doesn't support versioned libraries. 12252 need_lib_prefix=no 12253 need_version=no 12254 library_names_spec='$libname$release$shared_ext' 12255 soname_spec='$libname$release$shared_ext' 12256 finish_cmds= 12257 shlibpath_var=LD_LIBRARY_PATH 12258 shlibpath_overrides_runpath=yes 12259 12260 # This implies no fast_install, which is unacceptable. 12261 # Some rework will be needed to allow for fast_install 12262 # before this can be enabled. 12263 hardcode_into_libs=yes 12264 12265 dynamic_linker='Android linker' 12266 # Don't embed -rpath directories since the linker doesn't support them. 12267 hardcode_libdir_flag_spec='-L$libdir' 12268 ;; 12269 12270 # This must be glibc/ELF. 12271 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) 12272 version_type=linux # correct to gnu/linux during the next big refactor 12273 need_lib_prefix=no 12274 need_version=no 12275 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12276 soname_spec='$libname$release$shared_ext$major' 12277 finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' 12278 shlibpath_var=LD_LIBRARY_PATH 12279 shlibpath_overrides_runpath=no 12280 12281 # Some binutils ld are patched to set DT_RUNPATH 12282 if ${lt_cv_shlibpath_overrides_runpath+:} false; then : 12283 $as_echo_n "(cached) " >&6 12284 else 12285 lt_cv_shlibpath_overrides_runpath=no 12286 save_LDFLAGS=$LDFLAGS 12287 save_libdir=$libdir 12288 eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ 12289 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" 12290 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 12291 /* end confdefs.h. */ 12292 12293 int 12294 main () 12295 { 12296 12297 ; 12298 return 0; 12299 } 12300 _ACEOF 12301 if ac_fn_c_try_link "$LINENO"; then : 12302 if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : 12303 lt_cv_shlibpath_overrides_runpath=yes 12304 fi 12305 fi 12306 rm -f core conftest.err conftest.$ac_objext \ 12307 conftest$ac_exeext conftest.$ac_ext 12308 LDFLAGS=$save_LDFLAGS 12309 libdir=$save_libdir 12310 12311 fi 12312 12313 shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath 12314 12315 # This implies no fast_install, which is unacceptable. 12316 # Some rework will be needed to allow for fast_install 12317 # before this can be enabled. 12318 hardcode_into_libs=yes 12319 12320 # Ideally, we could use ldconfig to report *all* directores which are 12321 # searched for libraries, however this is still not possible. Aside from not 12322 # being certain /sbin/ldconfig is available, command 12323 # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, 12324 # even though it is searched at run-time. Try to do the best guess by 12325 # appending ld.so.conf contents (and includes) to the search path. 12326 if test -f /etc/ld.so.conf; then 12327 lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` 12328 sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" 12329 fi 12330 12331 # We used to test for /lib/ld.so.1 and disable shared libraries on 12332 # powerpc, because MkLinux only supported shared libraries with the 12333 # GNU dynamic linker. Since this was broken with cross compilers, 12334 # most powerpc-linux boxes support dynamic linking these days and 12335 # people can always --disable-shared, the test was removed, and we 12336 # assume the GNU/Linux dynamic linker is in use. 12337 dynamic_linker='GNU/Linux ld.so' 12338 ;; 12339 12340 netbsdelf*-gnu) 12341 version_type=linux 12342 need_lib_prefix=no 12343 need_version=no 12344 library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' 12345 soname_spec='${libname}${release}${shared_ext}$major' 12346 shlibpath_var=LD_LIBRARY_PATH 12347 shlibpath_overrides_runpath=no 12348 hardcode_into_libs=yes 12349 dynamic_linker='NetBSD ld.elf_so' 12350 ;; 12351 12352 netbsd*) 12353 version_type=sunos 12354 need_lib_prefix=no 12355 need_version=no 12356 if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then 12357 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 12358 finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' 12359 dynamic_linker='NetBSD (a.out) ld.so' 12360 else 12361 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12362 soname_spec='$libname$release$shared_ext$major' 12363 dynamic_linker='NetBSD ld.elf_so' 12364 fi 12365 shlibpath_var=LD_LIBRARY_PATH 12366 shlibpath_overrides_runpath=yes 12367 hardcode_into_libs=yes 12368 ;; 12369 12370 newsos6) 12371 version_type=linux # correct to gnu/linux during the next big refactor 12372 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12373 shlibpath_var=LD_LIBRARY_PATH 12374 shlibpath_overrides_runpath=yes 12375 ;; 12376 12377 *nto* | *qnx*) 12378 version_type=qnx 12379 need_lib_prefix=no 12380 need_version=no 12381 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12382 soname_spec='$libname$release$shared_ext$major' 12383 shlibpath_var=LD_LIBRARY_PATH 12384 shlibpath_overrides_runpath=no 12385 hardcode_into_libs=yes 12386 dynamic_linker='ldqnx.so' 12387 ;; 12388 12389 openbsd* | bitrig*) 12390 version_type=sunos 12391 sys_lib_dlsearch_path_spec=/usr/lib 12392 need_lib_prefix=no 12393 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then 12394 need_version=no 12395 else 12396 need_version=yes 12397 fi 12398 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 12399 finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' 12400 shlibpath_var=LD_LIBRARY_PATH 12401 shlibpath_overrides_runpath=yes 12402 ;; 12403 12404 os2*) 12405 libname_spec='$name' 12406 version_type=windows 12407 shrext_cmds=.dll 12408 need_version=no 12409 need_lib_prefix=no 12410 # OS/2 can only load a DLL with a base name of 8 characters or less. 12411 soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; 12412 v=$($ECHO $release$versuffix | tr -d .-); 12413 n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); 12414 $ECHO $n$v`$shared_ext' 12415 library_names_spec='${libname}_dll.$libext' 12416 dynamic_linker='OS/2 ld.exe' 12417 shlibpath_var=BEGINLIBPATH 12418 sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" 12419 sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 12420 postinstall_cmds='base_file=`basename \$file`~ 12421 dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ 12422 dldir=$destdir/`dirname \$dlpath`~ 12423 test -d \$dldir || mkdir -p \$dldir~ 12424 $install_prog $dir/$dlname \$dldir/$dlname~ 12425 chmod a+x \$dldir/$dlname~ 12426 if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then 12427 eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; 12428 fi' 12429 postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ 12430 dlpath=$dir/\$dldll~ 12431 $RM \$dlpath' 12432 ;; 12433 12434 osf3* | osf4* | osf5*) 12435 version_type=osf 12436 need_lib_prefix=no 12437 need_version=no 12438 soname_spec='$libname$release$shared_ext$major' 12439 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12440 shlibpath_var=LD_LIBRARY_PATH 12441 sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" 12442 sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 12443 ;; 12444 12445 rdos*) 12446 dynamic_linker=no 12447 ;; 12448 12449 solaris*) 12450 version_type=linux # correct to gnu/linux during the next big refactor 12451 need_lib_prefix=no 12452 need_version=no 12453 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12454 soname_spec='$libname$release$shared_ext$major' 12455 shlibpath_var=LD_LIBRARY_PATH 12456 shlibpath_overrides_runpath=yes 12457 hardcode_into_libs=yes 12458 # ldd complains unless libraries are executable 12459 postinstall_cmds='chmod +x $lib' 12460 ;; 12461 12462 sunos4*) 12463 version_type=sunos 12464 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 12465 finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' 12466 shlibpath_var=LD_LIBRARY_PATH 12467 shlibpath_overrides_runpath=yes 12468 if test yes = "$with_gnu_ld"; then 12469 need_lib_prefix=no 12470 fi 12471 need_version=yes 12472 ;; 12473 12474 sysv4 | sysv4.3*) 12475 version_type=linux # correct to gnu/linux during the next big refactor 12476 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12477 soname_spec='$libname$release$shared_ext$major' 12478 shlibpath_var=LD_LIBRARY_PATH 12479 case $host_vendor in 12480 sni) 12481 shlibpath_overrides_runpath=no 12482 need_lib_prefix=no 12483 runpath_var=LD_RUN_PATH 12484 ;; 12485 siemens) 12486 need_lib_prefix=no 12487 ;; 12488 motorola) 12489 need_lib_prefix=no 12490 need_version=no 12491 shlibpath_overrides_runpath=no 12492 sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' 12493 ;; 12494 esac 12495 ;; 12496 12497 sysv4*MP*) 12498 if test -d /usr/nec; then 12499 version_type=linux # correct to gnu/linux during the next big refactor 12500 library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' 12501 soname_spec='$libname$shared_ext.$major' 12502 shlibpath_var=LD_LIBRARY_PATH 12503 fi 12504 ;; 12505 12506 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) 12507 version_type=sco 12508 need_lib_prefix=no 12509 need_version=no 12510 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' 12511 soname_spec='$libname$release$shared_ext$major' 12512 shlibpath_var=LD_LIBRARY_PATH 12513 shlibpath_overrides_runpath=yes 12514 hardcode_into_libs=yes 12515 if test yes = "$with_gnu_ld"; then 12516 sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' 12517 else 12518 sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' 12519 case $host_os in 12520 sco3.2v5*) 12521 sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" 12522 ;; 12523 esac 12524 fi 12525 sys_lib_dlsearch_path_spec='/usr/lib' 12526 ;; 12527 12528 tpf*) 12529 # TPF is a cross-target only. Preferred cross-host = GNU/Linux. 12530 version_type=linux # correct to gnu/linux during the next big refactor 12531 need_lib_prefix=no 12532 need_version=no 12533 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12534 shlibpath_var=LD_LIBRARY_PATH 12535 shlibpath_overrides_runpath=no 12536 hardcode_into_libs=yes 12537 ;; 12538 12539 uts4*) 12540 version_type=linux # correct to gnu/linux during the next big refactor 12541 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 12542 soname_spec='$libname$release$shared_ext$major' 12543 shlibpath_var=LD_LIBRARY_PATH 12544 ;; 12545 12546 *) 12547 dynamic_linker=no 12548 ;; 12549 esac 12550 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 12551 $as_echo "$dynamic_linker" >&6; } 12552 test no = "$dynamic_linker" && can_build_shared=no 12553 12554 variables_saved_for_relink="PATH $shlibpath_var $runpath_var" 12555 if test yes = "$GCC"; then 12556 variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" 12557 fi 12558 12559 if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then 12560 sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec 12561 fi 12562 12563 if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then 12564 sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec 12565 fi 12566 12567 # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... 12568 configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec 12569 12570 # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code 12571 func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" 12572 12573 # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool 12574 configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH 12575 12576 12577 12578 12579 12580 12581 12582 12583 12584 12585 12586 12587 12588 12589 12590 12591 12592 12593 12594 12595 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 12673 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } 12674 hardcode_action= 12675 if test -n "$hardcode_libdir_flag_spec" || 12676 test -n "$runpath_var" || 12677 test yes = "$hardcode_automatic"; then 12678 12679 # We can hardcode non-existent directories. 12680 if test no != "$hardcode_direct" && 12681 # If the only mechanism to avoid hardcoding is shlibpath_var, we 12682 # have to relink, otherwise we might link with an installed library 12683 # when we should be linking with a yet-to-be-installed one 12684 ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && 12685 test no != "$hardcode_minus_L"; then 12686 # Linking always hardcodes the temporary library directory. 12687 hardcode_action=relink 12688 else 12689 # We can link without hardcoding, and we can hardcode nonexisting dirs. 12690 hardcode_action=immediate 12691 fi 12692 else 12693 # We cannot hardcode anything, or else we can only hardcode existing 12694 # directories. 12695 hardcode_action=unsupported 12696 fi 12697 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 12698 $as_echo "$hardcode_action" >&6; } 12699 12700 if test relink = "$hardcode_action" || 12701 test yes = "$inherit_rpath"; then 12702 # Fast installation is not supported 12703 enable_fast_install=no 12704 elif test yes = "$shlibpath_overrides_runpath" || 12705 test no = "$enable_shared"; then 12706 # Fast installation is not necessary 12707 enable_fast_install=needless 12708 fi 12709 12710 12711 12712 12713 12714 12715 if test yes != "$enable_dlopen"; then 12716 enable_dlopen=unknown 12717 enable_dlopen_self=unknown 12718 enable_dlopen_self_static=unknown 12719 else 12720 lt_cv_dlopen=no 12721 lt_cv_dlopen_libs= 12722 12723 case $host_os in 12724 beos*) 12725 lt_cv_dlopen=load_add_on 12726 lt_cv_dlopen_libs= 12727 lt_cv_dlopen_self=yes 12728 ;; 12729 12730 mingw* | pw32* | cegcc*) 12731 lt_cv_dlopen=LoadLibrary 12732 lt_cv_dlopen_libs= 12733 ;; 12734 12735 cygwin*) 12736 lt_cv_dlopen=dlopen 12737 lt_cv_dlopen_libs= 12738 ;; 12739 12740 darwin*) 12741 # if libdl is installed we need to link against it 12742 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 12743 $as_echo_n "checking for dlopen in -ldl... " >&6; } 12744 if ${ac_cv_lib_dl_dlopen+:} false; then : 12745 $as_echo_n "(cached) " >&6 12746 else 12747 ac_check_lib_save_LIBS=$LIBS 12748 LIBS="-ldl $LIBS" 12749 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 12750 /* end confdefs.h. */ 12751 12752 /* Override any GCC internal prototype to avoid an error. 12753 Use char because int might match the return type of a GCC 12754 builtin and then its argument prototype would still apply. */ 12755 #ifdef __cplusplus 12756 extern "C" 12757 #endif 12758 char dlopen (); 12759 int 12760 main () 12761 { 12762 return dlopen (); 12763 ; 12764 return 0; 12765 } 12766 _ACEOF 12767 if ac_fn_c_try_link "$LINENO"; then : 12768 ac_cv_lib_dl_dlopen=yes 12769 else 12770 ac_cv_lib_dl_dlopen=no 12771 fi 12772 rm -f core conftest.err conftest.$ac_objext \ 12773 conftest$ac_exeext conftest.$ac_ext 12774 LIBS=$ac_check_lib_save_LIBS 12775 fi 12776 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 12777 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } 12778 if test "x$ac_cv_lib_dl_dlopen" = xyes; then : 12779 lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl 12780 else 12781 12782 lt_cv_dlopen=dyld 12783 lt_cv_dlopen_libs= 12784 lt_cv_dlopen_self=yes 12785 12786 fi 12787 12788 ;; 12789 12790 tpf*) 12791 # Don't try to run any link tests for TPF. We know it's impossible 12792 # because TPF is a cross-compiler, and we know how we open DSOs. 12793 lt_cv_dlopen=dlopen 12794 lt_cv_dlopen_libs= 12795 lt_cv_dlopen_self=no 12796 ;; 12797 12798 *) 12799 ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" 12800 if test "x$ac_cv_func_shl_load" = xyes; then : 12801 lt_cv_dlopen=shl_load 12802 else 12803 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 12804 $as_echo_n "checking for shl_load in -ldld... " >&6; } 12805 if ${ac_cv_lib_dld_shl_load+:} false; then : 12806 $as_echo_n "(cached) " >&6 12807 else 12808 ac_check_lib_save_LIBS=$LIBS 12809 LIBS="-ldld $LIBS" 12810 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 12811 /* end confdefs.h. */ 12812 12813 /* Override any GCC internal prototype to avoid an error. 12814 Use char because int might match the return type of a GCC 12815 builtin and then its argument prototype would still apply. */ 12816 #ifdef __cplusplus 12817 extern "C" 12818 #endif 12819 char shl_load (); 12820 int 12821 main () 12822 { 12823 return shl_load (); 12824 ; 12825 return 0; 12826 } 12827 _ACEOF 12828 if ac_fn_c_try_link "$LINENO"; then : 12829 ac_cv_lib_dld_shl_load=yes 12830 else 12831 ac_cv_lib_dld_shl_load=no 12832 fi 12833 rm -f core conftest.err conftest.$ac_objext \ 12834 conftest$ac_exeext conftest.$ac_ext 12835 LIBS=$ac_check_lib_save_LIBS 12836 fi 12837 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 12838 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } 12839 if test "x$ac_cv_lib_dld_shl_load" = xyes; then : 12840 lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld 12841 else 12842 ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" 12843 if test "x$ac_cv_func_dlopen" = xyes; then : 12844 lt_cv_dlopen=dlopen 12845 else 12846 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 12847 $as_echo_n "checking for dlopen in -ldl... " >&6; } 12848 if ${ac_cv_lib_dl_dlopen+:} false; then : 12849 $as_echo_n "(cached) " >&6 12850 else 12851 ac_check_lib_save_LIBS=$LIBS 12852 LIBS="-ldl $LIBS" 12853 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 12854 /* end confdefs.h. */ 12855 12856 /* Override any GCC internal prototype to avoid an error. 12857 Use char because int might match the return type of a GCC 12858 builtin and then its argument prototype would still apply. */ 12859 #ifdef __cplusplus 12860 extern "C" 12861 #endif 12862 char dlopen (); 12863 int 12864 main () 12865 { 12866 return dlopen (); 12867 ; 12868 return 0; 12869 } 12870 _ACEOF 12871 if ac_fn_c_try_link "$LINENO"; then : 12872 ac_cv_lib_dl_dlopen=yes 12873 else 12874 ac_cv_lib_dl_dlopen=no 12875 fi 12876 rm -f core conftest.err conftest.$ac_objext \ 12877 conftest$ac_exeext conftest.$ac_ext 12878 LIBS=$ac_check_lib_save_LIBS 12879 fi 12880 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 12881 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } 12882 if test "x$ac_cv_lib_dl_dlopen" = xyes; then : 12883 lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl 12884 else 12885 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 12886 $as_echo_n "checking for dlopen in -lsvld... " >&6; } 12887 if ${ac_cv_lib_svld_dlopen+:} false; then : 12888 $as_echo_n "(cached) " >&6 12889 else 12890 ac_check_lib_save_LIBS=$LIBS 12891 LIBS="-lsvld $LIBS" 12892 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 12893 /* end confdefs.h. */ 12894 12895 /* Override any GCC internal prototype to avoid an error. 12896 Use char because int might match the return type of a GCC 12897 builtin and then its argument prototype would still apply. */ 12898 #ifdef __cplusplus 12899 extern "C" 12900 #endif 12901 char dlopen (); 12902 int 12903 main () 12904 { 12905 return dlopen (); 12906 ; 12907 return 0; 12908 } 12909 _ACEOF 12910 if ac_fn_c_try_link "$LINENO"; then : 12911 ac_cv_lib_svld_dlopen=yes 12912 else 12913 ac_cv_lib_svld_dlopen=no 12914 fi 12915 rm -f core conftest.err conftest.$ac_objext \ 12916 conftest$ac_exeext conftest.$ac_ext 12917 LIBS=$ac_check_lib_save_LIBS 12918 fi 12919 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 12920 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } 12921 if test "x$ac_cv_lib_svld_dlopen" = xyes; then : 12922 lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld 12923 else 12924 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 12925 $as_echo_n "checking for dld_link in -ldld... " >&6; } 12926 if ${ac_cv_lib_dld_dld_link+:} false; then : 12927 $as_echo_n "(cached) " >&6 12928 else 12929 ac_check_lib_save_LIBS=$LIBS 12930 LIBS="-ldld $LIBS" 12931 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 12932 /* end confdefs.h. */ 12933 12934 /* Override any GCC internal prototype to avoid an error. 12935 Use char because int might match the return type of a GCC 12936 builtin and then its argument prototype would still apply. */ 12937 #ifdef __cplusplus 12938 extern "C" 12939 #endif 12940 char dld_link (); 12941 int 12942 main () 12943 { 12944 return dld_link (); 12945 ; 12946 return 0; 12947 } 12948 _ACEOF 12949 if ac_fn_c_try_link "$LINENO"; then : 12950 ac_cv_lib_dld_dld_link=yes 12951 else 12952 ac_cv_lib_dld_dld_link=no 12953 fi 12954 rm -f core conftest.err conftest.$ac_objext \ 12955 conftest$ac_exeext conftest.$ac_ext 12956 LIBS=$ac_check_lib_save_LIBS 12957 fi 12958 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 12959 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } 12960 if test "x$ac_cv_lib_dld_dld_link" = xyes; then : 12961 lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld 12962 fi 12963 12964 12965 fi 12966 12967 12968 fi 12969 12970 12971 fi 12972 12973 12974 fi 12975 12976 12977 fi 12978 12979 ;; 12980 esac 12981 12982 if test no = "$lt_cv_dlopen"; then 12983 enable_dlopen=no 12984 else 12985 enable_dlopen=yes 12986 fi 12987 12988 case $lt_cv_dlopen in 12989 dlopen) 12990 save_CPPFLAGS=$CPPFLAGS 12991 test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" 12992 12993 save_LDFLAGS=$LDFLAGS 12994 wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" 12995 12996 save_LIBS=$LIBS 12997 LIBS="$lt_cv_dlopen_libs $LIBS" 12998 12999 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 13000 $as_echo_n "checking whether a program can dlopen itself... " >&6; } 13001 if ${lt_cv_dlopen_self+:} false; then : 13002 $as_echo_n "(cached) " >&6 13003 else 13004 if test yes = "$cross_compiling"; then : 13005 lt_cv_dlopen_self=cross 13006 else 13007 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 13008 lt_status=$lt_dlunknown 13009 cat > conftest.$ac_ext <<_LT_EOF 13010 #line $LINENO "configure" 13011 #include "confdefs.h" 13012 13013 #if HAVE_DLFCN_H 13014 #include <dlfcn.h> 13015 #endif 13016 13017 #include <stdio.h> 13018 13019 #ifdef RTLD_GLOBAL 13020 # define LT_DLGLOBAL RTLD_GLOBAL 13021 #else 13022 # ifdef DL_GLOBAL 13023 # define LT_DLGLOBAL DL_GLOBAL 13024 # else 13025 # define LT_DLGLOBAL 0 13026 # endif 13027 #endif 13028 13029 /* We may have to define LT_DLLAZY_OR_NOW in the command line if we 13030 find out it does not work in some platform. */ 13031 #ifndef LT_DLLAZY_OR_NOW 13032 # ifdef RTLD_LAZY 13033 # define LT_DLLAZY_OR_NOW RTLD_LAZY 13034 # else 13035 # ifdef DL_LAZY 13036 # define LT_DLLAZY_OR_NOW DL_LAZY 13037 # else 13038 # ifdef RTLD_NOW 13039 # define LT_DLLAZY_OR_NOW RTLD_NOW 13040 # else 13041 # ifdef DL_NOW 13042 # define LT_DLLAZY_OR_NOW DL_NOW 13043 # else 13044 # define LT_DLLAZY_OR_NOW 0 13045 # endif 13046 # endif 13047 # endif 13048 # endif 13049 #endif 13050 13051 /* When -fvisibility=hidden is used, assume the code has been annotated 13052 correspondingly for the symbols needed. */ 13053 #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) 13054 int fnord () __attribute__((visibility("default"))); 13055 #endif 13056 13057 int fnord () { return 42; } 13058 int main () 13059 { 13060 void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); 13061 int status = $lt_dlunknown; 13062 13063 if (self) 13064 { 13065 if (dlsym (self,"fnord")) status = $lt_dlno_uscore; 13066 else 13067 { 13068 if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; 13069 else puts (dlerror ()); 13070 } 13071 /* dlclose (self); */ 13072 } 13073 else 13074 puts (dlerror ()); 13075 13076 return status; 13077 } 13078 _LT_EOF 13079 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 13080 (eval $ac_link) 2>&5 13081 ac_status=$? 13082 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 13083 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then 13084 (./conftest; exit; ) >&5 2>/dev/null 13085 lt_status=$? 13086 case x$lt_status in 13087 x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; 13088 x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; 13089 x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; 13090 esac 13091 else : 13092 # compilation failed 13093 lt_cv_dlopen_self=no 13094 fi 13095 fi 13096 rm -fr conftest* 13097 13098 13099 fi 13100 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 13101 $as_echo "$lt_cv_dlopen_self" >&6; } 13102 13103 if test yes = "$lt_cv_dlopen_self"; then 13104 wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" 13105 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 13106 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } 13107 if ${lt_cv_dlopen_self_static+:} false; then : 13108 $as_echo_n "(cached) " >&6 13109 else 13110 if test yes = "$cross_compiling"; then : 13111 lt_cv_dlopen_self_static=cross 13112 else 13113 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 13114 lt_status=$lt_dlunknown 13115 cat > conftest.$ac_ext <<_LT_EOF 13116 #line $LINENO "configure" 13117 #include "confdefs.h" 13118 13119 #if HAVE_DLFCN_H 13120 #include <dlfcn.h> 13121 #endif 13122 13123 #include <stdio.h> 13124 13125 #ifdef RTLD_GLOBAL 13126 # define LT_DLGLOBAL RTLD_GLOBAL 13127 #else 13128 # ifdef DL_GLOBAL 13129 # define LT_DLGLOBAL DL_GLOBAL 13130 # else 13131 # define LT_DLGLOBAL 0 13132 # endif 13133 #endif 13134 13135 /* We may have to define LT_DLLAZY_OR_NOW in the command line if we 13136 find out it does not work in some platform. */ 13137 #ifndef LT_DLLAZY_OR_NOW 13138 # ifdef RTLD_LAZY 13139 # define LT_DLLAZY_OR_NOW RTLD_LAZY 13140 # else 13141 # ifdef DL_LAZY 13142 # define LT_DLLAZY_OR_NOW DL_LAZY 13143 # else 13144 # ifdef RTLD_NOW 13145 # define LT_DLLAZY_OR_NOW RTLD_NOW 13146 # else 13147 # ifdef DL_NOW 13148 # define LT_DLLAZY_OR_NOW DL_NOW 13149 # else 13150 # define LT_DLLAZY_OR_NOW 0 13151 # endif 13152 # endif 13153 # endif 13154 # endif 13155 #endif 13156 13157 /* When -fvisibility=hidden is used, assume the code has been annotated 13158 correspondingly for the symbols needed. */ 13159 #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) 13160 int fnord () __attribute__((visibility("default"))); 13161 #endif 13162 13163 int fnord () { return 42; } 13164 int main () 13165 { 13166 void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); 13167 int status = $lt_dlunknown; 13168 13169 if (self) 13170 { 13171 if (dlsym (self,"fnord")) status = $lt_dlno_uscore; 13172 else 13173 { 13174 if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; 13175 else puts (dlerror ()); 13176 } 13177 /* dlclose (self); */ 13178 } 13179 else 13180 puts (dlerror ()); 13181 13182 return status; 13183 } 13184 _LT_EOF 13185 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 13186 (eval $ac_link) 2>&5 13187 ac_status=$? 13188 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 13189 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then 13190 (./conftest; exit; ) >&5 2>/dev/null 13191 lt_status=$? 13192 case x$lt_status in 13193 x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; 13194 x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; 13195 x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; 13196 esac 13197 else : 13198 # compilation failed 13199 lt_cv_dlopen_self_static=no 13200 fi 13201 fi 13202 rm -fr conftest* 13203 13204 13205 fi 13206 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 13207 $as_echo "$lt_cv_dlopen_self_static" >&6; } 13208 fi 13209 13210 CPPFLAGS=$save_CPPFLAGS 13211 LDFLAGS=$save_LDFLAGS 13212 LIBS=$save_LIBS 13213 ;; 13214 esac 13215 13216 case $lt_cv_dlopen_self in 13217 yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; 13218 *) enable_dlopen_self=unknown ;; 13219 esac 13220 13221 case $lt_cv_dlopen_self_static in 13222 yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; 13223 *) enable_dlopen_self_static=unknown ;; 13224 esac 13225 fi 13226 13227 13228 13229 13230 13231 13232 13233 13234 13235 13236 13237 13238 13239 13240 13241 13242 13243 striplib= 13244 old_striplib= 13245 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 13246 $as_echo_n "checking whether stripping libraries is possible... " >&6; } 13247 if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then 13248 test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" 13249 test -z "$striplib" && striplib="$STRIP --strip-unneeded" 13250 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 13251 $as_echo "yes" >&6; } 13252 else 13253 # FIXME - insert some real tests, host_os isn't really good enough 13254 case $host_os in 13255 darwin*) 13256 if test -n "$STRIP"; then 13257 striplib="$STRIP -x" 13258 old_striplib="$STRIP -S" 13259 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 13260 $as_echo "yes" >&6; } 13261 else 13262 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 13263 $as_echo "no" >&6; } 13264 fi 13265 ;; 13266 *) 13267 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 13268 $as_echo "no" >&6; } 13269 ;; 13270 esac 13271 fi 13272 13273 13274 13275 13276 13277 13278 13279 13280 13281 13282 13283 13284 # Report what library types will actually be built 13285 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 13286 $as_echo_n "checking if libtool supports shared libraries... " >&6; } 13287 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 13288 $as_echo "$can_build_shared" >&6; } 13289 13290 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 13291 $as_echo_n "checking whether to build shared libraries... " >&6; } 13292 test no = "$can_build_shared" && enable_shared=no 13293 13294 # On AIX, shared libraries and static libraries use the same namespace, and 13295 # are all built from PIC. 13296 case $host_os in 13297 aix3*) 13298 test yes = "$enable_shared" && enable_static=no 13299 if test -n "$RANLIB"; then 13300 archive_cmds="$archive_cmds~\$RANLIB \$lib" 13301 postinstall_cmds='$RANLIB $lib' 13302 fi 13303 ;; 13304 13305 aix[4-9]*) 13306 if test ia64 != "$host_cpu"; then 13307 case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in 13308 yes,aix,yes) ;; # shared object as lib.so file only 13309 yes,svr4,*) ;; # shared object as lib.so archive member only 13310 yes,*) enable_static=no ;; # shared object in lib.a archive as well 13311 esac 13312 fi 13313 ;; 13314 esac 13315 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 13316 $as_echo "$enable_shared" >&6; } 13317 13318 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 13319 $as_echo_n "checking whether to build static libraries... " >&6; } 13320 # Make sure either enable_shared or enable_static is yes. 13321 test yes = "$enable_shared" || enable_static=yes 13322 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 13323 $as_echo "$enable_static" >&6; } 13324 13325 13326 13327 13328 fi 13329 ac_ext=c 13330 ac_cpp='$CPP $CPPFLAGS' 13331 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 13332 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 13333 ac_compiler_gnu=$ac_cv_c_compiler_gnu 13334 13335 CC=$lt_save_CC 13336 13337 if test -n "$CXX" && ( test no != "$CXX" && 13338 ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || 13339 (test g++ != "$CXX"))); then 13340 ac_ext=cpp 13341 ac_cpp='$CXXCPP $CPPFLAGS' 13342 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' 13343 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 13344 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu 13345 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 13346 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } 13347 if test -z "$CXXCPP"; then 13348 if ${ac_cv_prog_CXXCPP+:} false; then : 13349 $as_echo_n "(cached) " >&6 13350 else 13351 # Double quotes because CXXCPP needs to be expanded 13352 for CXXCPP in "$CXX -E" "/lib/cpp" 13353 do 13354 ac_preproc_ok=false 13355 for ac_cxx_preproc_warn_flag in '' yes 13356 do 13357 # Use a header file that comes with gcc, so configuring glibc 13358 # with a fresh cross-compiler works. 13359 # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since 13360 # <limits.h> exists even on freestanding compilers. 13361 # On the NeXT, cc -E runs the code through the compiler's parser, 13362 # not just through cpp. "Syntax error" is here to catch this case. 5916 13363 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5917 13364 /* end confdefs.h. */ 5918 #if defined CRAY && ! defined CRAY25919 webecray 13365 #ifdef __STDC__ 13366 # include <limits.h> 5920 13367 #else 5921 wenotbecray 13368 # include <assert.h> 5922 13369 #endif 5923 13370 Syntax error 5924 13371 _ACEOF 5925 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | 5926 $EGREP "webecray" >/dev/null 2>&1; then : 5927 ac_cv_os_cray=yes 5928 else 5929 ac_cv_os_cray=no 5930 fi 5931 rm -f conftest* 5932 5933 fi 5934 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 5935 $as_echo "$ac_cv_os_cray" >&6; } 5936 if test $ac_cv_os_cray = yes; then 5937 for ac_func in _getb67 GETB67 getb67; do 5938 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` 5939 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" 5940 if eval test \"x\$"$as_ac_var"\" = x"yes"; then : 5941 5942 cat >>confdefs.h <<_ACEOF 5943 #define CRAY_STACKSEG_END $ac_func 5944 _ACEOF 5945 5946 break 5947 fi 5948 5949 done 5950 fi 5951 5952 { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 5953 $as_echo_n "checking stack direction for C alloca... " >&6; } 5954 if ${ac_cv_c_stack_direction+:} false; then : 5955 $as_echo_n "(cached) " >&6 5956 else 5957 if test "$cross_compiling" = yes; then : 5958 ac_cv_c_stack_direction=0 5959 else 13372 if ac_fn_cxx_try_cpp "$LINENO"; then : 13373 13374 else 13375 # Broken: fails on valid input. 13376 continue 13377 fi 13378 rm -f conftest.err conftest.i conftest.$ac_ext 13379 13380 # OK, works on sane cases. Now check whether nonexistent headers 13381 # can be detected and how. 5960 13382 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 5961 13383 /* end confdefs.h. */ 5962 $ac_includes_default 13384 #include <ac_nonexistent.h> 13385 _ACEOF 13386 if ac_fn_cxx_try_cpp "$LINENO"; then : 13387 # Broken: success on invalid input. 13388 continue 13389 else 13390 # Passes both tests. 13391 ac_preproc_ok=: 13392 break 13393 fi 13394 rm -f conftest.err conftest.i conftest.$ac_ext 13395 13396 done 13397 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. 13398 rm -f conftest.i conftest.err conftest.$ac_ext 13399 if $ac_preproc_ok; then : 13400 break 13401 fi 13402 13403 done 13404 ac_cv_prog_CXXCPP=$CXXCPP 13405 13406 fi 13407 CXXCPP=$ac_cv_prog_CXXCPP 13408 else 13409 ac_cv_prog_CXXCPP=$CXXCPP 13410 fi 13411 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 13412 $as_echo "$CXXCPP" >&6; } 13413 ac_preproc_ok=false 13414 for ac_cxx_preproc_warn_flag in '' yes 13415 do 13416 # Use a header file that comes with gcc, so configuring glibc 13417 # with a fresh cross-compiler works. 13418 # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since 13419 # <limits.h> exists even on freestanding compilers. 13420 # On the NeXT, cc -E runs the code through the compiler's parser, 13421 # not just through cpp. "Syntax error" is here to catch this case. 13422 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 13423 /* end confdefs.h. */ 13424 #ifdef __STDC__ 13425 # include <limits.h> 13426 #else 13427 # include <assert.h> 13428 #endif 13429 Syntax error 13430 _ACEOF 13431 if ac_fn_cxx_try_cpp "$LINENO"; then : 13432 13433 else 13434 # Broken: fails on valid input. 13435 continue 13436 fi 13437 rm -f conftest.err conftest.i conftest.$ac_ext 13438 13439 # OK, works on sane cases. Now check whether nonexistent headers 13440 # can be detected and how. 13441 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 13442 /* end confdefs.h. */ 13443 #include <ac_nonexistent.h> 13444 _ACEOF 13445 if ac_fn_cxx_try_cpp "$LINENO"; then : 13446 # Broken: success on invalid input. 13447 continue 13448 else 13449 # Passes both tests. 13450 ac_preproc_ok=: 13451 break 13452 fi 13453 rm -f conftest.err conftest.i conftest.$ac_ext 13454 13455 done 13456 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. 13457 rm -f conftest.i conftest.err conftest.$ac_ext 13458 if $ac_preproc_ok; then : 13459 13460 else 13461 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 13462 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} 13463 as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check 13464 See \`config.log' for more details" "$LINENO" 5; } 13465 fi 13466 13467 ac_ext=c 13468 ac_cpp='$CPP $CPPFLAGS' 13469 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 13470 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 13471 ac_compiler_gnu=$ac_cv_c_compiler_gnu 13472 13473 else 13474 _lt_caught_CXX_error=yes 13475 fi 13476 13477 ac_ext=cpp 13478 ac_cpp='$CXXCPP $CPPFLAGS' 13479 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' 13480 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 13481 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu 13482 13483 archive_cmds_need_lc_CXX=no 13484 allow_undefined_flag_CXX= 13485 always_export_symbols_CXX=no 13486 archive_expsym_cmds_CXX= 13487 compiler_needs_object_CXX=no 13488 export_dynamic_flag_spec_CXX= 13489 hardcode_direct_CXX=no 13490 hardcode_direct_absolute_CXX=no 13491 hardcode_libdir_flag_spec_CXX= 13492 hardcode_libdir_separator_CXX= 13493 hardcode_minus_L_CXX=no 13494 hardcode_shlibpath_var_CXX=unsupported 13495 hardcode_automatic_CXX=no 13496 inherit_rpath_CXX=no 13497 module_cmds_CXX= 13498 module_expsym_cmds_CXX= 13499 link_all_deplibs_CXX=unknown 13500 old_archive_cmds_CXX=$old_archive_cmds 13501 reload_flag_CXX=$reload_flag 13502 reload_cmds_CXX=$reload_cmds 13503 no_undefined_flag_CXX= 13504 whole_archive_flag_spec_CXX= 13505 enable_shared_with_static_runtimes_CXX=no 13506 13507 # Source file extension for C++ test sources. 13508 ac_ext=cpp 13509 13510 # Object file extension for compiled C++ test sources. 13511 objext=o 13512 objext_CXX=$objext 13513 13514 # No sense in running all these tests if we already determined that 13515 # the CXX compiler isn't working. Some variables (like enable_shared) 13516 # are currently assumed to apply to all compilers on this platform, 13517 # and will be corrupted by setting them based on a non-working compiler. 13518 if test yes != "$_lt_caught_CXX_error"; then 13519 # Code to be used in simple compile tests 13520 lt_simple_compile_test_code="int some_variable = 0;" 13521 13522 # Code to be used in simple link tests 13523 lt_simple_link_test_code='int main(int, char *[]) { return(0); }' 13524 13525 # ltmain only uses $CC for tagged configurations so make sure $CC is set. 13526 13527 13528 13529 13530 13531 13532 # If no C compiler was specified, use CC. 13533 LTCC=${LTCC-"$CC"} 13534 13535 # If no C compiler flags were specified, use CFLAGS. 13536 LTCFLAGS=${LTCFLAGS-"$CFLAGS"} 13537 13538 # Allow CC to be a program name with arguments. 13539 compiler=$CC 13540 13541 13542 # save warnings/boilerplate of simple test code 13543 ac_outfile=conftest.$ac_objext 13544 echo "$lt_simple_compile_test_code" >conftest.$ac_ext 13545 eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err 13546 _lt_compiler_boilerplate=`cat conftest.err` 13547 $RM conftest* 13548 13549 ac_outfile=conftest.$ac_objext 13550 echo "$lt_simple_link_test_code" >conftest.$ac_ext 13551 eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err 13552 _lt_linker_boilerplate=`cat conftest.err` 13553 $RM -r conftest* 13554 13555 13556 # Allow CC to be a program name with arguments. 13557 lt_save_CC=$CC 13558 lt_save_CFLAGS=$CFLAGS 13559 lt_save_LD=$LD 13560 lt_save_GCC=$GCC 13561 GCC=$GXX 13562 lt_save_with_gnu_ld=$with_gnu_ld 13563 lt_save_path_LD=$lt_cv_path_LD 13564 if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then 13565 lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx 13566 else 13567 $as_unset lt_cv_prog_gnu_ld 13568 fi 13569 if test -n "${lt_cv_path_LDCXX+set}"; then 13570 lt_cv_path_LD=$lt_cv_path_LDCXX 13571 else 13572 $as_unset lt_cv_path_LD 13573 fi 13574 test -z "${LDCXX+set}" || LD=$LDCXX 13575 CC=${CXX-"c++"} 13576 CFLAGS=$CXXFLAGS 13577 compiler=$CC 13578 compiler_CXX=$CC 13579 func_cc_basename $compiler 13580 cc_basename=$func_cc_basename_result 13581 13582 13583 if test -n "$compiler"; then 13584 # We don't want -fno-exception when compiling C++ code, so set the 13585 # no_builtin_flag separately 13586 if test yes = "$GXX"; then 13587 lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' 13588 else 13589 lt_prog_compiler_no_builtin_flag_CXX= 13590 fi 13591 13592 if test yes = "$GXX"; then 13593 # Set up default GNU C++ configuration 13594 13595 13596 13597 # Check whether --with-gnu-ld was given. 13598 if test "${with_gnu_ld+set}" = set; then : 13599 withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes 13600 else 13601 with_gnu_ld=no 13602 fi 13603 13604 ac_prog=ld 13605 if test yes = "$GCC"; then 13606 # Check if gcc -print-prog-name=ld gives a path. 13607 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 13608 $as_echo_n "checking for ld used by $CC... " >&6; } 13609 case $host in 13610 *-*-mingw*) 13611 # gcc leaves a trailing carriage return, which upsets mingw 13612 ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; 13613 *) 13614 ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; 13615 esac 13616 case $ac_prog in 13617 # Accept absolute paths. 13618 [\\/]* | ?:[\\/]*) 13619 re_direlt='/[^/][^/]*/\.\./' 13620 # Canonicalize the pathname of ld 13621 ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` 13622 while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do 13623 ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` 13624 done 13625 test -z "$LD" && LD=$ac_prog 13626 ;; 13627 "") 13628 # If it fails, then pretend we aren't using GCC. 13629 ac_prog=ld 13630 ;; 13631 *) 13632 # If it is relative, then search for the first ld in PATH. 13633 with_gnu_ld=unknown 13634 ;; 13635 esac 13636 elif test yes = "$with_gnu_ld"; then 13637 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 13638 $as_echo_n "checking for GNU ld... " >&6; } 13639 else 13640 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 13641 $as_echo_n "checking for non-GNU ld... " >&6; } 13642 fi 13643 if ${lt_cv_path_LD+:} false; then : 13644 $as_echo_n "(cached) " >&6 13645 else 13646 if test -z "$LD"; then 13647 lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR 13648 for ac_dir in $PATH; do 13649 IFS=$lt_save_ifs 13650 test -z "$ac_dir" && ac_dir=. 13651 if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then 13652 lt_cv_path_LD=$ac_dir/$ac_prog 13653 # Check to see if the program is GNU ld. I'd rather use --version, 13654 # but apparently some variants of GNU ld only accept -v. 13655 # Break only if it was the GNU/non-GNU ld that we prefer. 13656 case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in 13657 *GNU* | *'with BFD'*) 13658 test no != "$with_gnu_ld" && break 13659 ;; 13660 *) 13661 test yes != "$with_gnu_ld" && break 13662 ;; 13663 esac 13664 fi 13665 done 13666 IFS=$lt_save_ifs 13667 else 13668 lt_cv_path_LD=$LD # Let the user override the test with a path. 13669 fi 13670 fi 13671 13672 LD=$lt_cv_path_LD 13673 if test -n "$LD"; then 13674 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 13675 $as_echo "$LD" >&6; } 13676 else 13677 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 13678 $as_echo "no" >&6; } 13679 fi 13680 test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 13681 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 13682 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } 13683 if ${lt_cv_prog_gnu_ld+:} false; then : 13684 $as_echo_n "(cached) " >&6 13685 else 13686 # I'd rather use --version here, but apparently some GNU lds only accept -v. 13687 case `$LD -v 2>&1 </dev/null` in 13688 *GNU* | *'with BFD'*) 13689 lt_cv_prog_gnu_ld=yes 13690 ;; 13691 *) 13692 lt_cv_prog_gnu_ld=no 13693 ;; 13694 esac 13695 fi 13696 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 13697 $as_echo "$lt_cv_prog_gnu_ld" >&6; } 13698 with_gnu_ld=$lt_cv_prog_gnu_ld 13699 13700 13701 13702 13703 13704 13705 13706 # Check if GNU C++ uses GNU ld as the underlying linker, since the 13707 # archiving commands below assume that GNU ld is being used. 13708 if test yes = "$with_gnu_ld"; then 13709 archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' 13710 archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 13711 13712 hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' 13713 export_dynamic_flag_spec_CXX='$wl--export-dynamic' 13714 13715 # If archive_cmds runs LD, not CC, wlarc should be empty 13716 # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to 13717 # investigate it a little bit more. (MM) 13718 wlarc='$wl' 13719 13720 # ancient GNU ld didn't support --whole-archive et. al. 13721 if eval "`$CC -print-prog-name=ld` --help 2>&1" | 13722 $GREP 'no-whole-archive' > /dev/null; then 13723 whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' 13724 else 13725 whole_archive_flag_spec_CXX= 13726 fi 13727 else 13728 with_gnu_ld=no 13729 wlarc= 13730 13731 # A generic and very simple default shared library creation 13732 # command for GNU C++ for the case where it uses the native 13733 # linker, instead of GNU ld. If possible, this setting should 13734 # overridden to take advantage of the native linker features on 13735 # the platform it is being used on. 13736 archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' 13737 fi 13738 13739 # Commands to make compiler produce verbose output that lists 13740 # what "hidden" libraries, object files and flags are used when 13741 # linking a shared library. 13742 output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' 13743 13744 else 13745 GXX=no 13746 with_gnu_ld=no 13747 wlarc= 13748 fi 13749 13750 # PORTME: fill in a description of your system's C++ link characteristics 13751 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 13752 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } 13753 ld_shlibs_CXX=yes 13754 case $host_os in 13755 aix3*) 13756 # FIXME: insert proper C++ library support 13757 ld_shlibs_CXX=no 13758 ;; 13759 aix[4-9]*) 13760 if test ia64 = "$host_cpu"; then 13761 # On IA64, the linker does run time linking by default, so we don't 13762 # have to do anything special. 13763 aix_use_runtimelinking=no 13764 exp_sym_flag='-Bexport' 13765 no_entry_flag= 13766 else 13767 aix_use_runtimelinking=no 13768 13769 # Test if we are trying to use run time linking or normal 13770 # AIX style linking. If -brtl is somewhere in LDFLAGS, we 13771 # have runtime linking enabled, and use it for executables. 13772 # For shared libraries, we enable/disable runtime linking 13773 # depending on the kind of the shared library created - 13774 # when "with_aix_soname,aix_use_runtimelinking" is: 13775 # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables 13776 # "aix,yes" lib.so shared, rtl:yes, for executables 13777 # lib.a static archive 13778 # "both,no" lib.so.V(shr.o) shared, rtl:yes 13779 # lib.a(lib.so.V) shared, rtl:no, for executables 13780 # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables 13781 # lib.a(lib.so.V) shared, rtl:no 13782 # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables 13783 # lib.a static archive 13784 case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) 13785 for ld_flag in $LDFLAGS; do 13786 case $ld_flag in 13787 *-brtl*) 13788 aix_use_runtimelinking=yes 13789 break 13790 ;; 13791 esac 13792 done 13793 if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then 13794 # With aix-soname=svr4, we create the lib.so.V shared archives only, 13795 # so we don't have lib.a shared libs to link our executables. 13796 # We have to force runtime linking in this case. 13797 aix_use_runtimelinking=yes 13798 LDFLAGS="$LDFLAGS -Wl,-brtl" 13799 fi 13800 ;; 13801 esac 13802 13803 exp_sym_flag='-bexport' 13804 no_entry_flag='-bnoentry' 13805 fi 13806 13807 # When large executables or shared objects are built, AIX ld can 13808 # have problems creating the table of contents. If linking a library 13809 # or program results in "error TOC overflow" add -mminimal-toc to 13810 # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not 13811 # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. 13812 13813 archive_cmds_CXX='' 13814 hardcode_direct_CXX=yes 13815 hardcode_direct_absolute_CXX=yes 13816 hardcode_libdir_separator_CXX=':' 13817 link_all_deplibs_CXX=yes 13818 file_list_spec_CXX='$wl-f,' 13819 case $with_aix_soname,$aix_use_runtimelinking in 13820 aix,*) ;; # no import file 13821 svr4,* | *,yes) # use import file 13822 # The Import File defines what to hardcode. 13823 hardcode_direct_CXX=no 13824 hardcode_direct_absolute_CXX=no 13825 ;; 13826 esac 13827 13828 if test yes = "$GXX"; then 13829 case $host_os in aix4.[012]|aix4.[012].*) 13830 # We only want to do this on AIX 4.2 and lower, the check 13831 # below for broken collect2 doesn't work under 4.3+ 13832 collect2name=`$CC -print-prog-name=collect2` 13833 if test -f "$collect2name" && 13834 strings "$collect2name" | $GREP resolve_lib_name >/dev/null 13835 then 13836 # We have reworked collect2 13837 : 13838 else 13839 # We have old collect2 13840 hardcode_direct_CXX=unsupported 13841 # It fails to find uninstalled libraries when the uninstalled 13842 # path is not listed in the libpath. Setting hardcode_minus_L 13843 # to unsupported forces relinking 13844 hardcode_minus_L_CXX=yes 13845 hardcode_libdir_flag_spec_CXX='-L$libdir' 13846 hardcode_libdir_separator_CXX= 13847 fi 13848 esac 13849 shared_flag='-shared' 13850 if test yes = "$aix_use_runtimelinking"; then 13851 shared_flag=$shared_flag' $wl-G' 13852 fi 13853 # Need to ensure runtime linking is disabled for the traditional 13854 # shared library, or the linker may eventually find shared libraries 13855 # /with/ Import File - we do not want to mix them. 13856 shared_flag_aix='-shared' 13857 shared_flag_svr4='-shared $wl-G' 13858 else 13859 # not using gcc 13860 if test ia64 = "$host_cpu"; then 13861 # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release 13862 # chokes on -Wl,-G. The following line is correct: 13863 shared_flag='-G' 13864 else 13865 if test yes = "$aix_use_runtimelinking"; then 13866 shared_flag='$wl-G' 13867 else 13868 shared_flag='$wl-bM:SRE' 13869 fi 13870 shared_flag_aix='$wl-bM:SRE' 13871 shared_flag_svr4='$wl-G' 13872 fi 13873 fi 13874 13875 export_dynamic_flag_spec_CXX='$wl-bexpall' 13876 # It seems that -bexpall does not export symbols beginning with 13877 # underscore (_), so it is better to generate a list of symbols to 13878 # export. 13879 always_export_symbols_CXX=yes 13880 if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then 13881 # Warning - without using the other runtime loading flags (-brtl), 13882 # -berok will link without error, but may produce a broken library. 13883 # The "-G" linker flag allows undefined symbols. 13884 no_undefined_flag_CXX='-bernotok' 13885 # Determine the default libpath from the value encoded in an empty 13886 # executable. 13887 if test set = "${lt_cv_aix_libpath+set}"; then 13888 aix_libpath=$lt_cv_aix_libpath 13889 else 13890 if ${lt_cv_aix_libpath__CXX+:} false; then : 13891 $as_echo_n "(cached) " >&6 13892 else 13893 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 13894 /* end confdefs.h. */ 13895 5963 13896 int 5964 find_stack_direction (int *addr, int depth)13897 main () 5965 13898 { 5966 int dir, dummy = 0; 5967 if (! addr) 5968 addr = &dummy; 5969 *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; 5970 dir = depth ? find_stack_direction (addr, depth - 1) : 0; 5971 return dir + dummy; 5972 } 5973 5974 int 5975 main (int argc, char **argv) 5976 { 5977 return find_stack_direction (0, argc + !argv + 20) < 0; 13899 13900 ; 13901 return 0; 5978 13902 } 5979 13903 _ACEOF 5980 if ac_fn_c_try_run "$LINENO"; then : 5981 ac_cv_c_stack_direction=1 5982 else 5983 ac_cv_c_stack_direction=-1 5984 fi 5985 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ 5986 conftest.$ac_objext conftest.beam conftest.$ac_ext 5987 fi 5988 5989 fi 5990 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 5991 $as_echo "$ac_cv_c_stack_direction" >&6; } 5992 cat >>confdefs.h <<_ACEOF 5993 #define STACK_DIRECTION $ac_cv_c_stack_direction 13904 if ac_fn_cxx_try_link "$LINENO"; then : 13905 13906 lt_aix_libpath_sed=' 13907 /Import File Strings/,/^$/ { 13908 /^0/ { 13909 s/^0 *\([^ ]*\) *$/\1/ 13910 p 13911 } 13912 }' 13913 lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 13914 # Check for a 64-bit object if we didn't find anything. 13915 if test -z "$lt_cv_aix_libpath__CXX"; then 13916 lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 13917 fi 13918 fi 13919 rm -f core conftest.err conftest.$ac_objext \ 13920 conftest$ac_exeext conftest.$ac_ext 13921 if test -z "$lt_cv_aix_libpath__CXX"; then 13922 lt_cv_aix_libpath__CXX=/usr/lib:/lib 13923 fi 13924 13925 fi 13926 13927 aix_libpath=$lt_cv_aix_libpath__CXX 13928 fi 13929 13930 hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" 13931 13932 archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag 13933 else 13934 if test ia64 = "$host_cpu"; then 13935 hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' 13936 allow_undefined_flag_CXX="-z nodefs" 13937 archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" 13938 else 13939 # Determine the default libpath from the value encoded in an 13940 # empty executable. 13941 if test set = "${lt_cv_aix_libpath+set}"; then 13942 aix_libpath=$lt_cv_aix_libpath 13943 else 13944 if ${lt_cv_aix_libpath__CXX+:} false; then : 13945 $as_echo_n "(cached) " >&6 13946 else 13947 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 13948 /* end confdefs.h. */ 13949 13950 int 13951 main () 13952 { 13953 13954 ; 13955 return 0; 13956 } 5994 13957 _ACEOF 5995 5996 5997 fi 5998 5999 for ac_header in fenv.h float.h inttypes.h libintl.h limits.h malloc.h stddef.h stdlib.h string.h unistd.h 13958 if ac_fn_cxx_try_link "$LINENO"; then : 13959 13960 lt_aix_libpath_sed=' 13961 /Import File Strings/,/^$/ { 13962 /^0/ { 13963 s/^0 *\([^ ]*\) *$/\1/ 13964 p 13965 } 13966 }' 13967 lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 13968 # Check for a 64-bit object if we didn't find anything. 13969 if test -z "$lt_cv_aix_libpath__CXX"; then 13970 lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` 13971 fi 13972 fi 13973 rm -f core conftest.err conftest.$ac_objext \ 13974 conftest$ac_exeext conftest.$ac_ext 13975 if test -z "$lt_cv_aix_libpath__CXX"; then 13976 lt_cv_aix_libpath__CXX=/usr/lib:/lib 13977 fi 13978 13979 fi 13980 13981 aix_libpath=$lt_cv_aix_libpath__CXX 13982 fi 13983 13984 hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" 13985 # Warning - without using the other run time loading flags, 13986 # -berok will link without error, but may produce a broken library. 13987 no_undefined_flag_CXX=' $wl-bernotok' 13988 allow_undefined_flag_CXX=' $wl-berok' 13989 if test yes = "$with_gnu_ld"; then 13990 # We only use this code for GNU lds that support --whole-archive. 13991 whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' 13992 else 13993 # Exported symbols can be pulled into shared objects from archives 13994 whole_archive_flag_spec_CXX='$convenience' 13995 fi 13996 archive_cmds_need_lc_CXX=yes 13997 archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' 13998 # -brtl affects multiple linker settings, -berok does not and is overridden later 13999 compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' 14000 if test svr4 != "$with_aix_soname"; then 14001 # This is similar to how AIX traditionally builds its shared 14002 # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. 14003 archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' 14004 fi 14005 if test aix != "$with_aix_soname"; then 14006 archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' 14007 else 14008 # used by -dlpreopen to get the symbols 14009 archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' 14010 fi 14011 archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' 14012 fi 14013 fi 14014 ;; 14015 14016 beos*) 14017 if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then 14018 allow_undefined_flag_CXX=unsupported 14019 # Joseph Beckenbach <jrb3@best.com> says some releases of gcc 14020 # support --undefined. This deserves some investigation. FIXME 14021 archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 14022 else 14023 ld_shlibs_CXX=no 14024 fi 14025 ;; 14026 14027 chorus*) 14028 case $cc_basename in 14029 *) 14030 # FIXME: insert proper C++ library support 14031 ld_shlibs_CXX=no 14032 ;; 14033 esac 14034 ;; 14035 14036 cygwin* | mingw* | pw32* | cegcc*) 14037 case $GXX,$cc_basename in 14038 ,cl* | no,cl*) 14039 # Native MSVC 14040 # hardcode_libdir_flag_spec is actually meaningless, as there is 14041 # no search path for DLLs. 14042 hardcode_libdir_flag_spec_CXX=' ' 14043 allow_undefined_flag_CXX=unsupported 14044 always_export_symbols_CXX=yes 14045 file_list_spec_CXX='@' 14046 # Tell ltmain to make .lib files, not .a files. 14047 libext=lib 14048 # Tell ltmain to make .dll files, not .so files. 14049 shrext_cmds=.dll 14050 # FIXME: Setting linknames here is a bad hack. 14051 archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' 14052 archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then 14053 cp "$export_symbols" "$output_objdir/$soname.def"; 14054 echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; 14055 else 14056 $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; 14057 fi~ 14058 $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ 14059 linknames=' 14060 # The linker will not automatically build a static lib if we build a DLL. 14061 # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' 14062 enable_shared_with_static_runtimes_CXX=yes 14063 # Don't use ranlib 14064 old_postinstall_cmds_CXX='chmod 644 $oldlib' 14065 postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ 14066 lt_tool_outputfile="@TOOL_OUTPUT@"~ 14067 case $lt_outputfile in 14068 *.exe|*.EXE) ;; 14069 *) 14070 lt_outputfile=$lt_outputfile.exe 14071 lt_tool_outputfile=$lt_tool_outputfile.exe 14072 ;; 14073 esac~ 14074 func_to_tool_file "$lt_outputfile"~ 14075 if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then 14076 $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; 14077 $RM "$lt_outputfile.manifest"; 14078 fi' 14079 ;; 14080 *) 14081 # g++ 14082 # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, 14083 # as there is no search path for DLLs. 14084 hardcode_libdir_flag_spec_CXX='-L$libdir' 14085 export_dynamic_flag_spec_CXX='$wl--export-all-symbols' 14086 allow_undefined_flag_CXX=unsupported 14087 always_export_symbols_CXX=no 14088 enable_shared_with_static_runtimes_CXX=yes 14089 14090 if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then 14091 archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' 14092 # If the export-symbols file already is a .def file, use it as 14093 # is; otherwise, prepend EXPORTS... 14094 archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then 14095 cp $export_symbols $output_objdir/$soname.def; 14096 else 14097 echo EXPORTS > $output_objdir/$soname.def; 14098 cat $export_symbols >> $output_objdir/$soname.def; 14099 fi~ 14100 $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' 14101 else 14102 ld_shlibs_CXX=no 14103 fi 14104 ;; 14105 esac 14106 ;; 14107 darwin* | rhapsody*) 14108 14109 14110 archive_cmds_need_lc_CXX=no 14111 hardcode_direct_CXX=no 14112 hardcode_automatic_CXX=yes 14113 hardcode_shlibpath_var_CXX=unsupported 14114 if test yes = "$lt_cv_ld_force_load"; then 14115 whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' 14116 14117 else 14118 whole_archive_flag_spec_CXX='' 14119 fi 14120 link_all_deplibs_CXX=yes 14121 allow_undefined_flag_CXX=$_lt_dar_allow_undefined 14122 case $cc_basename in 14123 ifort*|nagfor*) _lt_dar_can_shared=yes ;; 14124 *) _lt_dar_can_shared=$GCC ;; 14125 esac 14126 if test yes = "$_lt_dar_can_shared"; then 14127 output_verbose_link_cmd=func_echo_all 14128 archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" 14129 module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" 14130 archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" 14131 module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" 14132 if test yes != "$lt_cv_apple_cc_single_mod"; then 14133 archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" 14134 archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" 14135 fi 14136 14137 else 14138 ld_shlibs_CXX=no 14139 fi 14140 14141 ;; 14142 14143 os2*) 14144 hardcode_libdir_flag_spec_CXX='-L$libdir' 14145 hardcode_minus_L_CXX=yes 14146 allow_undefined_flag_CXX=unsupported 14147 shrext_cmds=.dll 14148 archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ 14149 $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ 14150 $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ 14151 $ECHO EXPORTS >> $output_objdir/$libname.def~ 14152 emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ 14153 $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ 14154 emximp -o $lib $output_objdir/$libname.def' 14155 archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ 14156 $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ 14157 $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ 14158 $ECHO EXPORTS >> $output_objdir/$libname.def~ 14159 prefix_cmds="$SED"~ 14160 if test EXPORTS = "`$SED 1q $export_symbols`"; then 14161 prefix_cmds="$prefix_cmds -e 1d"; 14162 fi~ 14163 prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ 14164 cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ 14165 $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ 14166 emximp -o $lib $output_objdir/$libname.def' 14167 old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' 14168 enable_shared_with_static_runtimes_CXX=yes 14169 ;; 14170 14171 dgux*) 14172 case $cc_basename in 14173 ec++*) 14174 # FIXME: insert proper C++ library support 14175 ld_shlibs_CXX=no 14176 ;; 14177 ghcx*) 14178 # Green Hills C++ Compiler 14179 # FIXME: insert proper C++ library support 14180 ld_shlibs_CXX=no 14181 ;; 14182 *) 14183 # FIXME: insert proper C++ library support 14184 ld_shlibs_CXX=no 14185 ;; 14186 esac 14187 ;; 14188 14189 freebsd2.*) 14190 # C++ shared libraries reported to be fairly broken before 14191 # switch to ELF 14192 ld_shlibs_CXX=no 14193 ;; 14194 14195 freebsd-elf*) 14196 archive_cmds_need_lc_CXX=no 14197 ;; 14198 14199 freebsd* | dragonfly*) 14200 # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF 14201 # conventions 14202 ld_shlibs_CXX=yes 14203 ;; 14204 14205 haiku*) 14206 archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 14207 link_all_deplibs_CXX=yes 14208 ;; 14209 14210 hpux9*) 14211 hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' 14212 hardcode_libdir_separator_CXX=: 14213 export_dynamic_flag_spec_CXX='$wl-E' 14214 hardcode_direct_CXX=yes 14215 hardcode_minus_L_CXX=yes # Not in the search PATH, 14216 # but as the default 14217 # location of the library. 14218 14219 case $cc_basename in 14220 CC*) 14221 # FIXME: insert proper C++ library support 14222 ld_shlibs_CXX=no 14223 ;; 14224 aCC*) 14225 archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' 14226 # Commands to make compiler produce verbose output that lists 14227 # what "hidden" libraries, object files and flags are used when 14228 # linking a shared library. 14229 # 14230 # There doesn't appear to be a way to prevent this compiler from 14231 # explicitly linking system object files so we need to strip them 14232 # from the output so that they don't get included in the library 14233 # dependencies. 14234 output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' 14235 ;; 14236 *) 14237 if test yes = "$GXX"; then 14238 archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' 14239 else 14240 # FIXME: insert proper C++ library support 14241 ld_shlibs_CXX=no 14242 fi 14243 ;; 14244 esac 14245 ;; 14246 14247 hpux10*|hpux11*) 14248 if test no = "$with_gnu_ld"; then 14249 hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' 14250 hardcode_libdir_separator_CXX=: 14251 14252 case $host_cpu in 14253 hppa*64*|ia64*) 14254 ;; 14255 *) 14256 export_dynamic_flag_spec_CXX='$wl-E' 14257 ;; 14258 esac 14259 fi 14260 case $host_cpu in 14261 hppa*64*|ia64*) 14262 hardcode_direct_CXX=no 14263 hardcode_shlibpath_var_CXX=no 14264 ;; 14265 *) 14266 hardcode_direct_CXX=yes 14267 hardcode_direct_absolute_CXX=yes 14268 hardcode_minus_L_CXX=yes # Not in the search PATH, 14269 # but as the default 14270 # location of the library. 14271 ;; 14272 esac 14273 14274 case $cc_basename in 14275 CC*) 14276 # FIXME: insert proper C++ library support 14277 ld_shlibs_CXX=no 14278 ;; 14279 aCC*) 14280 case $host_cpu in 14281 hppa*64*) 14282 archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14283 ;; 14284 ia64*) 14285 archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14286 ;; 14287 *) 14288 archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14289 ;; 14290 esac 14291 # Commands to make compiler produce verbose output that lists 14292 # what "hidden" libraries, object files and flags are used when 14293 # linking a shared library. 14294 # 14295 # There doesn't appear to be a way to prevent this compiler from 14296 # explicitly linking system object files so we need to strip them 14297 # from the output so that they don't get included in the library 14298 # dependencies. 14299 output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' 14300 ;; 14301 *) 14302 if test yes = "$GXX"; then 14303 if test no = "$with_gnu_ld"; then 14304 case $host_cpu in 14305 hppa*64*) 14306 archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14307 ;; 14308 ia64*) 14309 archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14310 ;; 14311 *) 14312 archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14313 ;; 14314 esac 14315 fi 14316 else 14317 # FIXME: insert proper C++ library support 14318 ld_shlibs_CXX=no 14319 fi 14320 ;; 14321 esac 14322 ;; 14323 14324 interix[3-9]*) 14325 hardcode_direct_CXX=no 14326 hardcode_shlibpath_var_CXX=no 14327 hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' 14328 export_dynamic_flag_spec_CXX='$wl-E' 14329 # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. 14330 # Instead, shared libraries are loaded at an image base (0x10000000 by 14331 # default) and relocated if they conflict, which is a slow very memory 14332 # consuming and fragmenting process. To avoid this, we pick a random, 14333 # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link 14334 # time. Moving up from 0x10000000 also allows more sbrk(2) space. 14335 archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' 14336 archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' 14337 ;; 14338 irix5* | irix6*) 14339 case $cc_basename in 14340 CC*) 14341 # SGI C++ 14342 archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' 14343 14344 # Archives containing C++ object files must be created using 14345 # "CC -ar", where "CC" is the IRIX C++ compiler. This is 14346 # necessary to make sure instantiated templates are included 14347 # in the archive. 14348 old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' 14349 ;; 14350 *) 14351 if test yes = "$GXX"; then 14352 if test no = "$with_gnu_ld"; then 14353 archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' 14354 else 14355 archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' 14356 fi 14357 fi 14358 link_all_deplibs_CXX=yes 14359 ;; 14360 esac 14361 hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' 14362 hardcode_libdir_separator_CXX=: 14363 inherit_rpath_CXX=yes 14364 ;; 14365 14366 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) 14367 case $cc_basename in 14368 KCC*) 14369 # Kuck and Associates, Inc. (KAI) C++ Compiler 14370 14371 # KCC will only create a shared library if the output file 14372 # ends with ".so" (or ".sl" for HP-UX), so rename the library 14373 # to its proper name (with version) after linking. 14374 archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' 14375 archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' 14376 # Commands to make compiler produce verbose output that lists 14377 # what "hidden" libraries, object files and flags are used when 14378 # linking a shared library. 14379 # 14380 # There doesn't appear to be a way to prevent this compiler from 14381 # explicitly linking system object files so we need to strip them 14382 # from the output so that they don't get included in the library 14383 # dependencies. 14384 output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' 14385 14386 hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' 14387 export_dynamic_flag_spec_CXX='$wl--export-dynamic' 14388 14389 # Archives containing C++ object files must be created using 14390 # "CC -Bstatic", where "CC" is the KAI C++ compiler. 14391 old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' 14392 ;; 14393 icpc* | ecpc* ) 14394 # Intel C++ 14395 with_gnu_ld=yes 14396 # version 8.0 and above of icpc choke on multiply defined symbols 14397 # if we add $predep_objects and $postdep_objects, however 7.1 and 14398 # earlier do not add the objects themselves. 14399 case `$CC -V 2>&1` in 14400 *"Version 7."*) 14401 archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' 14402 archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 14403 ;; 14404 *) # Version 8.0 or newer 14405 tmp_idyn= 14406 case $host_cpu in 14407 ia64*) tmp_idyn=' -i_dynamic';; 14408 esac 14409 archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 14410 archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 14411 ;; 14412 esac 14413 archive_cmds_need_lc_CXX=no 14414 hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' 14415 export_dynamic_flag_spec_CXX='$wl--export-dynamic' 14416 whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' 14417 ;; 14418 pgCC* | pgcpp*) 14419 # Portland Group C++ compiler 14420 case `$CC -V` in 14421 *pgCC\ [1-5].* | *pgcpp\ [1-5].*) 14422 prelink_cmds_CXX='tpldir=Template.dir~ 14423 rm -rf $tpldir~ 14424 $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ 14425 compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' 14426 old_archive_cmds_CXX='tpldir=Template.dir~ 14427 rm -rf $tpldir~ 14428 $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ 14429 $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ 14430 $RANLIB $oldlib' 14431 archive_cmds_CXX='tpldir=Template.dir~ 14432 rm -rf $tpldir~ 14433 $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ 14434 $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' 14435 archive_expsym_cmds_CXX='tpldir=Template.dir~ 14436 rm -rf $tpldir~ 14437 $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ 14438 $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 14439 ;; 14440 *) # Version 6 and above use weak symbols 14441 archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' 14442 archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' 14443 ;; 14444 esac 14445 14446 hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' 14447 export_dynamic_flag_spec_CXX='$wl--export-dynamic' 14448 whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' 14449 ;; 14450 cxx*) 14451 # Compaq C++ 14452 archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' 14453 archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' 14454 14455 runpath_var=LD_RUN_PATH 14456 hardcode_libdir_flag_spec_CXX='-rpath $libdir' 14457 hardcode_libdir_separator_CXX=: 14458 14459 # Commands to make compiler produce verbose output that lists 14460 # what "hidden" libraries, object files and flags are used when 14461 # linking a shared library. 14462 # 14463 # There doesn't appear to be a way to prevent this compiler from 14464 # explicitly linking system object files so we need to strip them 14465 # from the output so that they don't get included in the library 14466 # dependencies. 14467 output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' 14468 ;; 14469 xl* | mpixl* | bgxl*) 14470 # IBM XL 8.0 on PPC, with GNU ld 14471 hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' 14472 export_dynamic_flag_spec_CXX='$wl--export-dynamic' 14473 archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' 14474 if test yes = "$supports_anon_versioning"; then 14475 archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ 14476 cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ 14477 echo "local: *; };" >> $output_objdir/$libname.ver~ 14478 $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' 14479 fi 14480 ;; 14481 *) 14482 case `$CC -V 2>&1 | sed 5q` in 14483 *Sun\ C*) 14484 # Sun C++ 5.9 14485 no_undefined_flag_CXX=' -zdefs' 14486 archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14487 archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' 14488 hardcode_libdir_flag_spec_CXX='-R$libdir' 14489 whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' 14490 compiler_needs_object_CXX=yes 14491 14492 # Not sure whether something based on 14493 # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 14494 # would be better. 14495 output_verbose_link_cmd='func_echo_all' 14496 14497 # Archives containing C++ object files must be created using 14498 # "CC -xar", where "CC" is the Sun C++ compiler. This is 14499 # necessary to make sure instantiated templates are included 14500 # in the archive. 14501 old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' 14502 ;; 14503 esac 14504 ;; 14505 esac 14506 ;; 14507 14508 lynxos*) 14509 # FIXME: insert proper C++ library support 14510 ld_shlibs_CXX=no 14511 ;; 14512 14513 m88k*) 14514 # FIXME: insert proper C++ library support 14515 ld_shlibs_CXX=no 14516 ;; 14517 14518 mvs*) 14519 case $cc_basename in 14520 cxx*) 14521 # FIXME: insert proper C++ library support 14522 ld_shlibs_CXX=no 14523 ;; 14524 *) 14525 # FIXME: insert proper C++ library support 14526 ld_shlibs_CXX=no 14527 ;; 14528 esac 14529 ;; 14530 14531 netbsd*) 14532 if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then 14533 archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' 14534 wlarc= 14535 hardcode_libdir_flag_spec_CXX='-R$libdir' 14536 hardcode_direct_CXX=yes 14537 hardcode_shlibpath_var_CXX=no 14538 fi 14539 # Workaround some broken pre-1.5 toolchains 14540 output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' 14541 ;; 14542 14543 *nto* | *qnx*) 14544 ld_shlibs_CXX=yes 14545 ;; 14546 14547 openbsd* | bitrig*) 14548 if test -f /usr/libexec/ld.so; then 14549 hardcode_direct_CXX=yes 14550 hardcode_shlibpath_var_CXX=no 14551 hardcode_direct_absolute_CXX=yes 14552 archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' 14553 hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' 14554 if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then 14555 archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' 14556 export_dynamic_flag_spec_CXX='$wl-E' 14557 whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' 14558 fi 14559 output_verbose_link_cmd=func_echo_all 14560 else 14561 ld_shlibs_CXX=no 14562 fi 14563 ;; 14564 14565 osf3* | osf4* | osf5*) 14566 case $cc_basename in 14567 KCC*) 14568 # Kuck and Associates, Inc. (KAI) C++ Compiler 14569 14570 # KCC will only create a shared library if the output file 14571 # ends with ".so" (or ".sl" for HP-UX), so rename the library 14572 # to its proper name (with version) after linking. 14573 archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' 14574 14575 hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' 14576 hardcode_libdir_separator_CXX=: 14577 14578 # Archives containing C++ object files must be created using 14579 # the KAI C++ compiler. 14580 case $host in 14581 osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; 14582 *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; 14583 esac 14584 ;; 14585 RCC*) 14586 # Rational C++ 2.4.1 14587 # FIXME: insert proper C++ library support 14588 ld_shlibs_CXX=no 14589 ;; 14590 cxx*) 14591 case $host in 14592 osf3*) 14593 allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' 14594 archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' 14595 hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' 14596 ;; 14597 *) 14598 allow_undefined_flag_CXX=' -expect_unresolved \*' 14599 archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' 14600 archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ 14601 echo "-hidden">> $lib.exp~ 14602 $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ 14603 $RM $lib.exp' 14604 hardcode_libdir_flag_spec_CXX='-rpath $libdir' 14605 ;; 14606 esac 14607 14608 hardcode_libdir_separator_CXX=: 14609 14610 # Commands to make compiler produce verbose output that lists 14611 # what "hidden" libraries, object files and flags are used when 14612 # linking a shared library. 14613 # 14614 # There doesn't appear to be a way to prevent this compiler from 14615 # explicitly linking system object files so we need to strip them 14616 # from the output so that they don't get included in the library 14617 # dependencies. 14618 output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' 14619 ;; 14620 *) 14621 if test yes,no = "$GXX,$with_gnu_ld"; then 14622 allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' 14623 case $host in 14624 osf3*) 14625 archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' 14626 ;; 14627 *) 14628 archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' 14629 ;; 14630 esac 14631 14632 hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' 14633 hardcode_libdir_separator_CXX=: 14634 14635 # Commands to make compiler produce verbose output that lists 14636 # what "hidden" libraries, object files and flags are used when 14637 # linking a shared library. 14638 output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' 14639 14640 else 14641 # FIXME: insert proper C++ library support 14642 ld_shlibs_CXX=no 14643 fi 14644 ;; 14645 esac 14646 ;; 14647 14648 psos*) 14649 # FIXME: insert proper C++ library support 14650 ld_shlibs_CXX=no 14651 ;; 14652 14653 sunos4*) 14654 case $cc_basename in 14655 CC*) 14656 # Sun C++ 4.x 14657 # FIXME: insert proper C++ library support 14658 ld_shlibs_CXX=no 14659 ;; 14660 lcc*) 14661 # Lucid 14662 # FIXME: insert proper C++ library support 14663 ld_shlibs_CXX=no 14664 ;; 14665 *) 14666 # FIXME: insert proper C++ library support 14667 ld_shlibs_CXX=no 14668 ;; 14669 esac 14670 ;; 14671 14672 solaris*) 14673 case $cc_basename in 14674 CC* | sunCC*) 14675 # Sun C++ 4.2, 5.x and Centerline C++ 14676 archive_cmds_need_lc_CXX=yes 14677 no_undefined_flag_CXX=' -zdefs' 14678 archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' 14679 archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ 14680 $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' 14681 14682 hardcode_libdir_flag_spec_CXX='-R$libdir' 14683 hardcode_shlibpath_var_CXX=no 14684 case $host_os in 14685 solaris2.[0-5] | solaris2.[0-5].*) ;; 14686 *) 14687 # The compiler driver will combine and reorder linker options, 14688 # but understands '-z linker_flag'. 14689 # Supported since Solaris 2.6 (maybe 2.5.1?) 14690 whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' 14691 ;; 14692 esac 14693 link_all_deplibs_CXX=yes 14694 14695 output_verbose_link_cmd='func_echo_all' 14696 14697 # Archives containing C++ object files must be created using 14698 # "CC -xar", where "CC" is the Sun C++ compiler. This is 14699 # necessary to make sure instantiated templates are included 14700 # in the archive. 14701 old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' 14702 ;; 14703 gcx*) 14704 # Green Hills C++ Compiler 14705 archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' 14706 14707 # The C++ compiler must be used to create the archive. 14708 old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' 14709 ;; 14710 *) 14711 # GNU C++ compiler with Solaris linker 14712 if test yes,no = "$GXX,$with_gnu_ld"; then 14713 no_undefined_flag_CXX=' $wl-z ${wl}defs' 14714 if $CC --version | $GREP -v '^2\.7' > /dev/null; then 14715 archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' 14716 archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ 14717 $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' 14718 14719 # Commands to make compiler produce verbose output that lists 14720 # what "hidden" libraries, object files and flags are used when 14721 # linking a shared library. 14722 output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' 14723 else 14724 # g++ 2.7 appears to require '-G' NOT '-shared' on this 14725 # platform. 14726 archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' 14727 archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ 14728 $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' 14729 14730 # Commands to make compiler produce verbose output that lists 14731 # what "hidden" libraries, object files and flags are used when 14732 # linking a shared library. 14733 output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' 14734 fi 14735 14736 hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' 14737 case $host_os in 14738 solaris2.[0-5] | solaris2.[0-5].*) ;; 14739 *) 14740 whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' 14741 ;; 14742 esac 14743 fi 14744 ;; 14745 esac 14746 ;; 14747 14748 sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) 14749 no_undefined_flag_CXX='$wl-z,text' 14750 archive_cmds_need_lc_CXX=no 14751 hardcode_shlibpath_var_CXX=no 14752 runpath_var='LD_RUN_PATH' 14753 14754 case $cc_basename in 14755 CC*) 14756 archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14757 archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14758 ;; 14759 *) 14760 archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14761 archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14762 ;; 14763 esac 14764 ;; 14765 14766 sysv5* | sco3.2v5* | sco5v6*) 14767 # Note: We CANNOT use -z defs as we might desire, because we do not 14768 # link with -lc, and that would cause any symbols used from libc to 14769 # always be unresolved, which means just about no library would 14770 # ever link correctly. If we're not using GNU ld we use -z text 14771 # though, which does catch some bad symbols but isn't as heavy-handed 14772 # as -z defs. 14773 no_undefined_flag_CXX='$wl-z,text' 14774 allow_undefined_flag_CXX='$wl-z,nodefs' 14775 archive_cmds_need_lc_CXX=no 14776 hardcode_shlibpath_var_CXX=no 14777 hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' 14778 hardcode_libdir_separator_CXX=':' 14779 link_all_deplibs_CXX=yes 14780 export_dynamic_flag_spec_CXX='$wl-Bexport' 14781 runpath_var='LD_RUN_PATH' 14782 14783 case $cc_basename in 14784 CC*) 14785 archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14786 archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14787 old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ 14788 '"$old_archive_cmds_CXX" 14789 reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ 14790 '"$reload_cmds_CXX" 14791 ;; 14792 *) 14793 archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14794 archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' 14795 ;; 14796 esac 14797 ;; 14798 14799 tandem*) 14800 case $cc_basename in 14801 NCC*) 14802 # NonStop-UX NCC 3.20 14803 # FIXME: insert proper C++ library support 14804 ld_shlibs_CXX=no 14805 ;; 14806 *) 14807 # FIXME: insert proper C++ library support 14808 ld_shlibs_CXX=no 14809 ;; 14810 esac 14811 ;; 14812 14813 vxworks*) 14814 # FIXME: insert proper C++ library support 14815 ld_shlibs_CXX=no 14816 ;; 14817 14818 *) 14819 # FIXME: insert proper C++ library support 14820 ld_shlibs_CXX=no 14821 ;; 14822 esac 14823 14824 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 14825 $as_echo "$ld_shlibs_CXX" >&6; } 14826 test no = "$ld_shlibs_CXX" && can_build_shared=no 14827 14828 GCC_CXX=$GXX 14829 LD_CXX=$LD 14830 14831 ## CAVEAT EMPTOR: 14832 ## There is no encapsulation within the following macros, do not change 14833 ## the running order or otherwise move them around unless you know exactly 14834 ## what you are doing... 14835 # Dependencies to place before and after the object being linked: 14836 predep_objects_CXX= 14837 postdep_objects_CXX= 14838 predeps_CXX= 14839 postdeps_CXX= 14840 compiler_lib_search_path_CXX= 14841 14842 cat > conftest.$ac_ext <<_LT_EOF 14843 class Foo 14844 { 14845 public: 14846 Foo (void) { a = 0; } 14847 private: 14848 int a; 14849 }; 14850 _LT_EOF 14851 14852 14853 _lt_libdeps_save_CFLAGS=$CFLAGS 14854 case "$CC $CFLAGS " in #( 14855 *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; 14856 *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; 14857 *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; 14858 esac 14859 14860 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 14861 (eval $ac_compile) 2>&5 14862 ac_status=$? 14863 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 14864 test $ac_status = 0; }; then 14865 # Parse the compiler output and extract the necessary 14866 # objects, libraries and library flags. 14867 14868 # Sentinel used to keep track of whether or not we are before 14869 # the conftest object file. 14870 pre_test_object_deps_done=no 14871 14872 for p in `eval "$output_verbose_link_cmd"`; do 14873 case $prev$p in 14874 14875 -L* | -R* | -l*) 14876 # Some compilers place space between "-{L,R}" and the path. 14877 # Remove the space. 14878 if test x-L = "$p" || 14879 test x-R = "$p"; then 14880 prev=$p 14881 continue 14882 fi 14883 14884 # Expand the sysroot to ease extracting the directories later. 14885 if test -z "$prev"; then 14886 case $p in 14887 -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; 14888 -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; 14889 -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; 14890 esac 14891 fi 14892 case $p in 14893 =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; 14894 esac 14895 if test no = "$pre_test_object_deps_done"; then 14896 case $prev in 14897 -L | -R) 14898 # Internal compiler library paths should come after those 14899 # provided the user. The postdeps already come after the 14900 # user supplied libs so there is no need to process them. 14901 if test -z "$compiler_lib_search_path_CXX"; then 14902 compiler_lib_search_path_CXX=$prev$p 14903 else 14904 compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" 14905 fi 14906 ;; 14907 # The "-l" case would never come before the object being 14908 # linked, so don't bother handling this case. 14909 esac 14910 else 14911 if test -z "$postdeps_CXX"; then 14912 postdeps_CXX=$prev$p 14913 else 14914 postdeps_CXX="${postdeps_CXX} $prev$p" 14915 fi 14916 fi 14917 prev= 14918 ;; 14919 14920 *.lto.$objext) ;; # Ignore GCC LTO objects 14921 *.$objext) 14922 # This assumes that the test object file only shows up 14923 # once in the compiler output. 14924 if test "$p" = "conftest.$objext"; then 14925 pre_test_object_deps_done=yes 14926 continue 14927 fi 14928 14929 if test no = "$pre_test_object_deps_done"; then 14930 if test -z "$predep_objects_CXX"; then 14931 predep_objects_CXX=$p 14932 else 14933 predep_objects_CXX="$predep_objects_CXX $p" 14934 fi 14935 else 14936 if test -z "$postdep_objects_CXX"; then 14937 postdep_objects_CXX=$p 14938 else 14939 postdep_objects_CXX="$postdep_objects_CXX $p" 14940 fi 14941 fi 14942 ;; 14943 14944 *) ;; # Ignore the rest. 14945 14946 esac 14947 done 14948 14949 # Clean up. 14950 rm -f a.out a.exe 14951 else 14952 echo "libtool.m4: error: problem compiling CXX test program" 14953 fi 14954 14955 $RM -f confest.$objext 14956 CFLAGS=$_lt_libdeps_save_CFLAGS 14957 14958 # PORTME: override above test on systems where it is broken 14959 case $host_os in 14960 interix[3-9]*) 14961 # Interix 3.5 installs completely hosed .la files for C++, so rather than 14962 # hack all around it, let's just trust "g++" to DTRT. 14963 predep_objects_CXX= 14964 postdep_objects_CXX= 14965 postdeps_CXX= 14966 ;; 14967 esac 14968 14969 14970 case " $postdeps_CXX " in 14971 *" -lc "*) archive_cmds_need_lc_CXX=no ;; 14972 esac 14973 compiler_lib_search_dirs_CXX= 14974 if test -n "${compiler_lib_search_path_CXX}"; then 14975 compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` 14976 fi 14977 14978 14979 14980 14981 14982 14983 14984 14985 14986 14987 14988 14989 14990 14991 14992 14993 14994 14995 14996 14997 14998 14999 15000 15001 15002 15003 15004 15005 15006 15007 15008 lt_prog_compiler_wl_CXX= 15009 lt_prog_compiler_pic_CXX= 15010 lt_prog_compiler_static_CXX= 15011 15012 15013 # C++ specific cases for pic, static, wl, etc. 15014 if test yes = "$GXX"; then 15015 lt_prog_compiler_wl_CXX='-Wl,' 15016 lt_prog_compiler_static_CXX='-static' 15017 15018 case $host_os in 15019 aix*) 15020 # All AIX code is PIC. 15021 if test ia64 = "$host_cpu"; then 15022 # AIX 5 now supports IA64 processor 15023 lt_prog_compiler_static_CXX='-Bstatic' 15024 fi 15025 lt_prog_compiler_pic_CXX='-fPIC' 15026 ;; 15027 15028 amigaos*) 15029 case $host_cpu in 15030 powerpc) 15031 # see comment about AmigaOS4 .so support 15032 lt_prog_compiler_pic_CXX='-fPIC' 15033 ;; 15034 m68k) 15035 # FIXME: we need at least 68020 code to build shared libraries, but 15036 # adding the '-m68020' flag to GCC prevents building anything better, 15037 # like '-m68040'. 15038 lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' 15039 ;; 15040 esac 15041 ;; 15042 15043 beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) 15044 # PIC is the default for these OSes. 15045 ;; 15046 mingw* | cygwin* | os2* | pw32* | cegcc*) 15047 # This hack is so that the source file can tell whether it is being 15048 # built for inclusion in a dll (and should export symbols for example). 15049 # Although the cygwin gcc ignores -fPIC, still need this for old-style 15050 # (--disable-auto-import) libraries 15051 lt_prog_compiler_pic_CXX='-DDLL_EXPORT' 15052 case $host_os in 15053 os2*) 15054 lt_prog_compiler_static_CXX='$wl-static' 15055 ;; 15056 esac 15057 ;; 15058 darwin* | rhapsody*) 15059 # PIC is the default on this platform 15060 # Common symbols not allowed in MH_DYLIB files 15061 lt_prog_compiler_pic_CXX='-fno-common' 15062 ;; 15063 *djgpp*) 15064 # DJGPP does not support shared libraries at all 15065 lt_prog_compiler_pic_CXX= 15066 ;; 15067 haiku*) 15068 # PIC is the default for Haiku. 15069 # The "-static" flag exists, but is broken. 15070 lt_prog_compiler_static_CXX= 15071 ;; 15072 interix[3-9]*) 15073 # Interix 3.x gcc -fpic/-fPIC options generate broken code. 15074 # Instead, we relocate shared libraries at runtime. 15075 ;; 15076 sysv4*MP*) 15077 if test -d /usr/nec; then 15078 lt_prog_compiler_pic_CXX=-Kconform_pic 15079 fi 15080 ;; 15081 hpux*) 15082 # PIC is the default for 64-bit PA HP-UX, but not for 32-bit 15083 # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag 15084 # sets the default TLS model and affects inlining. 15085 case $host_cpu in 15086 hppa*64*) 15087 ;; 15088 *) 15089 lt_prog_compiler_pic_CXX='-fPIC' 15090 ;; 15091 esac 15092 ;; 15093 *qnx* | *nto*) 15094 # QNX uses GNU C++, but need to define -shared option too, otherwise 15095 # it will coredump. 15096 lt_prog_compiler_pic_CXX='-fPIC -shared' 15097 ;; 15098 *) 15099 lt_prog_compiler_pic_CXX='-fPIC' 15100 ;; 15101 esac 15102 else 15103 case $host_os in 15104 aix[4-9]*) 15105 # All AIX code is PIC. 15106 if test ia64 = "$host_cpu"; then 15107 # AIX 5 now supports IA64 processor 15108 lt_prog_compiler_static_CXX='-Bstatic' 15109 else 15110 lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' 15111 fi 15112 ;; 15113 chorus*) 15114 case $cc_basename in 15115 cxch68*) 15116 # Green Hills C++ Compiler 15117 # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" 15118 ;; 15119 esac 15120 ;; 15121 mingw* | cygwin* | os2* | pw32* | cegcc*) 15122 # This hack is so that the source file can tell whether it is being 15123 # built for inclusion in a dll (and should export symbols for example). 15124 lt_prog_compiler_pic_CXX='-DDLL_EXPORT' 15125 ;; 15126 dgux*) 15127 case $cc_basename in 15128 ec++*) 15129 lt_prog_compiler_pic_CXX='-KPIC' 15130 ;; 15131 ghcx*) 15132 # Green Hills C++ Compiler 15133 lt_prog_compiler_pic_CXX='-pic' 15134 ;; 15135 *) 15136 ;; 15137 esac 15138 ;; 15139 freebsd* | dragonfly*) 15140 # FreeBSD uses GNU C++ 15141 ;; 15142 hpux9* | hpux10* | hpux11*) 15143 case $cc_basename in 15144 CC*) 15145 lt_prog_compiler_wl_CXX='-Wl,' 15146 lt_prog_compiler_static_CXX='$wl-a ${wl}archive' 15147 if test ia64 != "$host_cpu"; then 15148 lt_prog_compiler_pic_CXX='+Z' 15149 fi 15150 ;; 15151 aCC*) 15152 lt_prog_compiler_wl_CXX='-Wl,' 15153 lt_prog_compiler_static_CXX='$wl-a ${wl}archive' 15154 case $host_cpu in 15155 hppa*64*|ia64*) 15156 # +Z the default 15157 ;; 15158 *) 15159 lt_prog_compiler_pic_CXX='+Z' 15160 ;; 15161 esac 15162 ;; 15163 *) 15164 ;; 15165 esac 15166 ;; 15167 interix*) 15168 # This is c89, which is MS Visual C++ (no shared libs) 15169 # Anyone wants to do a port? 15170 ;; 15171 irix5* | irix6* | nonstopux*) 15172 case $cc_basename in 15173 CC*) 15174 lt_prog_compiler_wl_CXX='-Wl,' 15175 lt_prog_compiler_static_CXX='-non_shared' 15176 # CC pic flag -KPIC is the default. 15177 ;; 15178 *) 15179 ;; 15180 esac 15181 ;; 15182 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) 15183 case $cc_basename in 15184 KCC*) 15185 # KAI C++ Compiler 15186 lt_prog_compiler_wl_CXX='--backend -Wl,' 15187 lt_prog_compiler_pic_CXX='-fPIC' 15188 ;; 15189 ecpc* ) 15190 # old Intel C++ for x86_64, which still supported -KPIC. 15191 lt_prog_compiler_wl_CXX='-Wl,' 15192 lt_prog_compiler_pic_CXX='-KPIC' 15193 lt_prog_compiler_static_CXX='-static' 15194 ;; 15195 icpc* ) 15196 # Intel C++, used to be incompatible with GCC. 15197 # ICC 10 doesn't accept -KPIC any more. 15198 lt_prog_compiler_wl_CXX='-Wl,' 15199 lt_prog_compiler_pic_CXX='-fPIC' 15200 lt_prog_compiler_static_CXX='-static' 15201 ;; 15202 pgCC* | pgcpp*) 15203 # Portland Group C++ compiler 15204 lt_prog_compiler_wl_CXX='-Wl,' 15205 lt_prog_compiler_pic_CXX='-fpic' 15206 lt_prog_compiler_static_CXX='-Bstatic' 15207 ;; 15208 cxx*) 15209 # Compaq C++ 15210 # Make sure the PIC flag is empty. It appears that all Alpha 15211 # Linux and Compaq Tru64 Unix objects are PIC. 15212 lt_prog_compiler_pic_CXX= 15213 lt_prog_compiler_static_CXX='-non_shared' 15214 ;; 15215 xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) 15216 # IBM XL 8.0, 9.0 on PPC and BlueGene 15217 lt_prog_compiler_wl_CXX='-Wl,' 15218 lt_prog_compiler_pic_CXX='-qpic' 15219 lt_prog_compiler_static_CXX='-qstaticlink' 15220 ;; 15221 *) 15222 case `$CC -V 2>&1 | sed 5q` in 15223 *Sun\ C*) 15224 # Sun C++ 5.9 15225 lt_prog_compiler_pic_CXX='-KPIC' 15226 lt_prog_compiler_static_CXX='-Bstatic' 15227 lt_prog_compiler_wl_CXX='-Qoption ld ' 15228 ;; 15229 esac 15230 ;; 15231 esac 15232 ;; 15233 lynxos*) 15234 ;; 15235 m88k*) 15236 ;; 15237 mvs*) 15238 case $cc_basename in 15239 cxx*) 15240 lt_prog_compiler_pic_CXX='-W c,exportall' 15241 ;; 15242 *) 15243 ;; 15244 esac 15245 ;; 15246 netbsd* | netbsdelf*-gnu) 15247 ;; 15248 *qnx* | *nto*) 15249 # QNX uses GNU C++, but need to define -shared option too, otherwise 15250 # it will coredump. 15251 lt_prog_compiler_pic_CXX='-fPIC -shared' 15252 ;; 15253 osf3* | osf4* | osf5*) 15254 case $cc_basename in 15255 KCC*) 15256 lt_prog_compiler_wl_CXX='--backend -Wl,' 15257 ;; 15258 RCC*) 15259 # Rational C++ 2.4.1 15260 lt_prog_compiler_pic_CXX='-pic' 15261 ;; 15262 cxx*) 15263 # Digital/Compaq C++ 15264 lt_prog_compiler_wl_CXX='-Wl,' 15265 # Make sure the PIC flag is empty. It appears that all Alpha 15266 # Linux and Compaq Tru64 Unix objects are PIC. 15267 lt_prog_compiler_pic_CXX= 15268 lt_prog_compiler_static_CXX='-non_shared' 15269 ;; 15270 *) 15271 ;; 15272 esac 15273 ;; 15274 psos*) 15275 ;; 15276 solaris*) 15277 case $cc_basename in 15278 CC* | sunCC*) 15279 # Sun C++ 4.2, 5.x and Centerline C++ 15280 lt_prog_compiler_pic_CXX='-KPIC' 15281 lt_prog_compiler_static_CXX='-Bstatic' 15282 lt_prog_compiler_wl_CXX='-Qoption ld ' 15283 ;; 15284 gcx*) 15285 # Green Hills C++ Compiler 15286 lt_prog_compiler_pic_CXX='-PIC' 15287 ;; 15288 *) 15289 ;; 15290 esac 15291 ;; 15292 sunos4*) 15293 case $cc_basename in 15294 CC*) 15295 # Sun C++ 4.x 15296 lt_prog_compiler_pic_CXX='-pic' 15297 lt_prog_compiler_static_CXX='-Bstatic' 15298 ;; 15299 lcc*) 15300 # Lucid 15301 lt_prog_compiler_pic_CXX='-pic' 15302 ;; 15303 *) 15304 ;; 15305 esac 15306 ;; 15307 sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) 15308 case $cc_basename in 15309 CC*) 15310 lt_prog_compiler_wl_CXX='-Wl,' 15311 lt_prog_compiler_pic_CXX='-KPIC' 15312 lt_prog_compiler_static_CXX='-Bstatic' 15313 ;; 15314 esac 15315 ;; 15316 tandem*) 15317 case $cc_basename in 15318 NCC*) 15319 # NonStop-UX NCC 3.20 15320 lt_prog_compiler_pic_CXX='-KPIC' 15321 ;; 15322 *) 15323 ;; 15324 esac 15325 ;; 15326 vxworks*) 15327 ;; 15328 *) 15329 lt_prog_compiler_can_build_shared_CXX=no 15330 ;; 15331 esac 15332 fi 15333 15334 case $host_os in 15335 # For platforms that do not support PIC, -DPIC is meaningless: 15336 *djgpp*) 15337 lt_prog_compiler_pic_CXX= 15338 ;; 15339 *) 15340 lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" 15341 ;; 15342 esac 15343 15344 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 15345 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } 15346 if ${lt_cv_prog_compiler_pic_CXX+:} false; then : 15347 $as_echo_n "(cached) " >&6 15348 else 15349 lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX 15350 fi 15351 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 15352 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } 15353 lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX 15354 15355 # 15356 # Check to make sure the PIC flag actually works. 15357 # 15358 if test -n "$lt_prog_compiler_pic_CXX"; then 15359 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 15360 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } 15361 if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : 15362 $as_echo_n "(cached) " >&6 15363 else 15364 lt_cv_prog_compiler_pic_works_CXX=no 15365 ac_outfile=conftest.$ac_objext 15366 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 15367 lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment 15368 # Insert the option either (1) after the last *FLAGS variable, or 15369 # (2) before a word containing "conftest.", or (3) at the end. 15370 # Note that $ac_compile itself does not contain backslashes and begins 15371 # with a dollar sign (not a hyphen), so the echo should work correctly. 15372 # The option is referenced via a variable to avoid confusing sed. 15373 lt_compile=`echo "$ac_compile" | $SED \ 15374 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ 15375 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ 15376 -e 's:$: $lt_compiler_flag:'` 15377 (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) 15378 (eval "$lt_compile" 2>conftest.err) 15379 ac_status=$? 15380 cat conftest.err >&5 15381 echo "$as_me:$LINENO: \$? = $ac_status" >&5 15382 if (exit $ac_status) && test -s "$ac_outfile"; then 15383 # The compiler can only warn and ignore the option if not recognized 15384 # So say no if there are warnings other than the usual output. 15385 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp 15386 $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 15387 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then 15388 lt_cv_prog_compiler_pic_works_CXX=yes 15389 fi 15390 fi 15391 $RM conftest* 15392 15393 fi 15394 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 15395 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } 15396 15397 if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then 15398 case $lt_prog_compiler_pic_CXX in 15399 "" | " "*) ;; 15400 *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; 15401 esac 15402 else 15403 lt_prog_compiler_pic_CXX= 15404 lt_prog_compiler_can_build_shared_CXX=no 15405 fi 15406 15407 fi 15408 15409 15410 15411 15412 15413 # 15414 # Check to make sure the static flag actually works. 15415 # 15416 wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" 15417 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 15418 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } 15419 if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : 15420 $as_echo_n "(cached) " >&6 15421 else 15422 lt_cv_prog_compiler_static_works_CXX=no 15423 save_LDFLAGS=$LDFLAGS 15424 LDFLAGS="$LDFLAGS $lt_tmp_static_flag" 15425 echo "$lt_simple_link_test_code" > conftest.$ac_ext 15426 if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then 15427 # The linker can only warn and ignore the option if not recognized 15428 # So say no if there are warnings 15429 if test -s conftest.err; then 15430 # Append any errors to the config.log. 15431 cat conftest.err 1>&5 15432 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp 15433 $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 15434 if diff conftest.exp conftest.er2 >/dev/null; then 15435 lt_cv_prog_compiler_static_works_CXX=yes 15436 fi 15437 else 15438 lt_cv_prog_compiler_static_works_CXX=yes 15439 fi 15440 fi 15441 $RM -r conftest* 15442 LDFLAGS=$save_LDFLAGS 15443 15444 fi 15445 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 15446 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } 15447 15448 if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then 15449 : 15450 else 15451 lt_prog_compiler_static_CXX= 15452 fi 15453 15454 15455 15456 15457 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 15458 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } 15459 if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : 15460 $as_echo_n "(cached) " >&6 15461 else 15462 lt_cv_prog_compiler_c_o_CXX=no 15463 $RM -r conftest 2>/dev/null 15464 mkdir conftest 15465 cd conftest 15466 mkdir out 15467 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 15468 15469 lt_compiler_flag="-o out/conftest2.$ac_objext" 15470 # Insert the option either (1) after the last *FLAGS variable, or 15471 # (2) before a word containing "conftest.", or (3) at the end. 15472 # Note that $ac_compile itself does not contain backslashes and begins 15473 # with a dollar sign (not a hyphen), so the echo should work correctly. 15474 lt_compile=`echo "$ac_compile" | $SED \ 15475 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ 15476 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ 15477 -e 's:$: $lt_compiler_flag:'` 15478 (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) 15479 (eval "$lt_compile" 2>out/conftest.err) 15480 ac_status=$? 15481 cat out/conftest.err >&5 15482 echo "$as_me:$LINENO: \$? = $ac_status" >&5 15483 if (exit $ac_status) && test -s out/conftest2.$ac_objext 15484 then 15485 # The compiler can only warn and ignore the option if not recognized 15486 # So say no if there are warnings 15487 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp 15488 $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 15489 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then 15490 lt_cv_prog_compiler_c_o_CXX=yes 15491 fi 15492 fi 15493 chmod u+w . 2>&5 15494 $RM conftest* 15495 # SGI C++ compiler will create directory out/ii_files/ for 15496 # template instantiation 15497 test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files 15498 $RM out/* && rmdir out 15499 cd .. 15500 $RM -r conftest 15501 $RM conftest* 15502 15503 fi 15504 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 15505 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } 15506 15507 15508 15509 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 15510 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } 15511 if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : 15512 $as_echo_n "(cached) " >&6 15513 else 15514 lt_cv_prog_compiler_c_o_CXX=no 15515 $RM -r conftest 2>/dev/null 15516 mkdir conftest 15517 cd conftest 15518 mkdir out 15519 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 15520 15521 lt_compiler_flag="-o out/conftest2.$ac_objext" 15522 # Insert the option either (1) after the last *FLAGS variable, or 15523 # (2) before a word containing "conftest.", or (3) at the end. 15524 # Note that $ac_compile itself does not contain backslashes and begins 15525 # with a dollar sign (not a hyphen), so the echo should work correctly. 15526 lt_compile=`echo "$ac_compile" | $SED \ 15527 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ 15528 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ 15529 -e 's:$: $lt_compiler_flag:'` 15530 (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) 15531 (eval "$lt_compile" 2>out/conftest.err) 15532 ac_status=$? 15533 cat out/conftest.err >&5 15534 echo "$as_me:$LINENO: \$? = $ac_status" >&5 15535 if (exit $ac_status) && test -s out/conftest2.$ac_objext 15536 then 15537 # The compiler can only warn and ignore the option if not recognized 15538 # So say no if there are warnings 15539 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp 15540 $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 15541 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then 15542 lt_cv_prog_compiler_c_o_CXX=yes 15543 fi 15544 fi 15545 chmod u+w . 2>&5 15546 $RM conftest* 15547 # SGI C++ compiler will create directory out/ii_files/ for 15548 # template instantiation 15549 test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files 15550 $RM out/* && rmdir out 15551 cd .. 15552 $RM -r conftest 15553 $RM conftest* 15554 15555 fi 15556 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 15557 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } 15558 15559 15560 15561 15562 hard_links=nottested 15563 if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then 15564 # do not overwrite the value of need_locks provided by the user 15565 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 15566 $as_echo_n "checking if we can lock with hard links... " >&6; } 15567 hard_links=yes 15568 $RM conftest* 15569 ln conftest.a conftest.b 2>/dev/null && hard_links=no 15570 touch conftest.a 15571 ln conftest.a conftest.b 2>&5 || hard_links=no 15572 ln conftest.a conftest.b 2>/dev/null && hard_links=no 15573 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 15574 $as_echo "$hard_links" >&6; } 15575 if test no = "$hard_links"; then 15576 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 15577 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} 15578 need_locks=warn 15579 fi 15580 else 15581 need_locks=no 15582 fi 15583 15584 15585 15586 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 15587 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } 15588 15589 export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' 15590 exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' 15591 case $host_os in 15592 aix[4-9]*) 15593 # If we're using GNU nm, then we don't want the "-C" option. 15594 # -C means demangle to GNU nm, but means don't demangle to AIX nm. 15595 # Without the "-l" option, or with the "-B" option, AIX nm treats 15596 # weak defined symbols like other global defined symbols, whereas 15597 # GNU nm marks them as "W". 15598 # While the 'weak' keyword is ignored in the Export File, we need 15599 # it in the Import File for the 'aix-soname' feature, so we have 15600 # to replace the "-B" option with "-P" for AIX nm. 15601 if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then 15602 export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' 15603 else 15604 export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' 15605 fi 15606 ;; 15607 pw32*) 15608 export_symbols_cmds_CXX=$ltdll_cmds 15609 ;; 15610 cygwin* | mingw* | cegcc*) 15611 case $cc_basename in 15612 cl*) 15613 exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' 15614 ;; 15615 *) 15616 export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' 15617 exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' 15618 ;; 15619 esac 15620 ;; 15621 linux* | k*bsd*-gnu | gnu*) 15622 link_all_deplibs_CXX=no 15623 ;; 15624 *) 15625 export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' 15626 ;; 15627 esac 15628 15629 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 15630 $as_echo "$ld_shlibs_CXX" >&6; } 15631 test no = "$ld_shlibs_CXX" && can_build_shared=no 15632 15633 with_gnu_ld_CXX=$with_gnu_ld 15634 15635 15636 15637 15638 15639 15640 # 15641 # Do we need to explicitly link libc? 15642 # 15643 case "x$archive_cmds_need_lc_CXX" in 15644 x|xyes) 15645 # Assume -lc should be added 15646 archive_cmds_need_lc_CXX=yes 15647 15648 if test yes,yes = "$GCC,$enable_shared"; then 15649 case $archive_cmds_CXX in 15650 *'~'*) 15651 # FIXME: we may have to deal with multi-command sequences. 15652 ;; 15653 '$CC '*) 15654 # Test whether the compiler implicitly links with -lc since on some 15655 # systems, -lgcc has to come before -lc. If gcc already passes -lc 15656 # to ld, don't add -lc before -lgcc. 15657 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 15658 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } 15659 if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : 15660 $as_echo_n "(cached) " >&6 15661 else 15662 $RM conftest* 15663 echo "$lt_simple_compile_test_code" > conftest.$ac_ext 15664 15665 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 15666 (eval $ac_compile) 2>&5 15667 ac_status=$? 15668 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 15669 test $ac_status = 0; } 2>conftest.err; then 15670 soname=conftest 15671 lib=conftest 15672 libobjs=conftest.$ac_objext 15673 deplibs= 15674 wl=$lt_prog_compiler_wl_CXX 15675 pic_flag=$lt_prog_compiler_pic_CXX 15676 compiler_flags=-v 15677 linker_flags=-v 15678 verstring= 15679 output_objdir=. 15680 libname=conftest 15681 lt_save_allow_undefined_flag=$allow_undefined_flag_CXX 15682 allow_undefined_flag_CXX= 15683 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 15684 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 15685 ac_status=$? 15686 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 15687 test $ac_status = 0; } 15688 then 15689 lt_cv_archive_cmds_need_lc_CXX=no 15690 else 15691 lt_cv_archive_cmds_need_lc_CXX=yes 15692 fi 15693 allow_undefined_flag_CXX=$lt_save_allow_undefined_flag 15694 else 15695 cat conftest.err 1>&5 15696 fi 15697 $RM conftest* 15698 15699 fi 15700 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 15701 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } 15702 archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX 15703 ;; 15704 esac 15705 fi 15706 ;; 15707 esac 15708 15709 15710 15711 15712 15713 15714 15715 15716 15717 15718 15719 15720 15721 15722 15723 15724 15725 15726 15727 15728 15729 15730 15731 15732 15733 15734 15735 15736 15737 15738 15739 15740 15741 15742 15743 15744 15745 15746 15747 15748 15749 15750 15751 15752 15753 15754 15755 15756 15757 15758 15759 15760 15761 15762 15763 15764 15765 15766 15767 15768 15769 15770 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 15771 $as_echo_n "checking dynamic linker characteristics... " >&6; } 15772 15773 library_names_spec= 15774 libname_spec='lib$name' 15775 soname_spec= 15776 shrext_cmds=.so 15777 postinstall_cmds= 15778 postuninstall_cmds= 15779 finish_cmds= 15780 finish_eval= 15781 shlibpath_var= 15782 shlibpath_overrides_runpath=unknown 15783 version_type=none 15784 dynamic_linker="$host_os ld.so" 15785 sys_lib_dlsearch_path_spec="/lib /usr/lib" 15786 need_lib_prefix=unknown 15787 hardcode_into_libs=no 15788 15789 # when you set need_version to no, make sure it does not cause -set_version 15790 # flags to be left without arguments 15791 need_version=unknown 15792 15793 15794 15795 case $host_os in 15796 aix3*) 15797 version_type=linux # correct to gnu/linux during the next big refactor 15798 library_names_spec='$libname$release$shared_ext$versuffix $libname.a' 15799 shlibpath_var=LIBPATH 15800 15801 # AIX 3 has no versioning support, so we append a major version to the name. 15802 soname_spec='$libname$release$shared_ext$major' 15803 ;; 15804 15805 aix[4-9]*) 15806 version_type=linux # correct to gnu/linux during the next big refactor 15807 need_lib_prefix=no 15808 need_version=no 15809 hardcode_into_libs=yes 15810 if test ia64 = "$host_cpu"; then 15811 # AIX 5 supports IA64 15812 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' 15813 shlibpath_var=LD_LIBRARY_PATH 15814 else 15815 # With GCC up to 2.95.x, collect2 would create an import file 15816 # for dependence libraries. The import file would start with 15817 # the line '#! .'. This would cause the generated library to 15818 # depend on '.', always an invalid library. This was fixed in 15819 # development snapshots of GCC prior to 3.0. 15820 case $host_os in 15821 aix4 | aix4.[01] | aix4.[01].*) 15822 if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' 15823 echo ' yes ' 15824 echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then 15825 : 15826 else 15827 can_build_shared=no 15828 fi 15829 ;; 15830 esac 15831 # Using Import Files as archive members, it is possible to support 15832 # filename-based versioning of shared library archives on AIX. While 15833 # this would work for both with and without runtime linking, it will 15834 # prevent static linking of such archives. So we do filename-based 15835 # shared library versioning with .so extension only, which is used 15836 # when both runtime linking and shared linking is enabled. 15837 # Unfortunately, runtime linking may impact performance, so we do 15838 # not want this to be the default eventually. Also, we use the 15839 # versioned .so libs for executables only if there is the -brtl 15840 # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. 15841 # To allow for filename-based versioning support, we need to create 15842 # libNAME.so.V as an archive file, containing: 15843 # *) an Import File, referring to the versioned filename of the 15844 # archive as well as the shared archive member, telling the 15845 # bitwidth (32 or 64) of that shared object, and providing the 15846 # list of exported symbols of that shared object, eventually 15847 # decorated with the 'weak' keyword 15848 # *) the shared object with the F_LOADONLY flag set, to really avoid 15849 # it being seen by the linker. 15850 # At run time we better use the real file rather than another symlink, 15851 # but for link time we create the symlink libNAME.so -> libNAME.so.V 15852 15853 case $with_aix_soname,$aix_use_runtimelinking in 15854 # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct 15855 # soname into executable. Probably we can add versioning support to 15856 # collect2, so additional links can be useful in future. 15857 aix,yes) # traditional libtool 15858 dynamic_linker='AIX unversionable lib.so' 15859 # If using run time linking (on AIX 4.2 or later) use lib<name>.so 15860 # instead of lib<name>.a to let people know that these are not 15861 # typical AIX shared libraries. 15862 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 15863 ;; 15864 aix,no) # traditional AIX only 15865 dynamic_linker='AIX lib.a(lib.so.V)' 15866 # We preserve .a as extension for shared libraries through AIX4.2 15867 # and later when we are not doing run time linking. 15868 library_names_spec='$libname$release.a $libname.a' 15869 soname_spec='$libname$release$shared_ext$major' 15870 ;; 15871 svr4,*) # full svr4 only 15872 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" 15873 library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' 15874 # We do not specify a path in Import Files, so LIBPATH fires. 15875 shlibpath_overrides_runpath=yes 15876 ;; 15877 *,yes) # both, prefer svr4 15878 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" 15879 library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' 15880 # unpreferred sharedlib libNAME.a needs extra handling 15881 postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' 15882 postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' 15883 # We do not specify a path in Import Files, so LIBPATH fires. 15884 shlibpath_overrides_runpath=yes 15885 ;; 15886 *,no) # both, prefer aix 15887 dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" 15888 library_names_spec='$libname$release.a $libname.a' 15889 soname_spec='$libname$release$shared_ext$major' 15890 # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling 15891 postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' 15892 postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' 15893 ;; 15894 esac 15895 shlibpath_var=LIBPATH 15896 fi 15897 ;; 15898 15899 amigaos*) 15900 case $host_cpu in 15901 powerpc) 15902 # Since July 2007 AmigaOS4 officially supports .so libraries. 15903 # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. 15904 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 15905 ;; 15906 m68k) 15907 library_names_spec='$libname.ixlibrary $libname.a' 15908 # Create ${libname}_ixlibrary.a entries in /sys/libs. 15909 finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' 15910 ;; 15911 esac 15912 ;; 15913 15914 beos*) 15915 library_names_spec='$libname$shared_ext' 15916 dynamic_linker="$host_os ld.so" 15917 shlibpath_var=LIBRARY_PATH 15918 ;; 15919 15920 bsdi[45]*) 15921 version_type=linux # correct to gnu/linux during the next big refactor 15922 need_version=no 15923 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 15924 soname_spec='$libname$release$shared_ext$major' 15925 finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' 15926 shlibpath_var=LD_LIBRARY_PATH 15927 sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" 15928 sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" 15929 # the default ld.so.conf also contains /usr/contrib/lib and 15930 # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow 15931 # libtool to hard-code these into programs 15932 ;; 15933 15934 cygwin* | mingw* | pw32* | cegcc*) 15935 version_type=windows 15936 shrext_cmds=.dll 15937 need_version=no 15938 need_lib_prefix=no 15939 15940 case $GCC,$cc_basename in 15941 yes,*) 15942 # gcc 15943 library_names_spec='$libname.dll.a' 15944 # DLL is installed to $(libdir)/../bin by postinstall_cmds 15945 postinstall_cmds='base_file=`basename \$file`~ 15946 dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ 15947 dldir=$destdir/`dirname \$dlpath`~ 15948 test -d \$dldir || mkdir -p \$dldir~ 15949 $install_prog $dir/$dlname \$dldir/$dlname~ 15950 chmod a+x \$dldir/$dlname~ 15951 if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then 15952 eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; 15953 fi' 15954 postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ 15955 dlpath=$dir/\$dldll~ 15956 $RM \$dlpath' 15957 shlibpath_overrides_runpath=yes 15958 15959 case $host_os in 15960 cygwin*) 15961 # Cygwin DLLs use 'cyg' prefix rather than 'lib' 15962 soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 15963 15964 ;; 15965 mingw* | cegcc*) 15966 # MinGW DLLs use traditional 'lib' prefix 15967 soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 15968 ;; 15969 pw32*) 15970 # pw32 DLLs use 'pw' prefix rather than 'lib' 15971 library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 15972 ;; 15973 esac 15974 dynamic_linker='Win32 ld.exe' 15975 ;; 15976 15977 *,cl*) 15978 # Native MSVC 15979 libname_spec='$name' 15980 soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' 15981 library_names_spec='$libname.dll.lib' 15982 15983 case $build_os in 15984 mingw*) 15985 sys_lib_search_path_spec= 15986 lt_save_ifs=$IFS 15987 IFS=';' 15988 for lt_path in $LIB 15989 do 15990 IFS=$lt_save_ifs 15991 # Let DOS variable expansion print the short 8.3 style file name. 15992 lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` 15993 sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" 15994 done 15995 IFS=$lt_save_ifs 15996 # Convert to MSYS style. 15997 sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` 15998 ;; 15999 cygwin*) 16000 # Convert to unix form, then to dos form, then back to unix form 16001 # but this time dos style (no spaces!) so that the unix form looks 16002 # like /cygdrive/c/PROGRA~1:/cygdr... 16003 sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` 16004 sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` 16005 sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` 16006 ;; 16007 *) 16008 sys_lib_search_path_spec=$LIB 16009 if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then 16010 # It is most probably a Windows format PATH. 16011 sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` 16012 else 16013 sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` 16014 fi 16015 # FIXME: find the short name or the path components, as spaces are 16016 # common. (e.g. "Program Files" -> "PROGRA~1") 16017 ;; 16018 esac 16019 16020 # DLL is installed to $(libdir)/../bin by postinstall_cmds 16021 postinstall_cmds='base_file=`basename \$file`~ 16022 dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ 16023 dldir=$destdir/`dirname \$dlpath`~ 16024 test -d \$dldir || mkdir -p \$dldir~ 16025 $install_prog $dir/$dlname \$dldir/$dlname' 16026 postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ 16027 dlpath=$dir/\$dldll~ 16028 $RM \$dlpath' 16029 shlibpath_overrides_runpath=yes 16030 dynamic_linker='Win32 link.exe' 16031 ;; 16032 16033 *) 16034 # Assume MSVC wrapper 16035 library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' 16036 dynamic_linker='Win32 ld.exe' 16037 ;; 16038 esac 16039 # FIXME: first we should search . and the directory the executable is in 16040 shlibpath_var=PATH 16041 ;; 16042 16043 darwin* | rhapsody*) 16044 dynamic_linker="$host_os dyld" 16045 version_type=darwin 16046 need_lib_prefix=no 16047 need_version=no 16048 library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' 16049 soname_spec='$libname$release$major$shared_ext' 16050 shlibpath_overrides_runpath=yes 16051 shlibpath_var=DYLD_LIBRARY_PATH 16052 shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' 16053 16054 sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' 16055 ;; 16056 16057 dgux*) 16058 version_type=linux # correct to gnu/linux during the next big refactor 16059 need_lib_prefix=no 16060 need_version=no 16061 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16062 soname_spec='$libname$release$shared_ext$major' 16063 shlibpath_var=LD_LIBRARY_PATH 16064 ;; 16065 16066 freebsd* | dragonfly*) 16067 # DragonFly does not have aout. When/if they implement a new 16068 # versioning mechanism, adjust this. 16069 if test -x /usr/bin/objformat; then 16070 objformat=`/usr/bin/objformat` 16071 else 16072 case $host_os in 16073 freebsd[23].*) objformat=aout ;; 16074 *) objformat=elf ;; 16075 esac 16076 fi 16077 version_type=freebsd-$objformat 16078 case $version_type in 16079 freebsd-elf*) 16080 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16081 soname_spec='$libname$release$shared_ext$major' 16082 need_version=no 16083 need_lib_prefix=no 16084 ;; 16085 freebsd-*) 16086 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 16087 need_version=yes 16088 ;; 16089 esac 16090 shlibpath_var=LD_LIBRARY_PATH 16091 case $host_os in 16092 freebsd2.*) 16093 shlibpath_overrides_runpath=yes 16094 ;; 16095 freebsd3.[01]* | freebsdelf3.[01]*) 16096 shlibpath_overrides_runpath=yes 16097 hardcode_into_libs=yes 16098 ;; 16099 freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ 16100 freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) 16101 shlibpath_overrides_runpath=no 16102 hardcode_into_libs=yes 16103 ;; 16104 *) # from 4.6 on, and DragonFly 16105 shlibpath_overrides_runpath=yes 16106 hardcode_into_libs=yes 16107 ;; 16108 esac 16109 ;; 16110 16111 haiku*) 16112 version_type=linux # correct to gnu/linux during the next big refactor 16113 need_lib_prefix=no 16114 need_version=no 16115 dynamic_linker="$host_os runtime_loader" 16116 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16117 soname_spec='$libname$release$shared_ext$major' 16118 shlibpath_var=LIBRARY_PATH 16119 shlibpath_overrides_runpath=no 16120 sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' 16121 hardcode_into_libs=yes 16122 ;; 16123 16124 hpux9* | hpux10* | hpux11*) 16125 # Give a soname corresponding to the major version so that dld.sl refuses to 16126 # link against other versions. 16127 version_type=sunos 16128 need_lib_prefix=no 16129 need_version=no 16130 case $host_cpu in 16131 ia64*) 16132 shrext_cmds='.so' 16133 hardcode_into_libs=yes 16134 dynamic_linker="$host_os dld.so" 16135 shlibpath_var=LD_LIBRARY_PATH 16136 shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. 16137 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16138 soname_spec='$libname$release$shared_ext$major' 16139 if test 32 = "$HPUX_IA64_MODE"; then 16140 sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" 16141 sys_lib_dlsearch_path_spec=/usr/lib/hpux32 16142 else 16143 sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" 16144 sys_lib_dlsearch_path_spec=/usr/lib/hpux64 16145 fi 16146 ;; 16147 hppa*64*) 16148 shrext_cmds='.sl' 16149 hardcode_into_libs=yes 16150 dynamic_linker="$host_os dld.sl" 16151 shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH 16152 shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. 16153 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16154 soname_spec='$libname$release$shared_ext$major' 16155 sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" 16156 sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 16157 ;; 16158 *) 16159 shrext_cmds='.sl' 16160 dynamic_linker="$host_os dld.sl" 16161 shlibpath_var=SHLIB_PATH 16162 shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH 16163 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16164 soname_spec='$libname$release$shared_ext$major' 16165 ;; 16166 esac 16167 # HP-UX runs *really* slowly unless shared libraries are mode 555, ... 16168 postinstall_cmds='chmod 555 $lib' 16169 # or fails outright, so override atomically: 16170 install_override_mode=555 16171 ;; 16172 16173 interix[3-9]*) 16174 version_type=linux # correct to gnu/linux during the next big refactor 16175 need_lib_prefix=no 16176 need_version=no 16177 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16178 soname_spec='$libname$release$shared_ext$major' 16179 dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' 16180 shlibpath_var=LD_LIBRARY_PATH 16181 shlibpath_overrides_runpath=no 16182 hardcode_into_libs=yes 16183 ;; 16184 16185 irix5* | irix6* | nonstopux*) 16186 case $host_os in 16187 nonstopux*) version_type=nonstopux ;; 16188 *) 16189 if test yes = "$lt_cv_prog_gnu_ld"; then 16190 version_type=linux # correct to gnu/linux during the next big refactor 16191 else 16192 version_type=irix 16193 fi ;; 16194 esac 16195 need_lib_prefix=no 16196 need_version=no 16197 soname_spec='$libname$release$shared_ext$major' 16198 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' 16199 case $host_os in 16200 irix5* | nonstopux*) 16201 libsuff= shlibsuff= 16202 ;; 16203 *) 16204 case $LD in # libtool.m4 will add one of these switches to LD 16205 *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") 16206 libsuff= shlibsuff= libmagic=32-bit;; 16207 *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") 16208 libsuff=32 shlibsuff=N32 libmagic=N32;; 16209 *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") 16210 libsuff=64 shlibsuff=64 libmagic=64-bit;; 16211 *) libsuff= shlibsuff= libmagic=never-match;; 16212 esac 16213 ;; 16214 esac 16215 shlibpath_var=LD_LIBRARY${shlibsuff}_PATH 16216 shlibpath_overrides_runpath=no 16217 sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" 16218 sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" 16219 hardcode_into_libs=yes 16220 ;; 16221 16222 # No shared lib support for Linux oldld, aout, or coff. 16223 linux*oldld* | linux*aout* | linux*coff*) 16224 dynamic_linker=no 16225 ;; 16226 16227 linux*android*) 16228 version_type=none # Android doesn't support versioned libraries. 16229 need_lib_prefix=no 16230 need_version=no 16231 library_names_spec='$libname$release$shared_ext' 16232 soname_spec='$libname$release$shared_ext' 16233 finish_cmds= 16234 shlibpath_var=LD_LIBRARY_PATH 16235 shlibpath_overrides_runpath=yes 16236 16237 # This implies no fast_install, which is unacceptable. 16238 # Some rework will be needed to allow for fast_install 16239 # before this can be enabled. 16240 hardcode_into_libs=yes 16241 16242 dynamic_linker='Android linker' 16243 # Don't embed -rpath directories since the linker doesn't support them. 16244 hardcode_libdir_flag_spec_CXX='-L$libdir' 16245 ;; 16246 16247 # This must be glibc/ELF. 16248 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) 16249 version_type=linux # correct to gnu/linux during the next big refactor 16250 need_lib_prefix=no 16251 need_version=no 16252 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16253 soname_spec='$libname$release$shared_ext$major' 16254 finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' 16255 shlibpath_var=LD_LIBRARY_PATH 16256 shlibpath_overrides_runpath=no 16257 16258 # Some binutils ld are patched to set DT_RUNPATH 16259 if ${lt_cv_shlibpath_overrides_runpath+:} false; then : 16260 $as_echo_n "(cached) " >&6 16261 else 16262 lt_cv_shlibpath_overrides_runpath=no 16263 save_LDFLAGS=$LDFLAGS 16264 save_libdir=$libdir 16265 eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ 16266 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" 16267 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 16268 /* end confdefs.h. */ 16269 16270 int 16271 main () 16272 { 16273 16274 ; 16275 return 0; 16276 } 16277 _ACEOF 16278 if ac_fn_cxx_try_link "$LINENO"; then : 16279 if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : 16280 lt_cv_shlibpath_overrides_runpath=yes 16281 fi 16282 fi 16283 rm -f core conftest.err conftest.$ac_objext \ 16284 conftest$ac_exeext conftest.$ac_ext 16285 LDFLAGS=$save_LDFLAGS 16286 libdir=$save_libdir 16287 16288 fi 16289 16290 shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath 16291 16292 # This implies no fast_install, which is unacceptable. 16293 # Some rework will be needed to allow for fast_install 16294 # before this can be enabled. 16295 hardcode_into_libs=yes 16296 16297 # Ideally, we could use ldconfig to report *all* directores which are 16298 # searched for libraries, however this is still not possible. Aside from not 16299 # being certain /sbin/ldconfig is available, command 16300 # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, 16301 # even though it is searched at run-time. Try to do the best guess by 16302 # appending ld.so.conf contents (and includes) to the search path. 16303 if test -f /etc/ld.so.conf; then 16304 lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` 16305 sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" 16306 fi 16307 16308 # We used to test for /lib/ld.so.1 and disable shared libraries on 16309 # powerpc, because MkLinux only supported shared libraries with the 16310 # GNU dynamic linker. Since this was broken with cross compilers, 16311 # most powerpc-linux boxes support dynamic linking these days and 16312 # people can always --disable-shared, the test was removed, and we 16313 # assume the GNU/Linux dynamic linker is in use. 16314 dynamic_linker='GNU/Linux ld.so' 16315 ;; 16316 16317 netbsdelf*-gnu) 16318 version_type=linux 16319 need_lib_prefix=no 16320 need_version=no 16321 library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' 16322 soname_spec='${libname}${release}${shared_ext}$major' 16323 shlibpath_var=LD_LIBRARY_PATH 16324 shlibpath_overrides_runpath=no 16325 hardcode_into_libs=yes 16326 dynamic_linker='NetBSD ld.elf_so' 16327 ;; 16328 16329 netbsd*) 16330 version_type=sunos 16331 need_lib_prefix=no 16332 need_version=no 16333 if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then 16334 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 16335 finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' 16336 dynamic_linker='NetBSD (a.out) ld.so' 16337 else 16338 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16339 soname_spec='$libname$release$shared_ext$major' 16340 dynamic_linker='NetBSD ld.elf_so' 16341 fi 16342 shlibpath_var=LD_LIBRARY_PATH 16343 shlibpath_overrides_runpath=yes 16344 hardcode_into_libs=yes 16345 ;; 16346 16347 newsos6) 16348 version_type=linux # correct to gnu/linux during the next big refactor 16349 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16350 shlibpath_var=LD_LIBRARY_PATH 16351 shlibpath_overrides_runpath=yes 16352 ;; 16353 16354 *nto* | *qnx*) 16355 version_type=qnx 16356 need_lib_prefix=no 16357 need_version=no 16358 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16359 soname_spec='$libname$release$shared_ext$major' 16360 shlibpath_var=LD_LIBRARY_PATH 16361 shlibpath_overrides_runpath=no 16362 hardcode_into_libs=yes 16363 dynamic_linker='ldqnx.so' 16364 ;; 16365 16366 openbsd* | bitrig*) 16367 version_type=sunos 16368 sys_lib_dlsearch_path_spec=/usr/lib 16369 need_lib_prefix=no 16370 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then 16371 need_version=no 16372 else 16373 need_version=yes 16374 fi 16375 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 16376 finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' 16377 shlibpath_var=LD_LIBRARY_PATH 16378 shlibpath_overrides_runpath=yes 16379 ;; 16380 16381 os2*) 16382 libname_spec='$name' 16383 version_type=windows 16384 shrext_cmds=.dll 16385 need_version=no 16386 need_lib_prefix=no 16387 # OS/2 can only load a DLL with a base name of 8 characters or less. 16388 soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; 16389 v=$($ECHO $release$versuffix | tr -d .-); 16390 n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); 16391 $ECHO $n$v`$shared_ext' 16392 library_names_spec='${libname}_dll.$libext' 16393 dynamic_linker='OS/2 ld.exe' 16394 shlibpath_var=BEGINLIBPATH 16395 sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" 16396 sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 16397 postinstall_cmds='base_file=`basename \$file`~ 16398 dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ 16399 dldir=$destdir/`dirname \$dlpath`~ 16400 test -d \$dldir || mkdir -p \$dldir~ 16401 $install_prog $dir/$dlname \$dldir/$dlname~ 16402 chmod a+x \$dldir/$dlname~ 16403 if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then 16404 eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; 16405 fi' 16406 postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ 16407 dlpath=$dir/\$dldll~ 16408 $RM \$dlpath' 16409 ;; 16410 16411 osf3* | osf4* | osf5*) 16412 version_type=osf 16413 need_lib_prefix=no 16414 need_version=no 16415 soname_spec='$libname$release$shared_ext$major' 16416 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16417 shlibpath_var=LD_LIBRARY_PATH 16418 sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" 16419 sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 16420 ;; 16421 16422 rdos*) 16423 dynamic_linker=no 16424 ;; 16425 16426 solaris*) 16427 version_type=linux # correct to gnu/linux during the next big refactor 16428 need_lib_prefix=no 16429 need_version=no 16430 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16431 soname_spec='$libname$release$shared_ext$major' 16432 shlibpath_var=LD_LIBRARY_PATH 16433 shlibpath_overrides_runpath=yes 16434 hardcode_into_libs=yes 16435 # ldd complains unless libraries are executable 16436 postinstall_cmds='chmod +x $lib' 16437 ;; 16438 16439 sunos4*) 16440 version_type=sunos 16441 library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' 16442 finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' 16443 shlibpath_var=LD_LIBRARY_PATH 16444 shlibpath_overrides_runpath=yes 16445 if test yes = "$with_gnu_ld"; then 16446 need_lib_prefix=no 16447 fi 16448 need_version=yes 16449 ;; 16450 16451 sysv4 | sysv4.3*) 16452 version_type=linux # correct to gnu/linux during the next big refactor 16453 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16454 soname_spec='$libname$release$shared_ext$major' 16455 shlibpath_var=LD_LIBRARY_PATH 16456 case $host_vendor in 16457 sni) 16458 shlibpath_overrides_runpath=no 16459 need_lib_prefix=no 16460 runpath_var=LD_RUN_PATH 16461 ;; 16462 siemens) 16463 need_lib_prefix=no 16464 ;; 16465 motorola) 16466 need_lib_prefix=no 16467 need_version=no 16468 shlibpath_overrides_runpath=no 16469 sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' 16470 ;; 16471 esac 16472 ;; 16473 16474 sysv4*MP*) 16475 if test -d /usr/nec; then 16476 version_type=linux # correct to gnu/linux during the next big refactor 16477 library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' 16478 soname_spec='$libname$shared_ext.$major' 16479 shlibpath_var=LD_LIBRARY_PATH 16480 fi 16481 ;; 16482 16483 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) 16484 version_type=sco 16485 need_lib_prefix=no 16486 need_version=no 16487 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' 16488 soname_spec='$libname$release$shared_ext$major' 16489 shlibpath_var=LD_LIBRARY_PATH 16490 shlibpath_overrides_runpath=yes 16491 hardcode_into_libs=yes 16492 if test yes = "$with_gnu_ld"; then 16493 sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' 16494 else 16495 sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' 16496 case $host_os in 16497 sco3.2v5*) 16498 sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" 16499 ;; 16500 esac 16501 fi 16502 sys_lib_dlsearch_path_spec='/usr/lib' 16503 ;; 16504 16505 tpf*) 16506 # TPF is a cross-target only. Preferred cross-host = GNU/Linux. 16507 version_type=linux # correct to gnu/linux during the next big refactor 16508 need_lib_prefix=no 16509 need_version=no 16510 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16511 shlibpath_var=LD_LIBRARY_PATH 16512 shlibpath_overrides_runpath=no 16513 hardcode_into_libs=yes 16514 ;; 16515 16516 uts4*) 16517 version_type=linux # correct to gnu/linux during the next big refactor 16518 library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 16519 soname_spec='$libname$release$shared_ext$major' 16520 shlibpath_var=LD_LIBRARY_PATH 16521 ;; 16522 16523 *) 16524 dynamic_linker=no 16525 ;; 16526 esac 16527 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 16528 $as_echo "$dynamic_linker" >&6; } 16529 test no = "$dynamic_linker" && can_build_shared=no 16530 16531 variables_saved_for_relink="PATH $shlibpath_var $runpath_var" 16532 if test yes = "$GCC"; then 16533 variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" 16534 fi 16535 16536 if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then 16537 sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec 16538 fi 16539 16540 if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then 16541 sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec 16542 fi 16543 16544 # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... 16545 configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec 16546 16547 # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code 16548 func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" 16549 16550 # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool 16551 configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH 16552 16553 16554 16555 16556 16557 16558 16559 16560 16561 16562 16563 16564 16565 16566 16567 16568 16569 16570 16571 16572 16573 16574 16575 16576 16577 16578 16579 16580 16581 16582 16583 16584 16585 16586 16587 16588 16589 16590 16591 16592 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 16593 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } 16594 hardcode_action_CXX= 16595 if test -n "$hardcode_libdir_flag_spec_CXX" || 16596 test -n "$runpath_var_CXX" || 16597 test yes = "$hardcode_automatic_CXX"; then 16598 16599 # We can hardcode non-existent directories. 16600 if test no != "$hardcode_direct_CXX" && 16601 # If the only mechanism to avoid hardcoding is shlibpath_var, we 16602 # have to relink, otherwise we might link with an installed library 16603 # when we should be linking with a yet-to-be-installed one 16604 ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && 16605 test no != "$hardcode_minus_L_CXX"; then 16606 # Linking always hardcodes the temporary library directory. 16607 hardcode_action_CXX=relink 16608 else 16609 # We can link without hardcoding, and we can hardcode nonexisting dirs. 16610 hardcode_action_CXX=immediate 16611 fi 16612 else 16613 # We cannot hardcode anything, or else we can only hardcode existing 16614 # directories. 16615 hardcode_action_CXX=unsupported 16616 fi 16617 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 16618 $as_echo "$hardcode_action_CXX" >&6; } 16619 16620 if test relink = "$hardcode_action_CXX" || 16621 test yes = "$inherit_rpath_CXX"; then 16622 # Fast installation is not supported 16623 enable_fast_install=no 16624 elif test yes = "$shlibpath_overrides_runpath" || 16625 test no = "$enable_shared"; then 16626 # Fast installation is not necessary 16627 enable_fast_install=needless 16628 fi 16629 16630 16631 16632 16633 16634 16635 16636 fi # test -n "$compiler" 16637 16638 CC=$lt_save_CC 16639 CFLAGS=$lt_save_CFLAGS 16640 LDCXX=$LD 16641 LD=$lt_save_LD 16642 GCC=$lt_save_GCC 16643 with_gnu_ld=$lt_save_with_gnu_ld 16644 lt_cv_path_LDCXX=$lt_cv_path_LD 16645 lt_cv_path_LD=$lt_save_path_LD 16646 lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld 16647 lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld 16648 fi # test yes != "$_lt_caught_CXX_error" 16649 16650 ac_ext=c 16651 ac_cpp='$CPP $CPPFLAGS' 16652 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 16653 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' 16654 ac_compiler_gnu=$ac_cv_c_compiler_gnu 16655 16656 16657 16658 16659 16660 16661 16662 16663 16664 16665 16666 16667 16668 16669 16670 ac_config_commands="$ac_config_commands libtool" 16671 16672 16673 16674 16675 # Only expand once: 16676 16677 16678 16679 16680 # Checks for libraries. 16681 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fibre::yield in -lfibre" >&5 16682 $as_echo_n "checking for Fibre::yield in -lfibre... " >&6; } 16683 if ${ac_cv_lib_fibre_Fibre__yield+:} false; then : 16684 $as_echo_n "(cached) " >&6 16685 else 16686 ac_check_lib_save_LIBS=$LIBS 16687 LIBS="-lfibre $LIBS" 16688 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 16689 /* end confdefs.h. */ 16690 16691 /* Override any GCC internal prototype to avoid an error. 16692 Use char because int might match the return type of a GCC 16693 builtin and then its argument prototype would still apply. */ 16694 #ifdef __cplusplus 16695 extern "C" 16696 #endif 16697 char Fibre::yield (); 16698 int 16699 main () 16700 { 16701 return Fibre::yield (); 16702 ; 16703 return 0; 16704 } 16705 _ACEOF 16706 if ac_fn_c_try_link "$LINENO"; then : 16707 ac_cv_lib_fibre_Fibre__yield=yes 16708 else 16709 ac_cv_lib_fibre_Fibre__yield=no 16710 fi 16711 rm -f core conftest.err conftest.$ac_objext \ 16712 conftest$ac_exeext conftest.$ac_ext 16713 LIBS=$ac_check_lib_save_LIBS 16714 fi 16715 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fibre_Fibre__yield" >&5 16716 $as_echo "$ac_cv_lib_fibre_Fibre__yield" >&6; } 16717 if test "x$ac_cv_lib_fibre_Fibre__yield" = xyes; then : 16718 HAVE_LIBFIBRE=1 16719 else 16720 HAVE_LIBFIBRE=0 16721 fi 16722 16723 if test "$HAVE_LIBFIBRE" -eq 1; then 16724 WITH_LIBFIBRE_TRUE= 16725 WITH_LIBFIBRE_FALSE='#' 16726 else 16727 WITH_LIBFIBRE_TRUE='#' 16728 WITH_LIBFIBRE_FALSE= 16729 fi 16730 16731 16732 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ProfilingIsEnabledForAllThreads in -lprofiler" >&5 16733 $as_echo_n "checking for ProfilingIsEnabledForAllThreads in -lprofiler... " >&6; } 16734 if ${ac_cv_lib_profiler_ProfilingIsEnabledForAllThreads+:} false; then : 16735 $as_echo_n "(cached) " >&6 16736 else 16737 ac_check_lib_save_LIBS=$LIBS 16738 LIBS="-lprofiler $LIBS" 16739 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 16740 /* end confdefs.h. */ 16741 16742 /* Override any GCC internal prototype to avoid an error. 16743 Use char because int might match the return type of a GCC 16744 builtin and then its argument prototype would still apply. */ 16745 #ifdef __cplusplus 16746 extern "C" 16747 #endif 16748 char ProfilingIsEnabledForAllThreads (); 16749 int 16750 main () 16751 { 16752 return ProfilingIsEnabledForAllThreads (); 16753 ; 16754 return 0; 16755 } 16756 _ACEOF 16757 if ac_fn_c_try_link "$LINENO"; then : 16758 ac_cv_lib_profiler_ProfilingIsEnabledForAllThreads=yes 16759 else 16760 ac_cv_lib_profiler_ProfilingIsEnabledForAllThreads=no 16761 fi 16762 rm -f core conftest.err conftest.$ac_objext \ 16763 conftest$ac_exeext conftest.$ac_ext 16764 LIBS=$ac_check_lib_save_LIBS 16765 fi 16766 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_profiler_ProfilingIsEnabledForAllThreads" >&5 16767 $as_echo "$ac_cv_lib_profiler_ProfilingIsEnabledForAllThreads" >&6; } 16768 if test "x$ac_cv_lib_profiler_ProfilingIsEnabledForAllThreads" = xyes; then : 16769 HAVE_LIBPROFILER=1 16770 else 16771 HAVE_LIBPROFILER=0 16772 fi 16773 16774 if test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBPROFILER" -eq 1; then 16775 WITH_LIBPROFILER_TRUE= 16776 WITH_LIBPROFILER_FALSE='#' 16777 else 16778 WITH_LIBPROFILER_TRUE='#' 16779 WITH_LIBPROFILER_FALSE= 16780 fi 16781 16782 16783 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for malloc in -ltcmalloc" >&5 16784 $as_echo_n "checking for malloc in -ltcmalloc... " >&6; } 16785 if ${ac_cv_lib_tcmalloc_malloc+:} false; then : 16786 $as_echo_n "(cached) " >&6 16787 else 16788 ac_check_lib_save_LIBS=$LIBS 16789 LIBS="-ltcmalloc $LIBS" 16790 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 16791 /* end confdefs.h. */ 16792 16793 /* Override any GCC internal prototype to avoid an error. 16794 Use char because int might match the return type of a GCC 16795 builtin and then its argument prototype would still apply. */ 16796 #ifdef __cplusplus 16797 extern "C" 16798 #endif 16799 char malloc (); 16800 int 16801 main () 16802 { 16803 return malloc (); 16804 ; 16805 return 0; 16806 } 16807 _ACEOF 16808 if ac_fn_c_try_link "$LINENO"; then : 16809 ac_cv_lib_tcmalloc_malloc=yes 16810 else 16811 ac_cv_lib_tcmalloc_malloc=no 16812 fi 16813 rm -f core conftest.err conftest.$ac_objext \ 16814 conftest$ac_exeext conftest.$ac_ext 16815 LIBS=$ac_check_lib_save_LIBS 16816 fi 16817 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tcmalloc_malloc" >&5 16818 $as_echo "$ac_cv_lib_tcmalloc_malloc" >&6; } 16819 if test "x$ac_cv_lib_tcmalloc_malloc" = xyes; then : 16820 HAVE_LIBTCMALLOC=1 16821 else 16822 HAVE_LIBTCMALLOC=0 16823 fi 16824 16825 if test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBTCMALLOC" -eq 1; then 16826 WITH_LIBTCMALLOC_TRUE= 16827 WITH_LIBTCMALLOC_FALSE='#' 16828 else 16829 WITH_LIBTCMALLOC_TRUE='#' 16830 WITH_LIBTCMALLOC_FALSE= 16831 fi 16832 16833 16834 # conditionnally build the demangler 16835 if test "x$enable_demangler" == xyes; then 16836 LIBDEMANGLE="libdemangle.a" 16837 DEMANGLER="demangler" 16838 else 16839 LIBDEMANGLE="" 16840 DEMANGLER="" 16841 fi 16842 16843 16844 16845 # Checks for header files. 16846 for ac_header in libintl.h malloc.h unistd.h 6000 16847 do : 6001 16848 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` … … 6006 16853 _ACEOF 6007 16854 16855 else 16856 echo "Error: Missing required header"; exit 1 6008 16857 fi 6009 16858 … … 6012 16861 6013 16862 # Checks for typedefs, structures, and compiler characteristics. 6014 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 6015 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } 6016 if ${ac_cv_header_stdbool_h+:} false; then : 16863 ac_fn_c_check_type "$LINENO" "_Float32" "ac_cv_type__Float32" " 16864 " 16865 if test "x$ac_cv_type__Float32" = xyes; then : 16866 16867 cat >>confdefs.h <<_ACEOF 16868 #define HAVE__FLOAT32 1 16869 _ACEOF 16870 16871 16872 $as_echo "#define HAVE_KEYWORDS_FLOATXX /**/" >>confdefs.h 16873 16874 fi 16875 16876 16877 # Checks for compiler flags. 16878 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wcast-function-type" >&5 16879 $as_echo_n "checking whether C compiler accepts -Wcast-function-type... " >&6; } 16880 if ${m4cfa_cv_check_cflags___Wcast_function_type+:} false; then : 6017 16881 $as_echo_n "(cached) " >&6 6018 16882 else 6019 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 16883 16884 m4cfa_check_save_flags=$CFLAGS 16885 CFLAGS="$CFLAGS -Wcast-function-type" 16886 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 6020 16887 /* end confdefs.h. */ 6021 6022 #include <stdbool.h>6023 #ifndef bool6024 "error: bool is not defined"6025 #endif6026 #ifndef false6027 "error: false is not defined"6028 #endif6029 #if false6030 "error: false is not 0"6031 #endif6032 #ifndef true6033 "error: true is not defined"6034 #endif6035 #if true != 16036 "error: true is not 1"6037 #endif6038 #ifndef __bool_true_false_are_defined6039 "error: __bool_true_false_are_defined is not defined"6040 #endif6041 6042 struct s { _Bool s: 1; _Bool t; } s;6043 6044 char a[true == 1 ? 1 : -1];6045 char b[false == 0 ? 1 : -1];6046 char c[__bool_true_false_are_defined == 1 ? 1 : -1];6047 char d[(bool) 0.5 == true ? 1 : -1];6048 /* See body of main program for 'e'. */6049 char f[(_Bool) 0.0 == false ? 1 : -1];6050 char g[true];6051 char h[sizeof (_Bool)];6052 char i[sizeof s.t];6053 enum { j = false, k = true, l = false * true, m = true * 256 };6054 /* The following fails for6055 HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */6056 _Bool n[m];6057 char o[sizeof n == m * sizeof n[0] ? 1 : -1];6058 char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];6059 /* Catch a bug in an HP-UX C compiler. See6060 http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html6061 http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html6062 */6063 _Bool q = true;6064 _Bool *pq = &q;6065 16888 6066 16889 int 6067 16890 main () 6068 16891 { 6069 6070 bool e = &s;6071 *pq |= q;6072 *pq |= ! q;6073 /* Refer to every declared value, to avoid compiler optimizations. */6074 return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l6075 + !m + !n + !o + !p + !q + !pq);6076 16892 6077 16893 ; … … 6080 16896 _ACEOF 6081 16897 if ac_fn_c_try_compile "$LINENO"; then : 6082 ac_cv_header_stdbool_h=yes6083 else 6084 ac_cv_header_stdbool_h=no16898 m4cfa_cv_check_cflags___Wcast_function_type=yes 16899 else 16900 m4cfa_cv_check_cflags___Wcast_function_type=no 6085 16901 fi 6086 16902 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 6087 fi 6088 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 6089 $as_echo "$ac_cv_header_stdbool_h" >&6; } 6090 ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" 6091 if test "x$ac_cv_type__Bool" = xyes; then : 16903 CFLAGS=$m4cfa_check_save_flags 16904 fi 16905 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $m4cfa_cv_check_cflags___Wcast_function_type" >&5 16906 $as_echo "$m4cfa_cv_check_cflags___Wcast_function_type" >&6; } 16907 if test "x$m4cfa_cv_check_cflags___Wcast_function_type" = xyes; then : 16908 16909 $as_echo "#define HAVE_CAST_FUNCTION_TYPE /**/" >>confdefs.h 16910 16911 else 16912 : 16913 fi 16914 16915 16916 #============================================================================== 16917 # backend compiler implementation 6092 16918 6093 16919 cat >>confdefs.h <<_ACEOF 6094 #define HAVE__BOOL 116920 #define CFA_BACKEND_CC "${CC}" 6095 16921 _ACEOF 6096 16922 6097 16923 6098 fi 6099 6100 6101 if test $ac_cv_header_stdbool_h = yes; then 6102 6103 $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h 6104 6105 fi 6106 6107 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 6108 $as_echo_n "checking for inline... " >&6; } 6109 if ${ac_cv_c_inline+:} false; then : 6110 $as_echo_n "(cached) " >&6 6111 else 6112 ac_cv_c_inline=no 6113 for ac_kw in inline __inline__ __inline; do 6114 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 6115 /* end confdefs.h. */ 6116 #ifndef __cplusplus 6117 typedef int foo_t; 6118 static $ac_kw foo_t static_foo () {return 0; } 6119 $ac_kw foo_t foo () {return 0; } 6120 #endif 6121 6122 _ACEOF 6123 if ac_fn_c_try_compile "$LINENO"; then : 6124 ac_cv_c_inline=$ac_kw 6125 fi 6126 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 6127 test "$ac_cv_c_inline" != no && break 6128 done 6129 6130 fi 6131 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 6132 $as_echo "$ac_cv_c_inline" >&6; } 6133 6134 case $ac_cv_c_inline in 6135 inline | yes) ;; 6136 *) 6137 case $ac_cv_c_inline in 6138 no) ac_val=;; 6139 *) ac_val=$ac_cv_c_inline;; 6140 esac 6141 cat >>confdefs.h <<_ACEOF 6142 #ifndef __cplusplus 6143 #define inline $ac_val 6144 #endif 6145 _ACEOF 6146 ;; 6147 esac 6148 6149 ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" 6150 case $ac_cv_c_int16_t in #( 6151 no|yes) ;; #( 6152 *) 6153 6154 cat >>confdefs.h <<_ACEOF 6155 #define int16_t $ac_cv_c_int16_t 6156 _ACEOF 6157 ;; 6158 esac 6159 6160 ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" 6161 case $ac_cv_c_int32_t in #( 6162 no|yes) ;; #( 6163 *) 6164 6165 cat >>confdefs.h <<_ACEOF 6166 #define int32_t $ac_cv_c_int32_t 6167 _ACEOF 6168 ;; 6169 esac 6170 6171 ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t" 6172 case $ac_cv_c_int8_t in #( 6173 no|yes) ;; #( 6174 *) 6175 6176 cat >>confdefs.h <<_ACEOF 6177 #define int8_t $ac_cv_c_int8_t 6178 _ACEOF 6179 ;; 6180 esac 6181 6182 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5 6183 $as_echo_n "checking for C/C++ restrict keyword... " >&6; } 6184 if ${ac_cv_c_restrict+:} false; then : 6185 $as_echo_n "(cached) " >&6 6186 else 6187 ac_cv_c_restrict=no 6188 # The order here caters to the fact that C++ does not require restrict. 6189 for ac_kw in __restrict __restrict__ _Restrict restrict; do 6190 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 6191 /* end confdefs.h. */ 6192 typedef int * int_ptr; 6193 int foo (int_ptr $ac_kw ip) { 6194 return ip[0]; 6195 } 6196 int 6197 main () 6198 { 6199 int s[1]; 6200 int * $ac_kw t = s; 6201 t[0] = 0; 6202 return foo(t) 6203 ; 6204 return 0; 6205 } 6206 _ACEOF 6207 if ac_fn_c_try_compile "$LINENO"; then : 6208 ac_cv_c_restrict=$ac_kw 6209 fi 6210 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 6211 test "$ac_cv_c_restrict" != no && break 6212 done 6213 6214 fi 6215 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5 6216 $as_echo "$ac_cv_c_restrict" >&6; } 6217 6218 case $ac_cv_c_restrict in 6219 restrict) ;; 6220 no) $as_echo "#define restrict /**/" >>confdefs.h 6221 ;; 6222 *) cat >>confdefs.h <<_ACEOF 6223 #define restrict $ac_cv_c_restrict 6224 _ACEOF 6225 ;; 6226 esac 6227 6228 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" 6229 if test "x$ac_cv_type_size_t" = xyes; then : 6230 6231 else 6232 6233 cat >>confdefs.h <<_ACEOF 6234 #define size_t unsigned int 6235 _ACEOF 6236 6237 fi 6238 6239 ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" 6240 case $ac_cv_c_uint16_t in #( 6241 no|yes) ;; #( 6242 *) 6243 6244 6245 cat >>confdefs.h <<_ACEOF 6246 #define uint16_t $ac_cv_c_uint16_t 6247 _ACEOF 6248 ;; 6249 esac 6250 6251 ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" 6252 case $ac_cv_c_uint32_t in #( 6253 no|yes) ;; #( 6254 *) 6255 6256 $as_echo "#define _UINT32_T 1" >>confdefs.h 6257 6258 6259 cat >>confdefs.h <<_ACEOF 6260 #define uint32_t $ac_cv_c_uint32_t 6261 _ACEOF 6262 ;; 6263 esac 6264 6265 ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" 6266 case $ac_cv_c_uint8_t in #( 6267 no|yes) ;; #( 6268 *) 6269 6270 $as_echo "#define _UINT8_T 1" >>confdefs.h 6271 6272 6273 cat >>confdefs.h <<_ACEOF 6274 #define uint8_t $ac_cv_c_uint8_t 6275 _ACEOF 6276 ;; 6277 esac 6278 6279 6280 # Checks for library functions. 6281 for ac_func in memset putenv strchr strtol 6282 do : 6283 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` 6284 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" 6285 if eval test \"x\$"$as_ac_var"\" = x"yes"; then : 6286 cat >>confdefs.h <<_ACEOF 6287 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 6288 _ACEOF 6289 6290 fi 6291 done 6292 6293 6294 ac_config_files="$ac_config_files Makefile src/driver/Makefile src/Makefile src/benchmark/Makefile src/examples/Makefile src/tests/Makefile src/tests/preempt_longrun/Makefile src/prelude/Makefile src/libcfa/Makefile tools/Makefile tools/prettyprinter/Makefile" 6295 16924 16925 #============================================================================== 16926 ac_config_files="$ac_config_files Makefile driver/Makefile src/Makefile benchmark/Makefile tests/Makefile longrun_tests/Makefile tools/Makefile tools/prettyprinter/Makefile" 16927 16928 16929 ac_config_links="$ac_config_links tests/test.py:tests/test.py" 16930 16931 16932 ac_config_files="$ac_config_files tests/config.py" 6296 16933 6297 16934 cat >confcache <<\_ACEOF … … 6420 17057 fi 6421 17058 6422 if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then 6423 as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. 6424 Usually this means the macro was only invoked conditionally." "$LINENO" 5 6425 fi 6426 if test -z "${BUILD_RELEASE_TRUE}" && test -z "${BUILD_RELEASE_FALSE}"; then 6427 as_fn_error $? "conditional \"BUILD_RELEASE\" was never defined. 6428 Usually this means the macro was only invoked conditionally." "$LINENO" 5 6429 fi 6430 if test -z "${BUILD_DEBUG_TRUE}" && test -z "${BUILD_DEBUG_FALSE}"; then 6431 as_fn_error $? "conditional \"BUILD_DEBUG\" was never defined. 6432 Usually this means the macro was only invoked conditionally." "$LINENO" 5 6433 fi 6434 if test -z "${BUILD_NO_LIB_TRUE}" && test -z "${BUILD_NO_LIB_FALSE}"; then 6435 as_fn_error $? "conditional \"BUILD_NO_LIB\" was never defined. 6436 Usually this means the macro was only invoked conditionally." "$LINENO" 5 6437 fi 6438 if test -z "${BUILD_CONCURRENCY_TRUE}" && test -z "${BUILD_CONCURRENCY_FALSE}"; then 6439 as_fn_error $? "conditional \"BUILD_CONCURRENCY\" was never defined. 17059 if test -z "${ENABLE_DISTCC_TRUE}" && test -z "${ENABLE_DISTCC_FALSE}"; then 17060 as_fn_error $? "conditional \"ENABLE_DISTCC\" was never defined. 6440 17061 Usually this means the macro was only invoked conditionally." "$LINENO" 5 6441 17062 fi … … 6454 17075 if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then 6455 17076 as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. 17077 Usually this means the macro was only invoked conditionally." "$LINENO" 5 17078 fi 17079 if test -z "${WITH_LIBFIBRE_TRUE}" && test -z "${WITH_LIBFIBRE_FALSE}"; then 17080 as_fn_error $? "conditional \"WITH_LIBFIBRE\" was never defined. 17081 Usually this means the macro was only invoked conditionally." "$LINENO" 5 17082 fi 17083 if test -z "${WITH_LIBPROFILER_TRUE}" && test -z "${WITH_LIBPROFILER_FALSE}"; then 17084 as_fn_error $? "conditional \"WITH_LIBPROFILER\" was never defined. 17085 Usually this means the macro was only invoked conditionally." "$LINENO" 5 17086 fi 17087 if test -z "${WITH_LIBTCMALLOC_TRUE}" && test -z "${WITH_LIBTCMALLOC_FALSE}"; then 17088 as_fn_error $? "conditional \"WITH_LIBTCMALLOC\" was never defined. 6456 17089 Usually this means the macro was only invoked conditionally." "$LINENO" 5 6457 17090 fi … … 6880 17513 config_files="$ac_config_files" 6881 17514 config_headers="$ac_config_headers" 17515 config_links="$ac_config_links" 6882 17516 config_commands="$ac_config_commands" 6883 17517 … … 6909 17543 Configuration headers: 6910 17544 $config_headers 17545 17546 Configuration links: 17547 $config_links 6911 17548 6912 17549 Configuration commands: … … 7040 17677 AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" 7041 17678 17679 17680 # The HP-UX ksh and POSIX shell print the target directory to stdout 17681 # if CDPATH is set. 17682 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH 17683 17684 sed_quote_subst='$sed_quote_subst' 17685 double_quote_subst='$double_quote_subst' 17686 delay_variable_subst='$delay_variable_subst' 17687 macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' 17688 macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' 17689 enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' 17690 enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' 17691 pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' 17692 enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' 17693 shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' 17694 SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' 17695 ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' 17696 PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' 17697 host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' 17698 host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' 17699 host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' 17700 build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' 17701 build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' 17702 build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' 17703 SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' 17704 Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' 17705 GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' 17706 EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' 17707 FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' 17708 LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' 17709 NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' 17710 LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' 17711 max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' 17712 ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' 17713 exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' 17714 lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' 17715 lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' 17716 lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' 17717 lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' 17718 lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' 17719 reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' 17720 reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' 17721 OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' 17722 deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' 17723 file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' 17724 file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' 17725 want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' 17726 DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' 17727 sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' 17728 AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' 17729 AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' 17730 archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' 17731 STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' 17732 RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' 17733 old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' 17734 old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' 17735 old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' 17736 lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' 17737 CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' 17738 CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' 17739 compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' 17740 GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' 17741 lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' 17742 lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' 17743 lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' 17744 lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' 17745 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' 17746 lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' 17747 nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' 17748 lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' 17749 lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' 17750 objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' 17751 MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' 17752 lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' 17753 lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' 17754 lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' 17755 lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' 17756 lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' 17757 need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' 17758 MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' 17759 DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' 17760 NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' 17761 LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' 17762 OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' 17763 OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' 17764 libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' 17765 shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' 17766 extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' 17767 archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' 17768 enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' 17769 export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' 17770 whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' 17771 compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' 17772 old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' 17773 old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' 17774 archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' 17775 archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' 17776 module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' 17777 module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' 17778 with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' 17779 allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' 17780 no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' 17781 hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' 17782 hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' 17783 hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' 17784 hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' 17785 hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' 17786 hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' 17787 hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' 17788 inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' 17789 link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' 17790 always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' 17791 export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' 17792 exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' 17793 include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' 17794 prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' 17795 postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' 17796 file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' 17797 variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' 17798 need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' 17799 need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' 17800 version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' 17801 runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' 17802 shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' 17803 shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' 17804 libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' 17805 library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' 17806 soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' 17807 install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' 17808 postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' 17809 postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' 17810 finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' 17811 finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' 17812 hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' 17813 sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' 17814 configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' 17815 configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' 17816 hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' 17817 enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' 17818 enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' 17819 enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' 17820 old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' 17821 striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' 17822 compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' 17823 predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' 17824 postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' 17825 predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' 17826 postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' 17827 compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' 17828 LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' 17829 reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' 17830 reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17831 old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17832 compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' 17833 GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' 17834 lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' 17835 lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' 17836 lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' 17837 lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' 17838 lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' 17839 archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' 17840 enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' 17841 export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' 17842 whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' 17843 compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' 17844 old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17845 old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17846 archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17847 archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17848 module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17849 module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17850 with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' 17851 allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' 17852 no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' 17853 hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' 17854 hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' 17855 hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' 17856 hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' 17857 hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' 17858 hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' 17859 hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' 17860 inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' 17861 link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' 17862 always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' 17863 export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17864 exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' 17865 include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' 17866 prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17867 postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' 17868 file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' 17869 hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' 17870 compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' 17871 predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' 17872 postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' 17873 predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' 17874 postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' 17875 compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' 17876 17877 LTCC='$LTCC' 17878 LTCFLAGS='$LTCFLAGS' 17879 compiler='$compiler_DEFAULT' 17880 17881 # A function that is used when there is no print builtin or printf. 17882 func_fallback_echo () 17883 { 17884 eval 'cat <<_LTECHO_EOF 17885 \$1 17886 _LTECHO_EOF' 17887 } 17888 17889 # Quote evaled strings. 17890 for var in SHELL \ 17891 ECHO \ 17892 PATH_SEPARATOR \ 17893 SED \ 17894 GREP \ 17895 EGREP \ 17896 FGREP \ 17897 LD \ 17898 NM \ 17899 LN_S \ 17900 lt_SP2NL \ 17901 lt_NL2SP \ 17902 reload_flag \ 17903 OBJDUMP \ 17904 deplibs_check_method \ 17905 file_magic_cmd \ 17906 file_magic_glob \ 17907 want_nocaseglob \ 17908 DLLTOOL \ 17909 sharedlib_from_linklib_cmd \ 17910 AR \ 17911 AR_FLAGS \ 17912 archiver_list_spec \ 17913 STRIP \ 17914 RANLIB \ 17915 CC \ 17916 CFLAGS \ 17917 compiler \ 17918 lt_cv_sys_global_symbol_pipe \ 17919 lt_cv_sys_global_symbol_to_cdecl \ 17920 lt_cv_sys_global_symbol_to_import \ 17921 lt_cv_sys_global_symbol_to_c_name_address \ 17922 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ 17923 lt_cv_nm_interface \ 17924 nm_file_list_spec \ 17925 lt_cv_truncate_bin \ 17926 lt_prog_compiler_no_builtin_flag \ 17927 lt_prog_compiler_pic \ 17928 lt_prog_compiler_wl \ 17929 lt_prog_compiler_static \ 17930 lt_cv_prog_compiler_c_o \ 17931 need_locks \ 17932 MANIFEST_TOOL \ 17933 DSYMUTIL \ 17934 NMEDIT \ 17935 LIPO \ 17936 OTOOL \ 17937 OTOOL64 \ 17938 shrext_cmds \ 17939 export_dynamic_flag_spec \ 17940 whole_archive_flag_spec \ 17941 compiler_needs_object \ 17942 with_gnu_ld \ 17943 allow_undefined_flag \ 17944 no_undefined_flag \ 17945 hardcode_libdir_flag_spec \ 17946 hardcode_libdir_separator \ 17947 exclude_expsyms \ 17948 include_expsyms \ 17949 file_list_spec \ 17950 variables_saved_for_relink \ 17951 libname_spec \ 17952 library_names_spec \ 17953 soname_spec \ 17954 install_override_mode \ 17955 finish_eval \ 17956 old_striplib \ 17957 striplib \ 17958 compiler_lib_search_dirs \ 17959 predep_objects \ 17960 postdep_objects \ 17961 predeps \ 17962 postdeps \ 17963 compiler_lib_search_path \ 17964 LD_CXX \ 17965 reload_flag_CXX \ 17966 compiler_CXX \ 17967 lt_prog_compiler_no_builtin_flag_CXX \ 17968 lt_prog_compiler_pic_CXX \ 17969 lt_prog_compiler_wl_CXX \ 17970 lt_prog_compiler_static_CXX \ 17971 lt_cv_prog_compiler_c_o_CXX \ 17972 export_dynamic_flag_spec_CXX \ 17973 whole_archive_flag_spec_CXX \ 17974 compiler_needs_object_CXX \ 17975 with_gnu_ld_CXX \ 17976 allow_undefined_flag_CXX \ 17977 no_undefined_flag_CXX \ 17978 hardcode_libdir_flag_spec_CXX \ 17979 hardcode_libdir_separator_CXX \ 17980 exclude_expsyms_CXX \ 17981 include_expsyms_CXX \ 17982 file_list_spec_CXX \ 17983 compiler_lib_search_dirs_CXX \ 17984 predep_objects_CXX \ 17985 postdep_objects_CXX \ 17986 predeps_CXX \ 17987 postdeps_CXX \ 17988 compiler_lib_search_path_CXX; do 17989 case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in 17990 *[\\\\\\\`\\"\\\$]*) 17991 eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes 17992 ;; 17993 *) 17994 eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" 17995 ;; 17996 esac 17997 done 17998 17999 # Double-quote double-evaled strings. 18000 for var in reload_cmds \ 18001 old_postinstall_cmds \ 18002 old_postuninstall_cmds \ 18003 old_archive_cmds \ 18004 extract_expsyms_cmds \ 18005 old_archive_from_new_cmds \ 18006 old_archive_from_expsyms_cmds \ 18007 archive_cmds \ 18008 archive_expsym_cmds \ 18009 module_cmds \ 18010 module_expsym_cmds \ 18011 export_symbols_cmds \ 18012 prelink_cmds \ 18013 postlink_cmds \ 18014 postinstall_cmds \ 18015 postuninstall_cmds \ 18016 finish_cmds \ 18017 sys_lib_search_path_spec \ 18018 configure_time_dlsearch_path \ 18019 configure_time_lt_sys_library_path \ 18020 reload_cmds_CXX \ 18021 old_archive_cmds_CXX \ 18022 old_archive_from_new_cmds_CXX \ 18023 old_archive_from_expsyms_cmds_CXX \ 18024 archive_cmds_CXX \ 18025 archive_expsym_cmds_CXX \ 18026 module_cmds_CXX \ 18027 module_expsym_cmds_CXX \ 18028 export_symbols_cmds_CXX \ 18029 prelink_cmds_CXX \ 18030 postlink_cmds_CXX; do 18031 case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in 18032 *[\\\\\\\`\\"\\\$]*) 18033 eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes 18034 ;; 18035 *) 18036 eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" 18037 ;; 18038 esac 18039 done 18040 18041 ac_aux_dir='$ac_aux_dir' 18042 18043 # See if we are running on zsh, and set the options that allow our 18044 # commands through without removal of \ escapes INIT. 18045 if test -n "\${ZSH_VERSION+set}"; then 18046 setopt NO_GLOB_SUBST 18047 fi 18048 18049 18050 PACKAGE='$PACKAGE' 18051 VERSION='$VERSION' 18052 RM='$RM' 18053 ofile='$ofile' 18054 18055 18056 18057 18058 18059 7042 18060 _ACEOF 7043 18061 … … 7048 18066 do 7049 18067 case $ac_config_target in 7050 "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h " ;;18068 "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:src/config.h.in" ;; 7051 18069 "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; 18070 "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; 7052 18071 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; 7053 " src/driver/Makefile") CONFIG_FILES="$CONFIG_FILES src/driver/Makefile" ;;18072 "driver/Makefile") CONFIG_FILES="$CONFIG_FILES driver/Makefile" ;; 7054 18073 "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; 7055 "src/benchmark/Makefile") CONFIG_FILES="$CONFIG_FILES src/benchmark/Makefile" ;; 7056 "src/examples/Makefile") CONFIG_FILES="$CONFIG_FILES src/examples/Makefile" ;; 7057 "src/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/tests/Makefile" ;; 7058 "src/tests/preempt_longrun/Makefile") CONFIG_FILES="$CONFIG_FILES src/tests/preempt_longrun/Makefile" ;; 7059 "src/prelude/Makefile") CONFIG_FILES="$CONFIG_FILES src/prelude/Makefile" ;; 7060 "src/libcfa/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcfa/Makefile" ;; 18074 "benchmark/Makefile") CONFIG_FILES="$CONFIG_FILES benchmark/Makefile" ;; 18075 "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; 18076 "longrun_tests/Makefile") CONFIG_FILES="$CONFIG_FILES longrun_tests/Makefile" ;; 7061 18077 "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; 7062 18078 "tools/prettyprinter/Makefile") CONFIG_FILES="$CONFIG_FILES tools/prettyprinter/Makefile" ;; 18079 "tests/test.py") CONFIG_LINKS="$CONFIG_LINKS tests/test.py:tests/test.py" ;; 18080 "tests/config.py") CONFIG_FILES="$CONFIG_FILES tests/config.py" ;; 7063 18081 7064 18082 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; … … 7074 18092 test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files 7075 18093 test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers 18094 test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links 7076 18095 test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands 7077 18096 fi … … 7371 18390 7372 18391 7373 eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"18392 eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS" 7374 18393 shift 7375 18394 for ac_tag … … 7648 18667 s/.*/./; q'`/stamp-h$_am_stamp_count 7649 18668 ;; 7650 18669 :L) 18670 # 18671 # CONFIG_LINK 18672 # 18673 18674 if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then 18675 : 18676 else 18677 # Prefer the file from the source tree if names are identical. 18678 if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then 18679 ac_source=$srcdir/$ac_source 18680 fi 18681 18682 { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 18683 $as_echo "$as_me: linking $ac_source to $ac_file" >&6;} 18684 18685 if test ! -r "$ac_source"; then 18686 as_fn_error $? "$ac_source: file not found" "$LINENO" 5 18687 fi 18688 rm -f "$ac_file" 18689 18690 # Try a relative symlink, then a hard link, then a copy. 18691 case $ac_source in 18692 [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; 18693 *) ac_rel_source=$ac_top_build_prefix$ac_source ;; 18694 esac 18695 ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || 18696 ln "$ac_source" "$ac_file" 2>/dev/null || 18697 cp -p "$ac_source" "$ac_file" || 18698 as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 18699 fi 18700 ;; 7651 18701 :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 7652 18702 $as_echo "$as_me: executing $ac_file commands" >&6;} … … 7749 18799 } 7750 18800 ;; 18801 "libtool":C) 18802 18803 # See if we are running on zsh, and set the options that allow our 18804 # commands through without removal of \ escapes. 18805 if test -n "${ZSH_VERSION+set}"; then 18806 setopt NO_GLOB_SUBST 18807 fi 18808 18809 cfgfile=${ofile}T 18810 trap "$RM \"$cfgfile\"; exit 1" 1 2 15 18811 $RM "$cfgfile" 18812 18813 cat <<_LT_EOF >> "$cfgfile" 18814 #! $SHELL 18815 # Generated automatically by $as_me ($PACKAGE) $VERSION 18816 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: 18817 # NOTE: Changes made to this file will be lost: look at ltmain.sh. 18818 18819 # Provide generalized library-building support services. 18820 # Written by Gordon Matzigkeit, 1996 18821 18822 # Copyright (C) 2014 Free Software Foundation, Inc. 18823 # This is free software; see the source for copying conditions. There is NO 18824 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18825 18826 # GNU Libtool is free software; you can redistribute it and/or modify 18827 # it under the terms of the GNU General Public License as published by 18828 # the Free Software Foundation; either version 2 of of the License, or 18829 # (at your option) any later version. 18830 # 18831 # As a special exception to the GNU General Public License, if you 18832 # distribute this file as part of a program or library that is built 18833 # using GNU Libtool, you may include this file under the same 18834 # distribution terms that you use for the rest of that program. 18835 # 18836 # GNU Libtool is distributed in the hope that it will be useful, but 18837 # WITHOUT ANY WARRANTY; without even the implied warranty of 18838 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18839 # GNU General Public License for more details. 18840 # 18841 # You should have received a copy of the GNU General Public License 18842 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18843 18844 18845 # The names of the tagged configurations supported by this script. 18846 available_tags='CXX ' 18847 18848 # Configured defaults for sys_lib_dlsearch_path munging. 18849 : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} 18850 18851 # ### BEGIN LIBTOOL CONFIG 18852 18853 # Which release of libtool.m4 was used? 18854 macro_version=$macro_version 18855 macro_revision=$macro_revision 18856 18857 # Whether or not to build shared libraries. 18858 build_libtool_libs=$enable_shared 18859 18860 # Whether or not to build static libraries. 18861 build_old_libs=$enable_static 18862 18863 # What type of objects to build. 18864 pic_mode=$pic_mode 18865 18866 # Whether or not to optimize for fast installation. 18867 fast_install=$enable_fast_install 18868 18869 # Shared archive member basename,for filename based shared library versioning on AIX. 18870 shared_archive_member_spec=$shared_archive_member_spec 18871 18872 # Shell to use when invoking shell scripts. 18873 SHELL=$lt_SHELL 18874 18875 # An echo program that protects backslashes. 18876 ECHO=$lt_ECHO 18877 18878 # The PATH separator for the build system. 18879 PATH_SEPARATOR=$lt_PATH_SEPARATOR 18880 18881 # The host system. 18882 host_alias=$host_alias 18883 host=$host 18884 host_os=$host_os 18885 18886 # The build system. 18887 build_alias=$build_alias 18888 build=$build 18889 build_os=$build_os 18890 18891 # A sed program that does not truncate output. 18892 SED=$lt_SED 18893 18894 # Sed that helps us avoid accidentally triggering echo(1) options like -n. 18895 Xsed="\$SED -e 1s/^X//" 18896 18897 # A grep program that handles long lines. 18898 GREP=$lt_GREP 18899 18900 # An ERE matcher. 18901 EGREP=$lt_EGREP 18902 18903 # A literal string matcher. 18904 FGREP=$lt_FGREP 18905 18906 # A BSD- or MS-compatible name lister. 18907 NM=$lt_NM 18908 18909 # Whether we need soft or hard links. 18910 LN_S=$lt_LN_S 18911 18912 # What is the maximum length of a command? 18913 max_cmd_len=$max_cmd_len 18914 18915 # Object file suffix (normally "o"). 18916 objext=$ac_objext 18917 18918 # Executable file suffix (normally ""). 18919 exeext=$exeext 18920 18921 # whether the shell understands "unset". 18922 lt_unset=$lt_unset 18923 18924 # turn spaces into newlines. 18925 SP2NL=$lt_lt_SP2NL 18926 18927 # turn newlines into spaces. 18928 NL2SP=$lt_lt_NL2SP 18929 18930 # convert \$build file names to \$host format. 18931 to_host_file_cmd=$lt_cv_to_host_file_cmd 18932 18933 # convert \$build files to toolchain format. 18934 to_tool_file_cmd=$lt_cv_to_tool_file_cmd 18935 18936 # An object symbol dumper. 18937 OBJDUMP=$lt_OBJDUMP 18938 18939 # Method to check whether dependent libraries are shared objects. 18940 deplibs_check_method=$lt_deplibs_check_method 18941 18942 # Command to use when deplibs_check_method = "file_magic". 18943 file_magic_cmd=$lt_file_magic_cmd 18944 18945 # How to find potential files when deplibs_check_method = "file_magic". 18946 file_magic_glob=$lt_file_magic_glob 18947 18948 # Find potential files using nocaseglob when deplibs_check_method = "file_magic". 18949 want_nocaseglob=$lt_want_nocaseglob 18950 18951 # DLL creation program. 18952 DLLTOOL=$lt_DLLTOOL 18953 18954 # Command to associate shared and link libraries. 18955 sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd 18956 18957 # The archiver. 18958 AR=$lt_AR 18959 18960 # Flags to create an archive. 18961 AR_FLAGS=$lt_AR_FLAGS 18962 18963 # How to feed a file listing to the archiver. 18964 archiver_list_spec=$lt_archiver_list_spec 18965 18966 # A symbol stripping program. 18967 STRIP=$lt_STRIP 18968 18969 # Commands used to install an old-style archive. 18970 RANLIB=$lt_RANLIB 18971 old_postinstall_cmds=$lt_old_postinstall_cmds 18972 old_postuninstall_cmds=$lt_old_postuninstall_cmds 18973 18974 # Whether to use a lock for old archive extraction. 18975 lock_old_archive_extraction=$lock_old_archive_extraction 18976 18977 # A C compiler. 18978 LTCC=$lt_CC 18979 18980 # LTCC compiler flags. 18981 LTCFLAGS=$lt_CFLAGS 18982 18983 # Take the output of nm and produce a listing of raw symbols and C names. 18984 global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe 18985 18986 # Transform the output of nm in a proper C declaration. 18987 global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl 18988 18989 # Transform the output of nm into a list of symbols to manually relocate. 18990 global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import 18991 18992 # Transform the output of nm in a C name address pair. 18993 global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address 18994 18995 # Transform the output of nm in a C name address pair when lib prefix is needed. 18996 global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix 18997 18998 # The name lister interface. 18999 nm_interface=$lt_lt_cv_nm_interface 19000 19001 # Specify filename containing input files for \$NM. 19002 nm_file_list_spec=$lt_nm_file_list_spec 19003 19004 # The root where to search for dependent libraries,and where our libraries should be installed. 19005 lt_sysroot=$lt_sysroot 19006 19007 # Command to truncate a binary pipe. 19008 lt_truncate_bin=$lt_lt_cv_truncate_bin 19009 19010 # The name of the directory that contains temporary libtool files. 19011 objdir=$objdir 19012 19013 # Used to examine libraries when file_magic_cmd begins with "file". 19014 MAGIC_CMD=$MAGIC_CMD 19015 19016 # Must we lock files when doing compilation? 19017 need_locks=$lt_need_locks 19018 19019 # Manifest tool. 19020 MANIFEST_TOOL=$lt_MANIFEST_TOOL 19021 19022 # Tool to manipulate archived DWARF debug symbol files on Mac OS X. 19023 DSYMUTIL=$lt_DSYMUTIL 19024 19025 # Tool to change global to local symbols on Mac OS X. 19026 NMEDIT=$lt_NMEDIT 19027 19028 # Tool to manipulate fat objects and archives on Mac OS X. 19029 LIPO=$lt_LIPO 19030 19031 # ldd/readelf like tool for Mach-O binaries on Mac OS X. 19032 OTOOL=$lt_OTOOL 19033 19034 # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. 19035 OTOOL64=$lt_OTOOL64 19036 19037 # Old archive suffix (normally "a"). 19038 libext=$libext 19039 19040 # Shared library suffix (normally ".so"). 19041 shrext_cmds=$lt_shrext_cmds 19042 19043 # The commands to extract the exported symbol list from a shared archive. 19044 extract_expsyms_cmds=$lt_extract_expsyms_cmds 19045 19046 # Variables whose values should be saved in libtool wrapper scripts and 19047 # restored at link time. 19048 variables_saved_for_relink=$lt_variables_saved_for_relink 19049 19050 # Do we need the "lib" prefix for modules? 19051 need_lib_prefix=$need_lib_prefix 19052 19053 # Do we need a version for libraries? 19054 need_version=$need_version 19055 19056 # Library versioning type. 19057 version_type=$version_type 19058 19059 # Shared library runtime path variable. 19060 runpath_var=$runpath_var 19061 19062 # Shared library path variable. 19063 shlibpath_var=$shlibpath_var 19064 19065 # Is shlibpath searched before the hard-coded library search path? 19066 shlibpath_overrides_runpath=$shlibpath_overrides_runpath 19067 19068 # Format of library name prefix. 19069 libname_spec=$lt_libname_spec 19070 19071 # List of archive names. First name is the real one, the rest are links. 19072 # The last name is the one that the linker finds with -lNAME 19073 library_names_spec=$lt_library_names_spec 19074 19075 # The coded name of the library, if different from the real name. 19076 soname_spec=$lt_soname_spec 19077 19078 # Permission mode override for installation of shared libraries. 19079 install_override_mode=$lt_install_override_mode 19080 19081 # Command to use after installation of a shared archive. 19082 postinstall_cmds=$lt_postinstall_cmds 19083 19084 # Command to use after uninstallation of a shared archive. 19085 postuninstall_cmds=$lt_postuninstall_cmds 19086 19087 # Commands used to finish a libtool library installation in a directory. 19088 finish_cmds=$lt_finish_cmds 19089 19090 # As "finish_cmds", except a single script fragment to be evaled but 19091 # not shown. 19092 finish_eval=$lt_finish_eval 19093 19094 # Whether we should hardcode library paths into libraries. 19095 hardcode_into_libs=$hardcode_into_libs 19096 19097 # Compile-time system search path for libraries. 19098 sys_lib_search_path_spec=$lt_sys_lib_search_path_spec 19099 19100 # Detected run-time system search path for libraries. 19101 sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path 19102 19103 # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. 19104 configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path 19105 19106 # Whether dlopen is supported. 19107 dlopen_support=$enable_dlopen 19108 19109 # Whether dlopen of programs is supported. 19110 dlopen_self=$enable_dlopen_self 19111 19112 # Whether dlopen of statically linked programs is supported. 19113 dlopen_self_static=$enable_dlopen_self_static 19114 19115 # Commands to strip libraries. 19116 old_striplib=$lt_old_striplib 19117 striplib=$lt_striplib 19118 19119 19120 # The linker used to build libraries. 19121 LD=$lt_LD 19122 19123 # How to create reloadable object files. 19124 reload_flag=$lt_reload_flag 19125 reload_cmds=$lt_reload_cmds 19126 19127 # Commands used to build an old-style archive. 19128 old_archive_cmds=$lt_old_archive_cmds 19129 19130 # A language specific compiler. 19131 CC=$lt_compiler 19132 19133 # Is the compiler the GNU compiler? 19134 with_gcc=$GCC 19135 19136 # Compiler flag to turn off builtin functions. 19137 no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag 19138 19139 # Additional compiler flags for building library objects. 19140 pic_flag=$lt_lt_prog_compiler_pic 19141 19142 # How to pass a linker flag through the compiler. 19143 wl=$lt_lt_prog_compiler_wl 19144 19145 # Compiler flag to prevent dynamic linking. 19146 link_static_flag=$lt_lt_prog_compiler_static 19147 19148 # Does compiler simultaneously support -c and -o options? 19149 compiler_c_o=$lt_lt_cv_prog_compiler_c_o 19150 19151 # Whether or not to add -lc for building shared libraries. 19152 build_libtool_need_lc=$archive_cmds_need_lc 19153 19154 # Whether or not to disallow shared libs when runtime libs are static. 19155 allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes 19156 19157 # Compiler flag to allow reflexive dlopens. 19158 export_dynamic_flag_spec=$lt_export_dynamic_flag_spec 19159 19160 # Compiler flag to generate shared objects directly from archives. 19161 whole_archive_flag_spec=$lt_whole_archive_flag_spec 19162 19163 # Whether the compiler copes with passing no objects directly. 19164 compiler_needs_object=$lt_compiler_needs_object 19165 19166 # Create an old-style archive from a shared archive. 19167 old_archive_from_new_cmds=$lt_old_archive_from_new_cmds 19168 19169 # Create a temporary old-style archive to link instead of a shared archive. 19170 old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds 19171 19172 # Commands used to build a shared archive. 19173 archive_cmds=$lt_archive_cmds 19174 archive_expsym_cmds=$lt_archive_expsym_cmds 19175 19176 # Commands used to build a loadable module if different from building 19177 # a shared archive. 19178 module_cmds=$lt_module_cmds 19179 module_expsym_cmds=$lt_module_expsym_cmds 19180 19181 # Whether we are building with GNU ld or not. 19182 with_gnu_ld=$lt_with_gnu_ld 19183 19184 # Flag that allows shared libraries with undefined symbols to be built. 19185 allow_undefined_flag=$lt_allow_undefined_flag 19186 19187 # Flag that enforces no undefined symbols. 19188 no_undefined_flag=$lt_no_undefined_flag 19189 19190 # Flag to hardcode \$libdir into a binary during linking. 19191 # This must work even if \$libdir does not exist 19192 hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec 19193 19194 # Whether we need a single "-rpath" flag with a separated argument. 19195 hardcode_libdir_separator=$lt_hardcode_libdir_separator 19196 19197 # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes 19198 # DIR into the resulting binary. 19199 hardcode_direct=$hardcode_direct 19200 19201 # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes 19202 # DIR into the resulting binary and the resulting library dependency is 19203 # "absolute",i.e impossible to change by setting \$shlibpath_var if the 19204 # library is relocated. 19205 hardcode_direct_absolute=$hardcode_direct_absolute 19206 19207 # Set to "yes" if using the -LDIR flag during linking hardcodes DIR 19208 # into the resulting binary. 19209 hardcode_minus_L=$hardcode_minus_L 19210 19211 # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR 19212 # into the resulting binary. 19213 hardcode_shlibpath_var=$hardcode_shlibpath_var 19214 19215 # Set to "yes" if building a shared library automatically hardcodes DIR 19216 # into the library and all subsequent libraries and executables linked 19217 # against it. 19218 hardcode_automatic=$hardcode_automatic 19219 19220 # Set to yes if linker adds runtime paths of dependent libraries 19221 # to runtime path list. 19222 inherit_rpath=$inherit_rpath 19223 19224 # Whether libtool must link a program against all its dependency libraries. 19225 link_all_deplibs=$link_all_deplibs 19226 19227 # Set to "yes" if exported symbols are required. 19228 always_export_symbols=$always_export_symbols 19229 19230 # The commands to list exported symbols. 19231 export_symbols_cmds=$lt_export_symbols_cmds 19232 19233 # Symbols that should not be listed in the preloaded symbols. 19234 exclude_expsyms=$lt_exclude_expsyms 19235 19236 # Symbols that must always be exported. 19237 include_expsyms=$lt_include_expsyms 19238 19239 # Commands necessary for linking programs (against libraries) with templates. 19240 prelink_cmds=$lt_prelink_cmds 19241 19242 # Commands necessary for finishing linking programs. 19243 postlink_cmds=$lt_postlink_cmds 19244 19245 # Specify filename containing input files. 19246 file_list_spec=$lt_file_list_spec 19247 19248 # How to hardcode a shared library path into an executable. 19249 hardcode_action=$hardcode_action 19250 19251 # The directories searched by this compiler when creating a shared library. 19252 compiler_lib_search_dirs=$lt_compiler_lib_search_dirs 19253 19254 # Dependencies to place before and after the objects being linked to 19255 # create a shared library. 19256 predep_objects=$lt_predep_objects 19257 postdep_objects=$lt_postdep_objects 19258 predeps=$lt_predeps 19259 postdeps=$lt_postdeps 19260 19261 # The library search path used internally by the compiler when linking 19262 # a shared library. 19263 compiler_lib_search_path=$lt_compiler_lib_search_path 19264 19265 # ### END LIBTOOL CONFIG 19266 19267 _LT_EOF 19268 19269 cat <<'_LT_EOF' >> "$cfgfile" 19270 19271 # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE 19272 19273 # func_munge_path_list VARIABLE PATH 19274 # ----------------------------------- 19275 # VARIABLE is name of variable containing _space_ separated list of 19276 # directories to be munged by the contents of PATH, which is string 19277 # having a format: 19278 # "DIR[:DIR]:" 19279 # string "DIR[ DIR]" will be prepended to VARIABLE 19280 # ":DIR[:DIR]" 19281 # string "DIR[ DIR]" will be appended to VARIABLE 19282 # "DIRP[:DIRP]::[DIRA:]DIRA" 19283 # string "DIRP[ DIRP]" will be prepended to VARIABLE and string 19284 # "DIRA[ DIRA]" will be appended to VARIABLE 19285 # "DIR[:DIR]" 19286 # VARIABLE will be replaced by "DIR[ DIR]" 19287 func_munge_path_list () 19288 { 19289 case x$2 in 19290 x) 19291 ;; 19292 *:) 19293 eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" 19294 ;; 19295 x:*) 19296 eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" 19297 ;; 19298 *::*) 19299 eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" 19300 eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" 19301 ;; 19302 *) 19303 eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" 19304 ;; 19305 esac 19306 } 19307 19308 19309 # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. 19310 func_cc_basename () 19311 { 19312 for cc_temp in $*""; do 19313 case $cc_temp in 19314 compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; 19315 distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; 19316 \-*) ;; 19317 *) break;; 19318 esac 19319 done 19320 func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` 19321 } 19322 19323 19324 # ### END FUNCTIONS SHARED WITH CONFIGURE 19325 19326 _LT_EOF 19327 19328 case $host_os in 19329 aix3*) 19330 cat <<\_LT_EOF >> "$cfgfile" 19331 # AIX sometimes has problems with the GCC collect2 program. For some 19332 # reason, if we set the COLLECT_NAMES environment variable, the problems 19333 # vanish in a puff of smoke. 19334 if test set != "${COLLECT_NAMES+set}"; then 19335 COLLECT_NAMES= 19336 export COLLECT_NAMES 19337 fi 19338 _LT_EOF 19339 ;; 19340 esac 19341 19342 19343 ltmain=$ac_aux_dir/ltmain.sh 19344 19345 19346 # We use sed instead of cat because bash on DJGPP gets confused if 19347 # if finds mixed CR/LF and LF-only lines. Since sed operates in 19348 # text mode, it properly converts lines to CR/LF. This bash problem 19349 # is reportedly fixed, but why not run on old versions too? 19350 sed '$q' "$ltmain" >> "$cfgfile" \ 19351 || (rm -f "$cfgfile"; exit 1) 19352 19353 mv -f "$cfgfile" "$ofile" || 19354 (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") 19355 chmod +x "$ofile" 19356 19357 19358 cat <<_LT_EOF >> "$ofile" 19359 19360 # ### BEGIN LIBTOOL TAG CONFIG: CXX 19361 19362 # The linker used to build libraries. 19363 LD=$lt_LD_CXX 19364 19365 # How to create reloadable object files. 19366 reload_flag=$lt_reload_flag_CXX 19367 reload_cmds=$lt_reload_cmds_CXX 19368 19369 # Commands used to build an old-style archive. 19370 old_archive_cmds=$lt_old_archive_cmds_CXX 19371 19372 # A language specific compiler. 19373 CC=$lt_compiler_CXX 19374 19375 # Is the compiler the GNU compiler? 19376 with_gcc=$GCC_CXX 19377 19378 # Compiler flag to turn off builtin functions. 19379 no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX 19380 19381 # Additional compiler flags for building library objects. 19382 pic_flag=$lt_lt_prog_compiler_pic_CXX 19383 19384 # How to pass a linker flag through the compiler. 19385 wl=$lt_lt_prog_compiler_wl_CXX 19386 19387 # Compiler flag to prevent dynamic linking. 19388 link_static_flag=$lt_lt_prog_compiler_static_CXX 19389 19390 # Does compiler simultaneously support -c and -o options? 19391 compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX 19392 19393 # Whether or not to add -lc for building shared libraries. 19394 build_libtool_need_lc=$archive_cmds_need_lc_CXX 19395 19396 # Whether or not to disallow shared libs when runtime libs are static. 19397 allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX 19398 19399 # Compiler flag to allow reflexive dlopens. 19400 export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX 19401 19402 # Compiler flag to generate shared objects directly from archives. 19403 whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX 19404 19405 # Whether the compiler copes with passing no objects directly. 19406 compiler_needs_object=$lt_compiler_needs_object_CXX 19407 19408 # Create an old-style archive from a shared archive. 19409 old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX 19410 19411 # Create a temporary old-style archive to link instead of a shared archive. 19412 old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX 19413 19414 # Commands used to build a shared archive. 19415 archive_cmds=$lt_archive_cmds_CXX 19416 archive_expsym_cmds=$lt_archive_expsym_cmds_CXX 19417 19418 # Commands used to build a loadable module if different from building 19419 # a shared archive. 19420 module_cmds=$lt_module_cmds_CXX 19421 module_expsym_cmds=$lt_module_expsym_cmds_CXX 19422 19423 # Whether we are building with GNU ld or not. 19424 with_gnu_ld=$lt_with_gnu_ld_CXX 19425 19426 # Flag that allows shared libraries with undefined symbols to be built. 19427 allow_undefined_flag=$lt_allow_undefined_flag_CXX 19428 19429 # Flag that enforces no undefined symbols. 19430 no_undefined_flag=$lt_no_undefined_flag_CXX 19431 19432 # Flag to hardcode \$libdir into a binary during linking. 19433 # This must work even if \$libdir does not exist 19434 hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX 19435 19436 # Whether we need a single "-rpath" flag with a separated argument. 19437 hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX 19438 19439 # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes 19440 # DIR into the resulting binary. 19441 hardcode_direct=$hardcode_direct_CXX 19442 19443 # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes 19444 # DIR into the resulting binary and the resulting library dependency is 19445 # "absolute",i.e impossible to change by setting \$shlibpath_var if the 19446 # library is relocated. 19447 hardcode_direct_absolute=$hardcode_direct_absolute_CXX 19448 19449 # Set to "yes" if using the -LDIR flag during linking hardcodes DIR 19450 # into the resulting binary. 19451 hardcode_minus_L=$hardcode_minus_L_CXX 19452 19453 # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR 19454 # into the resulting binary. 19455 hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX 19456 19457 # Set to "yes" if building a shared library automatically hardcodes DIR 19458 # into the library and all subsequent libraries and executables linked 19459 # against it. 19460 hardcode_automatic=$hardcode_automatic_CXX 19461 19462 # Set to yes if linker adds runtime paths of dependent libraries 19463 # to runtime path list. 19464 inherit_rpath=$inherit_rpath_CXX 19465 19466 # Whether libtool must link a program against all its dependency libraries. 19467 link_all_deplibs=$link_all_deplibs_CXX 19468 19469 # Set to "yes" if exported symbols are required. 19470 always_export_symbols=$always_export_symbols_CXX 19471 19472 # The commands to list exported symbols. 19473 export_symbols_cmds=$lt_export_symbols_cmds_CXX 19474 19475 # Symbols that should not be listed in the preloaded symbols. 19476 exclude_expsyms=$lt_exclude_expsyms_CXX 19477 19478 # Symbols that must always be exported. 19479 include_expsyms=$lt_include_expsyms_CXX 19480 19481 # Commands necessary for linking programs (against libraries) with templates. 19482 prelink_cmds=$lt_prelink_cmds_CXX 19483 19484 # Commands necessary for finishing linking programs. 19485 postlink_cmds=$lt_postlink_cmds_CXX 19486 19487 # Specify filename containing input files. 19488 file_list_spec=$lt_file_list_spec_CXX 19489 19490 # How to hardcode a shared library path into an executable. 19491 hardcode_action=$hardcode_action_CXX 19492 19493 # The directories searched by this compiler when creating a shared library. 19494 compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX 19495 19496 # Dependencies to place before and after the objects being linked to 19497 # create a shared library. 19498 predep_objects=$lt_predep_objects_CXX 19499 postdep_objects=$lt_postdep_objects_CXX 19500 predeps=$lt_predeps_CXX 19501 postdeps=$lt_postdeps_CXX 19502 19503 # The library search path used internally by the compiler when linking 19504 # a shared library. 19505 compiler_lib_search_path=$lt_compiler_lib_search_path_CXX 19506 19507 # ### END LIBTOOL TAG CONFIG: CXX 19508 _LT_EOF 19509 19510 ;; 7751 19511 7752 19512 esac … … 7788 19548 7789 19549 7790 if test -z "$BUILD_RELEASE_TRUE"; then :7791 if test -z "$BUILD_DEBUG_TRUE"; then :7792 { $as_echo "$as_me:${as_lineno-$LINENO}: Building libcfa for target: release & debug" >&57793 $as_echo "$as_me: Building libcfa for target: release & debug" >&6;}7794 else7795 { $as_echo "$as_me:${as_lineno-$LINENO}: Building libcfa for target: release" >&57796 $as_echo "$as_me: Building libcfa for target: release" >&6;}7797 fi7798 else7799 if test -z "$BUILD_DEBUG_TRUE"; then :7800 { $as_echo "$as_me:${as_lineno-$LINENO}: Building libcfa for target: debug" >&57801 $as_echo "$as_me: Building libcfa for target: debug" >&6;}7802 else7803 { $as_echo "$as_me:${as_lineno-$LINENO}: Running cfa without libcfa" >&57804 $as_echo "$as_me: Running cfa without libcfa" >&6;}7805 fi7806 fi7807 7808 19550 # Final text 7809 19551 { $as_echo "$as_me:${as_lineno-$LINENO}: result: Cforall configuraton completed. Type \"make -j 8 install\"." >&5 -
configure.ac
r7951100 rb067d9b 5 5 AC_INIT([cfa-cc],[1.0.0.0],[cforall@plg.uwaterloo.ca]) 6 6 AC_CONFIG_AUX_DIR([automake]) 7 AC_CONFIG_MACRO_DIRS([automake]) 7 8 #AC_CONFIG_SRCDIR([src/main.cc]) 8 AC_CONFIG_HEADERS([config.h]) 9 AM_SILENT_RULES([no]) 9 AC_CONFIG_HEADERS([config.h:src/config.h.in]) 10 AM_SILENT_RULES([yes]) 11 12 m4_include([automake/cfa.m4]) 13 14 # don't use the default CFLAGS as they unconditonnaly add -O2 15 : ${CFLAGS=""} 10 16 11 17 AM_INIT_AUTOMAKE([subdir-objects]) 12 AM_MAINTAINER_MODE(enable) # may require auto* software to be installed13 18 14 19 # Allow program name tansformation … … 16 21 AC_ARG_PROGRAM 17 22 23 #============================================================================== 18 24 #Trasforming cc1 will break compilation 19 if test "${program_transform_name}" = ""; then 20 AC_MSG_ERROR([Program transform not supported. 21 Use --with-cfa-name='[[Desired name here]]' instead]) 22 fi 23 24 AC_ARG_WITH(cfa-name, 25 [ --with-cfa-name=NAME NAME too which cfa will be installed], 26 cfa_name=$withval, cfa_name="cfa") 27 28 #Define the new name of the installed command 29 AC_SUBST(CFA_NAME, ${cfa_name}) 25 M4CFA_PROGRAM_NAME 26 27 #============================================================================== 28 # version information 30 29 31 30 rm -f version … … 47 46 AC_DEFINE_UNQUOTED(CFA_VERSION_FULL, ["${ver_major}.${ver_minor}.${ver_patch}.${ver_build}"], [Major.Minor.Patch.Build]) 48 47 49 # Installation paths 50 51 AC_ARG_WITH(backend-compiler, 52 [ --with-backend-compiler=PROGRAM PROGRAM that performs the final code compilation (must be gcc-compatible) ], 53 backendcompiler=$withval, backendcompiler="") 54 if test "x$backendcompiler" != "x"; then 55 BACKEND_CC=${backendcompiler} 56 else 57 AC_PATH_PROG(BACKEND_CC, gcc, []) # check gcc installed 58 if test "x$BACKEND_CC" = "x"; then 59 AC_MSG_ERROR(some version of gcc is needed. Get it at ftp://ftp.gnu.org) 60 exit 1 61 fi 62 fi 63 AC_DEFINE_UNQUOTED(CFA_BACKEND_CC, "${BACKEND_CC}", [Location of include files.]) 64 AC_SUBST(CFA_BACKEND_CC) 65 66 67 68 AC_ARG_ENABLE(target-release, AS_HELP_STRING([--enable-target-release], [Build and install the release target])) 69 AC_ARG_ENABLE(target-debug, AS_HELP_STRING([--enable-target-debug], [Build and install the debug target])) 70 AC_ARG_ENABLE(threading, AS_HELP_STRING([--enable-threading], [Build and install libcfa with threading support (Enabled by default)]), 71 [case "${enableval}" in 72 yes) build_threading="yes" ;; 73 no) build_threading="no" ;; 74 *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; 75 esac],[build_threading="yes"]) 76 77 case "$enable_target_release" in 78 yes) 79 case "$enable_target_debug" in 80 yes) 81 build_release="yes" 82 build_debug="yes" 83 ;; 84 no) 85 build_release="yes" 86 build_debug="no" 87 ;; 88 *) 89 build_release="yes" 90 build_debug="no" 91 ;; 92 esac 93 ;; 94 no) 95 case "$enable_target_debug" in 96 yes) 97 build_release="no" 98 build_debug="yes" 99 ;; 100 no) 101 build_release="no" 102 build_debug="no" 103 ;; 104 *) 105 build_release="no" 106 build_debug="yes" 107 ;; 108 esac 109 ;; 110 *) 111 case "$enable_target_debug" in 112 yes) 113 build_release="no" 114 build_debug="yes" 115 ;; 116 no) 117 build_release="yes" 118 build_debug="no" 119 ;; 120 *) 121 build_release="yes" 122 build_debug="yes" 123 ;; 124 esac 125 ;; 126 esac 127 128 AM_CONDITIONAL([BUILD_RELEASE], [test "x$build_release" = "xyes"]) 129 AM_CONDITIONAL([BUILD_DEBUG], [test "x$build_debug" = "xyes"]) 130 AM_CONDITIONAL([BUILD_NO_LIB], [test "x$build_release$build_debug" = "xnono"]) 131 AM_CONDITIONAL([BUILD_CONCURRENCY], [test "x$build_threading" = "xyes"]) 132 48 #============================================================================== 49 # HACK to be able to use conditionnals inside makefiles 133 50 DOifskipcompile='ifeq ($(skipcompile),yes) 134 51 else' … … 140 57 AM_SUBST_NOTMAKE([DOendif]) 141 58 142 if test "x$prefix" = "xNONE"; then 143 cfa_prefix=${ac_default_prefix} 144 else 145 cfa_prefix=${prefix} 59 #============================================================================== 60 # distcc support 61 62 AC_ARG_ENABLE(distcc, 63 [ --enable-distcc whether or not to enable distributed compilation], 64 enable_distcc=$enableval, enable_distcc=no) 65 66 AM_CONDITIONAL([ENABLE_DISTCC], [test x$enable_distcc = xyes]) 67 HAS_DISTCC="False" 68 69 if test x$enable_distcc = xyes; then 70 CXX="distcc ${CXX}" 71 LD="distcc ${LD} -lstdc++" 72 HAS_DISTCC="True" 73 echo "Enabling distributed builds" 146 74 fi 147 AC_DEFINE_UNQUOTED(CFA_PREFIX, "${cfa_prefix}", [Location of cfa install.]) 148 AC_SUBST(CFA_PREFIX, ${cfa_prefix}) 149 150 if test "$includedir" = '${prefix}/include'; then 151 cfa_incdir="${cfa_prefix}/include/${cfa_name}" 152 else 153 cfa_incdir=${includedir} 154 fi 155 AC_DEFINE_UNQUOTED(CFA_INCDIR, "${cfa_incdir}", [Location of include files.]) 156 AC_SUBST(CFA_INCDIR, ${cfa_incdir}) 157 158 if test "$bindir" = '${exec_prefix}/bin'; then 159 cfa_bindir="${cfa_prefix}/bin" 160 else 161 cfa_bindir=${bindir} 162 fi 163 AC_DEFINE_UNQUOTED(CFA_BINDIR, "${cfa_bindir}", [Location of cfa command.]) 164 AC_SUBST(CFA_BINDIR, ${cfa_bindir}) 165 166 if test "$libdir" = '${exec_prefix}/lib'; then 167 cfa_libdir="${cfa_prefix}/lib/${cfa_name}" 168 else 169 cfa_libdir=${libdir} 170 fi 171 AC_DEFINE_UNQUOTED(CFA_LIBDIR, "${cfa_libdir}", [Location of cc1 and cfa-cpp commands.]) 172 AC_SUBST(CFA_LIBDIR, ${cfa_libdir}) 173 75 76 AC_SUBST(CXX) 77 AC_SUBST(LD) 78 AC_SUBST(HAS_DISTCC) 79 80 #============================================================================== 81 # Installation paths 82 M4CFA_PARSE_PREFIX 83 84 #============================================================================== 85 # Create variables for commonly used targets 86 87 TOP_SRCDIR="$(readlink -m $ac_confdir/)/" 88 TOP_BUILDDIR="$(readlink -m $ac_pwd/)/" 89 90 AC_DEFINE_UNQUOTED(TOP_SRCDIR, "$TOP_SRCDIR", [Top src directory]) 91 AC_DEFINE_UNQUOTED(TOP_BUILDDIR, "$TOP_BUILDDIR", [Top build directory]) 92 93 DRIVER_DIR=${TOP_BUILDDIR}driver/ 94 CFACC=${DRIVER_DIR}cfa 95 CFACC_INSTALL=${CFA_BINDIR}${CFA_NAME} 96 CFACPP=${DRIVER_DIR}cfa-cpp 97 AC_SUBST(DRIVER_DIR) 98 AC_SUBST(CFACC) 99 AC_SUBST(CFACC_INSTALL) 100 AC_SUBST(CFACPP) 101 102 #============================================================================== 103 # Flag variables needed to build in tree 104 LIBCFA_SRC='${TOP_SRCDIR}/libcfa/src' 105 BUILD_IN_TREE_FLAGS="-XCFA -t -B${DRIVER_DIR}" 106 AC_SUBST(BUILD_IN_TREE_FLAGS) 107 108 #============================================================================== 109 # handle the list of hosts to build for 110 for var in $ac_configure_args 111 do 112 #strip quotes surrouding values 113 case $var in 114 # skip cross compilation related arguments 115 \'--host=*) ;; \'host_alias=*) ;; \'--build=*) ;; \'build_alias=*) ;; \'--target=*) ;; \'target_alias=*) ;; 116 117 # skip the target hosts 118 \'--with-target-hosts=*) ;; 119 120 # skip gprofiler for libcfa 121 \'--enable-gprofiler=*) ;; 122 \'--disable-gprofiler) ;; 123 124 # append all other arguments to the sub configure arguments 125 *) LIBCFA_GENERAL_ARGS="${LIBCFA_GENERAL_ARGS} $var";; 126 esac 127 done 128 129 #============================================================================== 130 # handle the list of hosts to build for 174 131 AC_CANONICAL_BUILD 175 132 AC_CANONICAL_HOST 176 AC_SUBST([MACHINE_TYPE],[$host_cpu])177 133 178 134 if ! test "$host_cpu" = "$build_cpu"; then 179 135 case $host_cpu in 180 136 i386) 181 CFLAGS+=" -m32 " 182 CXXFLAGS+=" -m32 " 183 CFAFLAGS+=" -m32 " 184 LDFLAGS+=" -m32 " 137 HOST_FLAGS="-m32" 185 138 ;; 186 139 i686) 187 CFLAGS+=" -m32 " 188 CXXFLAGS+=" -m32 " 189 CFAFLAGS+=" -m32 " 190 LDFLAGS+=" -m32 " 140 HOST_FLAGS="-m32" 191 141 ;; 192 142 x86_64) 193 CFLAGS+=" -m64 " 194 CXXFLAGS+=" -m64 " 195 CFAFLAGS+=" -m64 " 196 LDFLAGS+=" -m64 " 143 HOST_FLAGS="-m64" 197 144 ;; 198 145 esac 199 146 fi 200 147 AC_SUBST(HOST_FLAGS) 148 149 default_target="${host_cpu}:debug, ${host_cpu}:nodebug" 150 AC_ARG_WITH(target-hosts, 151 [ --with-target-hosts=HOSTS HOSTS comma seperated list of hosts to build for, format ARCH:[debug|nodebug|nolib]], 152 target_hosts=$withval, target_hosts=${default_target}) 153 154 AC_ARG_ENABLE(gprofiler, 155 [ --enable-gprofiler whether or not to enable gprofiler tools (if available)], 156 enable_gprofiler=$enableval, enable_gprofiler=yes) 157 158 AC_ARG_ENABLE(demangler, 159 [ --enable-demangler whether or not to build the demangler (executable and library)], 160 enable_demangler=$enableval, enable_demangler=yes) 161 162 AC_SUBST(TARGET_HOSTS, ${target_hosts}) 163 164 LIBCFA_PATHS="DRIVER_DIR=${DRIVER_DIR}" 165 166 for i in $(echo $target_hosts | sed "s/,/ /g") 167 do 168 # call your procedure/other scripts here below 169 arch_name=$(echo $i | sed -r "s/:(.*)//g") 170 lib_config=$(echo $i | sed -r "s/(.*)://g") 171 172 case $lib_config in 173 "nodebug") ;; 174 "debug") ;; 175 "nolib") ;; 176 "profile") ;; 177 *) 178 >&2 echo "Configuration must be 'debug', 'nodebug' or 'nolib'" 179 exit 1 180 ;; 181 esac 182 183 M4CFA_CANNON_CPU([${arch_name}]) 184 lib_arch=${cannon_arch_name} 185 lib_dir="libcfa/${lib_arch}-${lib_config}" 186 187 LIBCFA_TARGET_DIRS="${LIBCFA_TARGET_DIRS} ${lib_dir}" 188 LIBCFA_TARGET_MAKEFILES="${LIBCFA_TARGET_MAKEFILES} ${lib_dir}/Makefile" 189 190 mkdir -p ${lib_dir} 191 echo -n "${LIBCFA_GENERAL_ARGS} " > ${lib_dir}/config.data 192 echo -n "${LIBCFA_PATHS} " >> ${lib_dir}/config.data 193 echo -n "ARCHITECTURE=${lib_arch} " >> ${lib_dir}/config.data 194 echo -n "CONFIGURATION=${lib_config} " >> ${lib_dir}/config.data 195 echo -n "CFA_VERSION=${ver_major}:${ver_minor}:${ver_patch}" >> ${lib_dir}/config.data 196 done 197 198 AC_SUBST(LIBCFA_TARGET_DIRS) 199 AC_SUBST(LIBCFA_TARGET_MAKEFILES) 200 201 M4CFA_CANNON_CPU([${host_cpu}]) 202 AC_DEFINE_UNQUOTED(CFA_DEFAULT_CPU, "$cannon_arch_name", [Default cpu to use if neither -m32 or -m64 are defined.]) 203 AC_DEFINE_UNQUOTED(CFA_64_CPU, "x64", [CPU to use if the -m64 flags is given.]) 204 AC_DEFINE_UNQUOTED(CFA_32_CPU, "x86", [CPU to use if the -m32 flags is given.]) 205 206 #============================================================================== 207 # CAFLAGS 201 208 AC_DEFINE_UNQUOTED(CFA_FLAGS, "${CFAFLAGS}", [compilation flags for cfa libraries and test programs.]) 202 209 AC_SUBST(CFA_FLAGS, ${CFAFLAGS}) 203 210 211 #============================================================================== 204 212 # Checks for programs. 205 213 AC_PROG_CXX 206 214 AC_PROG_CC 207 215 AM_PROG_AS 208 AM_PROG_CC_C_O # deprecated209 216 # These are often not installed and people miss seeing the "no", so stop the configure. 210 217 AC_PROG_YACC … … 212 219 AC_PROG_LEX 213 220 if test "${LEX}" = "lex" ; then echo "Error: flex required." ; exit 1 ; fi 221 AC_PROG_LIBTOOL 214 222 AC_PROG_INSTALL 215 AC_PROG_MAKE_SET216 AC_PROG_RANLIB217 223 218 224 # Checks for libraries. 225 AC_CHECK_LIB([fibre], [Fibre::yield], [HAVE_LIBFIBRE=1], [HAVE_LIBFIBRE=0]) 226 AM_CONDITIONAL([WITH_LIBFIBRE], [test "$HAVE_LIBFIBRE" -eq 1]) 227 228 AC_CHECK_LIB([profiler], [ProfilingIsEnabledForAllThreads], [HAVE_LIBPROFILER=1], [HAVE_LIBPROFILER=0]) 229 AM_CONDITIONAL([WITH_LIBPROFILER], [test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBPROFILER" -eq 1]) 230 231 AC_CHECK_LIB([tcmalloc], [malloc], [HAVE_LIBTCMALLOC=1], [HAVE_LIBTCMALLOC=0]) 232 AM_CONDITIONAL([WITH_LIBTCMALLOC], [test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBTCMALLOC" -eq 1]) 233 234 # conditionnally build the demangler 235 if test "x$enable_demangler" == xyes; then 236 LIBDEMANGLE="libdemangle.a" 237 DEMANGLER="demangler" 238 else 239 LIBDEMANGLE="" 240 DEMANGLER="" 241 fi 242 AC_SUBST([LIBDEMANGLE]) 243 AC_SUBST([DEMANGLER]) 219 244 220 245 # Checks for header files. 221 AC_FUNC_ALLOCA 222 AC_CHECK_HEADERS([fenv.h float.h inttypes.h libintl.h limits.h malloc.h stddef.h stdlib.h string.h unistd.h]) 246 AC_CHECK_HEADERS([libintl.h malloc.h unistd.h], [], [echo "Error: Missing required header"; exit 1]) 223 247 224 248 # Checks for typedefs, structures, and compiler characteristics. 225 AC_HEADER_STDBOOL 226 AC_C_INLINE 227 AC_TYPE_INT16_T 228 AC_TYPE_INT32_T 229 AC_TYPE_INT8_T 230 AC_C_RESTRICT 231 AC_TYPE_SIZE_T 232 AC_TYPE_UINT16_T 233 AC_TYPE_UINT32_T 234 AC_TYPE_UINT8_T 235 236 # Checks for library functions. 237 AC_CHECK_FUNCS([memset putenv strchr strtol]) 238 249 AC_CHECK_TYPES([_Float32], AC_DEFINE([HAVE_KEYWORDS_FLOATXX], [], [Have keywords _FloatXX.]), [], [[]]) 250 251 # Checks for compiler flags. 252 M4CFA_CHECK_COMPILE_FLAG([-Wcast-function-type], AC_DEFINE([HAVE_CAST_FUNCTION_TYPE], [], [Have compiler warning cast-function-type.])) 253 254 #============================================================================== 255 # backend compiler implementation 256 AC_DEFINE_UNQUOTED(CFA_BACKEND_CC, "${CC}", [Backend compiler to use.]) 257 AC_SUBST(CFA_BACKEND_CC) 258 259 #============================================================================== 239 260 AC_CONFIG_FILES([ 240 261 Makefile 241 src/driver/Makefile262 driver/Makefile 242 263 src/Makefile 243 src/benchmark/Makefile 244 src/examples/Makefile 245 src/tests/Makefile 246 src/tests/preempt_longrun/Makefile 247 src/prelude/Makefile 248 src/libcfa/Makefile 264 benchmark/Makefile 265 tests/Makefile 266 longrun_tests/Makefile 249 267 tools/Makefile 250 268 tools/prettyprinter/Makefile 251 269 ]) 252 270 253 AC_OUTPUT 254 255 AM_COND_IF([BUILD_RELEASE], 256 [AM_COND_IF([BUILD_DEBUG], 257 [AC_MSG_NOTICE(Building libcfa for target: release & debug)], 258 [AC_MSG_NOTICE(Building libcfa for target: release)])], 259 [AM_COND_IF([BUILD_DEBUG], 260 [AC_MSG_NOTICE(Building libcfa for target: debug)], 261 [AC_MSG_NOTICE(Running cfa without libcfa)])]) 271 AC_CONFIG_LINKS([tests/test.py:tests/test.py]) 272 273 AC_OUTPUT(tests/config.py) 262 274 263 275 # Final text -
doc/LaTeXmacros/common.tex
r7951100 rb067d9b 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Mar 19 17:18:23 201814 %% Update Count : 3 7913 %% Last Modified On : Fri May 24 07:59:54 2019 14 %% Update Count : 382 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 55 55 \setlength{\parindentlnth}{\parindent} 56 56 57 \newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{#1}}} 57 58 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}} 58 59 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} … … 60 61 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 61 62 \newlength{\columnposn} 62 \setlength{\gcolumnposn}{2. 5in}63 \setlength{\gcolumnposn}{2.75in} 63 64 \setlength{\columnposn}{\gcolumnposn} 64 65 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@basicstyle{\LstCommentStyle{#2}}}} -
doc/LaTeXmacros/lstlang.sty
r7951100 rb067d9b 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Fri Apr 6 23:44:50 201811 %% Update Count : 2 010 %% Last Modified On : Tue Jan 8 14:40:33 2019 11 %% Update Count : 21 12 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 13 … … 114 114 _Alignas, _Alignof, __alignof, __alignof__, asm, __asm, __asm__, __attribute, __attribute__, 115 115 auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, __const, __const__, 116 coroutine, disable, dtype, enable, __extension__, exception, fallthrough, fallthru, finally,116 coroutine, disable, dtype, enable, exception, __extension__, fallthrough, fallthru, finally, 117 117 __float80, float80, __float128, float128, forall, ftype, _Generic, _Imaginary, __imag, __imag__, 118 118 inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or, -
doc/bibliography/pl.bib
r7951100 rb067d9b 21 21 % toplas: ACM Trans. on Prog. Lang. & Sys. 22 22 % tcs: Theoretical Computer Science 23 @string{ieeepds="IEEE Transactions on Parallel and Distributed Systems"} 24 % @string{ieeepds="IEEE Trans. Parallel Distrib. Syst."} 25 @string{ieeese="IEEE Transactions on Software Engineering"} 26 % @string{ieeese="IEEE Trans. Softw. Eng."} 27 @string{spe="Software---\-Practice and Experience"} 28 % @string{spe="Softw. Pract. Exp."} 29 @string{ccpe="Concurrency and Computation: Practice and Experience"} 30 % @string{ccpe="Concurrency Comput: Pract Experience"} 31 @string{sigplan="SIGPLAN Notices"} 32 % @string{sigplan="SIGPLAN Not."} 33 @string{joop="Journal of Object-Oriented Programming"} 34 % @string{joop="J. of Object-Oriented Program."} 23 24 string{ieeepds="IEEE Transactions on Parallel and Distributed Systems"} 25 @string{ieeepds="IEEE Trans. Parallel Distrib. Syst."} 26 string{ieeese="IEEE Transactions on Software Engineering"} 27 @string{ieeese="IEEE Trans. Softw. Eng."} 28 string{spe="Software---\-Practice and Experience"} 29 @string{spe="Softw. Pract. Exper."} 30 string{ccpe="Concurrency and Computation: Practice and Experience"} 31 @string{ccpe="Concurrency Comput.: Pract. Exper."} 32 string{sigplan="SIGPLAN Notices"} 33 @string{sigplan="SIGPLAN Not."} 34 string{joop="Journal of Object-Oriented Programming"} 35 @string{joop="J. of Object-Oriented Program."} 35 36 @string{popl="Conference Record of the ACM Symposium on Principles of Programming Languages"} 36 37 @string{osr="Operating Systems Review"} 37 38 @string{pldi="Programming Language Design and Implementation"} 38 39 @string{toplas="Transactions on Programming Languages and Systems"} 39 @string{mathann="Mathematische Annalen"}40 %@string{mathann="Math. Ann."}40 string{mathann="Mathematische Annalen"} 41 @string{mathann="Math. Ann."} 41 42 42 43 % A … … 329 330 contributer = {pabuhr@plg}, 330 331 author = {Nissim Francez}, 331 title = {Another Advantage of Key word Notation for Parameter Communication with Subprograms},332 title = {Another Advantage of Keyword Notation for Parameter Communication with Subprograms}, 332 333 journal = cacm, 333 334 volume = 20, … … 566 567 } 567 568 569 @inproceedings {Qin18, 570 author = {Henry Qin and Qian Li and Jacqueline Speiser and Peter Kraft and John Ousterhout}, 571 title = {Arachne: Core-Aware Thread Management}, 572 booktitle = {13th {USENIX} Symp. on Oper. Sys. Design and Impl. ({OSDI} 18)}, 573 year = {2018}, 574 address = {Carlsbad, CA}, 575 pages = {145-160}, 576 publisher = {{USENIX} Association}, 577 note = {\href{https://www.usenix.org/conference/osdi18/presentation/qin}{https://\-www.usenix.org/\-conference/\-osdi18/\-presentation/\-qin}}, 578 } 579 568 580 @article{Kessels82, 569 581 keywords = {concurrency, critical section}, … … 653 665 author = {Joung, Yuh-Jzer}, 654 666 title = {Asynchronous group mutual exclusion}, 655 journal = {Distributed Computing}, 667 journal = {Dist. Comput.}, 668 optjournal = {Distributed Computing}, 656 669 year = {2000}, 657 670 month = {Nov}, … … 700 713 701 714 % B 715 716 @article{Michael13, 717 contributer = {pabuhr@plg}, 718 author = {Maged M. Michael}, 719 title = {The Balancing Act of Choosing Nonblocking Features}, 720 journal = cacm, 721 volume = 56, 722 number = 9, 723 month = sep, 724 year = 2013, 725 pages = {46--53}, 726 publisher = {ACM}, 727 address = {New York, NY, USA}, 728 } 702 729 703 730 @incollection{beta:old, … … 782 809 time computable inheritance hierarchy. 783 810 }, 784 comment = {811 comment = { 785 812 Classes are predicates; if object {\tt o} is in class {\tt C}, then 786 813 {\tt C} is true of {\tt o}. Classes are combined with {\tt :AND}, … … 804 831 year = 2015, 805 832 howpublished= {\href{http://www.boost.org/doc/libs/1_61_0/libs/coroutine/doc/html/index.html} 806 {{http://www.boost.org/\-doc/\-libs/1\_61\_0/\-libs/\-coroutine/\-doc/\-html/\-index.html}}}, 807 optnote = {Accessed: 2016-09}, 833 {http://www.boost.org/\-doc/\-libs/1\_61\_0/\-libs/\-coroutine/\-doc/\-html/\-index.html}}, 834 } 835 836 @misc{BoostThreads, 837 keywords = {Boost Thread Library}, 838 contributer = {pabuhr@plg}, 839 author = {Anthony Williams and Vicente J. Botet Escriba}, 840 title = {Boost Thread Library}, 841 year = 2015, 842 howpublished= {\href{https://www.boost.org/doc/libs/1_61_0/doc/html/thread.html} 843 {https://\-www.boost.org/\-doc/\-libs/\-1\_61\_0/\-doc/\-html/\-thread.html}}, 808 844 } 809 845 … … 816 852 month = oct, 817 853 type = {Diplomarbeit}, 818 note = { {\small\textsf{ftp://\-plg.uwaterloo.ca/\-pub/\-theses/\-KrischerThesis.ps.gz}}},854 note = {\href{https://plg.uwaterloo.ca/~usystem/theses/KrischerThesis.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-theses/\-KrischerThesis.pdf}}, 819 855 } 820 856 … … 907 943 } 908 944 945 @article{Moss18, 946 keywords = {type systems, polymorphism, tuples, Cforall}, 947 contributer = {pabuhr@plg}, 948 author = {Aaron Moss and Robert Schluntz and Peter A. Buhr}, 949 title = {\textsf{C}$\mathbf{\forall}$ : Adding Modern Programming Language Features to {C}}, 950 journal = spe, 951 volume = 48, 952 number = 12, 953 month = dec, 954 year = 2018, 955 pages = {2111-2146}, 956 note = {\href{http://dx.doi.org/10.1002/spe.2624}{http://\-dx.doi.org/\-10.1002/\-spe.2624}}, 957 } 958 959 @misc{CforallBenchMarks, 960 contributer = {pabuhr@plg}, 961 key = {Cforall Benchmarks}, 962 author = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}}, 963 howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmark.tar}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmark.tar}}, 964 } 965 909 966 @misc{Cforall, 967 contributer = {pabuhr@plg}, 910 968 key = {Cforall}, 911 title = {\textsf{C}{$\mathbf{\forall}$} Features}, 912 howpublished= {\url{https://plg.uwaterloo.ca/~cforall/features}}, 913 optnote = {Accessed: 2018-01-01}, 969 author = {{\textsf{C}{$\mathbf{\forall}$} Features}}, 970 howpublished= {\href{https://plg.uwaterloo.ca/~cforall/features}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-features}}, 971 } 972 973 @misc{CFAStackEvaluation, 974 contributer = {a3moss@plg}, 975 author = {Aaron Moss}, 976 title = {\textsf{C}$\mathbf{\forall}$ Stack Evaluation Programs}, 977 year = 2018, 978 howpublished= {\href{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}{https://cforall.uwaterloo.ca/\-CFAStackEvaluation.zip}}, 914 979 } 915 980 … … 925 990 } 926 991 927 @misc{CFAStackEvaluation, 992 @phdthesis{Moss19, 993 keywords = {type system, generic type, resolution algorithm, type environment, Cforall}, 928 994 author = {Aaron Moss}, 929 title = {\textsf{C}$\mathbf{\forall}$ Stack Evaluation Programs}, 930 year = 2018, 931 howpublished= {\href{https://plg.uwaterloo.ca/~cforall/evaluation.zip}{https://plg.uwaterloo.ca/\-\-$\sim$cforall/\-StackEvaluation.zip}}, 932 optnote = {[Accessed May 2018]}, 933 } 934 935 @article{Moss18, 936 keywords = {concurrency, C++}, 937 contributer = {pabuhr@plg}, 938 author = {Aaron Moss and Robert Schluntz and Peter A. Buhr}, 939 title = {\textsf{C}$\mathbf{\forall}$ : Adding Modern Programming Language Features to C}, 940 year = 2018, 941 journal = spe, 942 note = {Accepted, to appear}, 995 title = {\textsf{C}$\mathbf{\forall}$ Type System Implementation}, 996 school = {School of Computer Science, University of Waterloo}, 997 year = 2019, 998 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 999 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/14584}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-14584}}, 943 1000 } 944 1001 … … 962 1019 comment = { 963 1020 The evidence given is thin. 964 } 1021 }, 965 1022 } 966 1023 … … 972 1029 journal = {Dr. Dobb's Journal of Software Tools}, 973 1030 year = 1989, 974 month = feb, volume = 14, number = 2, pages = {45-51}, 1031 month = feb, 1032 volume = 14, 1033 number = 2, 1034 pages = {45-51}, 975 1035 comment = { 976 1036 A light-weight multitasking kernel for MS-DOS. A task\_control … … 1048 1108 year = 2006, 1049 1109 edition = {4th}, 1110 } 1111 1112 @techreport{Prokopec11, 1113 keywords = {ctrie, concurrent map}, 1114 contributer = {a3moss@uwaterloo.ca}, 1115 title ={Cache-aware lock-free concurrent hash tries}, 1116 author ={Prokopec, Aleksandar and Bagwell, Phil and Odersky, Martin}, 1117 institution ={EPFL}, 1118 year ={2011} 1050 1119 } 1051 1120 … … 1084 1153 month = oct, 1085 1154 year = 2001, 1086 note = {\href{http://plg.uwaterloo.ca/~cforall/cfa.ps}{http://\-plg.uwaterloo.ca/\- \char`\~cforall/\-cfa.ps}},1155 note = {\href{http://plg.uwaterloo.ca/~cforall/cfa.ps}{http://\-plg.uwaterloo.ca/\-$\sim$cforall/\-cfa.ps}}, 1087 1156 } 1088 1157 … … 1096 1165 year = 1998, 1097 1166 note = {{\small\textsf{ftp://\-plg.uwaterloo.ca/\-pub/\-Cforall/\-refrat.ps.gz}}}, 1167 } 1168 1169 @phdthesis{Norrish98, 1170 title = {C formalised in HOL}, 1171 author = {Norrish, Michael}, 1172 year = {1998}, 1173 school = {University of Cambridge} 1174 } 1175 1176 @inproceedings{Tarditi18, 1177 keywords = {Checked C}, 1178 contributer = {a3moss@uwaterloo.ca}, 1179 author = {Tarditi, David and Elliott, Archibald Samuel and Ruef, Andrew and Hicks, Michael}, 1180 title = {Checked C: Making C Safe by Extension}, 1181 booktitle = {2018 IEEE Cybersecurity Development (SecDev)}, 1182 publisher = {IEEE}, 1183 year = {2018}, 1184 month = sep, 1185 pages = {53-60}, 1186 url = {https://www.microsoft.com/en-us/research/publication/checkedc-making-c-safe-by-extension/}, 1187 } 1188 1189 @misc{Clang, 1190 keywords = {clang}, 1191 contributer = {a3moss@uwaterloo.ca}, 1192 title = {Clang: a {C} language family frontend for {LLVM}}, 1193 howpublished= {\href{https://clang.llvm.org/}{https://\-clang.llvm.org/}} 1098 1194 } 1099 1195 … … 1183 1279 that is ``compiled''. 1184 1280 }, 1185 comment = {1186 Imagine the program, including the subroutines, spread out over a1187 table, with the compiler dropping Jello on the parts as they are1188 compiled. At first little drops appear in seemingly random places.1189 These get bigger and combine with other drops to form growing1190 globs. When two globs meet, ripples will go out through each as1191 they adjust to each other's presence, although the parts of the1192 globs that formed first are less affected by the ripples. When1193 compilation is complete, there is one congealed mass.1194 }1195 1281 } 1196 1282 … … 1206 1292 number = 11, 1207 1293 pages = {853-860}, 1294 } 1295 1296 @inproceedings{Odersky01, 1297 keywords = {Scala}, 1298 contributer = {a3moss@uwaterloo.ca}, 1299 author = {Odersky, Martin and Zenger, Christoph and Zenger, Matthias}, 1300 title = {Colored Local Type Inference}, 1301 booktitle = {Proceedings of the 28th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages}, 1302 series = {POPL '01}, 1303 year = {2001}, 1304 isbn = {1-58113-336-7}, 1305 location = {London, United Kingdom}, 1306 pages = {41--53}, 1307 numpages = {13}, 1308 url = {http://doi.acm.org/10.1145/360204.360207}, 1309 doi = {10.1145/360204.360207}, 1310 acmid = {360207}, 1311 publisher = {ACM}, 1312 address = {New York, NY, USA}, 1208 1313 } 1209 1314 … … 1268 1373 journal = sigplan, 1269 1374 year = 1986, 1270 month = oct, volume = 21, number = 10, pages = {19-28}, 1375 month = oct, 1376 volume = 21, 1377 number = 10, 1378 pages = {19-28}, 1271 1379 note = {Object Oriented Programming Workshop} 1272 1380 } … … 1388 1496 Process-valued expressions and process variables. Processes have 1389 1497 execution priority: Create {\em process-type-name}(args) [with 1390 priority(p)], 1391 and the priority can be changed on the fly. Complicated guard/ 1392 screen structure on accept: accept {\em transaction}(param names) 1498 priority(p)], and the priority can be changed on the fly. Complicated 1499 guard/screen structure on accept: accept {\em transaction}(param names) 1393 1500 [suchthat (exp)] [by (exp)] [compoundstatement]. Accepts cannot 1394 1501 appear in functions! Can specify timeouts on transaction calls. … … 1425 1532 Many errors in the two solutions. 1426 1533 } 1534 } 1535 1536 @misc{NThreadCode13, 1537 keywords = {N-thread software-solution mutual exclusion}, 1538 contributer = {pabuhr@plg}, 1539 key = {concurrent locking}, 1540 author = {Peter A. Buhr and David Dice and Wim H. Hesselink}, 1541 title = {concurrent-locking}, 1542 howpublished= {\href{https://github.com/pabuhr/concurrent-locking}{https://\-github.com/\-pabuhr/\-concurrent-locking}}, 1427 1543 } 1428 1544 … … 1491 1607 } 1492 1608 1493 @ techreport{uC++,1609 @manual{uC++, 1494 1610 keywords = {C++, concurrency, light-weight process, shared memory}, 1495 1611 contributer = {pabuhr@plg}, 1612 key = {uC++}, 1496 1613 author = {Peter A. Buhr}, 1497 1614 title = {$\mu${C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Annotated Reference Manual, Version 7.0.0}, 1498 institution = {School of Computer Science, University of Waterloo}, 1499 address = {Waterloo, Ontario, Canada, N2L 3G1}, 1500 month = dec, 1501 year = 2017, 1502 note = {\href{http://plg.uwaterloo.ca/~usystem/pub/uSystem/u++-7.0.0.sh}{http://\-plg.\-uwaterloo.\-ca/\-$\sim$usystem/\-pub/\-uSystem/\-u++-7.0.0.sh}}, 1615 organization= {University of Waterloo}, 1616 month = sep, 1617 year = 2018, 1618 note = {\href{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uC++.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-pub/\-uSystem/uC++.pdf}}, 1503 1619 } 1504 1620 … … 1567 1683 } 1568 1684 1685 @mastersthesis{Sun15, 1686 author = {Sun, Xianda}, 1687 title = {Concurrent High-performance Persistent Hash Table In {J}ava}, 1688 school = {School of Computer Sc., University of Waterloo}, 1689 year = 2015, 1690 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 1691 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/10013}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-10013}}, 1692 } 1693 1569 1694 @book{Andrews91:book, 1570 1695 keywords = {concurrency}, … … 1575 1700 address = {Redwood City}, 1576 1701 year = 1991, 1702 } 1703 1704 @inproceedings{Prokopec12, 1705 keywords = {ctrie, hash trie, concurrent map}, 1706 contributer = {a3moss@uwaterloo.ca}, 1707 title = {Concurrent tries with efficient non-blocking snapshots}, 1708 author = {Prokopec, Aleksandar and Bronson, Nathan Grasso and Bagwell, Phil and Odersky, Martin}, 1709 booktitle = {ACM SIGPLAN Notices}, 1710 volume = {47}, 1711 number = {8}, 1712 pages = {151--160}, 1713 year = {2012}, 1714 organization={ACM} 1577 1715 } 1578 1716 … … 1591 1729 1592 1730 @mastersthesis{Delisle18, 1593 author = {Thierry Delisle }, 1731 keywords = {concurrency, Cforall}, 1732 contributer = {pabuhr@plg}, 1733 author = {Thierry Delisle}, 1594 1734 title = {Concurrency in \textsf{C}$\mathbf{\forall}$}, 1595 1735 school = {School of Computer Science, University of Waterloo}, 1596 1736 year = 2018, 1597 address = {Waterloo, Ontario, Canada, N2L 3G1},1737 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 1598 1738 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/12888}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-12888}}, 1739 } 1740 1741 @article{Delisle19, 1742 keywords = {concurrency, Cforall}, 1743 contributer = {pabuhr@plg}, 1744 author = {Thierry Delisle and Peter A. Buhr}, 1745 title = {Advanced Control-flow and Concurrency in \textsf{C}$\mathbf{\forall}$}, 1746 year = 2019, 1747 journal = spe, 1748 pages = {1-33}, 1749 note = {submitted}, 1599 1750 } 1600 1751 … … 1690 1841 howpublished= {\href{https://www.airs.com/blog/archives/428} 1691 1842 {https://www.airs.com/\-blog/\-archives/\-428}}, 1692 optnote = {Accessed: 2018-05},1693 1843 } 1694 1844 … … 1771 1921 author = {Glen Ditchfield}, 1772 1922 title = {Conversions for \textsf{C}$\mathbf{\forall}$}, 1773 note = {\href{http://plg.uwaterloo.ca/~cforall/Conversions/index.html}{http://\-plg.uwaterloo.ca/\- \textasciitildecforall/\-Conversions/\-index.html}},1923 note = {\href{http://plg.uwaterloo.ca/~cforall/Conversions/index.html}{http://\-plg.uwaterloo.ca/\-$\sim$cforall/\-Conversions/\-index.html}}, 1774 1924 month = {Nov}, 1775 1925 year = {2002}, … … 1786 1936 year = 1965, 1787 1937 note = {Reprinted in \cite{Genuys68} pp. 43--112.} 1938 } 1939 1940 @inproceedings{Adya02, 1941 contributer = {pabuhr@plg}, 1942 author = {Adya, Atul and Howell, Jon and Theimer, Marvin and Bolosky, William J. and Douceur, John R.}, 1943 title = {Cooperative Task Management Without Manual Stack Management}, 1944 booktitle = {Proceedings of the General Track of the Annual Conference on USENIX Annual Technical Conference}, 1945 series = {ATEC '02}, 1946 year = {2002}, 1947 pages = {289-302}, 1948 publisher = {USENIX Association}, 1949 address = {Berkeley, CA, USA}, 1950 } 1951 1952 @misc{CoroutineTS, 1953 keywords = {Coroutines TS, C++20, working draft}, 1954 contributer = {pabuhr@plg}, 1955 author = {Gor Nishanov}, 1956 title = {Merge Coroutines TS into C++20 Working Draft}, 1957 year = 2019, 1958 month = feb, 1959 howpublished= {\href{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0912r5.html} 1960 {http://\-www.open-std.org/\-jtc1/\-sc22/\-wg21/\-docs/\-papers/\-2019/p0912r5.html}}, 1961 } 1962 1963 @manual{C++20Coroutine19, 1964 keywords = {coroutine}, 1965 contributer = {pabuhr@plg}, 1966 title = {Coroutines (C++20)}, 1967 organization= {cppreference.com}, 1968 month = apr, 1969 year = 2019, 1970 note = {\href{https://en.cppreference.com/w/cpp/language/coroutines}{https://\-en.cppreference.com/\-w/\-cpp/\-language/\-coroutines}}, 1788 1971 } 1789 1972 … … 1833 2016 } 1834 2017 1835 @article{Moore75, 1836 keywords = {approximation methods, integrated circuits}, 1837 contributer = {pabuhr@plg}, 1838 author = {Gordon E. Moore}, 1839 title = {Progress in Digital Integrated Electronics}, 1840 journal = {Technical Digest, International Electron Devices Meeting, IEEE}, 1841 year = 1975, 1842 pages = {11-13}, 2018 @misc{CS343, 2019 keywords = {uC++ teaching}, 2020 contributer = {pabuhr@plg}, 2021 key = {Peter Buhr}, 2022 title = {CS343}, 2023 year = 2018, 2024 howpublished= {\href{https://www.student.cs.uwaterloo.ca/~cs343}{https://\-www.student.cs.uwaterloo.ca/\-$\sim$cs343}}, 1843 2025 } 1844 2026 … … 1899 2081 note = {Svensk Standard SS 63 61 14}, 1900 2082 year = 1987, 1901 abstract = { 1902 Standard for the programming language SIMULA. Written in English. 1903 } 2083 abstract = {Standard for the programming language SIMULA. Written in English.} 2084 } 2085 2086 @article{Galil91, 2087 keywords = {union-find}, 2088 contributer = {a3moss@uwaterloo.ca}, 2089 title = {Data structures and algorithms for disjoint set union problems}, 2090 author = {Galil, Zvi and Italiano, Giuseppe F}, 2091 journal = {ACM Computing Surveys (CSUR)}, 2092 volume = 23, 2093 number = 3, 2094 pages = {319--344}, 2095 year = 1991, 2096 publisher = {ACM}, 1904 2097 } 1905 2098 … … 2041 2234 year = {1998}, 2042 2235 pages = {393-407}, 2236 } 2237 2238 @book{Aho74, 2239 keywords = {algorithms, textbook, union-find}, 2240 contributer = {a3moss@uwaterloo.ca}, 2241 title = {The Design and Analysis of Computer Algorithms}, 2242 author = {Aho, Alfred V and Hopcroft, John E and Ullman, Jeffrey D}, 2243 year = {1974}, 2244 publisher = {Addison-Wesley}, 2245 address = {Reading, MA, USA} 2043 2246 } 2044 2247 … … 2194 2397 } 2195 2398 2399 @article{Ritchie93, 2400 keywords = {C, history}, 2401 contributer = {pabuhr@plg}, 2402 author = {Ritchie, Dennis M.}, 2403 title = {The Development of the {C} Language}, 2404 journal = sigplan, 2405 volume = 28, 2406 number = 3, 2407 month = mar, 2408 year = 1993, 2409 pages = {201--208}, 2410 url = {http://doi.acm.org/10.1145/155360.155580}, 2411 publisher = {ACM}, 2412 address = {New York, NY, USA}, 2413 } 2414 2196 2415 @article{design, 2197 2416 keywords = {Smalltalk, designing classes}, … … 2201 2420 journal = joop, 2202 2421 year = 1988, 2203 volume = 1, number = 2, pages = {22-35}, 2422 volume = 1, 2423 number = 2, 2424 pages = {22-35}, 2204 2425 comment = { 2205 2426 Abstract classes represent standard protocols. ``It is better to … … 2286 2507 year = 1990, 2287 2508 pages = {315-323} 2509 } 2510 2511 @misc{Dotty-github, 2512 keywords = {dotty,scala}, 2513 contributer = {a3moss@uwaterloo.ca}, 2514 author = {Martin Odersky}, 2515 title = {Dotty}, 2516 howpublished= {\href{https://github.com/lampepfl/dotty}{https://\-github.com/\-lampepfl/\-dotty}}, 2517 note = {Acessed: 2019-02-22} 2288 2518 } 2289 2519 … … 2394 2624 } 2395 2625 2626 @article{Tarjan75, 2627 keywords = {union-find}, 2628 contributer = {a3moss@uwaterloo.ca}, 2629 author = {Tarjan, Robert Endre}, 2630 title = {Efficiency of a Good But Not Linear Set Union Algorithm}, 2631 journal = {J. ACM}, 2632 issue_date = {April 1975}, 2633 volume = {22}, 2634 number = {2}, 2635 month = apr, 2636 year = {1975}, 2637 issn = {0004-5411}, 2638 pages = {215--225}, 2639 numpages = {11}, 2640 url = {http://doi.acm.org/10.1145/321879.321884}, 2641 doi = {10.1145/321879.321884}, 2642 acmid = {321884}, 2643 publisher = {ACM}, 2644 address = {New York, NY, USA}, 2645 } 2646 2396 2647 @book{Eiffel, 2397 2648 keywords = {Eiffel}, … … 2412 2663 journal = ipl, 2413 2664 year = 1980, 2414 month = apr, volume = 10, number = 3, pages = {120-123}, 2665 month = apr, 2666 volume = 10, 2667 number = 3, 2668 pages = {120-123}, 2415 2669 comment = { 2416 2670 The ``two-pass'' algorithm. An upward pass over a parse tree … … 2446 2700 } 2447 2701 2448 @ InProceedings{chambers89a,2702 @inproceedings{chambers89a, 2449 2703 keywords = {maps, delegation}, 2450 2704 author = "Craig Chambers and David Ungar and Elgin Lee", 2451 title = "An Efficient Implementation of {SELF}, a Dynamically-Typed 2452 Object-Oriented Language Based on Prototypes", 2705 title = "An Efficient Implementation of {SELF}, a Dynamically-Typed Object-Oriented Language Based on Prototypes", 2453 2706 crossref = "OOPSLA89", 2454 2707 pages = {49-70} 2455 2708 } 2456 2709 2710 @misc{Turley99, 2711 keywords = {embedded system, micrprocessor}, 2712 contributer = {pabuhr@plg}, 2713 author = {Jim Turley}, 2714 title = {Embedded Processors by the Numbers}, 2715 year = 1999, 2716 month = may, 2717 note = {Electronic Engineering Times}, 2718 howpublished= {\href{https://www.eetimes.com/author.asp?sectionid=36&doc_id=1287712} 2719 {https://\-www.eetimes.com/\-author.asp?sectionid=\-36&doc_id=1287712}}, 2720 } 2721 2457 2722 @article{oop:encapsulation, 2458 2723 keywords = {Encapsulation, Inheritance, Subclasses, Multiple Inheritance}, 2459 2724 contributer = {gjditchfield@plg}, 2460 2725 author = {Alan Snyder}, 2461 title = {Encapsulation and Inheritance in Object-Oriented Programming 2462 Languages}, 2726 title = {Encapsulation and Inheritance in Object-Oriented Programming Languages}, 2463 2727 journal = sigplan, 2464 2728 volume = {21}, number = {11}, … … 2495 2759 title = {Encapsulators: A New Software Paradigm in Smalltalk-80}, 2496 2760 journal = sigplan, 2497 volume = {21}, number = {11}, 2761 volume = {21}, 2762 number = {11}, 2498 2763 pages = {341-346}, 2499 month = nov, year = 1986, 2764 month = nov, 2765 year = 1986, 2500 2766 comment = { 2501 2767 Encapsulators are objects that surround other objects. … … 2568 2834 year = 1979, 2569 2835 pages = {24-32} 2836 } 2837 2838 @inproceedings{XaaS, 2839 keywords = {Everything as a Service, Anything as a Service, Cloud computing, SOA}, 2840 contributer = {pabuhr@plg}, 2841 author = {Duan, Yucong and Fu, Guohua and Zhou, Nianjun and Sun, Xiaobing and Narendra, Nanjangud C. and Hu, Bo}, 2842 title = {Everything As a Service (XaaS) on the Cloud: Origins, Current and Future Trends}, 2843 booktitle = {Proceedings of the 2015 IEEE 8th International Conference on Cloud Computing}, 2844 series = {CLOUD'15}, 2845 year = {2015}, 2846 pages = {621--628}, 2847 publisher = {IEEE Computer Society}, 2848 address = {Washington, DC, USA}, 2570 2849 } 2571 2850 … … 2779 3058 title = {Extending Modula-2 to Build Large, Integrated Systems}, 2780 3059 journal = {IEEE Software}, 2781 month = nov, year = 1986, 2782 volume = 3, number = 6, pages = {46-57}, 3060 month = nov, 3061 year = 1986, 3062 volume = 3, 3063 number = 6, 3064 pages = {46-57}, 2783 3065 comment = { 2784 3066 Exceptions can have a parameter. Procedures can declare the … … 2813 3095 year = 2014, 2814 3096 howpublished= {\href{https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/C-Extensions.html}{https://\-gcc.gnu.org/\-onlinedocs/\-gcc-4.7.2/\-gcc/\-C\-Extensions.html}}, 2815 optnote = {Accessed: 2017-04-02},2816 3097 } 2817 3098 … … 2825 3106 year = 1988, 2826 3107 pages = {143-149} 3108 } 3109 3110 @inproceedings{Patwary10, 3111 keywords = {union-find}, 3112 contributer = {a3moss@uwaterloo.ca}, 3113 author = {Patwary, Md. Mostofa Ali and Blair, Jean and Manne, Fredrik}, 3114 editor = {Festa, Paola}, 3115 title = {Experiments on Union-Find Algorithms for the Disjoint-Set Data Structure}, 3116 booktitle = {Experimental Algorithms}, 3117 year = 2010, 3118 publisher = {Springer Berlin Heidelberg}, 3119 address = {Berlin, Heidelberg}, 3120 pages = {411--423}, 3121 isbn = {978-3-642-13193-6} 2827 3122 } 2828 3123 … … 2860 3155 keywords = {concurrency, mutual exclusion, performance experiment, software solutions}, 2861 3156 title = {Fast mutual exclusion by the {T}riangle algorithm}, 2862 author = {Wim H. Hesselink and Peter Buhr and David Dice},3157 author = {Wim H. Hesselink and Peter A. Buhr and David Dice}, 2863 3158 journal = ccpe, 2864 3159 volume = 30, … … 2867 3162 month = feb, 2868 3163 publisher = {John Wiley \& Sons}, 2869 note = {\ url{https://doi.org/10.1002/cpe.4183}}3164 note = {\href{https://doi.org/10.1002/cpe.4183}{https://\-doi.org/\-10.1002/\-cpe.4183}} 2870 3165 } 2871 3166 … … 2883 3178 } 2884 3179 3180 @manual{WindowsFibers, 3181 keywords = {threads, fibers}, 3182 contributer = {pabuhr@plg}, 3183 author = {Windows}, 3184 title = {Fibers}, 3185 organization= {Microsoft, Windows Development Center}, 3186 address = {\href{https://docs.microsoft.com/en-us/windows/desktop/ProcThread/fibers}{https://\-docs.microsoft.com/\-en-us/\-windows/\-desktop/\-ProcThread/\-fibers}}, 3187 year = 2018, 3188 } 3189 2885 3190 @inproceedings{F-bound, 2886 3191 keywords = {}, … … 2930 3235 } 2931 3236 3237 @manual{Folly, 3238 keywords = {Folly}, 3239 contributer = {pabuhr@plg}, 3240 author = {Folly}, 3241 title = {Facebook Open-source Library}, 3242 organization= {Facebook}, 3243 address = {\href{https://github.com/facebook/folly}{https://\-github.com/\-facebook/\-folly}}, 3244 year = 2018, 3245 } 3246 3247 @article{Leroy09, 3248 keywords = {C formalization}, 3249 contributer = {a3moss@uwaterloo.ca}, 3250 author = {Leroy, Xavier}, 3251 title = {Formal Verification of a Realistic Compiler}, 3252 journal = {Commun. ACM}, 3253 issue_date = {July 2009}, 3254 volume = {52}, 3255 number = {7}, 3256 month = jul, 3257 year = {2009}, 3258 issn = {0001-0782}, 3259 pages = {107--115}, 3260 numpages = {9}, 3261 url = {http://doi.acm.org/10.1145/1538788.1538814}, 3262 doi = {10.1145/1538788.1538814}, 3263 acmid = {1538814}, 3264 publisher = {ACM}, 3265 address = {New York, NY, USA}, 3266 } 3267 2932 3268 @manual{Fortran95, 2933 3269 keywords = {Fortran 95}, … … 2950 3286 address = {\href{https://www.iso.org/standard/50459.html}{https://\-www.iso.org/\-standard/\-50459.html}}, 2951 3287 year = 2010, 3288 } 3289 3290 @manual{Fortran18, 3291 keywords = {ISO/IEC Fortran 10}, 3292 contributer = {pabuhr@plg}, 3293 author = {Fortran18}, 3294 title = {Programming Languages -- {Fortran} Part 1:Base Language ISO/IEC 1539-1:2018}, 3295 edition = {4rd}, 3296 publisher = {International Standard Organization}, 3297 address = {\href{https://www.iso.org/standard/72320.html}{https://\-www.iso.org/\-standard/\-72320.html}}, 3298 year = 2018, 2952 3299 } 2953 3300 … … 3170 3517 keywords = {Go programming language}, 3171 3518 contributer = {pabuhr@plg}, 3519 author = {Robert Griesemer and Rob Pike and Ken Thompson}, 3172 3520 title = {{Go} Programming Language}, 3173 author = {Robert Griesemer and Rob Pike and Ken Thompson},3174 3521 organization= {Google}, 3175 3522 year = 2009, … … 3199 3546 year = 2014, 3200 3547 howpublished= {https://developer.gnome.org/gobject/stable/}, 3201 optnote = {Accessed: 2017-04},3202 3548 } 3203 3549 … … 3279 3625 edition = {{S}imon {M}arlow}, 3280 3626 year = 2010, 3281 note = {\href{https://haskell.org/definition/haskell2010.pdf}{https:// haskell.org/\-definition/\-haskell2010.pdf}},3627 note = {\href{https://haskell.org/definition/haskell2010.pdf}{https://\-haskell.org/\-definition/\-haskell2010.pdf}}, 3282 3628 } 3283 3629 … … 3353 3699 } 3354 3700 3701 @article{Hesselink17b, 3702 keywords = {concurrency, mutual exclusion, performance experiment, software solutions}, 3703 title = {High-Contention Mutual Exclusion by Elevator Algorithms}, 3704 author = {Peter A. Buhr and David Dice and Wim H. Hesselink}, 3705 journal = ccpe, 3706 volume = 30, 3707 number = 18, 3708 year = 2018, 3709 month = sep, 3710 publisher = {John Wiley \& Sons}, 3711 note = {\href{https://doi.org/10.1002/cpe.4475}{https://\-doi.org/\-10.1002/\-cpe.4475}}, 3712 } 3713 3355 3714 @article{Buhr15a, 3356 3715 keywords = {software solution, mutual exclusion, performance experiment}, … … 3488 3847 publisher = {ACM Press}, 3489 3848 address = {New York, NY, USA}, 3849 } 3850 3851 @article{Galler64, 3852 keywords = {union-find, original}, 3853 contributer = {a3moss@uwaterloo.ca}, 3854 title = {An improved equivalence algorithm}, 3855 author = {Galler, Bernard A and Fisher, Michael J}, 3856 journal = {Communications of the ACM}, 3857 volume = {7}, 3858 number = {5}, 3859 pages = {301--303}, 3860 year = {1964}, 3861 publisher = {ACM} 3862 } 3863 3864 @phdthesis{Barghi18, 3865 keywords = {concurrency, user threads, actors}, 3866 contributer = {pabuhr@plg}, 3867 author = {Saman Barghi}, 3868 title = {Improving the Performance of User-level Runtime Systems for Concurrent Applications}, 3869 school = {School of Computer Science, University of Waterloo}, 3870 year = 2018, 3871 month = sep, 3872 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 3873 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/13935}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-13935}}, 3874 } 3875 3876 @article{Swift05, 3877 contributer = {pabuhr@plg}, 3878 author = {Michael M. Swift and Brian N. Bershad and Henry M. Levy}, 3879 title = {Improving the Reliability of Commodity Operating Systems}, 3880 journal = tocs, 3881 volume = 23, 3882 number = 1, 3883 month = feb, 3884 year = 2005, 3885 pages = {77-110}, 3490 3886 } 3491 3887 … … 3794 4190 } 3795 4191 4192 @article{Morgado13, 4193 keywords = {expression resolution}, 4194 contributer = {a3moss@uwaterloo.ca}, 4195 title = {Iterative and core-guided {MaxSAT} solving: A survey and assessment}, 4196 author = {Morgado, Antonio and Heras, Federico and Liffiton, Mark and Planes, Jordi and Marques-Silva, Joao}, 4197 journal = {Constraints}, 4198 volume = {18}, 4199 number = {4}, 4200 pages = {478--534}, 4201 year = {2013}, 4202 publisher = {Springer} 4203 } 4204 3796 4205 % J 3797 4206 … … 3817 4226 } 3818 4227 4228 @manual{Java11, 4229 keywords = {Java SE 11}, 4230 contributer = {pabuhr@plg}, 4231 author = {James Gosling and Bill Joy and Guy Steele and Gilad Bracha and Alex Buckley and Daniel Smith}, 4232 title = {{Java} Language Specification}, 4233 publisher = {Oracle}, 4234 month = sep, 4235 year = 2018, 4236 edition = {{J}ava {SE} 11}, 4237 } 4238 4239 @manual{JDK1.1, 4240 keywords = {JDK 1.1}, 4241 contributer = {pabuhr@plg}, 4242 author = {{Multithreading Models}}, 4243 title = {JDK 1.1 for Solaris Developer's Guide}, 4244 publisher = {Oracle}, 4245 address = {\href{https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqk/index.html#ch2mt-41}{https://\-docs.oracle.com/\-cd/\-E19455-01/\-806-3461/\-6jck06gqk/\-index.html\#ch2mt-41}}, 4246 year = 2010, 4247 } 4248 3819 4249 @manual{JUC, 3820 4250 keywords = {Java concurrency library}, … … 3829 4259 % K 3830 4260 4261 @inproceedings{Buhr96b, 4262 author = {Peter A. Buhr and Martin Karsten and Jun Shih}, 4263 title = {{\small\textsf{KDB}}: A Multi-threaded Debugger for Multi-threaded Applications}, 4264 booktitle = {Proc. of SPDT'96: SIGMETRICS Symp. on Parallel and Distributed Tools}, 4265 publisher = {ACM Press}, 4266 address = {Philadelphia, Pennsylvania, U.S.A.}, 4267 month = may, 4268 year = 1996, 4269 pages = {80-87}, 4270 } 4271 3831 4272 @article{Duggan96, 3832 4273 keywords = {concurrency, critical section}, 3833 4274 contributer = {pabuhr@plg}, 3834 author = {Dominic Duggan and G .V. Cormack and John Ophel},4275 author = {Dominic Duggan and Gordon V. Cormack and John Ophel}, 3835 4276 title = {Kinded Type Inference for Parametric Overloading}, 3836 4277 journal = acta, … … 3972 4413 } 3973 4414 4415 @misc{libdill, 4416 keywords = {libdill/libmill Thread Library}, 4417 contributer = {pabuhr@plg}, 4418 author = {Alex Cornejo, et al}, 4419 title = {libdill Thread Library}, 4420 year = 2019, 4421 howpublished= {\href{http://libdill.org/libdill-2.14.tar.gz} 4422 {http://\-libdill.org/\-libdill-2.14.tar.gz}}, 4423 } 4424 3974 4425 @article{Linda, 3975 4426 keywords = {Linda, concurrency}, … … 3985 4436 } 3986 4437 4438 @manual{libmill, 4439 keywords = {libmill}, 4440 contributer = {pabuhr@plg}, 4441 author = {libmill}, 4442 title = {{G}o-style concurrency in {C}, Version 1.18}, 4443 organization= {libmill}, 4444 address = {\href{http://libmill.org/documentation.html}{http://\-libmill.org/\-documentation.html}}, 4445 month = jan, 4446 year = 2017, 4447 } 4448 3987 4449 @book{Weissman67, 3988 4450 keywords = {lisp}, … … 3994 4456 } 3995 4457 4458 @article{Pierce00, 4459 keywords = {Scala}, 4460 contributer = {a3moss@uwaterloo.ca}, 4461 author = {Pierce, Benjamin C. and Turner, David N.}, 4462 title = {Local Type Inference}, 4463 journal = {ACM Trans. Program. Lang. Syst.}, 4464 issue_date = {Jan. 2000}, 4465 volume = {22}, 4466 number = {1}, 4467 month = jan, 4468 year = {2000}, 4469 issn = {0164-0925}, 4470 pages = {1--44}, 4471 numpages = {44}, 4472 url = {http://doi.acm.org/10.1145/345099.345100}, 4473 doi = {10.1145/345099.345100}, 4474 acmid = {345100}, 4475 publisher = {ACM}, 4476 address = {New York, NY, USA}, 4477 keywords = {polymorphism, subtyping, type inference}, 4478 } 4479 3996 4480 @article{Sundell08, 3997 4481 keywords = {lock free, deque}, … … 4004 4488 year = 2008, 4005 4489 pages = {1008-1020}, 4490 } 4491 4492 @misc{Matsakis17, 4493 keywords = {Rust, Chalk, PROLOG}, 4494 contributer = {a3moss@uwaterloo.ca}, 4495 author = {Nicholas Matsakis}, 4496 title = {Lowering {Rust} traits to logic}, 4497 month = jan, 4498 year = 2017, 4499 howpublished= {\href{http://smallcultfollowing.com/babysteps/blog/2017/01/26/lowering-rust-traits-to-logic/} 4500 {http://smallcultfollowing.com/\-babysteps/\-blog/\-2017/\-01/\-26/\-lowering-rust-traits-to-logic/}}, 4501 optnote = {Accessed: 2019-01}, 4006 4502 } 4007 4503 … … 4020 4516 } 4021 4517 4518 @manual{Lua, 4519 keywords = {Lua}, 4520 contributer = {pabuhr@plg}, 4521 author = {Lua}, 4522 title = {Lua 5.3 Reference Manual}, 4523 address = {\href{https://www.lua.org/manual/5.3}{https://\-www.lua.org/\-manual/\-5.3}}, 4524 year = 2018, 4525 } 4526 4022 4527 % M 4023 4528 … … 4029 4534 publisher = {Motorola}, 4030 4535 year = 1992, 4536 } 4537 4538 @misc{Haberman16, 4539 keywords = {C++ template expansion}, 4540 contributer = {a3moss@uwaterloo.ca}, 4541 author = {Josh Haberman}, 4542 title = {Making arbitrarily-large binaries from fixed-size {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} code}, 4543 year = 2016, 4544 howpublished= {\href{http://blog.reverberate.org/2016/01/making-arbitrarily-large-binaries-from.html} 4545 {http://blog.reverberate.org/\-2016/\-01/\-making-arbitrarily-large-binaries-from.html}}, 4546 optnote = {Accessed: 2016-09}, 4031 4547 } 4032 4548 … … 4051 4567 } 4052 4568 4569 @misc{Marcel, 4570 keywords = {Marcel Thread Library}, 4571 contributer = {pabuhr@plg}, 4572 author = {Gabriel Antoniu, et al}, 4573 title = {Marcel Thread Library}, 4574 year = 2011, 4575 howpublished= {\href{https://gforge.inria.fr/frs/download.php/file/28643/marcel-2.99.3.tar.gz} 4576 {https://\-gforge.inria.fr/\-frs/\-download.php/\-file/\-28643/\-marcel-2.99.3.tar.gz}}, 4577 } 4578 4053 4579 @inproceedings{mprof, 4054 4580 keywords = {malloc}, … … 4067 4593 month = sep, 4068 4594 year = 2006, 4069 note = {\textsf{http://cs.anu.edu.au/\- \char`\~Robin.Garner/\-mmtk-guide.pdf}},4595 note = {\textsf{http://cs.anu.edu.au/\-$\sim$Robin.Garner/\-mmtk-guide.pdf}}, 4070 4596 } 4071 4597 … … 4171 4697 month = sep, 4172 4698 year = 1994, 4173 note = { {\small\textsf{ftp://\-plg.uwaterloo.ca/\-pub/\-uSystem/\-uSystem.ps.gz}}},4699 note = {\href{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uSystem.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-pub/\-uSystem/\-uSystem.pdf}}, 4174 4700 } 4175 4701 … … 4347 4873 } 4348 4874 % editor = {Allen Kent and James G. Williams}, 4875 4876 @incollection{MPC, 4877 keywords = {user-level threading}, 4878 contributer = {pabuhr@plg}, 4879 author = {Marc P\'erache and Herv\'e Jourdren and Raymond Namyst}, 4880 title = {MPC: A Unified Parallel Runtime for Clusters of {NUMA} Machines}, 4881 booktitle = {Euro-Par 2008}, 4882 pages = {329-342}, 4883 publisher = {Springer}, 4884 address = {Berlin, Heidelberg}, 4885 year = 2008, 4886 volume = 5168, 4887 series = {Lecture Notes in Computer Science}, 4888 } 4349 4889 4350 4890 @manual{MPI, … … 4515 5055 4516 5056 % N 5057 5058 @techreport{Drepper03, 5059 keywords = {NPTL, threading, 1:1 model}, 5060 contributer = {pabuhr@plg}, 5061 author = {Ulrich Drepper and Ingo Molnar}, 5062 title = {The Native POSIX Thread Library for Linux}, 5063 institution = {Red Hat}, 5064 year = 2003, 5065 note = {\href{http://www.cs.utexas.edu/~witchel/372/lectures/POSIX_Linux_Threading.pdf}{http://www.cs.utexas.edu/\-$\sim$witchel/\-372/\-lectures/\-POSIX\_Linux\_Threading.pdf}}, 5066 } 4517 5067 4518 5068 @article{Haddon77, … … 4641 5191 } 4642 5192 5193 @misc{nginx, 5194 key = {nginx}, 5195 author = {{NGINX}}, 5196 howpublished= {\href{https://www.nginx.com}{https://\-www.nginx.com}}, 5197 } 5198 4643 5199 @article{Herlihy05, 4644 5200 keywords = {Multiprocessors, concurrent data structures, dynamic data structures, memory management, nonblocking synchronization}, … … 4697 5253 year = 1995, 4698 5254 number = 31, 4699 note = {{\small\textsf{http://\-www.cs.wustl.edu/\- \char`\~schmidt/\-PDF/\-IPC\_SAP-92.pdf}}},5255 note = {{\small\textsf{http://\-www.cs.wustl.edu/\-$\sim$schmidt/\-PDF/\-IPC\_SAP-92.pdf}}}, 4700 5256 } 4701 5257 … … 4751 5307 @misc{obj-c-book, 4752 5308 keywords = {objective-c}, 4753 contributor = { a3moss@uwaterloo.ca},5309 contributor = {pabuhr@plg}, 4754 5310 key = {Objective-C}, 4755 title= {Objective-C},5311 author = {Objective-C}, 4756 5312 publisher = {Apple Inc.}, 4757 year = 2015, 4758 howpublished= {\href{https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectiveC.html}{https://developer.apple.com/\-library/\-content/\-documentation/\-General/\-Conceptual/\-DevPedia-\-CocoaCore/\-ObjectiveC.html}}, 4759 optnote = {Accessed: 2018-03} 5313 year = 2014, 5314 howpublished= {\href{https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC}{https://\-developer.apple.com/\-library/archive/\-documentation/\-Cocoa/\-Conceptual/\-ProgrammingWithObjectiveC}}, 4760 5315 } 4761 5316 … … 4766 5321 title = {{X}code 7 Release Notes}, 4767 5322 year = 2015, 4768 howpublished= {\href{https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html}{https://developer.apple.com/\-library/\-content/\-documentation/\-Xcode/\-Conceptual/\-RN-Xcode-Archive/\-Chapters/\-xc7\_release\_notes.html}}, 4769 optnote = {Accessed: 2017-04} 5323 howpublished= {\href{https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html}{https://\-developer.apple.com/\-library/\-content/\-documentation/\-Xcode/\-Conceptual/\-RN-Xcode-Archive/\-Chapters/\-xc7\_release\_notes.html}}, 4770 5324 } 4771 5325 … … 4893 5447 } 4894 5448 4895 @ techreport{OpenMP,5449 @manual{OpenMP, 4896 5450 keywords = {concurrency, openmp, spmd}, 4897 5451 contributer = {pabuhr@plg}, 4898 author = {OpenMP Architecture Review Board}, 4899 title = {OpenMP Application Program Interface, Version 4.0}, 4900 month = jul, 4901 year = 2013, 4902 note = {\href{http://www.openmp.org/mp-documents/OpenMP4.0.0.pdf}{http://\-www.openmp.org/\-mp-documents/\-OpenMP4.0.0.pdf}}, 4903 } 5452 key = {OpenMP}, 5453 title = {OpenMP Application Program Interface, Version 4.5}, 5454 month = nov, 5455 year = 2015, 5456 note = {\href{https://www.openmp.org/wp-content/uploads/openmp-4.5.pdf}{https://\-www.openmp.org/\-wp-content/\-uploads/\-openmp-4.5.pdf}}, 5457 } 5458 5459 @inproceedings{Krebbers14, 5460 keywords = {c formalization}, 5461 contributer = {a3moss@uwaterloo.ca}, 5462 author = {Krebbers, Robbert}, 5463 title = {An Operational and Axiomatic Semantics for Non-determinism and Sequence Points in C}, 5464 booktitle = {Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages}, 5465 series = {POPL '14}, 5466 year = {2014}, 5467 isbn = {978-1-4503-2544-8}, 5468 location = {San Diego, California, USA}, 5469 pages = {101--112}, 5470 numpages = {12}, 5471 url = {http://doi.acm.org/10.1145/2535838.2535878}, 5472 doi = {10.1145/2535838.2535878}, 5473 acmid = {2535878}, 5474 publisher = {ACM}, 5475 address = {New York, NY, USA}, 5476 } 4904 5477 4905 5478 @book{Deitel04, … … 5266 5839 } 5267 5840 5841 @misc{perf, 5842 contributer = {pabuhr@plg}, 5843 key = {perf}, 5844 author = {perf}, 5845 howpublished= {\href{https://perf.wiki.kernel.org/index.php/Tutorial}{https://\-perf.wiki.kernel.org/\-index.php/\-Tutorial}}, 5846 } 5847 5848 @misc{Verch12, 5849 contributer = {pabuhr@plg}, 5850 author = {Shaun Verch}, 5851 title = {Performance Analysis of 64-Bit Capriccio}, 5852 month = may, 5853 year = 2012, 5854 howpublished= {\href{http://cs.brown.edu/research/pubs/theses/masters/2012/verch.pdf}{http://cs.brown.edu/\-research/\-pubs/\-theses/\-masters/\-2012/\-verch.pdf}}, 5855 } 5856 5268 5857 @article{Anderson90, 5269 5858 keywords = {spin locks, back off, performance}, … … 5277 5866 number = 1, 5278 5867 pages = {6-16}, 5868 } 5869 5870 @inproceedings{Conchon07, 5871 keywords = {persistent array, union-find}, 5872 contributer = {a3moss@uwaterloo.ca}, 5873 title = {A persistent union-find data structure}, 5874 author = {Conchon, Sylvain and Filli{\^a}tre, Jean-Christophe}, 5875 booktitle = {Proceedings of the 2007 workshop on Workshop on ML}, 5876 pages = {37--46}, 5877 year = {2007}, 5878 organization= {ACM} 5279 5879 } 5280 5880 … … 5488 6088 } 5489 6089 6090 @inproceedings{Buhr98, 6091 keywords = {profiling, monitoring, visualization}, 6092 contributer = {pabuhr@plg}, 6093 author = {Peter A. Buhr and Robert Denda}, 6094 title = {{$\mu$Profiler} : Profiling User-Level Threads in a Shared-Memory Programming Environment}, 6095 booktitle = {Proc. of 2nd Inter. Symp. on Computing in Object-Oriented Parallel Environments}, 6096 series = {Lecture Notes in Computer Science}, 6097 publisher = {Springer-Verlag}, 6098 volume = 1505, 6099 opteditor = {Dennis Caromel and Rodney R. Oldehoeft and Marydell Tholburn}, 6100 address = {Santa Fe, New Mexico, U.S.A.}, 6101 month = dec, 6102 year = 1998, 6103 pages = {159-166}, 6104 } 6105 5490 6106 @book{PowerPC, 5491 6107 key = {PowerPC processor}, … … 5560 6176 address = {\href{https://www.iso.org/standard/64029.html}{https://\-www.iso.org/\-standard/\-64029.html}}, 5561 6177 year = 2014, 6178 } 6179 6180 @manual{C++17, 6181 keywords = {ISO/IEC C++ 17}, 6182 contributer = {pabuhr@plg}, 6183 key = {C++17}, 6184 title = {{C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Programming Language ISO/IEC 14882:2017}, 6185 edition = {5th}, 6186 publisher = {International Standard Organization}, 6187 address = {\href{https://www.iso.org/standard/68564.html}{https://\-www.iso.org/\-standard/\-68564.html}}, 6188 year = 2017, 5562 6189 } 5563 6190 … … 5713 6340 institution = {Carnegie Mellon University}, 5714 6341 year = 1991, 5715 month = feb, number = "CMU-CS-91-106", 6342 month = feb, 6343 number = {CMU-CS-91-106}, 5716 6344 annote = { 5717 6345 Discusses a typed lambda calculus with … … 5753 6381 } 5754 6382 6383 @article{Moore75, 6384 keywords = {approximation methods, integrated circuits}, 6385 contributer = {pabuhr@plg}, 6386 author = {Gordon E. Moore}, 6387 title = {Progress in Digital Integrated Electronics}, 6388 journal = {Technical Digest, International Electron Devices Meeting, IEEE}, 6389 year = 1975, 6390 pages = {11-13}, 6391 } 6392 5755 6393 @article{promises, 5756 6394 keywords = {futures, Argus, call streams, rpc}, 5757 6395 contributer = {gjditchfield@plg}, 5758 6396 author = {Barbara Liskov and Liuba Shrira}, 5759 title = {Promises: Linguistic Support for Efficient Asynchronous 5760 Procedure Calls in Distributed Systems}, 6397 title = {Promises: Linguistic Support for Efficient Asynchronous Procedure Calls in Distributed Systems}, 5761 6398 journal = sigplan, 5762 6399 year = 1988, 5763 month = jul, volume = 23, number = 7, pages = {260-267}, 5764 note = {Proceedings of the SIGPLAN '88 Conference on Programming Language 5765 Design and Implementation}, 6400 month = jul, 6401 volume = 23, 6402 number = 7, 6403 pages = {260-267}, 6404 note = {Proceedings of the SIGPLAN '88 Conference on Programming Language Design and Implementation}, 5766 6405 abstract = { 5767 6406 This paper deals with the integration of an efficient asynchronous … … 5813 6452 } 5814 6453 6454 @misc{Pthreads, 6455 keywords = {pthreads, C concurrency}, 6456 contributer = {pabuhr@plg}, 6457 key = {pthreads}, 6458 title = {{Pthread}.h, Specifications Issue 7, {IEEE} Std 1003.1-2017}, 6459 author = {IEEE and {The Open Group}}, 6460 year = 2018, 6461 howpublished= {\href{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html} 6462 {http://\-pubs.opengroup.org/\-onlinepubs/\-9699919799/\-basedefs/\-pthread.h.html}}, 6463 } 6464 5815 6465 @manual{Python, 5816 6466 keywords = {Python}, 5817 6467 contributer = {pabuhr@plg}, 5818 title = {Python Reference Manual, Release 2.5},5819 author = {Guido van Rossum},6468 author = {Python}, 6469 title = {Python Language Reference, Release 3.7.2}, 5820 6470 organization= {Python Software Foundation}, 5821 month = sep, 5822 year = 2006, 5823 note = {Fred L. Drake, Jr., editor}, 6471 address = {\href{https://docs.python.org/3/reference/index.html}{https://\-docs.python.org/\-3/\-reference/\-index.html}}, 6472 year = 2018, 5824 6473 } 5825 6474 5826 6475 % Q 6476 6477 @inproceedings{Qthreads, 6478 keywords = {user-level threading}, 6479 author = {Kyle B. Wheeler and Richard C. Murphy and Douglas Thain}, 6480 title = {Qthreads: An API for Programming with Millions of Lightweight Threads}, 6481 booktitle = {International Symposium on Parallel and Distributed Processing}, 6482 organization= {IEEE}, 6483 address = {Miami, FL, USA}, 6484 month = apr, 6485 year = 2008, 6486 } 5827 6487 5828 6488 @article{Grossman06, 5829 6489 keywords = {Cyclone, existential types, polymorphism, type variables}, 5830 6490 contributer = {a3moss@plg}, 5831 author = {D .Grossman},6491 author = {Dan Grossman}, 5832 6492 title = {Quantified Types in an Imperative Language}, 5833 6493 journal = toplas, … … 5839 6499 issn = {0164-0925}, 5840 6500 pages = {429-475}, 5841 url = {http://doi.acm.org .proxy.lib.uwaterloo.ca/10.1145/1133651.1133653},6501 url = {http://doi.acm.org/10.1145/1133651.1133653}, 5842 6502 doi = {10.1145/1133651.1133653}, 5843 6503 acmid = {1133653}, … … 5861 6521 } 5862 6522 6523 @manual{Quasar, 6524 keywords = {Quasar}, 6525 contributer = {pabuhr@plg}, 6526 author = {Quasar}, 6527 title = {Quasar Documentation, Release 0.8.0}, 6528 organization= {Parallel Universe}, 6529 address = {\href{http://docs.paralleluniverse.co/quasar}{http://\-docs.paralleluniverse.co/\-quasar}}, 6530 year = 2018, 6531 } 6532 5863 6533 % R 5864 6534 … … 5938 6608 } 5939 6609 6610 @article{Ronsse03, 6611 keywords = {profiling, replay}, 6612 contributer = {pabuhr@plg}, 6613 author = {Michiel Ronsse and De Bosschere, Koen and Mark Christiaens and Jacques Chassin de Kergommeaux and Dieter Kranzlm\"{u}ller}, 6614 title = {Record/Replay for Nondeterministic Program Executions}, 6615 journal = cacm, 6616 month = sep, 6617 year = 2003, 6618 volume = 46, 6619 number = 9, 6620 pages = {62-67}, 6621 } 6622 5940 6623 @article{Robinson48, 5941 6624 keywords = {recursion, Ackermann function}, … … 5963 6646 } 5964 6647 6648 @article{Hesselink06, 6649 author = {Wim H. Hesselink}, 6650 title = {Refinement Verification of the Lazy Caching Algorithm}, 6651 journal = acta, 6652 year = 2006, 6653 month = oct, 6654 volume = 43, 6655 number = 3, 6656 pages = {195--222}, 6657 } 6658 5965 6659 @article{RemoteRendezvous, 5966 6660 keywords = {rendezvous, concurrency}, … … 5976 6670 } 5977 6671 6672 @mastersthesis{Schuster99, 6673 author = {Oliver Schuster}, 6674 title = {Replay of Concurrent Shared-Memory Programs}, 6675 school = {Universit\"at Mannheim}, 6676 address = {Mannheim, Deutschland}, 6677 year = 1999, 6678 month = apr, 6679 type = {Diplomarbeit}, 6680 note = {\href{https://plg.uwaterloo.ca/~usystem/theses/SchusterThesis.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-theses/\-SchusterThesis.pdf}}, 6681 } 6682 5978 6683 @article{Euclid, 5979 6684 keywords = {Euclid}, … … 6007 6712 school = {School of Computer Science, University of Waterloo}, 6008 6713 year = 2017, 6009 address = {Waterloo, Ontario, Canada, N2L 3G1},6714 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 6010 6715 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/11830}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-11830}}, 6011 6716 } … … 6082 6787 contributer = {pabuhr@plg}, 6083 6788 key = {Rust}, 6084 title = { The{R}ust Programming Language},6085 address = {TheRust Project Developers},6789 title = {{R}ust Programming Language}, 6790 optaddress = {Rust Project Developers}, 6086 6791 year = 2015, 6087 6792 note = {\href{https://doc.rust-lang.org/reference.html}{https://\-doc.rust-lang\-.org/\-reference.html}}, 6793 } 6794 6795 @manual{Ruby, 6796 keywords = {Ruby}, 6797 contributer = {pabuhr@plg}, 6798 author = {Ruby}, 6799 title = {Ruby Documentation, Release 2.6.0}, 6800 organization= {Python Software Foundation}, 6801 address = {\href{https://www.ruby-lang.org/en/documentation}{https://\-www.ruby-lang.org/\-en/\-documentation}}, 6802 year = 2018, 6088 6803 } 6089 6804 … … 6149 6864 publisher = {Springer}, 6150 6865 note = {Lecture Notes in Computer Science v. 173}, 6866 } 6867 6868 @article{Baker78, 6869 keywords = {Algol display, FUNARG's, Lisp 1.5, deep binding, environment trees, multiprogramming, shallow binding}, 6870 contributer = {a3moss@uwaterloo.ca}, 6871 author = {Baker,Jr., Henry G.}, 6872 title = {Shallow Binding in Lisp 1.5}, 6873 journal = {Commun. ACM}, 6874 issue_date = {July 1978}, 6875 volume = 21, 6876 number = 7, 6877 month = jul, 6878 year = 1978, 6879 issn = {0001-0782}, 6880 pages = {565--569}, 6881 numpages = {5}, 6882 url = {http://doi.acm.org/10.1145/359545.359566}, 6883 doi = {10.1145/359545.359566}, 6884 acmid = {359566}, 6885 publisher = {ACM}, 6886 address = {New York, NY, USA} 6887 } 6888 6889 @article{Baker91, 6890 keywords = {shallow binding, functional arrays}, 6891 contributer = {a3moss@uwaterloo.ca}, 6892 author = {Baker, Henry G.}, 6893 title = {Shallow Binding Makes Functional Arrays Fast}, 6894 journal = {SIGPLAN Not.}, 6895 issue_date = {Aug. 1991}, 6896 volume = 26, 6897 number = 8, 6898 month = aug, 6899 year = 1991, 6900 issn = {0362-1340}, 6901 pages = {145--147}, 6902 numpages = {3}, 6903 url = {http://doi.acm.org/10.1145/122598.122614}, 6904 doi = {10.1145/122598.122614}, 6905 acmid = {122614}, 6906 publisher = {ACM}, 6907 address = {New York, NY, USA}, 6151 6908 } 6152 6909 … … 6782 7539 } 6783 7540 7541 @article{SysVABI, 7542 keywords = {System V ABI}, 7543 contributer = {a3moss@uwaterloo.ca}, 7544 title = {System {V} application binary interface}, 7545 author = {Matz, Michael and Hubicka, Jan and Jaeger, Andreas and Mitchell, Mark}, 7546 journal = {AMD64 Architecture Processor Supplement, Draft v0}, 7547 volume = {99}, 7548 year = {2013} 7549 } 7550 6784 7551 % T 6785 7552 … … 6834 7601 contributer = {pabuhr@plg}, 6835 7602 key = {TIOBE Index}, 6836 title = {{TIOBE} Index},7603 author = {{TIOBE Index}}, 6837 7604 howpublished= {\href{http://www.tiobe.com/tiobe_index}{http://\-www.tiobe.com/\-tiobe\_index}}, 6838 optnote = {Accessed: 2018-09}, 7605 } 7606 7607 @misc{ThreadModel, 7608 contributer = {pabuhr@plg}, 7609 key = {ThreadModel}, 7610 title = {Thread (computing)}, 7611 author = {{Threading Model}}, 7612 howpublished= {\href{https://en.wikipedia.org/wiki/Thread_(computing)}{https://\-en.wikipedia.org/\-wiki/\-Thread\_(computing)}}, 6839 7613 } 6840 7614 … … 6974 7748 year = 1980 6975 7749 } 7750 7751 @misc{TraceCompass, 7752 contributer = {pabuhr@plg}, 7753 key = {Trace Compass}, 7754 author = {{T}race {C}ompass}, 7755 howpublished= {\href{https://projects.eclipse.org/proposals/trace-compass}{https://\-projects.eclipse.org/\-proposals/\-trace-compass}}, 7756 } 6976 7757 6977 7758 @article{Leroy00, … … 6989 7770 Argues against declaring exceptions on routine definitions. 6990 7771 }, 7772 } 7773 7774 @techreport{Black90, 7775 title = {Typechecking polymorphism in {Emerald}}, 7776 author = {Black, Andrew P and Hutchinson, Norman C}, 7777 year = {1990}, 7778 institution = {Cambridge Research Laboratory, Digital Equipment Corporation} 6991 7779 } 6992 7780 … … 7109 7897 title = {Usability Challenges in Exception Handling}, 7110 7898 booktitle = {5th International Workshop on Exception Handling (WEH)}, 7111 o rganization= {16th International Symposium on the Foundations of Software Engineering (FSE 16)},7899 optorganization= {16th International Symposium on the Foundations of Software Engineering (FSE 16)}, 7112 7900 address = {Zurich, Switzerland}, 7113 7901 month = jun, … … 7161 7949 year = 2017, 7162 7950 howpublished= {\url{https://wiki.gnome.org/Projects/Vala/Manual}}, 7163 optnote = {Accessed: 2017-04}7164 7951 } 7165 7952 … … 7253 8040 } 7254 8041 8042 @inproceedings{vonBehren03, 8043 keywords = {threads, events, web server}, 8044 contributer = {pabuhr@plg}, 8045 author = {Rob von Behren and Jeremy Condit and Eric Brewer}, 8046 title = {Why Events Are a Bad Idea (for high-concurrency servers)}, 8047 booktitle = {HotOS IX: The 9th Workshop on Hot Topics in Operating Systems}, 8048 publisher = {USENIX Association}, 8049 address = {Lihue, Hawaii, U.S.A.}, 8050 month = may, 8051 year = 2003, 8052 pages = {19-24}, 8053 } 8054 7255 8055 @techreport{Moss90, 7256 8056 keywords = {Swizzling, database}, … … 7297 8097 } 7298 8098 8099 @article{Tarjan84, 8100 keywords = {union-find}, 8101 contributer = {a3moss@uwaterloo.ca}, 8102 author = {Tarjan, Robert E. and van Leeuwen, Jan}, 8103 title = {Worst-case Analysis of Set Union Algorithms}, 8104 journal = {J. ACM}, 8105 issue_date = {April 1984}, 8106 volume = 31, 8107 number = 2, 8108 month = mar, 8109 year = 1984, 8110 issn = {0004-5411}, 8111 pages = {245--281}, 8112 numpages = {37}, 8113 url = {http://doi.acm.org/10.1145/62.2160}, 8114 doi = {10.1145/62.2160}, 8115 acmid = {2160}, 8116 publisher = {ACM}, 8117 address = {New York, NY, USA}, 8118 } 8119 7299 8120 % X 7300 8121 7301 8122 % Y 8123 8124 @article{Boehm12, 8125 keywords = {memory model, race condition}, 8126 contributer = {pabuhr@plg}, 8127 author = {Boehm, Hans-J. and Adve, Sarita V.}, 8128 title = {You Don'T Know Jack About Shared Variables or Memory Models}, 8129 journal = cacm, 8130 volume = 55, 8131 number = 2, 8132 month = feb, 8133 year = 2012, 8134 pages = {48--54}, 8135 publisher = {ACM}, 8136 address = {New York, NY, USA}, 8137 } 7302 8138 7303 8139 % Z … … 7317 8153 year = 1986, 7318 8154 editor = {Norman Meyrowitz}, 7319 publisher = sigplan # " 21(11)",8155 publisher = sigplan, 7320 8156 organization= {Association for Computing Machinery}, 7321 8157 address = {Portland, Oregon}, 7322 month = sep # { 29}8158 month = sep, 7323 8159 } 7324 8160 … … 7329 8165 year = 1987, 7330 8166 editor = {Norman Meyrowitz}, 7331 publisher = sigplan # " 22(12)",8167 publisher = sigplan, 7332 8168 organization= {Association for Computing Machinery}, 7333 8169 address = {Orlando, Florida}, 7334 month = oct # { 4--8}8170 month = oct, 7335 8171 } 7336 8172 … … 7341 8177 year = 1988, 7342 8178 editor = {Norman Meyrowitz}, 7343 publisher = sigplan # " 23(11)",8179 publisher = sigplan, 7344 8180 organization= {Association for Computing Machinery}, 7345 8181 address = {San Diego, California}, 7346 month = sep # { 25--30}8182 month = sep, 7347 8183 } 7348 8184 … … 7353 8189 year = 1989, 7354 8190 editor = {Norman Meyrowitz}, 7355 publisher = sigplan # " 24(10)",8191 publisher = sigplan, 7356 8192 organization= {Association for Computing Machinery}, 7357 8193 address = {New Orleans, Louisiana}, 7358 month = oct # { 1--6}8194 month = oct, 7359 8195 } 7360 8196 … … 7365 8201 year = 1990, 7366 8202 editor = {Norman Meyrowitz}, 7367 publisher = sigplan # " 25(10)",8203 publisher = sigplan, 7368 8204 organization= {Association for Computing Machinery}, 7369 8205 address = {Ottawa, Canada}, 7370 month = oct # { 21--25}8206 month = oct, 7371 8207 } 7372 8208 … … 7377 8213 year = 1991, 7378 8214 editor = {Andreas Paepcke}, 7379 publisher = sigplan # " 26(11)",8215 publisher = sigplan, 7380 8216 organization= {Association for Computing Machinery}, 7381 8217 address = {Phoenix, Arizona}, 7382 month = oct # { 6--11}7383 } 8218 month = oct, 8219 } -
doc/papers/AMA/AMA-stix/ama/WileyNJD-v2.cls
r7951100 rb067d9b 1854 1854 \vspace*{8.5\p@}% 1855 1855 \rightskip0pt\raggedright\hspace*{7\p@}\hbox{\reset@font\abstractfont{\absheadfont#1}}\par\vskip3pt% LN20feb2016 1856 {\abstractfont\baselineskip15pt\ifFWabstract\hsize\textwidth\fi #2\par\vspace*{0\p@}}%1856 {\abstractfont\baselineskip15pt\ifFWabstract\hsize\textwidth\fi\hsize0.68\textwidth#2\par\vspace*{0\p@}}% 1857 1857 \addcontentsline{toc}{section}{\abstractname}% 1858 1858 }}%\abstract{}% … … 1882 1882 }% 1883 1883 % 1884 \def\fundinginfohead#1{\gdef\@fundinginfo@head{#1}}\fundinginfohead{Funding Information}%1884 \def\fundinginfohead#1{\gdef\@fundinginfo@head{#1}}\fundinginfohead{Funding information}% 1885 1885 \def\fundinginfoheadtext#1{\gdef\@fundinginfo@head@text{#1}}\fundinginfoheadtext{}% 1886 1886 \gdef\@fundinginfo{{% … … 2319 2319 %% Keywords %% 2320 2320 2321 \def\keywords#1{\def\@keywords{{\keywordsheadfont\textbf{KEYWORDS :}\par\removelastskip\nointerlineskip\vskip6pt \keywordsfont#1\par}}}\def\@keywords{}%2321 \def\keywords#1{\def\@keywords{{\keywordsheadfont\textbf{KEYWORDS}\par\removelastskip\nointerlineskip\vskip6pt \keywordsfont#1\par}}}\def\@keywords{}% 2322 2322 2323 2323 \def\@fnsymbol#1{\ifcase#1\or \dagger\or \ddagger\or … … 2444 2444 \@afterheading} 2445 2445 2446 \renewcommand\section{\@startsection{section}{1}{\z@}{-2 7pt \@plus -2pt \@minus -2pt}{12\p@}{\sectionfont}}%2447 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2 3pt \@plus -2pt \@minus -2pt}{5\p@}{\subsectionfont}}%2446 \renewcommand\section{\@startsection{section}{1}{\z@}{-25pt \@plus -2pt \@minus -2pt}{12\p@}{\sectionfont}}% 2447 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-22pt \@plus -2pt \@minus -2pt}{5\p@}{\subsectionfont}}% 2448 2448 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-20pt \@plus -2pt \@minus -2pt}{2\p@}{\subsubsectionfont}}% 2449 2449 % … … 3406 3406 \hskip-\parindentvalue\fbox{\vbox{\noindent\@jnlcitation}}}% 3407 3407 3408 \AtEndDocument{\ifappendixsec\else\printjnlcitation\fi}%3408 %\AtEndDocument{\ifappendixsec\else\printjnlcitation\fi}% 3409 3409 3410 3410 %% Misc math macros %% -
doc/papers/OOPSLA17/Makefile
r7951100 rb067d9b 33 33 34 34 DOCUMENT = generic_types.pdf 35 BASE = ${basename ${DOCUMENT}} 35 36 36 37 # Directives # … … 41 42 42 43 clean : 43 @rm -frv ${DOCUMENT} ${ basename ${DOCUMENT}}.ps ${Build}44 @rm -frv ${DOCUMENT} ${BASE}.ps ${Build} 44 45 45 46 # File Dependencies # 46 47 47 ${DOCUMENT} : ${ basename ${DOCUMENT}}.ps48 ${DOCUMENT} : ${BASE}.ps 48 49 ps2pdf $< 49 50 50 ${ basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi51 ${BASE}.ps : ${BASE}.dvi 51 52 dvips ${Build}/$< -o $@ 52 53 53 ${basename ${DOCUMENT}}.dvi : Makefile ${Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ../../bibliography/pl.bib 54 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 55 ../../bibliography/pl.bib | ${Build} 54 56 # Must have *.aux file containing citations for bibtex 55 57 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi … … 63 65 ## Define the default recipes. 64 66 65 ${Build} :67 ${Build} : 66 68 mkdir -p ${Build} 67 69 … … 69 71 gnuplot -e Build="'${Build}/'" evaluation/timing.gp 70 72 71 %.tex : %.fig 73 %.tex : %.fig | ${Build} 72 74 fig2dev -L eepic $< > ${Build}/$@ 73 75 74 %.ps : %.fig 76 %.ps : %.fig | ${Build} 75 77 fig2dev -L ps $< > ${Build}/$@ 76 78 77 %.pstex : %.fig 79 %.pstex : %.fig | ${Build} 78 80 fig2dev -L pstex $< > ${Build}/$@ 79 81 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t -
doc/papers/concurrency/Makefile
r7951100 rb067d9b 4 4 Figures = figures 5 5 Macros = ../AMA/AMA-stix/ama 6 TeXLIB = .: annex:../../LaTeXmacros:${Macros}:${Build}:../../bibliography:6 TeXLIB = .:../../LaTeXmacros:${Macros}:${Build}: 7 7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 8 BibTeX = BIBINPUTS= ${TeXLIB}&& export BIBINPUTS && bibtex8 BibTeX = BIBINPUTS=annex:../../bibliography: && export BIBINPUTS && bibtex 9 9 10 10 MAKEFLAGS = --no-print-directory # --silent … … 15 15 SOURCES = ${addsuffix .tex, \ 16 16 Paper \ 17 style/style \18 style/cfa-format \19 17 } 20 18 21 19 FIGURES = ${addsuffix .tex, \ 22 monitor \23 ext_monitor \24 20 int_monitor \ 25 21 dependency \ 22 RunTimeStructure \ 26 23 } 27 24 28 25 PICTURES = ${addsuffix .pstex, \ 26 FullProdConsStack \ 27 FullCoroutinePhases \ 28 corlayout \ 29 CondSigWait \ 30 monitor \ 31 ext_monitor \ 29 32 system \ 30 33 monitor_structs \ … … 59 62 dvips ${Build}/$< -o $@ 60 63 61 ${BASE}.dvi : Makefile ${B uild} ${BASE}.out.ps WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \62 annex/local.bib ../../bibliography/pl.bib 64 ${BASE}.dvi : Makefile ${BASE}.out.ps WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 65 annex/local.bib ../../bibliography/pl.bib | ${Build} 63 66 # Must have *.aux file containing citations for bibtex 64 67 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi 65 ${BibTeX} ${Build}/${basename $@}68 -${BibTeX} ${Build}/${basename $@} 66 69 # Some citations reference others so run again to resolve these citations 67 70 ${LaTeX} ${basename $@}.tex 68 ${BibTeX} ${Build}/${basename $@}71 -${BibTeX} ${Build}/${basename $@} 69 72 # Run again to finish citations 70 73 ${LaTeX} ${basename $@}.tex … … 72 75 ## Define the default recipes. 73 76 74 ${Build} :77 ${Build} : 75 78 mkdir -p ${Build} 76 79 77 ${BASE}.out.ps :${Build}80 ${BASE}.out.ps : | ${Build} 78 81 ln -fs ${Build}/Paper.out.ps . 79 82 80 WileyNJD-AMA.bst :83 WileyNJD-AMA.bst : 81 84 ln -fs ../AMA/AMA-stix/ama/WileyNJD-AMA.bst . 82 85 83 %.tex : %.fig ${Build}86 %.tex : %.fig | ${Build} 84 87 fig2dev -L eepic $< > ${Build}/$@ 85 88 86 %.ps : %.fig ${Build}89 %.ps : %.fig | ${Build} 87 90 fig2dev -L ps $< > ${Build}/$@ 88 91 89 %.pstex : %.fig ${Build}92 %.pstex : %.fig | ${Build} 90 93 fig2dev -L pstex $< > ${Build}/$@ 91 94 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t -
doc/papers/concurrency/Paper.tex
r7951100 rb067d9b 3 3 \articletype{RESEARCH ARTICLE}% 4 4 5 \received{26 April 2016} 6 \revised{6 June 2016} 7 \accepted{6 June 2016} 5 % Referees 6 % Doug Lea, dl@cs.oswego.edu, SUNY Oswego 7 % Herb Sutter, hsutter@microsoft.com, Microsoft Corp 8 % Gor Nishanov, gorn@microsoft.com, Microsoft Corp 9 % James Noble, kjx@ecs.vuw.ac.nz, Victoria University of Wellington, School of Engineering and Computer Science 10 11 \received{XXXXX} 12 \revised{XXXXX} 13 \accepted{XXXXX} 8 14 9 15 \raggedbottom … … 15 21 \usepackage{epic,eepic} 16 22 \usepackage{xspace} 23 \usepackage{enumitem} 17 24 \usepackage{comment} 18 25 \usepackage{upquote} % switch curled `'" to straight … … 21 28 \renewcommand{\thesubfigure}{(\Alph{subfigure})} 22 29 \captionsetup{justification=raggedright,singlelinecheck=false} 23 \usepackage{siunitx} 24 \sisetup{binary-units=true} 30 \usepackage{dcolumn} % align decimal points in tables 31 \usepackage{capt-of} 32 \setlength{\multicolsep}{6.0pt plus 2.0pt minus 1.5pt} 25 33 26 34 \hypersetup{breaklinks=true} … … 32 40 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 33 41 42 \renewcommand{\topfraction}{0.8} % float must be greater than X of the page before it is forced onto its own page 43 \renewcommand{\bottomfraction}{0.8} % float must be greater than X of the page before it is forced onto its own page 44 \renewcommand{\floatpagefraction}{0.8} % float must be greater than X of the page before it is forced onto its own page 34 45 \renewcommand{\textfraction}{0.0} % the entire page maybe devoted to floats with no text on the page at all 35 46 … … 132 143 \makeatother 133 144 134 \newenvironment{cquote}{% 135 \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=3pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}% 136 \item\relax 137 }{% 138 \endlist 139 }% cquote 145 \newenvironment{cquote} 146 {\list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=3pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}% 147 \item\relax} 148 {\endlist} 149 150 %\newenvironment{cquote}{% 151 %\list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=3pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}% 152 %\item\relax% 153 %}{% 154 %\endlist% 155 %}% cquote 140 156 141 157 % CFA programming language, based on ANSI C (with some gcc additions) … … 145 161 auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, __const, __const__, 146 162 coroutine, disable, dtype, enable, exception, __extension__, fallthrough, fallthru, finally, 147 __float80, float80, __float128, float128, forall, ftype, _Generic, _Imaginary, __imag, __imag__,163 __float80, float80, __float128, float128, forall, ftype, generator, _Generic, _Imaginary, __imag, __imag__, 148 164 inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or, 149 165 otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, thread, 150 166 _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__, 151 167 virtual, __volatile, __volatile__, waitfor, when, with, zero_t}, 152 moredirectives={defined,include_next}% 168 moredirectives={defined,include_next}, 169 % replace/adjust listing characters that look bad in sanserif 170 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptstyle\land\,$}}1 171 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1 172 {<}{\textrm{\textless}}1 {>}{\textrm{\textgreater}}1 173 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.5ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex{\textrm{\textgreater}}}2, 153 174 } 154 175 … … 167 188 aboveskip=4pt, % spacing above/below code block 168 189 belowskip=3pt, 169 % replace/adjust listing characters that look bad in sanserif170 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptstyle\land\,$}}1171 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1172 {<}{\textrm{\textless}}1 {>}{\textrm{\textgreater}}1173 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.5ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex{\textrm{\textgreater}}}2,174 190 moredelim=**[is][\color{red}]{`}{`}, 175 191 }% lstset … … 197 213 } 198 214 215 % Go programming language: https://github.com/julienc91/listings-golang/blob/master/listings-golang.sty 216 \lstdefinelanguage{Golang}{ 217 morekeywords=[1]{package,import,func,type,struct,return,defer,panic,recover,select,var,const,iota,}, 218 morekeywords=[2]{string,uint,uint8,uint16,uint32,uint64,int,int8,int16,int32,int64, 219 bool,float32,float64,complex64,complex128,byte,rune,uintptr, error,interface}, 220 morekeywords=[3]{map,slice,make,new,nil,len,cap,copy,close,true,false,delete,append,real,imag,complex,chan,}, 221 morekeywords=[4]{for,break,continue,range,goto,switch,case,fallthrough,if,else,default,}, 222 morekeywords=[5]{Println,Printf,Error,}, 223 sensitive=true, 224 morecomment=[l]{//}, 225 morecomment=[s]{/*}{*/}, 226 morestring=[b]', 227 morestring=[b]", 228 morestring=[s]{`}{`}, 229 % replace/adjust listing characters that look bad in sanserif 230 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptstyle\land\,$}}1 231 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1 232 {<}{\textrm{\textless}}1 {>}{\textrm{\textgreater}}1 233 {<-}{\makebox[2ex][c]{\textrm{\textless}\raisebox{0.5ex}{\rule{0.8ex}{0.075ex}}}}2, 234 } 235 199 236 \lstnewenvironment{cfa}[1][] 200 237 {\lstset{#1}} … … 207 244 {} 208 245 \lstnewenvironment{Go}[1][] 209 {\lstset{#1}} 246 {\lstset{language=Golang,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}} 247 {} 248 \lstnewenvironment{python}[1][] 249 {\lstset{language=python,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}} 210 250 {} 211 251 … … 222 262 } 223 263 224 \title{\texorpdfstring{Concurrency in \protect\CFA}{Concurrency in Cforall}} 264 \newbox\myboxA 265 \newbox\myboxB 266 \newbox\myboxC 267 \newbox\myboxD 268 269 \title{\texorpdfstring{Advanced Control-flow and Concurrency in \protect\CFA}{Advanced Control-flow in Cforall}} 225 270 226 271 \author[1]{Thierry Delisle} … … 232 277 \corres{*Peter A. Buhr, Cheriton School of Computer Science, University of Waterloo, 200 University Avenue West, Waterloo, ON, N2L 3G1, Canada. \email{pabuhr{\char`\@}uwaterloo.ca}} 233 278 234 \fundingInfo{Natural Sciences and Engineering Research Council of Canada}279 % \fundingInfo{Natural Sciences and Engineering Research Council of Canada} 235 280 236 281 \abstract[Summary]{ 237 \CFA is a modern, polymorphic, \emph{non-object-oriented} extension of the C programming language. 238 This paper discusses the design of the concurrency and parallelism features in \CFA, and the concurrent runtime-system. 239 These features are created from scratch as ISO C lacks concurrency, relying largely on the pthreads library. 240 Coroutines and lightweight (user) threads are introduced into the language. 241 In addition, monitors are added as a high-level mechanism for mutual exclusion and synchronization. 242 A unique contribution is allowing multiple monitors to be safely acquired simultaneously. 243 All features respect the expectations of C programmers, while being fully integrate with the \CFA polymorphic type-system and other language features. 244 Finally, experimental results are presented to compare the performance of the new features with similar mechanisms in other concurrent programming-languages. 282 \CFA is a polymorphic, non-object-oriented, concurrent, backwards-compatible extension of the C programming language. 283 This paper discusses the design philosophy and implementation of its advanced control-flow and concurrent/parallel features, along with the supporting runtime written in \CFA. 284 These features are created from scratch as ISO C has only low-level and/or unimplemented concurrency, so C programmers continue to rely on library features like pthreads. 285 \CFA introduces modern language-level control-flow mechanisms, like generators, coroutines, user-level threading, and monitors for mutual exclusion and synchronization. 286 % Library extension for executors, futures, and actors are built on these basic mechanisms. 287 The runtime provides significant programmer simplification and safety by eliminating spurious wakeup and monitor barging. 288 The runtime also ensures multiple monitors can be safely acquired \emph{simultaneously} (deadlock free), and this feature is fully integrated with all monitor synchronization mechanisms. 289 All control-flow features integrate with the \CFA polymorphic type-system and exception handling, while respecting the expectations and style of C programmers. 290 Experimental results show comparable performance of the new features with similar mechanisms in other concurrent programming languages. 245 291 }% 246 292 247 \keywords{ concurrency, parallelism, coroutines, threads, monitors, runtime, C, Cforall}293 \keywords{generator, coroutine, concurrency, parallelism, thread, monitor, runtime, C, \CFA (Cforall)} 248 294 249 295 … … 256 302 \section{Introduction} 257 303 258 This paper provides a minimal concurrency \newterm{Application Program Interface} (API) that is simple, efficient and can be used to build other concurrency features. 259 While the simplest concurrency system is a thread and a lock, this low-level approach is hard to master. 260 An easier approach for programmers is to support higher-level constructs as the basis of concurrency. 261 Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{Hochstein05}. 262 Examples of high-level approaches are task (work) based~\cite{TBB}, implicit threading~\cite{OpenMP}, monitors~\cite{Java}, channels~\cite{CSP,Go}, and message passing~\cite{Erlang,MPI}. 263 264 The following terminology is used. 265 A \newterm{thread} is a fundamental unit of execution that runs a sequence of code and requires a stack to maintain state. 266 Multiple simultaneous threads give rise to \newterm{concurrency}, which requires locking to ensure safe communication and access to shared data. 267 % Correspondingly, concurrency is defined as the concepts and challenges that occur when multiple independent (sharing memory, timing dependencies, \etc) concurrent threads are introduced. 268 \newterm{Locking}, and by extension \newterm{locks}, are defined as a mechanism to prevent progress of threads to provide safety. 269 \newterm{Parallelism} is running multiple threads simultaneously. 270 Parallelism implies \emph{actual} simultaneous execution, where concurrency only requires \emph{apparent} simultaneous execution. 271 As such, parallelism only affects performance, which is observed through differences in space and/or time at runtime. 272 273 Hence, there are two problems to be solved: concurrency and parallelism. 274 While these two concepts are often combined, they are distinct, requiring different tools~\cite[\S~2]{Buhr05a}. 275 Concurrency tools handle synchronization and mutual exclusion, while parallelism tools handle performance, cost and resource utilization. 276 277 The proposed concurrency API is implemented in a dialect of C, called \CFA. 278 The paper discusses how the language features are added to the \CFA translator with respect to parsing, semantic, and type checking, and the corresponding high-performance runtime-library to implement the concurrency features. 279 280 281 \section{\CFA Overview} 282 283 The following is a quick introduction to the \CFA language, specifically tailored to the features needed to support concurrency. 284 Extended versions and explanation of the following code examples are available at the \CFA website~\cite{Cforall} or in Moss~\etal~\cite{Moss18}. 285 286 \CFA is an extension of ISO-C, and hence, supports all C paradigms. 287 %It is a non-object-oriented system-language, meaning most of the major abstractions have either no runtime overhead or can be opted out easily. 288 Like C, the basics of \CFA revolve around structures and routines. 289 Virtually all of the code generated by the \CFA translator respects C memory layouts and calling conventions. 290 While \CFA is not an object-oriented language, lacking the concept of a receiver (\eg @this@) and nominal inheritance-relationships, C does have a notion of objects: ``region of data storage in the execution environment, the contents of which can represent values''~\cite[3.15]{C11}. 291 While some \CFA features are common in object-oriented programming-languages, they are an independent capability allowing \CFA to adopt them while retaining a procedural paradigm. 292 293 294 \subsection{References} 295 296 \CFA provides multi-level rebindable references, as an alternative to pointers, which significantly reduces syntactic noise. 297 \begin{cfa} 298 int x = 1, y = 2, z = 3; 299 int * p1 = &x, ** p2 = &p1, *** p3 = &p2, $\C{// pointers to x}$ 300 `&` r1 = x, `&&` r2 = r1, `&&&` r3 = r2; $\C{// references to x}$ 301 int * p4 = &z, `&` r4 = z; 302 303 *p1 = 3; **p2 = 3; ***p3 = 3; // change x 304 r1 = 3; r2 = 3; r3 = 3; // change x: implicit dereferences *r1, **r2, ***r3 305 **p3 = &y; *p3 = &p4; // change p1, p2 306 `&`r3 = &y; `&&`r3 = &`&`r4; // change r1, r2: cancel implicit dereferences (&*)**r3, (&(&*)*)*r3, &(&*)r4 307 \end{cfa} 308 A reference is a handle to an object, like a pointer, but is automatically dereferenced by the specified number of levels. 309 Referencing (address-of @&@) a reference variable cancels one of the implicit dereferences, until there are no more implicit references, after which normal expression behaviour applies. 310 311 312 \subsection{\texorpdfstring{\protect\lstinline{with} Statement}{with Statement}} 313 \label{s:WithStatement} 314 315 Heterogeneous data is aggregated into a structure/union. 316 To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate field-qualification by opening a scope containing the field identifiers. 317 \begin{cquote} 318 \vspace*{-\baselineskip}%??? 319 \lstDeleteShortInline@% 320 \begin{cfa} 321 struct S { char c; int i; double d; }; 322 struct T { double m, n; }; 323 // multiple aggregate parameters 324 \end{cfa} 325 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}} 326 \begin{cfa} 327 void f( S & s, T & t ) { 328 `s.`c; `s.`i; `s.`d; 329 `t.`m; `t.`n; 330 } 331 \end{cfa} 332 & 333 \begin{cfa} 334 void f( S & s, T & t ) `with ( s, t )` { 335 c; i; d; // no qualification 336 m; n; 337 } 338 \end{cfa} 339 \end{tabular} 340 \lstMakeShortInline@% 341 \end{cquote} 342 Object-oriented programming languages only provide implicit qualification for the receiver. 343 344 In detail, the @with@ statement has the form: 345 \begin{cfa} 346 $\emph{with-statement}$: 347 'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$ 348 \end{cfa} 349 and may appear as the body of a routine or nested within a routine body. 350 Each expression in the expression-list provides a type and object. 351 The type must be an aggregate type. 352 (Enumerations are already opened.) 353 The object is the implicit qualifier for the open structure-fields. 354 All expressions in the expression list are open in parallel within the compound statement, which is different from Pascal, which nests the openings from left to right. 355 356 357 \subsection{Overloading} 358 359 \CFA maximizes the ability to reuse names via overloading to aggressively address the naming problem. 360 Both variables and routines may be overloaded, where selection is based on types, and number of returns (as in Ada~\cite{Ada}) and arguments. 361 \begin{cquote} 362 \vspace*{-\baselineskip}%??? 363 \lstDeleteShortInline@% 364 \begin{cfa} 365 // selection based on type 366 \end{cfa} 367 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}} 368 \begin{cfa} 369 const short int `MIN` = -32768; 370 const int `MIN` = -2147483648; 371 const long int `MIN` = -9223372036854775808L; 372 \end{cfa} 373 & 374 \begin{cfa} 375 short int si = `MIN`; 376 int i = `MIN`; 377 long int li = `MIN`; 378 \end{cfa} 379 \end{tabular} 380 \begin{cfa} 381 // selection based on type and number of parameters 382 \end{cfa} 383 \begin{tabular}{@{}l@{\hspace{2.7\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}} 384 \begin{cfa} 385 void `f`( void ); 386 void `f`( char ); 387 void `f`( int, double ); 388 \end{cfa} 389 & 390 \begin{cfa} 391 `f`(); 392 `f`( 'a' ); 393 `f`( 3, 5.2 ); 394 \end{cfa} 395 \end{tabular} 396 \begin{cfa} 397 // selection based on type and number of returns 398 \end{cfa} 399 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}|@{\hspace{2\parindentlnth}}l@{}} 400 \begin{cfa} 401 char `f`( int ); 402 double `f`( int ); 403 [char, double] `f`( int ); 404 \end{cfa} 405 & 406 \begin{cfa} 407 char c = `f`( 3 ); 408 double d = `f`( 3 ); 409 [d, c] = `f`( 3 ); 410 \end{cfa} 411 \end{tabular} 412 \lstMakeShortInline@% 413 \end{cquote} 414 Overloading is important for \CFA concurrency since the runtime system relies on creating different types to represent concurrency objects. 415 Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions to prevent name clashes. 416 As seen in Section~\ref{basics}, routine @main@ is heavily overloaded. 417 418 Variable overloading is useful in the parallel semantics of the @with@ statement for fields with the same name: 419 \begin{cfa} 420 struct S { int `i`; int j; double m; } s; 421 struct T { int `i`; int k; int m; } t; 422 with ( s, t ) { 423 j + k; $\C{// unambiguous, s.j + t.k}$ 424 m = 5.0; $\C{// unambiguous, s.m = 5.0}$ 425 m = 1; $\C{// unambiguous, t.m = 1}$ 426 int a = m; $\C{// unambiguous, a = t.m }$ 427 double b = m; $\C{// unambiguous, b = s.m}$ 428 int c = `s.i` + `t.i`; $\C{// unambiguous, qualification}$ 429 (double)m; $\C{// unambiguous, cast s.m}$ 430 } 431 \end{cfa} 432 For parallel semantics, both @s.i@ and @t.i@ are visible the same type, so only @i@ is ambiguous without qualification. 433 434 435 \subsection{Operators} 436 437 Overloading also extends to operators. 438 Operator-overloading syntax creates a routine name with an operator symbol and question marks for the operands: 439 \begin{cquote} 440 \lstDeleteShortInline@% 441 \begin{tabular}{@{}ll@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 442 \begin{cfa} 443 int ++? (int op); 444 int ?++ (int op); 445 int `?+?` (int op1, int op2); 446 int ?<=?(int op1, int op2); 447 int ?=? (int & op1, int op2); 448 int ?+=?(int & op1, int op2); 449 \end{cfa} 450 & 451 \begin{cfa} 452 // unary prefix increment 453 // unary postfix increment 454 // binary plus 455 // binary less than 456 // binary assignment 457 // binary plus-assignment 458 \end{cfa} 459 & 460 \begin{cfa} 461 struct S { int i, j; }; 462 S `?+?`( S op1, S op2) { // add two structures 463 return (S){op1.i + op2.i, op1.j + op2.j}; 464 } 465 S s1 = {1, 2}, s2 = {2, 3}, s3; 466 s3 = s1 `+` s2; // compute sum: s3 == {2, 5} 467 \end{cfa} 468 \end{tabular} 469 \lstMakeShortInline@% 470 \end{cquote} 471 While concurrency does not use operator overloading directly, it provides an introduction for the syntax of constructors. 472 473 474 \subsection{Parametric Polymorphism} 475 \label{s:ParametricPolymorphism} 476 477 The signature feature of \CFA is parametric-polymorphic routines~\cite{} with routines generalized using a @forall@ clause (giving the language its name), which allow separately compiled routines to support generic usage over multiple types. 478 For example, the following sum routine works for any type that supports construction from 0 and addition \commenttd{constructors have not been introduced yet.}: 479 \begin{cfa} 480 forall( otype T | { void `?{}`( T *, zero_t ); T `?+?`( T, T ); } ) // constraint type, 0 and + 481 T sum( T a[$\,$], size_t size ) { 482 `T` total = { `0` }; $\C{// initialize by 0 constructor}$ 483 for ( size_t i = 0; i < size; i += 1 ) 484 total = total `+` a[i]; $\C{// select appropriate +}$ 485 return total; 486 } 487 S sa[5]; 488 int i = sum( sa, 5 ); $\C{// use S's 0 construction and +}$ 489 \end{cfa} 490 491 \CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each routine declaration: 492 \begin{cfa} 493 trait `sumable`( otype T ) { 494 void `?{}`( T &, zero_t ); $\C{// 0 literal constructor}$ 495 T `?+?`( T, T ); $\C{// assortment of additions}$ 496 T ?+=?( T &, T ); 497 T ++?( T & ); 498 T ?++( T & ); 499 }; 500 forall( otype T `| sumable( T )` ) $\C{// use trait}$ 501 T sum( T a[$\,$], size_t size ); 502 \end{cfa} 503 504 Assertions can be @otype@ or @dtype@. 505 @otype@ refers to a ``complete'' object, \ie an object has a size, default constructor, copy constructor, destructor and an assignment operator. 506 @dtype@ only guarantees an object has a size and alignment. 507 508 Using the return type for discrimination, it is possible to write a type-safe @alloc@ based on the C @malloc@: 509 \begin{cfa} 510 forall( dtype T | sized(T) ) T * alloc( void ) { return (T *)malloc( sizeof(T) ); } 511 int * ip = alloc(); $\C{// select type and size from left-hand side}$ 512 double * dp = alloc(); 513 struct S {...} * sp = alloc(); 514 \end{cfa} 515 where the return type supplies the type/size of the allocation, which is impossible in most type systems. 516 517 518 \subsection{Constructors / Destructors} 519 520 Object lifetime is a challenge in non-managed programming languages. 521 \CFA responds with \CC-like constructors and destructors: 522 \begin{cfa} 523 struct VLA { int len, * data; }; $\C{// variable length array of integers}$ 524 void ?{}( VLA & vla ) with ( vla ) { len = 10; data = alloc( len ); } $\C{// default constructor}$ 525 void ?{}( VLA & vla, int size, char fill ) with ( vla ) { len = size; data = alloc( len, fill ); } // initialization 526 void ?{}( VLA & vla, VLA other ) { vla.len = other.len; vla.data = other.data; } $\C{// copy, shallow}$ 527 void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$ 528 { 529 VLA x, y = { 20, 0x01 }, z = y; $\C{// z points to y}$ 530 // x{}; y{ 20, 0x01 }; z{ z, y }; 531 ^x{}; $\C{// deallocate x}$ 532 x{}; $\C{// reallocate x}$ 533 z{ 5, 0xff }; $\C{// reallocate z, not pointing to y}$ 534 ^y{}; $\C{// deallocate y}$ 535 y{ x }; $\C{// reallocate y, points to x}$ 536 x{}; $\C{// reallocate x, not pointing to y}$ 537 // ^z{}; ^y{}; ^x{}; 538 } 539 \end{cfa} 540 Like \CC, construction is implicit on allocation (stack/heap) and destruction is implicit on deallocation. 541 The object and all their fields are constructed/destructed. 542 \CFA also provides @new@ and @delete@, which behave like @malloc@ and @free@, in addition to constructing and destructing objects: 543 \begin{cfa} 544 { struct S s = {10}; $\C{// allocation, call constructor}$ 545 ... 546 } $\C{// deallocation, call destructor}$ 547 struct S * s = new(); $\C{// allocation, call constructor}$ 548 ... 549 delete( s ); $\C{// deallocation, call destructor}$ 550 \end{cfa} 551 \CFA concurrency uses object lifetime as a means of synchronization and/or mutual exclusion. 552 553 554 \section{Concurrency Basics}\label{basics} 555 556 At its core, concurrency is based on multiple call-stacks and scheduling threads executing on these stacks. 557 Multiple call stacks (or contexts) and a single thread of execution, called \newterm{coroutining}~\cite{Conway63,Marlin80}, does \emph{not} imply concurrency~\cite[\S~2]{Buhr05a}. 558 In coroutining, the single thread is self-scheduling across the stacks, so execution is deterministic, \ie given fixed inputs, the execution path to the outputs is fixed and predictable. 559 A \newterm{stackless} coroutine executes on the caller's stack~\cite{Python} but this approach is restrictive, \eg preventing modularization and supporting only iterator/generator-style programming; 560 a \newterm{stackfull} coroutine executes on its own stack, allowing full generality. 561 Only stackfull coroutines are a stepping-stone to concurrency. 562 563 The transition to concurrency, even for execution with a single thread and multiple stacks, occurs when coroutines also context switch to a scheduling oracle, introducing non-determinism from the coroutine perspective~\cite[\S~3]{Buhr05a}. 564 Therefore, a minimal concurrency system is possible using coroutines (see Section \ref{coroutine}) in conjunction with a scheduler to decide where to context switch next. 565 The resulting execution system now follows a cooperative threading-model, called \newterm{non-preemptive scheduling}. 566 567 Because the scheduler is special, it can either be a stackless or stackfull coroutine. \commenttd{I dislike this sentence, it seems imply 1-step vs 2-step but also seems to say that some kind of coroutine is required, which is not the case.} 568 For stackless, the scheduler performs scheduling on the stack of the current coroutine and switches directly to the next coroutine, so there is one context switch. 569 For stackfull, the current coroutine switches to the scheduler, which performs scheduling, and it then switches to the next coroutine, so there are two context switches. 570 A stackfull scheduler is often used for simplicity and security, even through there is a slightly higher runtime-cost. \commenttd{I'm not a fan of the fact that we don't quantify this but yet imply it is negligeable.} 571 572 Regardless of the approach used, a subset of concurrency related challenges start to appear. 573 For the complete set of concurrency challenges to occur, the missing feature is \newterm{preemption}, where context switching occurs randomly between any two instructions, often based on a timer interrupt, called \newterm{preemptive scheduling}. 574 While a scheduler introduces uncertainty in the order of execution, preemption introduces uncertainty where context switches occur. 575 Interestingly, uncertainty is necessary for the runtime (operating) system to give the illusion of parallelism on a single processor and increase performance on multiple processors. 576 The reason is that only the runtime has complete knowledge about resources and how to best utilized them. 577 However, the introduction of unrestricted non-determinism results in the need for \newterm{mutual exclusion} and \newterm{synchronization} to restrict non-determinism for correctness; 578 otherwise, it is impossible to write meaningful programs. 579 Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows. 580 581 582 \subsection{\protect\CFA's Thread Building Blocks} 583 584 An important missing feature in C is threading\footnote{While the C11 standard defines a ``threads.h'' header, it is minimal and defined as optional. 585 As such, library support for threading is far from widespread. 586 At the time of writing the paper, neither \protect\lstinline|gcc| nor \protect\lstinline|clang| support ``threads.h'' in their standard libraries.}. 587 In modern programming languages, a lack of threading is unacceptable~\cite{Sutter05, Sutter05b}, and therefore existing and new programming languages must have tools for writing efficient concurrent programs to take advantage of parallelism. 588 As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages. 589 Furthermore, because C is a system-level language, programmers expect to choose precisely which features they need and which cost they are willing to pay. 590 Hence, concurrent programs should be written using high-level mechanisms, and only step down to lower-level mechanisms when performance bottlenecks are encountered. 591 592 593 \subsection{Coroutines: A Stepping Stone}\label{coroutine} 594 595 While the focus of this discussion is concurrency and parallelism, it is important to address coroutines, which are a significant building block of a concurrency system. 596 Coroutines are generalized routines allowing execution to be temporarily suspend and later resumed. 597 Hence, unlike a normal routine, a coroutine may not terminate when it returns to its caller, allowing it to be restarted with the values and execution location present at the point of suspension. 598 This capability is accomplish via the coroutine's stack, where suspend/resume context switch among stacks. 599 Because threading design-challenges are present in coroutines, their design effort is relevant, and this effort can be easily exposed to programmers giving them a useful new programming paradigm because a coroutine handles the class of problems that need to retain state between calls, \eg plugins, device drivers, and finite-state machines. 600 Therefore, the core \CFA coroutine-API for has two fundamental features: independent call-stacks and @suspend@/@resume@ operations. 601 602 For example, a problem made easier with coroutines is unbounded generators, \eg generating an infinite sequence of Fibonacci numbers, where Figure~\ref{f:C-fibonacci} shows conventional approaches for writing a Fibonacci generator in C. 603 \begin{displaymath} 604 \mathsf{fib}(n) = \left \{ 605 \begin{array}{ll} 606 0 & n = 0 \\ 607 1 & n = 1 \\ 608 \mathsf{fib}(n-1) + \mathsf{fib}(n-2) & n \ge 2 \\ 609 \end{array} 610 \right. 611 \end{displaymath} 612 Figure~\ref{f:GlobalVariables} illustrates the following problems: 613 unique unencapsulated global variables necessary to retain state between calls; 614 only one Fibonacci generator; 615 execution state must be explicitly retained via explicit state variables. 616 Figure~\ref{f:ExternalState} addresses these issues: 617 unencapsulated program global variables become encapsulated structure variables; 618 unique global variables are replaced by multiple Fibonacci objects; 619 explicit execution state is removed by precomputing the first two Fibonacci numbers and returning $\mathsf{fib}(n-2)$. 304 This paper discusses the design philosophy and implementation of advanced language-level control-flow and concurrent/parallel features in \CFA~\cite{Moss18,Cforall} and its runtime, which is written entirely in \CFA. 305 \CFA is a modern, polymorphic, non-object-oriented\footnote{ 306 \CFA has features often associated with object-oriented programming languages, such as constructors, destructors, virtuals and simple inheritance. 307 However, functions \emph{cannot} be nested in structures, so there is no lexical binding between a structure and set of functions (member/method) implemented by an implicit \lstinline@this@ (receiver) parameter.}, 308 backwards-compatible extension of the C programming language. 309 In many ways, \CFA is to C as Scala~\cite{Scala} is to Java, providing a \emph{research vehicle} for new typing and control-flow capabilities on top of a highly popular programming language allowing immediate dissemination. 310 Within the \CFA framework, new control-flow features are created from scratch because ISO \Celeven defines only a subset of the \CFA extensions, where the overlapping features are concurrency~\cite[\S~7.26]{C11}. 311 However, \Celeven concurrency is largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}, and \Celeven and pthreads concurrency is simple, based on thread fork/join in a function and mutex/condition locks, which is low-level and error-prone; 312 no high-level language concurrency features are defined. 313 Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-9 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach (possibly because the effort to add concurrency to \CC). 314 Finally, while the \Celeven standard does not state a threading model, the historical association with pthreads suggests implementations would adopt kernel-level threading (1:1)~\cite{ThreadModel}. 315 316 In contrast, there has been a renewed interest during the past decade in user-level (M:N, green) threading in old and new programming languages. 317 As multi-core hardware became available in the 1980/90s, both user and kernel threading were examined. 318 Kernel threading was chosen, largely because of its simplicity and fit with the simpler operating systems and hardware architectures at the time, which gave it a performance advantage~\cite{Drepper03}. 319 Libraries like pthreads were developed for C, and the Solaris operating-system switched from user (JDK 1.1~\cite{JDK1.1}) to kernel threads. 320 As a result, languages like Java, Scala, Objective-C~\cite{obj-c-book}, \CCeleven~\cite{C11}, and C\#~\cite{Csharp} adopt the 1:1 kernel-threading model, with a variety of presentation mechanisms. 321 From 2000 onwards, languages like Go~\cite{Go}, Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, D~\cite{D}, and \uC~\cite{uC++,uC++book} have championed the M:N user-threading model, and many user-threading libraries have appeared~\cite{Qthreads,MPC,Marcel}, including putting green threads back into Java~\cite{Quasar}. 322 The main argument for user-level threading is that it is lighter weight than kernel threading (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work units to facilitate load balancing by the runtime~\cite{Verch12}. 323 As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{Adya02,vonBehren03}. 324 Finally, performant user-threading implementations (both time and space) meet or exceed direct kernel-threading implementations, while achieving the programming advantages of high concurrency levels and safety. 325 326 A further effort over the past two decades is the development of language memory models to deal with the conflict between language features and compiler/hardware optimizations, \ie some language features are unsafe in the presence of aggressive sequential optimizations~\cite{Buhr95a,Boehm05}. 327 The consequence is that a language must provide sufficient tools to program around safety issues, as inline and library code is all sequential to the compiler. 328 One solution is low-level qualifiers and functions (\eg @volatile@ and atomics) allowing \emph{programmers} to explicitly write safe (race-free~\cite{Boehm12}) programs. 329 A safer solution is high-level language constructs so the \emph{compiler} knows the optimization boundaries, and hence, provides implicit safety. 330 This problem is best known with respect to concurrency, but applies to other complex control-flow, like exceptions\footnote{ 331 \CFA exception handling will be presented in a separate paper. 332 The key feature that dovetails with this paper is nonlocal exceptions allowing exceptions to be raised across stacks, with synchronous exceptions raised among coroutines and asynchronous exceptions raised among threads, similar to that in \uC~\cite[\S~5]{uC++} 333 } and coroutines. 334 Finally, language solutions allow matching constructs with language paradigm, \ie imperative and functional languages often have different presentations of the same concept to fit their programming model. 335 336 Finally, it is important for a language to provide safety over performance \emph{as the default}, allowing careful reduction of safety for performance when necessary. 337 Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging}\footnote{ 338 The notion of competitive succession instead of direct handoff, \ie a lock owner releases the lock and an arriving thread acquires it ahead of preexisting waiter threads. 339 } (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie once there is spurious wakeup, signals-as-hints follow. 340 However, spurious wakeup is \emph{not} a foundational concurrency property~\cite[\S~8]{Buhr05a}, it is a performance design choice. 341 Similarly, signals-as-hints are often a performance decision. 342 We argue removing spurious wakeup and signals-as-hints make concurrent programming significantly safer because it removes local non-determinism and matches with programmer expectation. 343 (Author experience teaching concurrency is that students are highly confused by these semantics.) 344 Clawing back performance, when local non-determinism is unimportant, should be an option not the default. 345 346 \begin{comment} 347 Most augmented traditional (Fortran 18~\cite{Fortran18}, Cobol 14~\cite{Cobol14}, Ada 12~\cite{Ada12}, Java 11~\cite{Java11}) and new languages (Go~\cite{Go}, Rust~\cite{Rust}, and D~\cite{D}), except \CC, diverge from C with different syntax and semantics, only interoperate indirectly with C, and are not systems languages, for those with managed memory. 348 As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten. 349 While \CC, like \CFA, takes an evolutionary approach to extend C, \CC's constantly growing complex and interdependent features-set (\eg objects, inheritance, templates, etc.) mean idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC. 350 Hence, rewriting and retraining costs for these languages, even \CC, are prohibitive for companies with a large C software-base. 351 \CFA with its orthogonal feature-set, its high-performance runtime, and direct access to all existing C libraries circumvents these problems. 352 \end{comment} 353 354 \CFA embraces user-level threading, language extensions for advanced control-flow, and safety as the default. 355 We present comparative examples so the reader can judge if the \CFA control-flow extensions are better and safer than those in other concurrent, imperative programming languages, and perform experiments to show the \CFA runtime is competitive with other similar mechanisms. 356 The main contributions of this work are: 357 \begin{itemize}[topsep=3pt,itemsep=1pt] 358 \item 359 language-level generators, coroutines and user-level threading, which respect the expectations of C programmers. 360 \item 361 monitor synchronization without barging, and the ability to safely acquiring multiple monitors \emph{simultaneously} (deadlock free), while seamlessly integrating these capabilities with all monitor synchronization mechanisms. 362 \item 363 providing statically type-safe interfaces that integrate with the \CFA polymorphic type-system and other language features. 364 % \item 365 % library extensions for executors, futures, and actors built on the basic mechanisms. 366 \item 367 a runtime system with no spurious wakeup. 368 \item 369 a dynamic partitioning mechanism to segregate the execution environment for specialized requirements. 370 % \item 371 % a non-blocking I/O library 372 \item 373 experimental results showing comparable performance of the new features with similar mechanisms in other programming languages. 374 \end{itemize} 375 376 Section~\ref{s:StatefulFunction} begins advanced control by introducing sequential functions that retain data and execution state between calls, which produces constructs @generator@ and @coroutine@. 377 Section~\ref{s:Concurrency} begins concurrency, or how to create (fork) and destroy (join) a thread, which produces the @thread@ construct. 378 Section~\ref{s:MutualExclusionSynchronization} discusses the two mechanisms to restricted nondeterminism when controlling shared access to resources (mutual exclusion) and timing relationships among threads (synchronization). 379 Section~\ref{s:Monitor} shows how both mutual exclusion and synchronization are safely embedded in the @monitor@ and @thread@ constructs. 380 Section~\ref{s:CFARuntimeStructure} describes the large-scale mechanism to structure (cluster) threads and virtual processors (kernel threads). 381 Section~\ref{s:Performance} uses a series of microbenchmarks to compare \CFA threading with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0. 382 383 384 \section{Stateful Function} 385 \label{s:StatefulFunction} 386 387 The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg plugin, device driver, finite-state machine. 388 Hence, a stateful function may not end when it returns to its caller, allowing it to be restarted with the data and execution location present at the point of suspension. 389 This capability is accomplished by retaining a data/execution \emph{closure} between invocations. 390 If the closure is fixed size, we call it a \emph{generator} (or \emph{stackless}), and its control flow is restricted, \eg suspending outside the generator is prohibited. 391 If the closure is variable size, we call it a \emph{coroutine} (or \emph{stackful}), and as the names implies, often implemented with a separate stack with no programming restrictions. 392 Hence, refactoring a stackless coroutine may require changing it to stackful. 393 A foundational property of all \emph{stateful functions} is that resume/suspend \emph{do not} cause incremental stack growth, \ie resume/suspend operations are remembered through the closure not the stack. 394 As well, activating a stateful function is \emph{asymmetric} or \emph{symmetric}, identified by resume/suspend (no cycles) and resume/resume (cycles). 395 A fixed closure activated by modified call/return is faster than a variable closure activated by context switching. 396 Additionally, any storage management for the closure (especially in unmanaged languages, \ie no garbage collection) must also be factored into design and performance. 397 Therefore, selecting between stackless and stackful semantics is a tradeoff between programming requirements and performance, where stackless is faster and stackful is more general. 398 Note, creation cost is amortized across usage, so activation cost is usually the dominant factor. 620 399 621 400 \begin{figure} 622 401 \centering 623 \newbox\myboxA624 402 \begin{lrbox}{\myboxA} 625 403 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 626 `int f1, f2, state = 1;` // single global variables 627 int fib() { 628 int fn; 629 `switch ( state )` { // explicit execution state 630 case 1: fn = 0; f1 = fn; state = 2; break; 631 case 2: fn = 1; f2 = f1; f1 = fn; state = 3; break; 632 case 3: fn = f1 + f2; f2 = f1; f1 = fn; break; 633 } 404 typedef struct { 405 int fn1, fn; 406 } Fib; 407 #define FibCtor { 1, 0 } 408 int fib( Fib * f ) { 409 410 411 412 int fn = f->fn; f->fn = f->fn1; 413 f->fn1 = f->fn + fn; 634 414 return fn; 415 635 416 } 636 417 int main() { 637 638 for ( int i = 0; i < 10; i += 1 ) {639 printf( "%d \n", fib() );640 }418 Fib f1 = FibCtor, f2 = FibCtor; 419 for ( int i = 0; i < 10; i += 1 ) 420 printf( "%d %d\n", 421 fib( &f1 ), fib( &f2 ) ); 641 422 } 642 423 \end{cfa} 643 424 \end{lrbox} 644 425 645 \newbox\myboxB646 426 \begin{lrbox}{\myboxB} 647 427 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 648 #define FIB_INIT `{ 0, 1 }` 649 typedef struct { int f2, f1; } Fib; 650 int fib( Fib * f ) { 651 652 int ret = f->f2; 653 int fn = f->f1 + f->f2; 654 f->f2 = f->f1; f->f1 = fn; 655 656 return ret; 428 `generator` Fib { 429 int fn1, fn; 430 }; 431 432 void `main(Fib & fib)` with(fib) { 433 434 [fn1, fn] = [1, 0]; 435 for () { 436 `suspend;` 437 [fn1, fn] = [fn, fn + fn1]; 438 439 } 657 440 } 658 441 int main() { 659 Fib f1 = FIB_INIT, f2 = FIB_INIT; 660 for ( int i = 0; i < 10; i += 1 ) { 661 printf( "%d %d\n", fib( &f1 ), fib( &f2 ) ); 442 Fib f1, f2; 443 for ( 10 ) 444 sout | `resume( f1 )`.fn 445 | `resume( f2 )`.fn; 446 } 447 \end{cfa} 448 \end{lrbox} 449 450 \begin{lrbox}{\myboxC} 451 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 452 typedef struct { 453 int fn1, fn; void * `next`; 454 } Fib; 455 #define FibCtor { 1, 0, NULL } 456 Fib * comain( Fib * f ) { 457 if ( f->next ) goto *f->next; 458 f->next = &&s1; 459 for ( ;; ) { 460 return f; 461 s1:; int fn = f->fn + f->fn1; 462 f->fn1 = f->fn; f->fn = fn; 662 463 } 663 464 } 465 int main() { 466 Fib f1 = FibCtor, f2 = FibCtor; 467 for ( int i = 0; i < 10; i += 1 ) 468 printf("%d %d\n",comain(&f1)->fn, 469 comain(&f2)->fn); 470 } 664 471 \end{cfa} 665 472 \end{lrbox} 666 473 667 \subfloat[3 States: global variables]{\label{f:GlobalVariables}\usebox\myboxA} 668 \qquad 669 \subfloat[1 State: external variables]{\label{f:ExternalState}\usebox\myboxB} 670 \caption{C Fibonacci Implementations} 671 \label{f:C-fibonacci} 474 \subfloat[C asymmetric generator]{\label{f:CFibonacci}\usebox\myboxA} 475 \hspace{3pt} 476 \vrule 477 \hspace{3pt} 478 \subfloat[\CFA asymmetric generator]{\label{f:CFAFibonacciGen}\usebox\myboxB} 479 \hspace{3pt} 480 \vrule 481 \hspace{3pt} 482 \subfloat[C generator implementation]{\label{f:CFibonacciSim}\usebox\myboxC} 483 \caption{Fibonacci (output) asymmetric generator} 484 \label{f:FibonacciAsymmetricGenerator} 672 485 673 486 \bigskip 674 487 675 \newbox\myboxA676 488 \begin{lrbox}{\myboxA} 677 489 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 678 `coroutine` Fib { int fn; }; 679 void main( Fib & fib ) with( fib ) { 680 int f1, f2; 681 fn = 0; f1 = fn; `suspend()`; 682 fn = 1; f2 = f1; f1 = fn; `suspend()`; 683 for ( ;; ) { 684 fn = f1 + f2; f2 = f1; f1 = fn; `suspend()`; 490 `generator Fmt` { 491 char ch; 492 int g, b; 493 }; 494 void ?{}( Fmt & fmt ) { `resume(fmt);` } // constructor 495 void ^?{}( Fmt & f ) with(f) { $\C[1.75in]{// destructor}$ 496 if ( g != 0 || b != 0 ) sout | nl; } 497 void `main( Fmt & f )` with(f) { 498 for () { $\C{// until destructor call}$ 499 for ( ; g < 5; g += 1 ) { $\C{// groups}$ 500 for ( ; b < 4; b += 1 ) { $\C{// blocks}$ 501 `suspend;` $\C{// wait for character}$ 502 while ( ch == '\n' ) `suspend;` // ignore 503 sout | ch; // newline 504 } sout | " "; // block spacer 505 } sout | nl; // group newline 685 506 } 686 507 } 687 int next( Fib & fib ) with( fib ) {688 `resume( fib );`689 return fn;690 }691 508 int main() { 692 Fib f1, f2; 693 for ( int i = 1; i <= 10; i += 1 ) { 694 sout | next( f1 ) | next( f2 ) | endl; 509 Fmt fmt; $\C{// fmt constructor called}$ 510 for () { 511 sin | fmt.ch; $\C{// read into generator}$ 512 if ( eof( sin ) ) break; 513 `resume( fmt );` 695 514 } 696 } 515 516 } $\C{// fmt destructor called}\CRT$ 697 517 \end{cfa} 698 518 \end{lrbox} 699 \newbox\myboxB 519 700 520 \begin{lrbox}{\myboxB} 701 521 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 702 `coroutine` Fib { int ret; }; 703 void main( Fib & f ) with( fib ) { 704 int fn, f1 = 1, f2 = 0; 522 typedef struct { 523 void * next; 524 char ch; 525 int g, b; 526 } Fmt; 527 void comain( Fmt * f ) { 528 if ( f->next ) goto *f->next; 529 f->next = &&s1; 705 530 for ( ;; ) { 706 ret = f2; 707 708 fn = f1 + f2; f2 = f1; f1 = fn; `suspend();` 531 for ( f->g = 0; f->g < 5; f->g += 1 ) { 532 for ( f->b = 0; f->b < 4; f->b += 1 ) { 533 return; 534 s1:; while ( f->ch == '\n' ) return; 535 printf( "%c", f->ch ); 536 } printf( " " ); 537 } printf( "\n" ); 709 538 } 710 539 } 711 int next( Fib & fib ) with( fib ) { 712 `resume( fib );` 713 return ret; 714 } 715 716 717 718 719 720 540 int main() { 541 Fmt fmt = { NULL }; comain( &fmt ); // prime 542 for ( ;; ) { 543 scanf( "%c", &fmt.ch ); 544 if ( feof( stdin ) ) break; 545 comain( &fmt ); 546 } 547 if ( fmt.g != 0 || fmt.b != 0 ) printf( "\n" ); 548 } 721 549 \end{cfa} 722 550 \end{lrbox} 723 \subfloat[3 States, internal variables]{\label{f:Coroutine3States}\usebox\myboxA} 724 \qquad\qquad 725 \subfloat[1 State, internal variables]{\label{f:Coroutine1State}\usebox\myboxB} 726 \caption{\CFA Coroutine Fibonacci Implementations} 727 \label{f:fibonacci-cfa} 551 552 \subfloat[\CFA asymmetric generator]{\label{f:CFAFormatGen}\usebox\myboxA} 553 \hspace{3pt} 554 \vrule 555 \hspace{3pt} 556 \subfloat[C generator simulation]{\label{f:CFormatSim}\usebox\myboxB} 557 \hspace{3pt} 558 \caption{Formatter (input) asymmetric generator} 559 \label{f:FormatterAsymmetricGenerator} 728 560 \end{figure} 729 561 730 Using a coroutine, it is possible to express the Fibonacci formula directly without any of the C problems. 731 Figure~\ref{f:Coroutine3States} creates a @coroutine@ type: 732 \begin{cfa} 733 `coroutine` Fib { int fn; }; 734 \end{cfa} 735 which provides communication, @fn@, for the \newterm{coroutine main}, @main@, which runs on the coroutine stack, and possibly multiple interface routines @next@. 736 Like the structure in Figure~\ref{f:ExternalState}, the coroutine type allows multiple instances, where instances of this type are passed to the (overloaded) coroutine main. 737 The coroutine main's stack holds the state for the next generation, @f1@ and @f2@, and the code has the three suspend points, representing the three states in the Fibonacci formula, to context switch back to the caller's resume. 738 The interface routine @next@, takes a Fibonacci instance and context switches to it using @resume@; 739 on restart, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned. 740 The first @resume@ is special because it cocalls the coroutine at its coroutine main and allocates the stack; 741 when the coroutine main returns, its stack is deallocated. 742 Hence, @Fib@ is an object at creation, transitions to a coroutine on its first resume, and transitions back to an object when the coroutine main finishes. 743 Figure~\ref{f:Coroutine1State} shows the coroutine version of the C version in Figure~\ref{f:ExternalState}. 744 Coroutine generators are called \newterm{output coroutines} because values are only returned. 745 746 Figure~\ref{f:CFAFmt} shows an \newterm{input coroutine}, @Format@, for restructuring text into groups of characters of fixed-size blocks. 747 For example, the input of the left is reformatted into the output on the right. 748 \begin{quote} 562 Stateful functions appear as generators, coroutines, and threads, where presentations are based on function objects or pointers~\cite{Butenhof97, C++14, MS:VisualC++, BoostCoroutines15}. 563 For example, Python presents generators as a function object: 564 \begin{python} 565 def Gen(): 566 ... `yield val` ... 567 gen = Gen() 568 for i in range( 10 ): 569 print( next( gen ) ) 570 \end{python} 571 Boost presents coroutines in terms of four functor object-types: 572 \begin{cfa} 573 asymmetric_coroutine<>::pull_type 574 asymmetric_coroutine<>::push_type 575 symmetric_coroutine<>::call_type 576 symmetric_coroutine<>::yield_type 577 \end{cfa} 578 and many languages present threading using function pointers, @pthreads@~\cite{Butenhof97}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}, \eg pthreads: 579 \begin{cfa} 580 void * rtn( void * arg ) { ... } 581 int i = 3, rc; 582 pthread_t t; $\C{// thread id}$ 583 `rc = pthread_create( &t, rtn, (void *)i );` $\C{// create and initialized task, type-unsafe input parameter}$ 584 \end{cfa} 585 % void mycor( pthread_t cid, void * arg ) { 586 % int * value = (int *)arg; $\C{// type unsafe, pointer-size only}$ 587 % // thread body 588 % } 589 % int main() { 590 % int input = 0, output; 591 % coroutine_t cid = coroutine_create( &mycor, (void *)&input ); $\C{// type unsafe, pointer-size only}$ 592 % coroutine_resume( cid, (void *)input, (void **)&output ); $\C{// type unsafe, pointer-size only}$ 593 % } 594 \CFA's preferred presentation model for generators/coroutines/threads is a hybrid of objects and functions, with an object-oriented flavour. 595 Essentially, the generator/coroutine/thread function is semantically coupled with a generator/coroutine/thread custom type. 596 The custom type solves several issues, while accessing the underlying mechanisms used by the custom types is still allowed. 597 598 599 \subsection{Generator} 600 601 Stackless generators have the potential to be very small and fast, \ie as small and fast as function call/return for both creation and execution. 602 The \CFA goal is to achieve this performance target, possibly at the cost of some semantic complexity. 603 A series of different kinds of generators and their implementation demonstrate how this goal is accomplished. 604 605 Figure~\ref{f:FibonacciAsymmetricGenerator} shows an unbounded asymmetric generator for an infinite sequence of Fibonacci numbers written in C and \CFA, with a simple C implementation for the \CFA version. 606 This generator is an \emph{output generator}, producing a new result on each resumption. 607 To compute Fibonacci, the previous two values in the sequence are retained to generate the next value, \ie @fn1@ and @fn@, plus the execution location where control restarts when the generator is resumed, \ie top or middle. 608 An additional requirement is the ability to create an arbitrary number of generators (of any kind), \ie retaining one state in global variables is insufficient; 609 hence, state is retained in a closure between calls. 610 Figure~\ref{f:CFibonacci} shows the C approach of manually creating the closure in structure @Fib@, and multiple instances of this closure provide multiple Fibonacci generators. 611 The C version only has the middle execution state because the top execution state is declaration initialization. 612 Figure~\ref{f:CFAFibonacciGen} shows the \CFA approach, which also has a manual closure, but replaces the structure with a custom \CFA @generator@ type. 613 This generator type is then connected to a function that \emph{must be named \lstinline|main|},\footnote{ 614 The name \lstinline|main| has special meaning in C, specifically the function where a program starts execution. 615 Hence, overloading this name for other starting points (generator/coroutine/thread) is a logical extension.} 616 called a \emph{generator main},which takes as its only parameter a reference to the generator type. 617 The generator main contains @suspend@ statements that suspend execution without ending the generator versus @return@. 618 For the Fibonacci generator-main,\footnote{ 619 The \CFA \lstinline|with| opens an aggregate scope making its fields directly accessible, like Pascal \lstinline|with|, but using parallel semantics. 620 Multiple aggregates may be opened.} 621 the top initialization state appears at the start and the middle execution state is denoted by statement @suspend@. 622 Any local variables in @main@ \emph{are not retained} between calls; 623 hence local variables are only for temporary computations \emph{between} suspends. 624 All retained state \emph{must} appear in the generator's type. 625 As well, generator code containing a @suspend@ cannot be refactored into a helper function called by the generator, because @suspend@ is implemented via @return@, so a return from the helper function goes back to the current generator not the resumer. 626 The generator is started by calling function @resume@ with a generator instance, which begins execution at the top of the generator main, and subsequent @resume@ calls restart the generator at its point of last suspension. 627 Resuming an ended (returned) generator is undefined. 628 Function @resume@ returns its argument generator so it can be cascaded in an expression, in this case to print the next Fibonacci value @fn@ computed in the generator instance. 629 Figure~\ref{f:CFibonacciSim} shows the C implementation of the \CFA generator only needs one additional field, @next@, to handle retention of execution state. 630 The computed @goto@ at the start of the generator main, which branches after the previous suspend, adds very little cost to the resume call. 631 Finally, an explicit generator type provides both design and performance benefits, such as multiple type-safe interface functions taking and returning arbitrary types.\footnote{ 632 The \CFA operator syntax uses \lstinline|?| to denote operands, which allows precise definitions for pre, post, and infix operators, \eg \lstinline|++?|, \lstinline|?++|, and \lstinline|?+?|, in addition \lstinline|?\{\}| denotes a constructor, as in \lstinline|foo `f` = `\{`...`\}`|, \lstinline|^?\{\}| denotes a destructor, and \lstinline|?()| is \CC function call \lstinline|operator()|. 633 }% 634 \begin{cfa} 635 int ?()( Fib & fib ) { return `resume( fib )`.fn; } $\C[3.9in]{// function-call interface}$ 636 int ?()( Fib & fib, int N ) { for ( N - 1 ) `fib()`; return `fib()`; } $\C{// use function-call interface to skip N values}$ 637 double ?()( Fib & fib ) { return (int)`fib()` / 3.14159; } $\C{// different return type, cast prevents recursive call}\CRT$ 638 sout | (int)f1() | (double)f1() | f2( 2 ); // alternative interface, cast selects call based on return type, step 2 values 639 \end{cfa} 640 Now, the generator can be a separately compiled opaque-type only accessed through its interface functions. 641 For contrast, Figure~\ref{f:PythonFibonacci} shows the equivalent Python Fibonacci generator, which does not use a generator type, and hence only has a single interface, but an implicit closure. 642 643 Having to manually create the generator closure by moving local-state variables into the generator type is an additional programmer burden. 644 (This restriction is removed by the coroutine in Section~\ref{s:Coroutine}.) 645 This requirement follows from the generality of variable-size local-state, \eg local state with a variable-length array requires dynamic allocation because the array size is unknown at compile time. 646 However, dynamic allocation significantly increases the cost of generator creation/destruction and is a showstopper for embedded real-time programming. 647 But more importantly, the size of the generator type is tied to the local state in the generator main, which precludes separate compilation of the generator main, \ie a generator must be inlined or local state must be dynamically allocated. 648 With respect to safety, we believe static analysis can discriminate local state from temporary variables in a generator, \ie variable usage spanning @suspend@, and generate a compile-time error. 649 Finally, our current experience is that most generator problems have simple data state, including local state, but complex execution state, so the burden of creating the generator type is small. 650 As well, C programmers are not afraid of this kind of semantic programming requirement, if it results in very small, fast generators. 651 652 Figure~\ref{f:CFAFormatGen} shows an asymmetric \newterm{input generator}, @Fmt@, for restructuring text into groups of characters of fixed-size blocks, \ie the input on the left is reformatted into the output on the right, where newlines are ignored. 653 \begin{center} 749 654 \tt 750 655 \begin{tabular}{@{}l|l@{}} 751 656 \multicolumn{1}{c|}{\textbf{\textrm{input}}} & \multicolumn{1}{c}{\textbf{\textrm{output}}} \\ 752 abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz 657 \begin{tabular}[t]{@{}ll@{}} 658 abcdefghijklmnopqrstuvwxyz \\ 659 abcdefghijklmnopqrstuvwxyz 660 \end{tabular} 753 661 & 754 662 \begin{tabular}[t]{@{}lllll@{}} … … 758 666 \end{tabular} 759 667 \end{tabular} 760 \end{quote} 761 The example takes advantage of resuming a coroutine in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops. 762 The destruction provides a newline if formatted text ends with a full line. 763 Figure~\ref{f:CFmt} shows the C equivalent formatter, where the loops of the coroutine are flatten (linearized) and rechecked on each call because execution location is not retained between calls. 668 \end{center} 669 The example takes advantage of resuming a generator in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops. 670 The destructor provides a newline, if formatted text ends with a full line. 671 Figure~\ref{f:CFormatSim} shows the C implementation of the \CFA input generator with one additional field and the computed @goto@. 672 For contrast, Figure~\ref{f:PythonFormatter} shows the equivalent Python format generator with the same properties as the Fibonacci generator. 673 674 Figure~\ref{f:DeviceDriverGen} shows a \emph{killer} asymmetric generator, a device-driver, because device drivers caused 70\%-85\% of failures in Windows/Linux~\cite{Swift05}. 675 Device drives follow the pattern of simple data state but complex execution state, \ie finite state-machine (FSM) parsing a protocol. 676 For example, the following protocol: 677 \begin{center} 678 \ldots\, STX \ldots\, message \ldots\, ESC ETX \ldots\, message \ldots\, ETX 2-byte crc \ldots 679 \end{center} 680 is a network message beginning with the control character STX, ending with an ETX, and followed by a 2-byte cyclic-redundancy check. 681 Control characters may appear in a message if preceded by an ESC. 682 When a message byte arrives, it triggers an interrupt, and the operating system services the interrupt by calling the device driver with the byte read from a hardware register. 683 The device driver returns a status code of its current state, and when a complete message is obtained, the operating system knows the message is in the message buffer. 684 Hence, the device driver is an input/output generator. 685 686 Note, the cost of creating and resuming the device-driver generator, @Driver@, is virtually identical to call/return, so performance in an operating-system kernel is excellent. 687 As well, the data state is small, where variables @byte@ and @msg@ are communication variables for passing in message bytes and returning the message, and variables @lnth@, @crc@, and @sum@ are local variable that must be retained between calls and are manually hoisted into the generator type. 688 % Manually, detecting and hoisting local-state variables is easy when the number is small. 689 In contrast, the execution state is large, with one @resume@ and seven @suspend@s. 690 Hence, the key benefits of the generator are correctness, safety, and maintenance because the execution states are transcribed directly into the programming language rather than using a table-driven approach. 691 Because FSMs can be complex and frequently occur in important domains, direct generator support is important in a system programming language. 764 692 765 693 \begin{figure} … … 767 695 \newbox\myboxA 768 696 \begin{lrbox}{\myboxA} 697 \begin{python}[aboveskip=0pt,belowskip=0pt] 698 def Fib(): 699 fn1, fn = 0, 1 700 while True: 701 `yield fn1` 702 fn1, fn = fn, fn1 + fn 703 f1 = Fib() 704 f2 = Fib() 705 for i in range( 10 ): 706 print( next( f1 ), next( f2 ) ) 707 708 709 710 711 712 713 \end{python} 714 \end{lrbox} 715 716 \newbox\myboxB 717 \begin{lrbox}{\myboxB} 718 \begin{python}[aboveskip=0pt,belowskip=0pt] 719 def Fmt(): 720 try: 721 while True: 722 for g in range( 5 ): 723 for b in range( 4 ): 724 print( `(yield)`, end='' ) 725 print( ' ', end='' ) 726 print() 727 except GeneratorExit: 728 if g != 0 | b != 0: 729 print() 730 fmt = Fmt() 731 `next( fmt )` # prime, next prewritten 732 for i in range( 41 ): 733 `fmt.send( 'a' );` # send to yield 734 \end{python} 735 \end{lrbox} 736 \subfloat[Fibonacci]{\label{f:PythonFibonacci}\usebox\myboxA} 737 \hspace{3pt} 738 \vrule 739 \hspace{3pt} 740 \subfloat[Formatter]{\label{f:PythonFormatter}\usebox\myboxB} 741 \caption{Python generator} 742 \label{f:PythonGenerator} 743 744 \bigskip 745 746 \begin{tabular}{@{}l|l@{}} 769 747 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 770 `coroutine` Format { 771 char ch; // used for communication 772 int g, b; // global because used in destructor 748 enum Status { CONT, MSG, ESTX, 749 ELNTH, ECRC }; 750 `generator` Driver { 751 Status status; 752 unsigned char byte, * msg; // communication 753 unsigned int lnth, sum; // local state 754 unsigned short int crc; 773 755 }; 774 void main( Format & fmt ) with( fmt ) { 775 for ( ;; ) { 776 for ( g = 0; g < 5; g += 1 ) { // group 777 for ( b = 0; b < 4; b += 1 ) { // block 778 `suspend();` 779 sout | ch; // separator 756 void ?{}( Driver & d, char * m ) { d.msg = m; } 757 Status next( Driver & d, char b ) with( d ) { 758 byte = b; `resume( d );` return status; 759 } 760 void main( Driver & d ) with( d ) { 761 enum { STX = '\002', ESC = '\033', 762 ETX = '\003', MaxMsg = 64 }; 763 msg: for () { // parse message 764 status = CONT; 765 lnth = 0; sum = 0; 766 while ( byte != STX ) `suspend;` 767 emsg: for () { 768 `suspend;` // process byte 769 \end{cfa} 770 & 771 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 772 choose ( byte ) { // switch with implicit break 773 case STX: 774 status = ESTX; `suspend;` continue msg; 775 case ETX: 776 break emsg; 777 case ESC: 778 `suspend;` 780 779 } 781 sout | " "; // separator 780 if ( lnth >= MaxMsg ) { // buffer full ? 781 status = ELNTH; `suspend;` continue msg; } 782 msg[lnth++] = byte; 783 sum += byte; 782 784 } 783 sout | endl; 785 msg[lnth] = '\0'; // terminate string 786 `suspend;` 787 crc = byte << 8; 788 `suspend;` 789 status = (crc | byte) == sum ? MSG : ECRC; 790 `suspend;` 784 791 } 785 792 } 786 void ?{}( Format & fmt ) { `resume( fmt );` } 787 void ^?{}( Format & fmt ) with( fmt ) { 788 if ( g != 0 || b != 0 ) sout | endl; 789 } 790 void format( Format & fmt ) { 791 `resume( fmt );` 793 \end{cfa} 794 \end{tabular} 795 \caption{Device-driver generator for communication protocol} 796 \label{f:DeviceDriverGen} 797 \end{figure} 798 799 Figure~\ref{f:CFAPingPongGen} shows a symmetric generator, where the generator resumes another generator, forming a resume/resume cycle. 800 (The trivial cycle is a generator resuming itself.) 801 This control flow is similar to recursion for functions but without stack growth. 802 The steps for symmetric control-flow are creating, executing, and terminating the cycle. 803 Constructing the cycle must deal with definition-before-use to close the cycle, \ie, the first generator must know about the last generator, which is not within scope. 804 (This issue occurs for any cyclic data structure.) 805 % The example creates all the generators and then assigns the partners that form the cycle. 806 % Alternatively, the constructor can assign the partners as they are declared, except the first, and the first-generator partner is set after the last generator declaration to close the cycle. 807 Once the cycle is formed, the program main resumes one of the generators, and the generators can then traverse an arbitrary cycle using @resume@ to activate partner generator(s). 808 Terminating the cycle is accomplished by @suspend@ or @return@, both of which go back to the stack frame that started the cycle (program main in the example). 809 The starting stack-frame is below the last active generator because the resume/resume cycle does not grow the stack. 810 Also, since local variables are not retained in the generator function, it does not contain any objects with destructors that must be called, so the cost is the same as a function return. 811 Destructor cost occurs when the generator instance is deallocated, which is easily controlled by the programmer. 812 813 Figure~\ref{f:CPingPongSim} shows the implementation of the symmetric generator, where the complexity is the @resume@, which needs an extension to the calling convention to perform a forward rather than backward jump. 814 This jump-starts at the top of the next generator main to re-execute the normal calling convention to make space on the stack for its local variables. 815 However, before the jump, the caller must reset its stack (and any registers) equivalent to a @return@, but subsequently jump forward. 816 This semantics is basically a tail-call optimization, which compilers already perform. 817 The example shows the assembly code to undo the generator's entry code before the direct jump. 818 This assembly code depends on what entry code is generated, specifically if there are local variables and the level of optimization. 819 To provide this new calling convention requires a mechanism built into the compiler, which is beyond the scope of \CFA at this time. 820 Nevertheless, it is possible to hand generate any symmetric generators for proof of concept and performance testing. 821 A compiler could also eliminate other artifacts in the generator simulation to further increase performance, \eg LLVM has various coroutine support~\cite{CoroutineTS}, and \CFA can leverage this support should it fork @clang@. 822 823 \begin{figure} 824 \centering 825 \begin{lrbox}{\myboxA} 826 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 827 `generator PingPong` { 828 const char * name; 829 int N; 830 int i; // local state 831 PingPong & partner; // rebindable reference 832 }; 833 834 void `main( PingPong & pp )` with(pp) { 835 for ( ; i < N; i += 1 ) { 836 sout | name | i; 837 `resume( partner );` 838 } 792 839 } 793 840 int main() { 794 Format fmt; 795 eof: for ( ;; ) { 796 sin | fmt.ch; 797 if ( eof( sin ) ) break eof; 798 format( fmt ); 841 enum { N = 5 }; 842 PingPong ping = {"ping",N,0}, pong = {"pong",N,0}; 843 &ping.partner = &pong; &pong.partner = &ping; 844 `resume( ping );` 845 } 846 \end{cfa} 847 \end{lrbox} 848 849 \begin{lrbox}{\myboxB} 850 \begin{cfa}[escapechar={},aboveskip=0pt,belowskip=0pt] 851 typedef struct PingPong { 852 const char * name; 853 int N, i; 854 struct PingPong * partner; 855 void * next; 856 } PingPong; 857 #define PPCtor(name, N) {name,N,0,NULL,NULL} 858 void comain( PingPong * pp ) { 859 if ( pp->next ) goto *pp->next; 860 pp->next = &&cycle; 861 for ( ; pp->i < pp->N; pp->i += 1 ) { 862 printf( "%s %d\n", pp->name, pp->i ); 863 asm( "mov %0,%%rdi" : "=m" (pp->partner) ); 864 asm( "mov %rdi,%rax" ); 865 asm( "popq %rbx" ); 866 asm( "jmp comain" ); 867 cycle: ; 868 } 869 } 870 \end{cfa} 871 \end{lrbox} 872 873 \subfloat[\CFA symmetric generator]{\label{f:CFAPingPongGen}\usebox\myboxA} 874 \hspace{3pt} 875 \vrule 876 \hspace{3pt} 877 \subfloat[C generator simulation]{\label{f:CPingPongSim}\usebox\myboxB} 878 \hspace{3pt} 879 \caption{Ping-Pong symmetric generator} 880 \label{f:PingPongSymmetricGenerator} 881 \end{figure} 882 883 Finally, part of this generator work was inspired by the recent \CCtwenty generator proposal~\cite{C++20Coroutine19} (which they call coroutines). 884 Our work provides the same high-performance asymmetric generators as \CCtwenty, and extends their work with symmetric generators. 885 An additional \CCtwenty generator feature allows @suspend@ and @resume@ to be followed by a restricted compound statement that is executed after the current generator has reset its stack but before calling the next generator, specified with \CFA syntax: 886 \begin{cfa} 887 ... suspend`{ ... }`; 888 ... resume( C )`{ ... }` ... 889 \end{cfa} 890 Since the current generator's stack is released before calling the compound statement, the compound statement can only reference variables in the generator's type. 891 This feature is useful when a generator is used in a concurrent context to ensure it is stopped before releasing a lock in the compound statement, which might immediately allow another thread to resume the generator. 892 Hence, this mechanism provides a general and safe handoff of the generator among competing threads. 893 894 895 \subsection{Coroutine} 896 \label{s:Coroutine} 897 898 Stackful coroutines extend generator semantics, \ie there is an implicit closure and @suspend@ may appear in a helper function called from the coroutine main. 899 A coroutine is specified by replacing @generator@ with @coroutine@ for the type. 900 Coroutine generality results in higher cost for creation, due to dynamic stack allocation, execution, due to context switching among stacks, and terminating, due to possible stack unwinding and dynamic stack deallocation. 901 A series of different kinds of coroutines and their implementations demonstrate how coroutines extend generators. 902 903 First, the previous generator examples are converted to their coroutine counterparts, allowing local-state variables to be moved from the generator type into the coroutine main. 904 \begin{description} 905 \item[Fibonacci] 906 Move the declaration of @fn1@ to the start of coroutine main. 907 \begin{cfa}[xleftmargin=0pt] 908 void main( Fib & fib ) with(fib) { 909 `int fn1;` 910 \end{cfa} 911 \item[Formatter] 912 Move the declaration of @g@ and @b@ to the for loops in the coroutine main. 913 \begin{cfa}[xleftmargin=0pt] 914 for ( `g`; 5 ) { 915 for ( `b`; 4 ) { 916 \end{cfa} 917 \item[Device Driver] 918 Move the declaration of @lnth@ and @sum@ to their points of initialization. 919 \begin{cfa}[xleftmargin=0pt] 920 status = CONT; 921 `unsigned int lnth = 0, sum = 0;` 922 ... 923 `unsigned short int crc = byte << 8;` 924 \end{cfa} 925 \item[PingPong] 926 Move the declaration of @i@ to the for loop in the coroutine main. 927 \begin{cfa}[xleftmargin=0pt] 928 void main( PingPong & pp ) with(pp) { 929 for ( `i`; N ) { 930 \end{cfa} 931 \end{description} 932 It is also possible to refactor code containing local-state and @suspend@ statements into a helper function, like the computation of the CRC for the device driver. 933 \begin{cfa} 934 unsigned int Crc() { 935 `suspend;` 936 unsigned short int crc = byte << 8; 937 `suspend;` 938 status = (crc | byte) == sum ? MSG : ECRC; 939 return crc; 940 } 941 \end{cfa} 942 A call to this function is placed at the end of the driver's coroutine-main. 943 For complex finite-state machines, refactoring is part of normal program abstraction, especially when code is used in multiple places. 944 Again, this complexity is usually associated with execution state rather than data state. 945 946 \begin{comment} 947 Figure~\ref{f:Coroutine3States} creates a @coroutine@ type, @`coroutine` Fib { int fn; }@, which provides communication, @fn@, for the \newterm{coroutine main}, @main@, which runs on the coroutine stack, and possibly multiple interface functions, \eg @next@. 948 Like the structure in Figure~\ref{f:ExternalState}, the coroutine type allows multiple instances, where instances of this type are passed to the (overloaded) coroutine main. 949 The coroutine main's stack holds the state for the next generation, @f1@ and @f2@, and the code represents the three states in the Fibonacci formula via the three suspend points, to context switch back to the caller's @resume@. 950 The interface function @next@, takes a Fibonacci instance and context switches to it using @resume@; 951 on restart, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned. 952 The first @resume@ is special because it allocates the coroutine stack and cocalls its coroutine main on that stack; 953 when the coroutine main returns, its stack is deallocated. 954 Hence, @Fib@ is an object at creation, transitions to a coroutine on its first resume, and transitions back to an object when the coroutine main finishes. 955 Figure~\ref{f:Coroutine1State} shows the coroutine version of the C version in Figure~\ref{f:ExternalState}. 956 Coroutine generators are called \newterm{output coroutines} because values are only returned. 957 958 \begin{figure} 959 \centering 960 \newbox\myboxA 961 % \begin{lrbox}{\myboxA} 962 % \begin{cfa}[aboveskip=0pt,belowskip=0pt] 963 % `int fn1, fn2, state = 1;` // single global variables 964 % int fib() { 965 % int fn; 966 % `switch ( state )` { // explicit execution state 967 % case 1: fn = 0; fn1 = fn; state = 2; break; 968 % case 2: fn = 1; fn2 = fn1; fn1 = fn; state = 3; break; 969 % case 3: fn = fn1 + fn2; fn2 = fn1; fn1 = fn; break; 970 % } 971 % return fn; 972 % } 973 % int main() { 974 % 975 % for ( int i = 0; i < 10; i += 1 ) { 976 % printf( "%d\n", fib() ); 977 % } 978 % } 979 % \end{cfa} 980 % \end{lrbox} 981 \begin{lrbox}{\myboxA} 982 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 983 #define FibCtor { 0, 1 } 984 typedef struct { int fn1, fn; } Fib; 985 int fib( Fib * f ) { 986 987 int ret = f->fn1; 988 f->fn1 = f->fn; 989 f->fn = ret + f->fn; 990 return ret; 991 } 992 993 994 995 int main() { 996 Fib f1 = FibCtor, f2 = FibCtor; 997 for ( int i = 0; i < 10; i += 1 ) { 998 printf( "%d %d\n", 999 fib( &f1 ), fib( &f2 ) ); 799 1000 } 800 1001 } … … 805 1006 \begin{lrbox}{\myboxB} 806 1007 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 807 struct Format { 808 char ch; 809 int g, b; 810 }; 811 void format( struct Format * fmt ) { 812 if ( fmt->ch != -1 ) { // not EOF ? 813 printf( "%c", fmt->ch ); 814 fmt->b += 1; 815 if ( fmt->b == 4 ) { // block 816 printf( " " ); // separator 817 fmt->b = 0; 818 fmt->g += 1; 819 } 820 if ( fmt->g == 5 ) { // group 821 printf( "\n" ); // separator 822 fmt->g = 0; 823 } 824 } else { 825 if ( fmt->g != 0 || fmt->b != 0 ) printf( "\n" ); 1008 `coroutine` Fib { int fn1; }; 1009 void main( Fib & fib ) with( fib ) { 1010 int fn; 1011 [fn1, fn] = [0, 1]; 1012 for () { 1013 `suspend;` 1014 [fn1, fn] = [fn, fn1 + fn]; 826 1015 } 827 1016 } 1017 int ?()( Fib & fib ) with( fib ) { 1018 return `resume( fib )`.fn1; 1019 } 828 1020 int main() { 829 struct Format fmt = { 0, 0, 0 }; 830 for ( ;; ) { 831 scanf( "%c", &fmt.ch ); 832 if ( feof( stdin ) ) break; 833 format( &fmt ); 834 } 835 fmt.ch = -1; 836 format( &fmt ); 837 } 1021 Fib f1, f2; 1022 for ( 10 ) { 1023 sout | f1() | f2(); 1024 } 1025 1026 838 1027 \end{cfa} 839 1028 \end{lrbox} 840 \subfloat[\CFA Coroutine]{\label{f:CFAFmt}\usebox\myboxA} 1029 1030 \newbox\myboxC 1031 \begin{lrbox}{\myboxC} 1032 \begin{python}[aboveskip=0pt,belowskip=0pt] 1033 1034 def Fib(): 1035 1036 fn1, fn = 0, 1 1037 while True: 1038 `yield fn1` 1039 fn1, fn = fn, fn1 + fn 1040 1041 1042 // next prewritten 1043 1044 1045 f1 = Fib() 1046 f2 = Fib() 1047 for i in range( 10 ): 1048 print( next( f1 ), next( f2 ) ) 1049 1050 1051 1052 \end{python} 1053 \end{lrbox} 1054 1055 \subfloat[C]{\label{f:GlobalVariables}\usebox\myboxA} 1056 \hspace{3pt} 1057 \vrule 1058 \hspace{3pt} 1059 \subfloat[\CFA]{\label{f:ExternalState}\usebox\myboxB} 1060 \hspace{3pt} 1061 \vrule 1062 \hspace{3pt} 1063 \subfloat[Python]{\label{f:ExternalState}\usebox\myboxC} 1064 \caption{Fibonacci generator} 1065 \label{f:C-fibonacci} 1066 \end{figure} 1067 1068 \bigskip 1069 1070 \newbox\myboxA 1071 \begin{lrbox}{\myboxA} 1072 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1073 `coroutine` Fib { int fn; }; 1074 void main( Fib & fib ) with( fib ) { 1075 fn = 0; int fn1 = fn; `suspend`; 1076 fn = 1; int fn2 = fn1; fn1 = fn; `suspend`; 1077 for () { 1078 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `suspend`; } 1079 } 1080 int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; } 1081 int main() { 1082 Fib f1, f2; 1083 for ( 10 ) 1084 sout | next( f1 ) | next( f2 ); 1085 } 1086 \end{cfa} 1087 \end{lrbox} 1088 \newbox\myboxB 1089 \begin{lrbox}{\myboxB} 1090 \begin{python}[aboveskip=0pt,belowskip=0pt] 1091 1092 def Fibonacci(): 1093 fn = 0; fn1 = fn; `yield fn` # suspend 1094 fn = 1; fn2 = fn1; fn1 = fn; `yield fn` 1095 while True: 1096 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `yield fn` 1097 1098 1099 f1 = Fibonacci() 1100 f2 = Fibonacci() 1101 for i in range( 10 ): 1102 print( `next( f1 )`, `next( f2 )` ) # resume 1103 1104 \end{python} 1105 \end{lrbox} 1106 \subfloat[\CFA]{\label{f:Coroutine3States}\usebox\myboxA} 841 1107 \qquad 842 \subfloat[ C Linearized]{\label{f:CFmt}\usebox\myboxB}843 \caption{F ormatting text into lines of 5 blocks of 4 characters.}844 \label{f: fmt-line}1108 \subfloat[Python]{\label{f:Coroutine1State}\usebox\myboxB} 1109 \caption{Fibonacci input coroutine, 3 states, internal variables} 1110 \label{f:cfa-fibonacci} 845 1111 \end{figure} 846 847 The previous examples are \newterm{asymmetric (semi) coroutine}s because one coroutine always calls a resuming routine for another coroutine, and the resumed coroutine always suspends back to its last resumer, similar to call/return for normal routines 848 However, there is no stack growth because @resume@/@suspend@ context switch to existing stack-frames rather than create new ones. 849 \newterm{Symmetric (full) coroutine}s have a coroutine call a resuming routine for another coroutine, which eventually forms a resuming-call cycle. 850 (The trivial cycle is a coroutine resuming itself.) 851 This control flow is similar to recursion for normal routines, but again there is no stack growth from the context switch. 1112 \end{comment} 852 1113 853 1114 \begin{figure} … … 857 1118 \begin{cfa} 858 1119 `coroutine` Prod { 859 Cons & c; 1120 Cons & c; // communication 860 1121 int N, money, receipt; 861 1122 }; 862 1123 void main( Prod & prod ) with( prod ) { 863 1124 // 1st resume starts here 864 for ( i nt i = 0; i < N; i += 1) {1125 for ( i; N ) { 865 1126 int p1 = random( 100 ), p2 = random( 100 ); 866 sout | p1 | " " | p2 | endl;1127 sout | p1 | " " | p2; 867 1128 int status = delivery( c, p1, p2 ); 868 sout | " $" | money | endl | status | endl;1129 sout | " $" | money | nl | status; 869 1130 receipt += 1; 870 1131 } 871 1132 stop( c ); 872 sout | "prod stops" | endl;1133 sout | "prod stops"; 873 1134 } 874 1135 int payment( Prod & prod, int money ) { … … 891 1152 \begin{cfa} 892 1153 `coroutine` Cons { 893 Prod & p; 1154 Prod & p; // communication 894 1155 int p1, p2, status; 895 _Bool done;1156 bool done; 896 1157 }; 897 1158 void ?{}( Cons & cons, Prod & p ) { 898 &cons.p = &p; 1159 &cons.p = &p; // reassignable reference 899 1160 cons.[status, done ] = [0, false]; 900 1161 } 901 void ^?{}( Cons & cons ) {}902 1162 void main( Cons & cons ) with( cons ) { 903 1163 // 1st resume starts here 904 1164 int money = 1, receipt; 905 1165 for ( ; ! done; ) { 906 sout | p1 | " " | p2 | endl | " $" | money | endl;1166 sout | p1 | " " | p2 | nl | " $" | money; 907 1167 status += 1; 908 1168 receipt = payment( p, money ); 909 sout | " #" | receipt | endl;1169 sout | " #" | receipt; 910 1170 money += 1; 911 1171 } 912 sout | "cons stops" | endl;1172 sout | "cons stops"; 913 1173 } 914 1174 int delivery( Cons & cons, int p1, int p2 ) { … … 921 1181 `resume( cons );` 922 1182 } 1183 923 1184 \end{cfa} 924 1185 \end{tabular} 925 \caption{Producer / consumer: resume-resume cycle, bi -directional communication}1186 \caption{Producer / consumer: resume-resume cycle, bidirectional communication} 926 1187 \label{f:ProdCons} 927 1188 \end{figure} 928 1189 929 Figure~\ref{f:ProdCons} shows a producer/consumer symmetric-coroutine performing bi-directional communication.930 Since the solution involves a full-coroutining cycle, the program main creates one coroutine in isolation, passes this coroutine to its partner, and closes the cycle at the call to @start@.931 The @start@ routine communicates both the number of elements to be produced and the consumer into the producer's coroutine structure.932 The n the @resume@ to@prod@ creates @prod@'s stack with a frame for @prod@'s coroutine main at the top, and context switches to it.933 @prod@'s coroutine main starts, creates local variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random values, calling the consumer to deliver the values, and printing the status returned from the consumer.1190 Figure~\ref{f:ProdCons} shows the ping-pong example in Figure~\ref{f:CFAPingPongGen} extended into a producer/consumer symmetric-coroutine performing bidirectional communication. 1191 This example is illustrative because both producer/consumer have two interface functions with @resume@s that suspend execution in these interface (helper) functions. 1192 The program main creates the producer coroutine, passes it to the consumer coroutine in its initialization, and closes the cycle at the call to @start@ along with the number of items to be produced. 1193 The first @resume@ of @prod@ creates @prod@'s stack with a frame for @prod@'s coroutine main at the top, and context switches to it. 1194 @prod@'s coroutine main starts, creates local-state variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random values, calling the consumer to deliver the values, and printing the status returned from the consumer. 934 1195 935 1196 The producer call to @delivery@ transfers values into the consumer's communication variables, resumes the consumer, and returns the consumer status. 936 For the first resume, @cons@'s stack is initialized, creating localvariables retained between subsequent activations of the coroutine.937 The consumer iterates until the @done@ flag is set, prints , increments status, and calls back to the producer via @payment@, and on return from @payment@, prints the receipt from the producer and increments @money@ (inflation).938 The call from the consumer to the@payment@ introduces the cycle between producer and consumer.1197 On the first resume, @cons@'s stack is created and initialized, holding local-state variables retained between subsequent activations of the coroutine. 1198 The consumer iterates until the @done@ flag is set, prints the values delivered by the producer, increments status, and calls back to the producer via @payment@, and on return from @payment@, prints the receipt from the producer and increments @money@ (inflation). 1199 The call from the consumer to @payment@ introduces the cycle between producer and consumer. 939 1200 When @payment@ is called, the consumer copies values into the producer's communication variable and a resume is executed. 940 The context switch restarts the producer at the point where it was last context switched, so it continues in @delivery@ after the resume. 941 1201 The context switch restarts the producer at the point where it last context switched, so it continues in @delivery@ after the resume. 942 1202 @delivery@ returns the status value in @prod@'s coroutine main, where the status is printed. 943 1203 The loop then repeats calling @delivery@, where each call resumes the consumer coroutine. … … 945 1205 The consumer increments and returns the receipt to the call in @cons@'s coroutine main. 946 1206 The loop then repeats calling @payment@, where each call resumes the producer coroutine. 947 948 After iterating $N$ times, the producer calls @stop@. 949 The @done@ flag is set to stop the consumer's execution and a resume is executed. 950 The context switch restarts @cons@ in @payment@ and it returns with the last receipt. 951 The consumer terminates its loops because @done@ is true, its @main@ terminates, so @cons@ transitions from a coroutine back to an object, and @prod@ reactivates after the resume in @stop@. 952 @stop@ returns and @prod@'s coroutine main terminates. 953 The program main restarts after the resume in @start@. 954 @start@ returns and the program main terminates. 955 956 957 \subsection{Coroutine Implementation} 958 959 A significant implementation challenge for coroutines (and threads, see section \ref{threads}) is adding extra fields and executing code after/before the coroutine constructor/destructor and coroutine main to create/initialize/de-initialize/destroy extra fields and the stack. 960 There are several solutions to this problem and the chosen option forced the \CFA coroutine design. 961 962 Object-oriented inheritance provides extra fields and code in a restricted context, but it requires programmers to explicitly perform the inheritance: 963 \begin{cfa} 964 struct mycoroutine $\textbf{\textsf{inherits}}$ baseCoroutine { ... } 965 \end{cfa} 966 and the programming language (and possibly its tool set, \eg debugger) may need to understand @baseCoroutine@ because of the stack. 967 Furthermore, the execution of constructs/destructors is in the wrong order for certain operations, \eg for threads; 968 \eg, if the thread is implicitly started, it must start \emph{after} all constructors, because the thread relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived. 969 970 An alternatively is composition: 971 \begin{cfa} 972 struct mycoroutine { 973 ... // declarations 1207 Figure~\ref{f:ProdConsRuntimeStacks} shows the runtime stacks of the program main, and the coroutine mains for @prod@ and @cons@ during the cycling. 1208 1209 \begin{figure} 1210 \begin{center} 1211 \input{FullProdConsStack.pstex_t} 1212 \end{center} 1213 \vspace*{-10pt} 1214 \caption{Producer / consumer runtime stacks} 1215 \label{f:ProdConsRuntimeStacks} 1216 1217 \medskip 1218 1219 \begin{center} 1220 \input{FullCoroutinePhases.pstex_t} 1221 \end{center} 1222 \vspace*{-10pt} 1223 \caption{Ping / Pong coroutine steps} 1224 \label{f:PingPongFullCoroutineSteps} 1225 \end{figure} 1226 1227 Terminating a coroutine cycle is more complex than a generator cycle, because it requires context switching to the program main's \emph{stack} to shutdown the program, whereas generators started by the program main run on its stack. 1228 Furthermore, each deallocated coroutine must guarantee all destructors are run for object allocated in the coroutine type \emph{and} allocated on the coroutine's stack at the point of suspension, which can be arbitrarily deep. 1229 When a coroutine's main ends, its stack is already unwound so any stack allocated objects with destructors have been finalized. 1230 The na\"{i}ve semantics for coroutine-cycle termination is to context switch to the last resumer, like executing a @suspend@/@return@ in a generator. 1231 However, for coroutines, the last resumer is \emph{not} implicitly below the current stack frame, as for generators, because each coroutine's stack is independent. 1232 Unfortunately, it is impossible to determine statically if a coroutine is in a cycle and unrealistic to check dynamically (graph-cycle problem). 1233 Hence, a compromise solution is necessary that works for asymmetric (acyclic) and symmetric (cyclic) coroutines. 1234 1235 Our solution is to context switch back to the first resumer (starter) once the coroutine ends. 1236 This semantics works well for the most common asymmetric and symmetric coroutine usage patterns. 1237 For asymmetric coroutines, it is common for the first resumer (starter) coroutine to be the only resumer. 1238 All previous generators converted to coroutines have this property. 1239 For symmetric coroutines, it is common for the cycle creator to persist for the lifetime of the cycle. 1240 Hence, the starter coroutine is remembered on the first resume and ending the coroutine resumes the starter. 1241 Figure~\ref{f:ProdConsRuntimeStacks} shows this semantic by the dashed lines from the end of the coroutine mains: @prod@ starts @cons@ so @cons@ resumes @prod@ at the end, and the program main starts @prod@ so @prod@ resumes the program main at the end. 1242 For other scenarios, it is always possible to devise a solution with additional programming effort, such as forcing the cycle forward (backward) to a safe point before starting termination. 1243 1244 The producer/consumer example does not illustrate the full power of the starter semantics because @cons@ always ends first. 1245 Assume generator @PingPong@ is converted to a coroutine. 1246 Figure~\ref{f:PingPongFullCoroutineSteps} shows the creation, starter, and cyclic execution steps of the coroutine version. 1247 The program main creates (declares) coroutine instances @ping@ and @pong@. 1248 Next, program main resumes @ping@, making it @ping@'s starter, and @ping@'s main resumes @pong@'s main, making it @pong@'s starter. 1249 Execution forms a cycle when @pong@ resumes @ping@, and cycles $N$ times. 1250 By adjusting $N$ for either @ping@/@pong@, it is possible to have either one finish first, instead of @pong@ always ending first. 1251 If @pong@ ends first, it resumes its starter @ping@ in its coroutine main, then @ping@ ends and resumes its starter the program main in function @start@. 1252 If @ping@ ends first, it resumes its starter the program main in function @start@. 1253 Regardless of the cycle complexity, the starter stack always leads back to the program main, but the stack can be entered at an arbitrary point. 1254 Once back at the program main, coroutines @ping@ and @pong@ are deallocated. 1255 For generators, deallocation runs the destructors for all objects in the generator type. 1256 For coroutines, deallocation deals with objects in the coroutine type and must also run the destructors for any objects pending on the coroutine's stack for any unterminated coroutine. 1257 Hence, if a coroutine's destructor detects the coroutine is not ended, it implicitly raises a cancellation exception (uncatchable exception) at the coroutine and resumes it so the cancellation exception can propagate to the root of the coroutine's stack destroying all local variable on the stack. 1258 So the \CFA semantics for the generator and coroutine, ensure both can be safely deallocated at any time, regardless of their current state, like any other aggregate object. 1259 Explicitly raising normal exceptions at another coroutine can replace flag variables, like @stop@, \eg @prod@ raises a @stop@ exception at @cons@ after it finishes generating values and resumes @cons@, which catches the @stop@ exception to terminate its loop. 1260 1261 Finally, there is an interesting effect for @suspend@ with symmetric coroutines. 1262 A coroutine must retain its last resumer to suspend back because the resumer is on a different stack. 1263 These reverse pointers allow @suspend@ to cycle \emph{backwards}, which may be useful in certain cases. 1264 However, there is an anomaly if a coroutine resumes itself, because it overwrites its last resumer with itself, losing the ability to resume the last external resumer. 1265 To prevent losing this information, a self-resume does not overwrite the last resumer. 1266 1267 1268 \subsection{Generator / Coroutine Implementation} 1269 1270 A significant implementation challenge for generators/coroutines (and threads in Section~\ref{s:threads}) is adding extra fields to the custom types and related functions, \eg inserting code after/before the coroutine constructor/destructor and @main@ to create/initialize/de-initialize/destroy any extra fields, \eg stack. 1271 There are several solutions to these problem, which follow from the object-oriented flavour of adopting custom types. 1272 1273 For object-oriented languages, inheritance is used to provide extra fields and code via explicit inheritance: 1274 \begin{cfa}[morekeywords={class,inherits}] 1275 class myCoroutine inherits baseCoroutine { ... } 1276 \end{cfa} 1277 % The problem is that the programming language and its tool chain, \eg debugger, @valgrind@, need to understand @baseCoroutine@ because it infers special property, so type @baseCoroutine@ becomes a de facto keyword and all types inheriting from it are implicitly custom types. 1278 The problem is that some special properties are not handled by existing language semantics, \eg the execution of constructors/destructors is in the wrong order to implicitly start threads because the thread must start \emph{after} all constructors as it relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived. 1279 Alternatives, such as explicitly starting threads as in Java, are repetitive and forgetting to call start is a common source of errors. 1280 An alternative is composition: 1281 \begin{cfa} 1282 struct myCoroutine { 1283 ... // declaration/communication variables 974 1284 baseCoroutine dummy; // composition, last declaration 975 1285 } 976 1286 \end{cfa} 977 which also requires an explicit declaration that must be the last oneto ensure correct initialization order.1287 which also requires an explicit declaration that must be last to ensure correct initialization order. 978 1288 However, there is nothing preventing wrong placement or multiple declarations. 979 1289 980 For coroutines as for threads, many implementations are based on routine pointers or routine objects~\cite{Butenhof97, C++14, MS:VisualC++, BoostCoroutines15}. 981 For example, Boost implements coroutines in terms of four functor object-types: 982 \begin{cfa} 983 asymmetric_coroutine<>::pull_type 984 asymmetric_coroutine<>::push_type 985 symmetric_coroutine<>::call_type 986 symmetric_coroutine<>::yield_type 987 \end{cfa} 988 Similarly, the canonical threading paradigm is often based on routine pointers, \eg @pthread@~\cite{pthreads}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}. 989 However, the generic thread-handle (identifier) is limited (few operations), unless it is wrapped in a custom type. 990 \begin{cfa} 991 void mycor( coroutine_t cid, void * arg ) { 992 int * value = (int *)arg; $\C{// type unsafe, pointer-size only}$ 993 // Coroutine body 994 } 995 int main() { 996 int input = 0, output; 997 coroutine_t cid = coroutine_create( &mycor, (void *)&input ); $\C{// type unsafe, pointer-size only}$ 998 coroutine_resume( cid, (void *)input, (void **)&output ); $\C{// type unsafe, pointer-size only}$ 999 } 1000 \end{cfa} 1001 Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda-based coroutines adds very little. 1002 1003 Note, the type @coroutine_t@ must be an abstract handle to the coroutine, because the coroutine descriptor and its stack are non-copyable. 1004 Copying the coroutine descriptor results in copies being out of date with the current state of the stack. 1005 Correspondingly, copying the stack results is copies being out of date with coroutine descriptor, and pointers in the stack being out of date to data on the stack. 1006 (There is no mechanism in C to find all stack-specific pointers and update them as part of a copy.) 1007 1008 The selected approach is to use language support by introducing a new kind of aggregate (structure): 1009 \begin{cfa} 1010 coroutine Fibonacci { 1011 int fn; // communication variables 1012 }; 1013 \end{cfa} 1014 The @coroutine@ keyword means the compiler (and tool set) can find and inject code where needed. 1015 The downside of this approach is that it makes coroutine a special case in the language. 1016 Users wanting to extend coroutines or build their own for various reasons can only do so in ways offered by the language. 1017 Furthermore, implementing coroutines without language supports also displays the power of a programming language. 1018 While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can still be constructed without using the language support. 1019 The reserved keyword eases use for the common cases. 1020 1021 Part of the mechanism to generalize coroutines is using a \CFA trait, which defines a coroutine as anything satisfying the trait @is_coroutine@, and this trait is used to restrict coroutine-manipulation routines: 1290 \CFA custom types make any special properties explicit to the language and its tool chain, \eg the language code-generator knows where to inject code 1291 % and when it is unsafe to perform certain optimizations, 1292 and IDEs using simple parsing can find and manipulate types with special properties. 1293 The downside of this approach is that it makes custom types a special case in the language. 1294 Users wanting to extend custom types or build their own can only do so in ways offered by the language. 1295 Furthermore, implementing custom types without language support may display the power of a programming language. 1296 \CFA blends the two approaches, providing custom type for idiomatic \CFA code, while extending and building new custom types is still possible, similar to Java concurrency with builtin and library. 1297 1298 Part of the mechanism to generalize custom types is the \CFA trait~\cite[\S~2.3]{Moss18}, \eg the definition for custom-type @coroutine@ is anything satisfying the trait @is_coroutine@, and this trait both enforces and restricts the coroutine-interface functions. 1022 1299 \begin{cfa} 1023 1300 trait is_coroutine( `dtype` T ) { … … 1025 1302 coroutine_desc * get_coroutine( T & ); 1026 1303 }; 1027 forall( `dtype` T | is_coroutine(T) ) void suspend( T & ); 1028 forall( `dtype` T | is_coroutine(T) ) void resume( T & ); 1029 \end{cfa} 1030 The @dtype@ property of the trait ensures the coroutine descriptor is non-copyable, so all coroutines must be passed by reference (pointer). 1031 The routine definitions ensures there is a statically-typed @main@ routine that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the currently executing coroutine handle. 1032 The @main@ routine has no return value or additional parameters because the coroutine type allows an arbitrary number of interface routines with corresponding arbitrary typed input/output values versus fixed ones. 1033 The generic routines @suspend@ and @resume@ can be redefined, but any object passed to them is a coroutine since it must satisfy the @is_coroutine@ trait to compile. 1034 The advantage of this approach is that users can easily create different types of coroutines, for example, changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ routine, and possibly redefining @suspend@ and @resume@. 1035 The \CFA keyword @coroutine@ implicitly implements the getter and forward declarations required for implementing the coroutine main: 1304 forall( `dtype` T | is_coroutine(T) ) void $suspend$( T & ), resume( T & ); 1305 \end{cfa} 1306 Note, copying generators/coroutines/threads is not meaningful. 1307 For example, both the resumer and suspender descriptors can have bidirectional pointers; 1308 copying these coroutines does not update the internal pointers so behaviour of both copies would be difficult to understand. 1309 Furthermore, two coroutines cannot logically execute on the same stack. 1310 A deep coroutine copy, which copies the stack, is also meaningless in an unmanaged language (no garbage collection), like C, because the stack may contain pointers to object within it that require updating for the copy. 1311 The \CFA @dtype@ property provides no \emph{implicit} copying operations and the @is_coroutine@ trait provides no \emph{explicit} copying operations, so all coroutines must be passed by reference (pointer). 1312 The function definitions ensure there is a statically typed @main@ function that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the coroutine descriptor from its handle. 1313 The @main@ function has no return value or additional parameters because the coroutine type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values versus fixed ones. 1314 The advantage of this approach is that users can easily create different types of coroutines, \eg changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ function, and possibly redefining \textsf{suspend} and @resume@. 1315 1316 The \CFA custom-type @coroutine@ implicitly implements the getter and forward declarations for the coroutine main. 1036 1317 \begin{cquote} 1037 1318 \begin{tabular}{@{}ccc@{}} … … 1069 1350 \end{tabular} 1070 1351 \end{cquote} 1071 The combination of these two approaches allows an easy and concise specification to coroutining (and concurrency) for normal users, while more advanced users have tighter control on memory layout and initialization. 1072 1073 1074 \subsection{Thread Interface} 1075 \label{threads} 1076 1077 Both user and kernel threads are supported, where user threads provide concurrency and kernel threads provide parallelism. 1078 Like coroutines and for the same design reasons, the selected approach for user threads is to use language support by introducing a new kind of aggregate (structure) and a \CFA trait: 1352 The combination of custom types and fundamental @trait@ description of these types allows a concise specification for programmers and tools, while more advanced programmers can have tighter control over memory layout and initialization. 1353 1354 Figure~\ref{f:CoroutineMemoryLayout} shows different memory-layout options for a coroutine (where a task is similar). 1355 The coroutine handle is the @coroutine@ instance containing programmer specified type global/communication variables across interface functions. 1356 The coroutine descriptor contains all implicit declarations needed by the runtime, \eg @suspend@/@resume@, and can be part of the coroutine handle or separate. 1357 The coroutine stack can appear in a number of locations and be fixed or variable sized. 1358 Hence, the coroutine's stack could be a VLS\footnote{ 1359 We are examining variable-sized structures (VLS), where fields can be variable-sized structures or arrays. 1360 Once allocated, a VLS is fixed sized.} 1361 on the allocating stack, provided the allocating stack is large enough. 1362 For a VLS stack allocation/deallocation is an inexpensive adjustment of the stack pointer, modulo any stack constructor costs (\eg initial frame setup). 1363 For heap stack allocation, allocation/deallocation is an expensive heap allocation (where the heap can be a shared resource), modulo any stack constructor costs. 1364 With heap stack allocation, it is also possible to use a split (segmented) stack calling convention, available with gcc and clang, so the stack is variable sized. 1365 Currently, \CFA supports stack/heap allocated descriptors but only fixed-sized heap allocated stacks. 1366 In \CFA debug-mode, the fixed-sized stack is terminated with a write-only page, which catches most stack overflows. 1367 Experience teaching concurrency with \uC~\cite{CS343} shows fixed-sized stacks are rarely an issue for students. 1368 Split-stack allocation is under development but requires recompilation of legacy code, which may be impossible. 1369 1370 \begin{figure} 1371 \centering 1372 \input{corlayout.pstex_t} 1373 \caption{Coroutine memory layout} 1374 \label{f:CoroutineMemoryLayout} 1375 \end{figure} 1376 1377 1378 \section{Concurrency} 1379 \label{s:Concurrency} 1380 1381 Concurrency is nondeterministic scheduling of independent sequential execution paths (threads), where each thread has its own stack. 1382 A single thread with multiple call stacks, \newterm{coroutining}~\cite{Conway63,Marlin80}, does \emph{not} imply concurrency~\cite[\S~2]{Buhr05a}. 1383 In coroutining, coroutines self-schedule the thread across stacks so execution is deterministic. 1384 (It is \emph{impossible} to generate a concurrency error when coroutining.) 1385 However, coroutines are a stepping stone towards concurrency. 1386 1387 The transition to concurrency, even for a single thread with multiple stacks, occurs when coroutines context switch to a \newterm{scheduling coroutine}, introducing non-determinism from the coroutine perspective~\cite[\S~3,]{Buhr05a}. 1388 Therefore, a minimal concurrency system requires coroutines \emph{in conjunction with a nondeterministic scheduler}. 1389 The resulting execution system now follows a cooperative threading model~\cite{Adya02,libdill}, called \newterm{non-preemptive scheduling}. 1390 Adding \newterm{preemption} introduces non-cooperative scheduling, where context switching occurs randomly between any two instructions often based on a timer interrupt, called \newterm{preemptive scheduling}. 1391 While a scheduler introduces uncertain execution among explicit context switches, preemption introduces uncertainty by introducing implicit context switches. 1392 Uncertainty gives the illusion of parallelism on a single processor and provides a mechanism to access and increase performance on multiple processors. 1393 The reason is that the scheduler/runtime have complete knowledge about resources and how to best utilized them. 1394 However, the introduction of unrestricted nondeterminism results in the need for \newterm{mutual exclusion} and \newterm{synchronization}, which restrict nondeterminism for correctness; 1395 otherwise, it is impossible to write meaningful concurrent programs. 1396 Optimal concurrent performance is often obtained by having as much nondeterminism as mutual exclusion and synchronization correctness allow. 1397 1398 A scheduler can either be a stackless or stackful. 1399 For stackless, the scheduler performs scheduling on the stack of the current coroutine and switches directly to the next coroutine, so there is one context switch. 1400 For stackful, the current coroutine switches to the scheduler, which performs scheduling, and it then switches to the next coroutine, so there are two context switches. 1401 The \CFA runtime uses a stackful scheduler for uniformity and security. 1402 1403 1404 \subsection{Thread} 1405 \label{s:threads} 1406 1407 Threading needs the ability to start a thread and wait for its completion. 1408 A common API for this ability is @fork@ and @join@. 1409 \begin{cquote} 1410 \begin{tabular}{@{}lll@{}} 1411 \multicolumn{1}{c}{\textbf{Java}} & \multicolumn{1}{c}{\textbf{\Celeven}} & \multicolumn{1}{c}{\textbf{pthreads}} \\ 1412 \begin{cfa} 1413 class MyTask extends Thread {...} 1414 mytask t = new MyTask(...); 1415 `t.start();` // start 1416 // concurrency 1417 `t.join();` // wait 1418 \end{cfa} 1419 & 1420 \begin{cfa} 1421 class MyTask { ... } // functor 1422 MyTask mytask; 1423 `thread t( mytask, ... );` // start 1424 // concurrency 1425 `t.join();` // wait 1426 \end{cfa} 1427 & 1428 \begin{cfa} 1429 void * rtn( void * arg ) {...} 1430 pthread_t t; int i = 3; 1431 `pthread_create( &t, rtn, (void *)i );` // start 1432 // concurrency 1433 `pthread_join( t, NULL );` // wait 1434 \end{cfa} 1435 \end{tabular} 1436 \end{cquote} 1437 \CFA has a simpler approach using a custom @thread@ type and leveraging declaration semantics (allocation/deallocation), where threads implicitly @fork@ after construction and @join@ before destruction. 1438 \begin{cfa} 1439 thread MyTask {}; 1440 void main( MyTask & this ) { ... } 1441 int main() { 1442 MyTask team`[10]`; $\C[2.5in]{// allocate stack-based threads, implicit start after construction}$ 1443 // concurrency 1444 } $\C{// deallocate stack-based threads, implicit joins before destruction}$ 1445 \end{cfa} 1446 This semantic ensures a thread is started and stopped exactly once, eliminating some programming error, and scales to multiple threads for basic (termination) synchronization. 1447 For block allocation to arbitrary depth, including recursion, threads are created/destroyed in a lattice structure (tree with top and bottom). 1448 Arbitrary topologies are possible using dynamic allocation, allowing threads to outlive their declaration scope, identical to normal dynamic allocation. 1449 \begin{cfa} 1450 MyTask * factory( int N ) { ... return `anew( N )`; } $\C{// allocate heap-based threads, implicit start after construction}$ 1451 int main() { 1452 MyTask * team = factory( 10 ); 1453 // concurrency 1454 `delete( team );` $\C{// deallocate heap-based threads, implicit joins before destruction}\CRT$ 1455 } 1456 \end{cfa} 1457 1458 Figure~\ref{s:ConcurrentMatrixSummation} shows concurrently adding the rows of a matrix and then totalling the subtotals sequentially, after all the row threads have terminated. 1459 The program uses heap-based threads because each thread needs different constructor values. 1460 (Python provides a simple iteration mechanism to initialize array elements to different values allowing stack allocation.) 1461 The allocation/deallocation pattern appears unusual because allocated objects are immediately deallocated without any intervening code. 1462 However, for threads, the deletion provides implicit synchronization, which is the intervening code. 1463 % While the subtotals are added in linear order rather than completion order, which slightly inhibits concurrency, the computation is restricted by the critical-path thread (\ie the thread that takes the longest), and so any inhibited concurrency is very small as totalling the subtotals is trivial. 1464 1465 \begin{figure} 1466 \begin{cfa} 1467 `thread` Adder { int * row, cols, & subtotal; } $\C{// communication variables}$ 1468 void ?{}( Adder & adder, int row[], int cols, int & subtotal ) { 1469 adder.[ row, cols, &subtotal ] = [ row, cols, &subtotal ]; 1470 } 1471 void main( Adder & adder ) with( adder ) { 1472 subtotal = 0; 1473 for ( c; cols ) { subtotal += row[c]; } 1474 } 1475 int main() { 1476 const int rows = 10, cols = 1000; 1477 int matrix[rows][cols], subtotals[rows], total = 0; 1478 // read matrix 1479 Adder * adders[rows]; 1480 for ( r; rows; ) { $\C{// start threads to sum rows}$ 1481 adders[r] = `new( matrix[r], cols, &subtotals[r] );` 1482 } 1483 for ( r; rows ) { $\C{// wait for threads to finish}$ 1484 `delete( adders[r] );` $\C{// termination join}$ 1485 total += subtotals[r]; $\C{// total subtotal}$ 1486 } 1487 sout | total; 1488 } 1489 \end{cfa} 1490 \caption{Concurrent matrix summation} 1491 \label{s:ConcurrentMatrixSummation} 1492 \end{figure} 1493 1494 1495 \subsection{Thread Implementation} 1496 1497 Threads in \CFA are user level run by runtime kernel threads (see Section~\ref{s:CFARuntimeStructure}), where user threads provide concurrency and kernel threads provide parallelism. 1498 Like coroutines, and for the same design reasons, \CFA provides a custom @thread@ type and a @trait@ to enforce and restrict the task-interface functions. 1079 1499 \begin{cquote} 1080 1500 \begin{tabular}{@{}c@{\hspace{3\parindentlnth}}c@{}} 1081 1501 \begin{cfa} 1082 1502 thread myThread { 1083 //communication variables1503 ... // declaration/communication variables 1084 1504 }; 1085 1505 … … 1089 1509 \begin{cfa} 1090 1510 trait is_thread( `dtype` T ) { 1091 void main( T & );1092 thread_desc * get_thread( T & );1093 void ^?{}( T & `mutex` );1511 void main( T & ); 1512 thread_desc * get_thread( T & ); 1513 void ^?{}( T & `mutex` ); 1094 1514 }; 1095 1515 \end{cfa} 1096 1516 \end{tabular} 1097 1517 \end{cquote} 1098 (The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitors}.) 1099 Like a coroutine, the statically-typed @main@ routine is the starting point (first stack frame) of a user thread. 1100 The difference is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates an instance of @main@; 1101 whereas, a user thread receives its own thread from the runtime system, which starts in @main@ as some point after the thread constructor is run.\footnote{ 1102 The \lstinline@main@ routine is already a special routine in C (where the program begins), so it is a natural extension of the semantics to use overloading to declare mains for different coroutines/threads (the normal main being the main of the initial thread).} 1103 No return value or additional parameters are necessary for this routine because the task type allows an arbitrary number of interface routines with corresponding arbitrary typed input/output values. 1104 1105 \begin{comment} % put in appendix with coroutine version ??? 1106 As such the @main@ routine of a thread can be defined as 1107 \begin{cfa} 1108 thread foo {}; 1109 1110 void main(foo & this) { 1111 sout | "Hello World!" | endl; 1112 } 1113 \end{cfa} 1114 1115 In this example, threads of type @foo@ start execution in the @void main(foo &)@ routine, which prints @"Hello World!".@ While this paper encourages this approach to enforce strongly typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity. 1116 With the static semantics it is trivial to write a thread type that takes a routine pointer as a parameter and executes it on its stack asynchronously. 1117 \begin{cfa} 1118 typedef void (*voidRtn)(int); 1119 1120 thread RtnRunner { 1121 voidRtn func; 1122 int arg; 1123 }; 1124 1125 void ?{}(RtnRunner & this, voidRtn inRtn, int arg) { 1126 this.func = inRtn; 1127 this.arg = arg; 1128 } 1129 1130 void main(RtnRunner & this) { 1131 // thread starts here and runs the routine 1132 this.func( this.arg ); 1133 } 1134 1135 void hello(/*unused*/ int) { 1136 sout | "Hello World!" | endl; 1137 } 1138 1139 int main() { 1140 RtnRunner f = {hello, 42}; 1141 return 0? 1142 } 1143 \end{cfa} 1144 A consequence of the strongly typed approach to main is that memory layout of parameters and return values to/from a thread are now explicitly specified in the \textbf{api}. 1145 \end{comment} 1146 1147 For user threads to be useful, it must be possible to start and stop the underlying thread, and wait for it to complete execution. 1148 While using an API such as @fork@ and @join@ is relatively common, such an interface is awkward and unnecessary. 1149 A simple approach is to use allocation/deallocation principles, and have threads implicitly @fork@ after construction and @join@ before destruction. 1150 \begin{cfa} 1151 thread World {}; 1152 void main( World & this ) { 1153 sout | "World!" | endl; 1154 } 1155 int main() { 1156 World w`[10]`; $\C{// implicit forks after creation}$ 1157 sout | "Hello " | endl; $\C{// "Hello " and 10 "World!" printed concurrently}$ 1158 } $\C{// implicit joins before destruction}$ 1159 \end{cfa} 1160 This semantics ensures a thread is started and stopped exactly once, eliminating some programming error, and scales to multiple threads for basic (termination) synchronization. 1161 This tree-structure (lattice) create/delete from C block-structure is generalized by using dynamic allocation, so threads can outlive the scope in which they are created, much like dynamically allocating memory lets objects outlive the scope in which they are created. 1162 \begin{cfa} 1163 int main() { 1164 MyThread * heapLived; 1165 { 1166 MyThread blockLived; $\C{// fork block-based thread}$ 1167 heapLived = `new`( MyThread ); $\C{// fork heap-based thread}$ 1168 ... 1169 } $\C{// join block-based thread}$ 1170 ... 1171 `delete`( heapLived ); $\C{// join heap-based thread}$ 1172 } 1173 \end{cfa} 1174 The heap-based approach allows arbitrary thread-creation topologies, with respect to fork/join-style concurrency. 1175 1176 Figure~\ref{s:ConcurrentMatrixSummation} shows concurrently adding the rows of a matrix and then totalling the subtotals sequential, after all the row threads have terminated. 1177 The program uses heap-based threads because each thread needs different constructor values. 1178 (Python provides a simple iteration mechanism to initialize array elements to different values allowing stack allocation.) 1179 The allocation/deallocation pattern appears unusual because allocated objects are immediately deleted without any intervening code. 1180 However, for threads, the deletion provides implicit synchronization, which is the intervening code. 1181 While the subtotals are added in linear order rather than completion order, which slight inhibits concurrency, the computation is restricted by the critical-path thread (\ie the thread that takes the longest), and so any inhibited concurrency is very small as totalling the subtotals is trivial. 1182 1183 \begin{figure} 1184 \begin{cfa} 1185 thread Adder { 1186 int * row, cols, & subtotal; $\C{// communication}$ 1187 }; 1188 void ?{}( Adder & adder, int row[], int cols, int & subtotal ) { 1189 adder.[ row, cols, &subtotal ] = [ row, cols, &subtotal ]; 1190 } 1191 void main( Adder & adder ) with( adder ) { 1192 subtotal = 0; 1193 for ( int c = 0; c < cols; c += 1 ) { 1194 subtotal += row[c]; 1195 } 1196 } 1197 int main() { 1198 const int rows = 10, cols = 1000; 1199 int matrix[rows][cols], subtotals[rows], total = 0; 1200 // read matrix 1201 Adder * adders[rows]; 1202 for ( int r = 0; r < rows; r += 1 ) { $\C{// start threads to sum rows}$ 1203 adders[r] = new( matrix[r], cols, &subtotals[r] ); 1204 } 1205 for ( int r = 0; r < rows; r += 1 ) { $\C{// wait for threads to finish}$ 1206 delete( adders[r] ); $\C{// termination join}$ 1207 total += subtotals[r]; $\C{// total subtotal}$ 1208 } 1209 sout | total | endl; 1210 } 1211 \end{cfa} 1212 \caption{Concurrent Matrix Summation} 1213 \label{s:ConcurrentMatrixSummation} 1214 \end{figure} 1518 Like coroutines, the @dtype@ property prevents \emph{implicit} copy operations and the @is_thread@ trait provides no \emph{explicit} copy operations, so threads must be passed by reference (pointer). 1519 Similarly, the function definitions ensure there is a statically typed @main@ function that is the thread starting point (first stack frame), a mechanism to get (read) the thread descriptor from its handle, and a special destructor to prevent deallocation while the thread is executing. 1520 (The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitor}.) 1521 The difference between the coroutine and thread is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates the coroutine's stack and starts running the coroutine main on the stack; 1522 whereas, a thread is scheduling for execution in @main@ immediately after its constructor is run. 1523 No return value or additional parameters are necessary for this function because the @thread@ type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values. 1215 1524 1216 1525 1217 1526 \section{Mutual Exclusion / Synchronization} 1218 1219 Uncontrolled non-deterministic execution is meaningless. 1220 To reestablish meaningful execution requires mechanisms to reintroduce determinism (\ie restrict non-determinism), called mutual exclusion and synchronization, where mutual exclusion is an access-control mechanism on data shared by threads, and synchronization is a timing relationship among threads~\cite[\S~4]{Buhr05a}.1221 Since many deterministic challenges appear with the use of mutable shared state, some languages/libraries disallow it, \eg Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka~\cite{Akka} (Scala).1222 In these paradigms, interaction among concurrent objects is performed by stateless message-passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (\eg channels~\cite{CSP,Go}).1223 However, in call/return-based languages, these approaches force a clear distinction (\ie introduce a new programming paradigm) between regular and concurrent computation (\ie routine call versus message passing).1224 Hence, a programmer must learn and manipulate two sets of design patterns.1527 \label{s:MutualExclusionSynchronization} 1528 1529 Unrestricted nondeterminism is meaningless as there is no way to know when the result is completed without synchronization. 1530 To produce meaningful execution requires clawing back some determinism using mutual exclusion and synchronization, where mutual exclusion provides access control for threads using shared data, and synchronization is a timing relationship among threads~\cite[\S~4]{Buhr05a}. 1531 Some concurrent systems eliminate mutable shared-state by switching to stateless communication like message passing~\cite{Thoth,Harmony,V-Kernel,MPI} (Erlang, MPI), channels~\cite{CSP} (CSP,Go), actors~\cite{Akka} (Akka, Scala), or functional techniques (Haskell). 1532 However, these approaches introduce a new communication mechanism for concurrency different from the standard communication using function call/return. 1533 Hence, a programmer must learn and manipulate two sets of design/programming patterns. 1225 1534 While this distinction can be hidden away in library code, effective use of the library still has to take both paradigms into account. 1226 In contrast, approaches based on stateful l models more closely resemble the standard call/return programming-model, resulting in a single programming paradigm.1227 1228 At the lowest level, concurrent control is implemented by atomic operations, upon which different kinds of lock s mechanismare constructed, \eg semaphores~\cite{Dijkstra68b}, barriers, and path expressions~\cite{Campbell74}.1535 In contrast, approaches based on stateful models more closely resemble the standard call/return programming model, resulting in a single programming paradigm. 1536 1537 At the lowest level, concurrent control is implemented by atomic operations, upon which different kinds of locking mechanisms are constructed, \eg semaphores~\cite{Dijkstra68b}, barriers, and path expressions~\cite{Campbell74}. 1229 1538 However, for productivity it is always desirable to use the highest-level construct that provides the necessary efficiency~\cite{Hochstein05}. 1230 1539 A newer approach for restricting non-determinism is transactional memory~\cite{Herlihy93}. 1231 While this approach is pursued in hardware~\cite{Nakaike15} and system languages, like \CC~\cite{Cpp-Transactions}, the performance and feature set is still too restrictive to be the main concurrency paradigm for system languages, which is why it was rejected as the core paradigm for concurrency in \CFA.1540 While this approach is pursued in hardware~\cite{Nakaike15} and system languages, like \CC~\cite{Cpp-Transactions}, the performance and feature set is still too restrictive to be the main concurrency paradigm for system languages, which is why it is rejected as the core paradigm for concurrency in \CFA. 1232 1541 1233 1542 One of the most natural, elegant, and efficient mechanisms for mutual exclusion and synchronization for shared-memory systems is the \emph{monitor}. 1234 First proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}, many concurrent programming -languages provide monitors as an explicit language construct: \eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}.1543 First proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}, many concurrent programming languages provide monitors as an explicit language construct: \eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}. 1235 1544 In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as mutex locks or semaphores to simulate monitors. 1236 For these reasons, \CFA selected monitors as the core high-level concurrency -construct, upon which higher-level approaches can be easily constructed.1545 For these reasons, \CFA selected monitors as the core high-level concurrency construct, upon which higher-level approaches can be easily constructed. 1237 1546 1238 1547 1239 1548 \subsection{Mutual Exclusion} 1240 1549 1241 A group of instructions manipulating a specific instance of shared data that must be performed atomically is called an (individual) \newterm{critical-section}~\cite{Dijkstra65}. 1242 The generalization is called a \newterm{group critical-section}~\cite{Joung00}, where multiple tasks with the same session may use the resource simultaneously, but different sessions may not use the resource simultaneously. 1243 The readers/writer problem~\cite{Courtois71} is an instance of a group critical-section, where readers have the same session and all writers have a unique session. 1244 \newterm{Mutual exclusion} enforces that the correct kind and number of threads are using a critical section. 1550 A group of instructions manipulating a specific instance of shared data that must be performed atomically is called a \newterm{critical section}~\cite{Dijkstra65}, which is enforced by \newterm{simple mutual-exclusion}. 1551 The generalization is called a \newterm{group critical-section}~\cite{Joung00}, where multiple tasks with the same session use the resource simultaneously and different sessions are segregated, which is enforced by \newterm{complex mutual-exclusion} providing the correct kind and number of threads using a group critical-section. 1552 The readers/writer problem~\cite{Courtois71} is an instance of a group critical-section, where readers share a session but writers have a unique session. 1245 1553 1246 1554 However, many solutions exist for mutual exclusion, which vary in terms of performance, flexibility and ease of use. 1247 1555 Methods range from low-level locks, which are fast and flexible but require significant attention for correctness, to higher-level concurrency techniques, which sacrifice some performance to improve ease of use. 1248 Ease of use comes by either guaranteeing some problems cannot occur (\eg deadlock free), or by offering a more explicit coupling between shared data and critical section.1249 For example, the \CC @std::atomic<T>@ offers an easy way to express mutual-exclusion on a restricted set of operations (\eg reading/writing)for numerical types.1556 Ease of use comes by either guaranteeing some problems cannot occur, \eg deadlock free, or by offering a more explicit coupling between shared data and critical section. 1557 For example, the \CC @std::atomic<T>@ offers an easy way to express mutual-exclusion on a restricted set of operations, \eg reading/writing, for numerical types. 1250 1558 However, a significant challenge with locks is composability because it takes careful organization for multiple locks to be used while preventing deadlock. 1251 1559 Easing composability is another feature higher-level mutual-exclusion mechanisms can offer. … … 1256 1564 Synchronization enforces relative ordering of execution, and synchronization tools provide numerous mechanisms to establish these timing relationships. 1257 1565 Low-level synchronization primitives offer good performance and flexibility at the cost of ease of use; 1258 higher-level mechanisms often simplify usage by adding better coupling between synchronization and data (\eg message passing), or offering a simpler solution to otherwise involved challenges, \eg barrier lock.1259 Often synchronization is used to order access to a critical section, \eg ensuring a reader thread is the next kind of thread to enter a critical section.1260 If a writer thread is scheduled for next access, but another reader thread acquires the critical section first, that reader has \newterm{barged}.1566 higher-level mechanisms often simplify usage by adding better coupling between synchronization and data, \eg receive-specific versus receive-any thread in message passing or offering specialized solutions, \eg barrier lock. 1567 Often synchronization is used to order access to a critical section, \eg ensuring a waiting writer thread enters the critical section before a calling reader thread. 1568 If the calling reader is scheduled before the waiting writer, the reader has barged. 1261 1569 Barging can result in staleness/freshness problems, where a reader barges ahead of a writer and reads temporally stale data, or a writer barges ahead of another writer overwriting data with a fresh value preventing the previous value from ever being read (lost computation). 1262 Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs. 1263 This challenge is often split into two different approaches: barging avoidance and barging prevention. 1264 Algorithms that allow a barger, but divert it until later using current synchronization state (flags), are avoiding the barger; 1265 algorithms that preclude a barger from entering during synchronization in the critical section prevent barging completely. 1266 Techniques like baton-pass locks~\cite{Andrews89} between threads instead of unconditionally releasing locks is an example of barging prevention. 1267 1268 1269 \section{Monitors} 1270 \label{s:Monitors} 1271 1272 A \textbf{monitor} is a set of routines that ensure mutual exclusion when accessing shared state. 1273 More precisely, a monitor is a programming technique that binds mutual exclusion to routine scope, as opposed to locks, where mutual-exclusion is defined by acquire/release calls, independent of lexical context (analogous to block and heap storage allocation). 1274 The strong association with the call/return paradigm eases programmability, readability and maintainability, at a slight cost in flexibility and efficiency. 1275 1276 Note, like coroutines/threads, both locks and monitors require an abstract handle to reference them, because at their core, both mechanisms are manipulating non-copyable shared state. 1277 Copying a lock is insecure because it is possible to copy an open lock and then use the open copy when the original lock is closed to simultaneously access the shared data. 1278 Copying a monitor is secure because both the lock and shared data are copies, but copying the shared data is meaningless because it no longer represents a unique entity. 1279 As for coroutines/tasks, a non-copyable (@dtype@) trait is used to capture this requirement, so all locks/monitors must be passed by reference (pointer). 1570 Preventing or detecting barging is an involved challenge with low-level locks, which is made easier through higher-level constructs. 1571 This challenge is often split into two different approaches: barging avoidance and prevention. 1572 Algorithms that unconditionally releasing a lock for competing threads to acquire use barging avoidance during synchronization to force a barging thread to wait; 1573 algorithms that conditionally hold locks during synchronization, \eg baton-passing~\cite{Andrews89}, prevent barging completely. 1574 1575 1576 \section{Monitor} 1577 \label{s:Monitor} 1578 1579 A \textbf{monitor} is a set of functions that ensure mutual exclusion when accessing shared state. 1580 More precisely, a monitor is a programming technique that implicitly binds mutual exclusion to static function scope, as opposed to locks, where mutual-exclusion is defined by acquire/release calls, independent of lexical context (analogous to block and heap storage allocation). 1581 Restricting acquire/release points eases programming, comprehension, and maintenance, at a slight cost in flexibility and efficiency. 1582 \CFA uses a custom @monitor@ type and leverages declaration semantics (deallocation) to protect active or waiting threads in a monitor. 1583 1584 The following is a \CFA monitor implementation of an atomic counter. 1585 \begin{cfa}[morekeywords=nomutex] 1586 `monitor` Aint { int cnt; }; $\C[4.25in]{// atomic integer counter}$ 1587 int ++?( Aint & `mutex`$\(_{opt}\)$ this ) with( this ) { return ++cnt; } $\C{// increment}$ 1588 int ?=?( Aint & `mutex`$\(_{opt}\)$ lhs, int rhs ) with( lhs ) { cnt = rhs; } $\C{// conversions with int}\CRT$ 1589 int ?=?( int & lhs, Aint & `mutex`$\(_{opt}\)$ rhs ) with( rhs ) { lhs = cnt; } 1590 \end{cfa} 1591 % The @Aint@ constructor, @?{}@, uses the \lstinline[morekeywords=nomutex]@nomutex@ qualifier indicating mutual exclusion is unnecessary during construction because an object is inaccessible (private) until after it is initialized. 1592 % (While a constructor may publish its address into a global variable, doing so generates a race-condition.) 1593 The prefix increment operation, @++?@, is normally @mutex@, indicating mutual exclusion is necessary during function execution, to protect the incrementing from race conditions, unless there is an atomic increment instruction for the implementation type. 1594 The assignment operators provide bidirectional conversion between an atomic and normal integer without accessing field @cnt@; 1595 these operations only need @mutex@, if reading/writing the implementation type is not atomic. 1596 The atomic counter is used without any explicit mutual-exclusion and provides thread-safe semantics, which is similar to the \CC template @std::atomic@. 1597 \begin{cfa} 1598 int i = 0, j = 0, k = 5; 1599 Aint x = { 0 }, y = { 0 }, z = { 5 }; $\C{// no mutex required}$ 1600 ++x; ++y; ++z; $\C{// safe increment by multiple threads}$ 1601 x = 2; y = i; z = k; $\C{// conversions}$ 1602 i = x; j = y; k = z; 1603 \end{cfa} 1604 1605 \CFA monitors have \newterm{multi-acquire} semantics so the thread in the monitor may acquire it multiple times without deadlock, allowing recursion and calling other interface functions. 1606 \begin{cfa} 1607 monitor M { ... } m; 1608 void foo( M & mutex m ) { ... } $\C{// acquire mutual exclusion}$ 1609 void bar( M & mutex m ) { $\C{// acquire mutual exclusion}$ 1610 ... `bar( m );` ... `foo( m );` ... $\C{// reacquire mutual exclusion}$ 1611 } 1612 \end{cfa} 1613 \CFA monitors also ensure the monitor lock is released regardless of how an acquiring function ends (normal or exceptional), and returning a shared variable is safe via copying before the lock is released. 1614 Similar safety is offered by \emph{explicit} mechanisms like \CC RAII; 1615 monitor \emph{implicit} safety ensures no programmer usage errors. 1616 Furthermore, RAII mechanisms cannot handle complex synchronization within a monitor, where the monitor lock may not be released on function exit because it is passed to an unblocking thread; 1617 RAII is purely a mutual-exclusion mechanism (see Section~\ref{s:Scheduling}). 1618 1619 1620 \subsection{Monitor Implementation} 1621 1622 For the same design reasons, \CFA provides a custom @monitor@ type and a @trait@ to enforce and restrict the monitor-interface functions. 1623 \begin{cquote} 1624 \begin{tabular}{@{}c@{\hspace{3\parindentlnth}}c@{}} 1625 \begin{cfa} 1626 monitor M { 1627 ... // shared data 1628 }; 1629 1630 \end{cfa} 1631 & 1280 1632 \begin{cfa} 1281 1633 trait is_monitor( `dtype` T ) { … … 1284 1636 }; 1285 1637 \end{cfa} 1638 \end{tabular} 1639 \end{cquote} 1640 The @dtype@ property prevents \emph{implicit} copy operations and the @is_monitor@ trait provides no \emph{explicit} copy operations, so monitors must be passed by reference (pointer). 1641 % Copying a lock is insecure because it is possible to copy an open lock and then use the open copy when the original lock is closed to simultaneously access the shared data. 1642 % Copying a monitor is secure because both the lock and shared data are copies, but copying the shared data is meaningless because it no longer represents a unique entity. 1643 Similarly, the function definitions ensures there is a mechanism to get (read) the monitor descriptor from its handle, and a special destructor to prevent deallocation if a thread using the shared data. 1644 The custom monitor type also inserts any locks needed to implement the mutual exclusion semantics. 1286 1645 1287 1646 … … 1289 1648 \label{s:MutexAcquisition} 1290 1649 1291 While correctness implicitly implies a monitor's mutual exclusion is acquired and released, there are implementation options aboutwhen and where the locking/unlocking occurs.1650 While the monitor lock provides mutual exclusion for shared data, there are implementation options for when and where the locking/unlocking occurs. 1292 1651 (Much of this discussion also applies to basic locks.) 1293 For example, a monitor may need to be passed through multiple helper routines before it becomes necessary to acquire the monitor mutual-exclusion. 1294 \begin{cfa}[morekeywords=nomutex] 1295 monitor Aint { int cnt; }; $\C{// atomic integer counter}$ 1296 void ?{}( Aint & `nomutex` this ) with( this ) { cnt = 0; } $\C{// constructor}$ 1297 int ?=?( Aint & `mutex`$\(_{opt}\)$ lhs, int rhs ) with( lhs ) { cnt = rhs; } $\C{// conversions}$ 1298 void ?{}( int & this, Aint & `mutex`$\(_{opt}\)$ v ) { this = v.cnt; } 1299 int ?=?( int & lhs, Aint & `mutex`$\(_{opt}\)$ rhs ) with( rhs ) { lhs = cnt; } 1300 int ++?( Aint & `mutex`$\(_{opt}\)$ this ) with( this ) { return ++cnt; } $\C{// increment}$ 1301 \end{cfa} 1302 The @Aint@ constructor, @?{}@, uses the \lstinline[morekeywords=nomutex]@nomutex@ qualifier indicating mutual exclusion is unnecessary during construction because an object is inaccessible (private) until after it is initialized. 1303 (While a constructor may publish its address into a global variable, doing so generates a race-condition.) 1304 The conversion operators for initializing and assigning with a normal integer only need @mutex@, if reading/writing the implementation type is not atomic. 1305 Finally, the prefix increment operato, @++?@, is normally @mutex@ to protect the incrementing from race conditions, unless there is an atomic increment instruction for the implementation type. 1306 1307 The atomic counter is used without any explicit mutual-exclusion and provides thread-safe semantics, which is similar to the \CC template @std::atomic@. 1308 \begin{cfa} 1309 Aint x, y, z; 1310 ++x; ++y; ++z; $\C{// safe increment by multiple threads}$ 1311 x = 2; y = 2; z = 2; $\C{// conversions}$ 1312 int i = x, j = y, k = z; 1313 i = x; j = y; k = z; 1314 \end{cfa} 1315 1316 For maximum usability, monitors have \newterm{multi-acquire} semantics allowing a thread to acquire it multiple times without deadlock. 1317 For example, atomically printing the contents of a binary tree: 1318 \begin{cfa} 1319 monitor Tree { 1320 Tree * left, right; 1321 // value 1322 }; 1323 void print( Tree & mutex tree ) { $\C{// prefix traversal}$ 1324 // write value 1325 print( tree->left ); $\C{// multiply acquire monitor lock on each recursion}$ 1326 print( tree->right ); 1327 } 1328 \end{cfa} 1329 1330 Mandatory monitor qualifiers have the benefit of being self-documented, but requiring both @mutex@ and \lstinline[morekeywords=nomutex]@nomutex@ for all monitor parameter is redundant. 1331 Instead, one of qualifier semantics can be the default, and the other required. 1332 For example, assume the safe @mutex@ option for a monitor parameter because assuming \lstinline[morekeywords=nomutex]@nomutex@ may cause subtle errors. 1333 On the other hand, assuming \lstinline[morekeywords=nomutex]@nomutex@ is the \emph{normal} parameter behaviour, stating explicitly ``this parameter is not special''. 1652 For example, a monitor may be passed through multiple helper functions before it is necessary to acquire the monitor's mutual exclusion. 1653 1654 The benefit of mandatory monitor qualifiers is self-documentation, but requiring both @mutex@ and \lstinline[morekeywords=nomutex]@nomutex@ for all monitor parameters is redundant. 1655 Instead, the semantics has one qualifier as the default and the other required. 1656 For example, make the safe @mutex@ qualifier the default because assuming \lstinline[morekeywords=nomutex]@nomutex@ may cause subtle errors. 1657 Alternatively, make the unsafe \lstinline[morekeywords=nomutex]@nomutex@ qualifier the default because it is the \emph{normal} parameter semantics while @mutex@ parameters are rare. 1334 1658 Providing a default qualifier implies knowing whether a parameter is a monitor. 1335 Since \CFA relies heavily on traits as an abstraction mechanism, t he distinction between a type that is a monitor and a type that looks like a monitor can become blurred.1659 Since \CFA relies heavily on traits as an abstraction mechanism, types can coincidentally match the monitor trait but not be a monitor, similar to inheritance where a shape and playing card can both be drawable. 1336 1660 For this reason, \CFA requires programmers to identify the kind of parameter with the @mutex@ keyword and uses no keyword to mean \lstinline[morekeywords=nomutex]@nomutex@. 1337 1661 1338 1662 The next semantic decision is establishing which parameter \emph{types} may be qualified with @mutex@. 1339 Given: 1663 The following has monitor parameter types that are composed of multiple objects. 1340 1664 \begin{cfa} 1341 1665 monitor M { ... } 1342 int f1( M & mutex m ); 1343 int f2( M * mutex m ); 1344 int f3( M * mutex m[] ); 1345 int f4( stack( M * ) & mutex m ); 1346 \end{cfa} 1347 the issue is that some of these parameter types are composed of multiple objects. 1348 For @f1@, there is only a single parameter object. 1349 Adding indirection in @f2@ still identifies a single object. 1350 However, the matrix in @f3@ introduces multiple objects. 1351 While shown shortly, multiple acquisition is possible; 1352 however array lengths are often unknown in C. 1353 This issue is exacerbated in @f4@, where the data structure must be safely traversed to acquire all of its elements. 1354 1355 To make the issue tractable, \CFA only acquires one monitor per parameter with at most one level of indirection. 1356 However, the C type-system has an ambiguity with respects to arrays. 1357 Is the argument for @f2@ a single object or an array of objects? 1358 If it is an array, only the first element of the array is acquired, which seems unsafe; 1359 hence, @mutex@ is disallowed for array parameters. 1360 \begin{cfa} 1361 int f1( M & mutex m ); $\C{// allowed: recommended case}$ 1362 int f2( M * mutex m ); $\C{// disallowed: could be an array}$ 1363 int f3( M mutex m[$\,$] ); $\C{// disallowed: array length unknown}$ 1364 int f4( M ** mutex m ); $\C{// disallowed: could be an array}$ 1365 int f5( M * mutex m[$\,$] ); $\C{// disallowed: array length unknown}$ 1366 \end{cfa} 1367 % Note, not all array routines have distinct types: @f2@ and @f3@ have the same type, as do @f4@ and @f5@. 1368 % However, even if the code generation could tell the difference, the extra information is still not sufficient to extend meaningfully the monitor call semantic. 1369 1370 For object-oriented monitors, calling a mutex member \emph{implicitly} acquires mutual exclusion of the receiver object, @`rec`.foo(...)@. 1371 \CFA has no receiver, and hence, must use an explicit mechanism to specify which object has mutual exclusion acquired. 1372 A positive consequence of this design decision is the ability to support multi-monitor routines. 1373 \begin{cfa} 1374 int f( M & mutex x, M & mutex y ); $\C{// multiple monitor parameter of any type}$ 1375 M m1, m2; 1376 f( m1, m2 ); 1377 \end{cfa} 1378 (While object-oriented monitors can be extended with a mutex qualifier for multiple-monitor members, no prior example of this feature could be found.) 1379 In practice, writing multi-locking routines that do not deadlocks is tricky. 1380 Having language support for such a feature is therefore a significant asset for \CFA. 1381 1382 The capability to acquire multiple locks before entering a critical section is called \newterm{bulk acquire}. 1383 In previous example, \CFA guarantees the order of acquisition is consistent across calls to different routines using the same monitors as arguments. 1384 This consistent ordering means acquiring multiple monitors is safe from deadlock. 1385 However, users can force the acquiring order. 1386 For example, notice the use of @mutex@/\lstinline[morekeywords=nomutex]@nomutex@ and how this affects the acquiring order: 1387 \begin{cfa} 1388 void foo( M & mutex m1, M & mutex m2 ); $\C{// acquire m1 and m2}$ 1666 int f1( M & mutex m ); $\C{// single parameter object}$ 1667 int f2( M * mutex m ); $\C{// single or multiple parameter object}$ 1668 int f3( M * mutex m[$\,$] ); $\C{// multiple parameter object}$ 1669 int f4( stack( M * ) & mutex m ); $\C{// multiple parameters object}$ 1670 \end{cfa} 1671 Function @f1@ has a single parameter object, while @f2@'s indirection could be a single or multi-element array, where static array size is often unknown in C. 1672 Function @f3@ has a multiple object matrix, and @f4@ a multiple object data structure. 1673 While shown shortly, multiple object acquisition is possible, but the number of objects must be statically known. 1674 Therefore, \CFA only acquires one monitor per parameter with at most one level of indirection, excluding pointers as it is impossible to statically determine the size. 1675 1676 For object-oriented monitors, \eg Java, calling a mutex member \emph{implicitly} acquires mutual exclusion of the receiver object, @`rec`.foo(...)@. 1677 \CFA has no receiver, and hence, the explicit @mutex@ qualifier is used to specify which objects acquire mutual exclusion. 1678 A positive consequence of this design decision is the ability to support multi-monitor functions,\footnote{ 1679 While object-oriented monitors can be extended with a mutex qualifier for multiple-monitor members, no prior example of this feature could be found.} 1680 called \newterm{bulk acquire}. 1681 \CFA guarantees acquisition order is consistent across calls to @mutex@ functions using the same monitors as arguments, so acquiring multiple monitors is safe from deadlock. 1682 Figure~\ref{f:BankTransfer} shows a trivial solution to the bank transfer problem~\cite{BankTransfer}, where two resources must be locked simultaneously, using \CFA monitors with implicit locking and \CC with explicit locking. 1683 A \CFA programmer only has to manage when to acquire mutual exclusion; 1684 a \CC programmer must select the correct lock and acquisition mechanism from a panoply of locking options. 1685 Making good choices for common cases in \CFA simplifies the programming experience and enhances safety. 1686 1687 \begin{figure} 1688 \centering 1689 \begin{lrbox}{\myboxA} 1690 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1691 monitor BankAccount { 1692 1693 int balance; 1694 } b1 = { 0 }, b2 = { 0 }; 1695 void deposit( BankAccount & `mutex` b, 1696 int deposit ) with(b) { 1697 balance += deposit; 1698 } 1699 void transfer( BankAccount & `mutex` my, 1700 BankAccount & `mutex` your, int me2you ) { 1701 1702 deposit( my, -me2you ); // debit 1703 deposit( your, me2you ); // credit 1704 } 1705 `thread` Person { BankAccount & b1, & b2; }; 1706 void main( Person & person ) with(person) { 1707 for ( 10_000_000 ) { 1708 if ( random() % 3 ) deposit( b1, 3 ); 1709 if ( random() % 3 ) transfer( b1, b2, 7 ); 1710 } 1711 } 1712 int main() { 1713 `Person p1 = { b1, b2 }, p2 = { b2, b1 };` 1714 1715 } // wait for threads to complete 1716 \end{cfa} 1717 \end{lrbox} 1718 1719 \begin{lrbox}{\myboxB} 1720 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1721 struct BankAccount { 1722 `recursive_mutex m;` 1723 int balance = 0; 1724 } b1, b2; 1725 void deposit( BankAccount & b, int deposit ) { 1726 `scoped_lock lock( b.m );` 1727 b.balance += deposit; 1728 } 1729 void transfer( BankAccount & my, 1730 BankAccount & your, int me2you ) { 1731 `scoped_lock lock( my.m, your.m );` 1732 deposit( my, -me2you ); // debit 1733 deposit( your, me2you ); // credit 1734 } 1735 1736 void person( BankAccount & b1, BankAccount & b2 ) { 1737 for ( int i = 0; i < 10$'$000$'$000; i += 1 ) { 1738 if ( random() % 3 ) deposit( b1, 3 ); 1739 if ( random() % 3 ) transfer( b1, b2, 7 ); 1740 } 1741 } 1742 int main() { 1743 `thread p1(person, ref(b1), ref(b2)), p2(person, ref(b2), ref(b1));` 1744 `p1.join(); p2.join();` 1745 } 1746 \end{cfa} 1747 \end{lrbox} 1748 1749 \subfloat[\CFA]{\label{f:CFABank}\usebox\myboxA} 1750 \hspace{3pt} 1751 \vrule 1752 \hspace{3pt} 1753 \subfloat[\CC]{\label{f:C++Bank}\usebox\myboxB} 1754 \hspace{3pt} 1755 \caption{Bank transfer problem} 1756 \label{f:BankTransfer} 1757 \end{figure} 1758 1759 Users can still force the acquiring order by using @mutex@/\lstinline[morekeywords=nomutex]@nomutex@. 1760 \begin{cfa} 1761 void foo( M & mutex m1, M & mutex m2 ); $\C{// acquire m1 and m2}$ 1389 1762 void bar( M & mutex m1, M & /* nomutex */ m2 ) { $\C{// acquire m1}$ 1390 ... foo( m1, m2 ); ... $\C{// acquire m2}$1763 ... foo( m1, m2 ); ... $\C{// acquire m2}$ 1391 1764 } 1392 1765 void baz( M & /* nomutex */ m1, M & mutex m2 ) { $\C{// acquire m2}$ 1393 ... foo( m1, m2 ); ... $\C{// acquire m1}$ 1394 } 1395 \end{cfa} 1396 The multi-acquire semantics allows @bar@ or @baz@ to acquire a monitor lock and reacquire it in @foo@. 1397 In the calls to @bar@ and @baz@, the monitors are acquired in opposite order. 1398 1399 However, such use leads to lock acquiring order problems resulting in deadlock~\cite{Lister77}, where detecting it requires dynamically tracking of monitor calls, and dealing with it requires implement rollback semantics~\cite{Dice10}. 1400 In \CFA, safety is guaranteed by using bulk acquire of all monitors to shared objects, whereas other monitor systems provide no aid. 1401 While \CFA provides only a partial solution, the \CFA partial solution handles many useful cases. 1402 \begin{cfa} 1403 monitor Bank { ... }; 1404 void deposit( Bank & `mutex` b, int deposit ); 1405 void transfer( Bank & `mutex` mybank, Bank & `mutex` yourbank, int me2you) { 1406 deposit( mybank, `-`me2you ); $\C{// debit}$ 1407 deposit( yourbank, me2you ); $\C{// credit}$ 1408 } 1409 \end{cfa} 1410 This example shows a trivial solution to the bank-account transfer problem~\cite{BankTransfer}. 1411 Without multi- and bulk acquire, the solution to this problem requires careful engineering. 1412 1413 1414 \subsection{\protect\lstinline|mutex| statement} \label{mutex-stmt} 1415 1416 The monitor call-semantics associate all locking semantics to routines. 1417 Like Java, \CFA offers an alternative @mutex@ statement to reduce refactoring and naming. 1766 ... foo( m1, m2 ); ... $\C{// acquire m1}$ 1767 } 1768 \end{cfa} 1769 The bulk-acquire semantics allow @bar@ or @baz@ to acquire a monitor lock and reacquire it in @foo@. 1770 The calls to @bar@ and @baz@ acquired the monitors in opposite order, possibly resulting in deadlock. 1771 However, this case is the simplest instance of the \emph{nested-monitor problem}~\cite{Lister77}, where monitors are acquired in sequence versus bulk. 1772 Detecting the nested-monitor problem requires dynamic tracking of monitor calls, and dealing with it requires rollback semantics~\cite{Dice10}. 1773 \CFA does not deal with this fundamental problem. 1774 1775 Finally, like Java, \CFA offers an alternative @mutex@ statement to reduce refactoring and naming. 1418 1776 \begin{cquote} 1419 \begin{tabular}{@{}c|@{\hspace{\parindentlnth}}c@{}} 1420 routine call & @mutex@ statement \\ 1421 \begin{cfa} 1422 monitor M {}; 1777 \renewcommand{\arraystretch}{0.0} 1778 \begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}} 1779 \multicolumn{1}{c}{\textbf{\lstinline@mutex@ call}} & \multicolumn{1}{c}{\lstinline@mutex@ \textbf{statement}} \\ 1780 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1781 monitor M { ... }; 1423 1782 void foo( M & mutex m1, M & mutex m2 ) { 1424 1783 // critical section … … 1429 1788 \end{cfa} 1430 1789 & 1431 \begin{cfa} 1790 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1432 1791 1433 1792 void bar( M & m1, M & m2 ) { … … 1442 1801 1443 1802 1444 \section{Internal Scheduling} 1445 \label{s:InternalScheduling} 1446 1447 While monitor mutual-exclusion provides safe access to shared data, the monitor data may indicate that a thread accessing it cannot proceed, \eg a bounded buffer, Figure~\ref{f:GenericBoundedBuffer}, may be full/empty so produce/consumer threads must block. 1803 \subsection{Scheduling} 1804 \label{s:Scheduling} 1805 1806 % There are many aspects of scheduling in a concurrency system, all related to resource utilization by waiting threads, \ie which thread gets the resource next. 1807 % Different forms of scheduling include access to processors by threads (see Section~\ref{s:RuntimeStructureCluster}), another is access to a shared resource by a lock or monitor. 1808 This section discusses monitor scheduling for waiting threads eligible for entry, \ie which thread gets the shared resource next. (See Section~\ref{s:RuntimeStructureCluster} for scheduling threads on virtual processors.) 1809 While monitor mutual-exclusion provides safe access to shared data, the monitor data may indicate that a thread accessing it cannot proceed, \eg a bounded buffer may be full/empty so produce/consumer threads must block. 1448 1810 Leaving the monitor and trying again (busy waiting) is impractical for high-level programming. 1449 Monitors eliminate busy waiting by providing internal synchronization to schedule threads needing access to the shared data, where the synchronization is blocking (threads are parked)versus spinning.1450 The synchronization is generally achieved with internal~\cite{Hoare74} or external~\cite[\S~2.9.2]{uC++} scheduling, where \newterm{scheduling} is defined as indicating which thread acquires the critical section next.1811 Monitors eliminate busy waiting by providing synchronization to schedule threads needing access to the shared data, where threads block versus spinning. 1812 Synchronization is generally achieved with internal~\cite{Hoare74} or external~\cite[\S~2.9.2]{uC++} scheduling. 1451 1813 \newterm{Internal scheduling} is characterized by each thread entering the monitor and making an individual decision about proceeding or blocking, while \newterm{external scheduling} is characterized by an entering thread making a decision about proceeding for itself and on behalf of other threads attempting entry. 1452 1453 Figure~\ref{f:BBInt} shows a \CFA bounded-buffer with internal scheduling, where producers/consumers enter the monitor, see the buffer is full/empty, and block on an appropriate condition lock, @full@/@empty@. 1454 The @wait@ routine atomically blocks the calling thread and implicitly releases the monitor lock(s) for all monitors in the routine's parameter list. 1455 The appropriate condition lock is signalled to unblock an opposite kind of thread after an element is inserted/removed from the buffer. 1456 Signalling is unconditional, because signalling an empty condition lock does nothing. 1457 Signalling semantics cannot have the signaller and signalled thread in the monitor simultaneously, which means: 1458 \begin{enumerate} 1459 \item 1460 The signalling thread returns immediately, and the signalled thread continues. 1461 \item 1462 The signalling thread continues and the signalled thread is marked for urgent unblocking at the next scheduling point (exit/wait). 1463 \item 1464 The signalling thread blocks but is marked for urgrent unblocking at the next scheduling point and the signalled thread continues. 1465 \end{enumerate} 1466 The first approach is too restrictive, as it precludes solving a reasonable class of problems (\eg dating service). 1467 \CFA supports the next two semantics as both are useful. 1468 Finally, while it is common to store a @condition@ as a field of the monitor, in \CFA, a @condition@ variable can be created/stored independently. 1469 Furthermore, a condition variable is tied to a \emph{group} of monitors on first use (called \newterm{branding}), which means that using internal scheduling with distinct sets of monitors requires one condition variable per set of monitors. 1814 Finally, \CFA monitors do not allow calling threads to barge ahead of signalled threads, which simplifies synchronization among threads in the monitor and increases correctness. 1815 If barging is allowed, synchronization between a signaller and signallee is difficult, often requiring additional flags and multiple unblock/block cycles. 1816 In fact, signals-as-hints is completely opposite from that proposed by Hoare in the seminal paper on monitors~\cite[p.~550]{Hoare74}. 1817 % \begin{cquote} 1818 % However, we decree that a signal operation be followed immediately by resumption of a waiting program, without possibility of an intervening procedure call from yet a third program. 1819 % It is only in this way that a waiting program has an absolute guarantee that it can acquire the resource just released by the signalling program without any danger that a third program will interpose a monitor entry and seize the resource instead.~\cite[p.~550]{Hoare74} 1820 % \end{cquote} 1821 Furthermore, \CFA concurrency has no spurious wakeup~\cite[\S~9]{Buhr05a}, which eliminates an implicit form of self barging. 1822 Hence, a \CFA @wait@ statement is not enclosed in a @while@ loop retesting a blocking predicate, which can cause thread starvation due to barging. 1823 1824 Figure~\ref{f:MonitorScheduling} shows general internal/external scheduling (for the bounded-buffer example in Figure~\ref{f:InternalExternalScheduling}). 1825 External calling threads block on the calling queue, if the monitor is occupied, otherwise they enter in FIFO order. 1826 Internal threads block on condition queues via @wait@ and reenter from the condition in FIFO order. 1827 Alternatively, internal threads block on urgent from the @signal_block@ or @waitfor@, and reenter implicitly when the monitor becomes empty, \ie, the thread in the monitor exits or waits. 1828 1829 There are three signalling mechanisms to unblock waiting threads to enter the monitor. 1830 Note, signalling cannot have the signaller and signalled thread in the monitor simultaneously because of the mutual exclusion, so either the signaller or signallee can proceed. 1831 For internal scheduling, threads are unblocked from condition queues using @signal@, where the signallee is moved to urgent and the signaller continues (solid line). 1832 Multiple signals move multiple signallees to urgent until the condition is empty. 1833 When the signaller exits or waits, a thread blocked on urgent is processed before calling threads to prevent barging. 1834 (Java conceptually moves the signalled thread to the calling queue, and hence, allows barging.) 1835 The alternative unblock is in the opposite order using @signal_block@, where the signaller is moved to urgent and the signallee continues (dashed line), and is implicitly unblocked from urgent when the signallee exits or waits. 1836 1837 For external scheduling, the condition queues are not used; 1838 instead threads are unblocked directly from the calling queue using @waitfor@ based on function names requesting mutual exclusion. 1839 (The linear search through the calling queue to locate a particular call can be reduced to $O(1)$.) 1840 The @waitfor@ has the same semantics as @signal_block@, where the signalled thread executes before the signallee, which waits on urgent. 1841 Executing multiple @waitfor@s from different signalled functions causes the calling threads to move to urgent. 1842 External scheduling requires urgent to be a stack, because the signaller expects to execute immediately after the specified monitor call has exited or waited. 1843 Internal scheduling behaves the same for an urgent stack or queue, except for multiple signalling, where the threads unblock from urgent in reverse order from signalling. 1844 If the restart order is important, multiple signalling by a signal thread can be transformed into daisy-chain signalling among threads, where each thread signals the next thread. 1845 We tried both a stack for @waitfor@ and queue for signalling, but that resulted in complex semantics about which thread enters next. 1846 Hence, \CFA uses a single urgent stack to correctly handle @waitfor@ and adequately support both forms of signalling. 1847 1848 \begin{figure} 1849 \centering 1850 % \subfloat[Scheduling Statements] { 1851 % \label{fig:SchedulingStatements} 1852 % {\resizebox{0.45\textwidth}{!}{\input{CondSigWait.pstex_t}}} 1853 \input{CondSigWait.pstex_t} 1854 % }% subfloat 1855 % \quad 1856 % \subfloat[Bulk acquire monitor] { 1857 % \label{fig:BulkMonitor} 1858 % {\resizebox{0.45\textwidth}{!}{\input{ext_monitor.pstex_t}}} 1859 % }% subfloat 1860 \caption{Monitor Scheduling} 1861 \label{f:MonitorScheduling} 1862 \end{figure} 1863 1864 Figure~\ref{f:BBInt} shows a \CFA generic bounded-buffer with internal scheduling, where producers/consumers enter the monitor, detect the buffer is full/empty, and block on an appropriate condition variable, @full@/@empty@. 1865 The @wait@ function atomically blocks the calling thread and implicitly releases the monitor lock(s) for all monitors in the function's parameter list. 1866 The appropriate condition variable is signalled to unblock an opposite kind of thread after an element is inserted/removed from the buffer. 1867 Signalling is unconditional, because signalling an empty condition variable does nothing. 1868 It is common to declare condition variables as monitor fields to prevent shared access, hence no locking is required for access as the conditions are protected by the monitor lock. 1869 In \CFA, a condition variable can be created/stored independently. 1870 % To still prevent expensive locking on access, a condition variable is tied to a \emph{group} of monitors on first use, called \newterm{branding}, resulting in a low-cost boolean test to detect sharing from other monitors. 1871 1872 % Signalling semantics cannot have the signaller and signalled thread in the monitor simultaneously, which means: 1873 % \begin{enumerate} 1874 % \item 1875 % The signalling thread returns immediately and the signalled thread continues. 1876 % \item 1877 % The signalling thread continues and the signalled thread is marked for urgent unblocking at the next scheduling point (exit/wait). 1878 % \item 1879 % The signalling thread blocks but is marked for urgent unblocking at the next scheduling point and the signalled thread continues. 1880 % \end{enumerate} 1881 % The first approach is too restrictive, as it precludes solving a reasonable class of problems, \eg dating service (see Figure~\ref{f:DatingService}). 1882 % \CFA supports the next two semantics as both are useful. 1470 1883 1471 1884 \begin{figure} … … 1481 1894 }; 1482 1895 void ?{}( Buffer(T) & buffer ) with(buffer) { 1483 [front, back, count]= 0;1896 front = back = count = 0; 1484 1897 } 1485 1486 1898 void insert( Buffer(T) & mutex buffer, T elem ) 1487 1899 with(buffer) { … … 1500 1912 \end{lrbox} 1501 1913 1914 % \newbox\myboxB 1915 % \begin{lrbox}{\myboxB} 1916 % \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1917 % forall( otype T ) { // distribute forall 1918 % monitor Buffer { 1919 % 1920 % int front, back, count; 1921 % T elements[10]; 1922 % }; 1923 % void ?{}( Buffer(T) & buffer ) with(buffer) { 1924 % [front, back, count] = 0; 1925 % } 1926 % T remove( Buffer(T) & mutex buffer ); // forward 1927 % void insert( Buffer(T) & mutex buffer, T elem ) 1928 % with(buffer) { 1929 % if ( count == 10 ) `waitfor( remove, buffer )`; 1930 % // insert elem into buffer 1931 % 1932 % } 1933 % T remove( Buffer(T) & mutex buffer ) with(buffer) { 1934 % if ( count == 0 ) `waitfor( insert, buffer )`; 1935 % // remove elem from buffer 1936 % 1937 % return elem; 1938 % } 1939 % } 1940 % \end{cfa} 1941 % \end{lrbox} 1942 1502 1943 \newbox\myboxB 1503 1944 \begin{lrbox}{\myboxB} 1504 1945 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1505 forall( otype T ) { // distribute forall 1506 monitor Buffer { 1507 1508 int front, back, count; 1509 T elements[10]; 1510 }; 1511 void ?{}( Buffer(T) & buffer ) with(buffer) { 1512 [front, back, count] = 0; 1513 } 1514 T remove( Buffer(T) & mutex buffer ); // forward 1515 void insert( Buffer(T) & mutex buffer, T elem ) 1516 with(buffer) { 1517 if ( count == 10 ) `waitfor( remove, buffer )`; 1518 // insert elem into buffer 1519 1520 } 1521 T remove( Buffer(T) & mutex buffer ) with(buffer) { 1522 if ( count == 0 ) `waitfor( insert, buffer )`; 1523 // remove elem from buffer 1524 1525 return elem; 1526 } 1527 } 1946 monitor ReadersWriter { 1947 int rcnt, wcnt; // readers/writer using resource 1948 }; 1949 void ?{}( ReadersWriter & rw ) with(rw) { 1950 rcnt = wcnt = 0; 1951 } 1952 void EndRead( ReadersWriter & mutex rw ) with(rw) { 1953 rcnt -= 1; 1954 } 1955 void EndWrite( ReadersWriter & mutex rw ) with(rw) { 1956 wcnt = 0; 1957 } 1958 void StartRead( ReadersWriter & mutex rw ) with(rw) { 1959 if ( wcnt > 0 ) `waitfor( EndWrite, rw );` 1960 rcnt += 1; 1961 } 1962 void StartWrite( ReadersWriter & mutex rw ) with(rw) { 1963 if ( wcnt > 0 ) `waitfor( EndWrite, rw );` 1964 else while ( rcnt > 0 ) `waitfor( EndRead, rw );` 1965 wcnt = 1; 1966 } 1967 1528 1968 \end{cfa} 1529 1969 \end{lrbox} 1530 1970 1531 \subfloat[Internal Scheduling]{\label{f:BBInt}\usebox\myboxA} 1532 %\qquad 1533 \subfloat[External Scheduling]{\label{f:BBExt}\usebox\myboxB} 1534 \caption{Generic Bounded-Buffer} 1535 \label{f:GenericBoundedBuffer} 1971 \subfloat[Generic bounded buffer, internal scheduling]{\label{f:BBInt}\usebox\myboxA} 1972 \hspace{3pt} 1973 \vrule 1974 \hspace{3pt} 1975 \subfloat[Readers / writer lock, external scheduling]{\label{f:RWExt}\usebox\myboxB} 1976 1977 \caption{Internal / external scheduling} 1978 \label{f:InternalExternalScheduling} 1536 1979 \end{figure} 1537 1980 1538 Figure~\ref{f:BBExt} shows a \CFA bounded-buffer with external scheduling, where producers/consumers detecting a full/empty buffer block and prevent more producers/consumers from entering the monitor until the buffer has a free/empty slot. 1539 External scheduling is controlled by the @waitfor@ statement, which atomically blocks the calling thread, releases the monitor lock, and restricts the routine calls that can next acquire mutual exclusion. 1981 Figure~\ref{f:BBInt} can be transformed into external scheduling by removing the condition variables and signals/waits, and adding the following lines at the locations of the current @wait@s in @insert@/@remove@, respectively. 1982 \begin{cfa}[aboveskip=2pt,belowskip=1pt] 1983 if ( count == 10 ) `waitfor( remove, buffer )`; | if ( count == 0 ) `waitfor( insert, buffer )`; 1984 \end{cfa} 1985 Here, the producers/consumers detects a full/\-empty buffer and prevents more producers/consumers from entering the monitor until there is a free/empty slot in the buffer. 1986 External scheduling is controlled by the @waitfor@ statement, which atomically blocks the calling thread, releases the monitor lock, and restricts the function calls that can next acquire mutual exclusion. 1540 1987 If the buffer is full, only calls to @remove@ can acquire the buffer, and if the buffer is empty, only calls to @insert@ can acquire the buffer. 1541 Threads making calls to routines that are currently excluded block outside (externally) of the monitor on a calling queue, versus blocking on condition queues inside the monitor. 1542 1543 Both internal and external scheduling extend to multiple monitors in a natural way. 1544 \begin{cfa} 1545 monitor M { `condition e`; ... }; 1546 void foo( M & mutex m1, M & mutex m2 ) { 1547 ... wait( `e` ); ... $\C{// wait( e, m1, m2 )}$ 1548 ... wait( `e, m1` ); ... 1549 ... wait( `e, m2` ); ... 1550 } 1551 1552 void rtn$\(_1\)$( M & mutex m1, M & mutex m2 ); 1553 void rtn$\(_2\)$( M & mutex m1 ); 1554 void bar( M & mutex m1, M & mutex m2 ) { 1555 ... waitfor( `rtn` ); ... $\C{// waitfor( rtn\(_1\), m1, m2 )}$ 1556 ... waitfor( `rtn, m1` ); ... $\C{// waitfor( rtn\(_2\), m1 )}$ 1557 } 1558 \end{cfa} 1559 For @wait( e )@, the default semantics is to atomically block the signaller and release all acquired mutex types in the parameter list, \ie @wait( e, m1, m2 )@. 1560 To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @wait( e, m1 )@. 1561 Wait statically verifies the released monitors are the acquired mutex-parameters so unconditional release is safe. 1562 Similarly, for @waitfor( rtn, ... )@, the default semantics is to atomically block the acceptor and release all acquired mutex types in the parameter list, \ie @waitfor( rtn, m1, m2 )@. 1563 To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @waitfor( rtn, m1 )@. 1564 Waitfor statically verifies the released monitors are the same as the acquired mutex-parameters of the given routine or routine pointer. 1565 To statically verify the released monitors match with the accepted routine's mutex parameters, the routine (pointer) prototype must be accessible. 1566 1567 Given the ability to release a subset of acquired monitors can result in a \newterm{nested monitor}~\cite{Lister77} deadlock. 1568 \begin{cfa} 1569 void foo( M & mutex m1, M & mutex m2 ) { 1570 ... wait( `e, m1` ); ... $\C{// release m1, keeping m2 acquired )}$ 1571 void baz( M & mutex m1, M & mutex m2 ) { $\C{// must acquire m1 and m2 )}$ 1572 ... signal( `e` ); ... 1573 \end{cfa} 1574 The @wait@ only releases @m1@ so the signalling thread cannot acquire both @m1@ and @m2@ to enter @baz@ to get to the @signal@. 1575 While deadlock issues can occur with multiple/nesting acquisition, this issue results from the fact that locks, and by extension monitors, are not perfectly composable. 1576 1577 Finally, an important aspect of monitor implementation is barging, \ie can calling threads barge ahead of signalled threads? 1578 If barging is allowed, synchronization between a singller and signallee is difficult, often requiring multiple unblock/block cycles (looping around a wait rechecking if a condition is met). 1579 \begin{quote} 1580 However, we decree that a signal operation be followed immediately by resumption of a waiting program, without possibility of an intervening procedure call from yet a third program. 1581 It is only in this way that a waiting program has an absolute guarantee that it can acquire the resource just released by the signalling program without any danger that a third program will interpose a monitor entry and seize the resource instead.~\cite[p.~550]{Hoare74} 1582 \end{quote} 1583 \CFA scheduling \emph{precludes} barging, which simplifies synchronization among threads in the monitor and increases correctness. 1584 For example, there are no loops in either bounded buffer solution in Figure~\ref{f:GenericBoundedBuffer}. 1585 Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design and implementation of \CFA concurrency. 1586 1587 1588 \subsection{Barging Prevention} 1589 1590 Figure~\ref{f:BargingPrevention} shows \CFA code where bulk acquire adds complexity to the internal-signalling semantics. 1591 The complexity begins at the end of the inner @mutex@ statement, where the semantics of internal scheduling need to be extended for multiple monitors. 1592 The problem is that bulk acquire is used in the inner @mutex@ statement where one of the monitors is already acquired. 1593 When the signalling thread reaches the end of the inner @mutex@ statement, it should transfer ownership of @m1@ and @m2@ to the waiting thread to prevent barging into the outer @mutex@ statement by another thread. 1594 However, both the signalling and signalled threads still need monitor @m1@. 1595 1596 \begin{figure} 1597 \newbox\myboxA 1598 \begin{lrbox}{\myboxA} 1599 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1600 monitor M m1, m2; 1601 condition c; 1602 mutex( m1 ) { 1603 ... 1604 mutex( m1, m2 ) { 1605 ... `wait( c )`; // block and release m1, m2 1606 // m1, m2 acquired 1607 } // $\LstCommentStyle{\color{red}release m2}$ 1608 // m1 acquired 1609 } // release m1 1610 \end{cfa} 1611 \end{lrbox} 1612 1613 \newbox\myboxB 1614 \begin{lrbox}{\myboxB} 1615 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1616 1617 1618 mutex( m1 ) { 1619 ... 1620 mutex( m1, m2 ) { 1621 ... `signal( c )`; ... 1622 // m1, m2 acquired 1623 } // $\LstCommentStyle{\color{red}release m2}$ 1624 // m1 acquired 1625 } // release m1 1626 \end{cfa} 1627 \end{lrbox} 1628 1629 \newbox\myboxC 1630 \begin{lrbox}{\myboxC} 1631 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 1632 1633 1634 mutex( m1 ) { 1635 ... `wait( c )`; ... 1636 // m1 acquired 1637 } // $\LstCommentStyle{\color{red}release m1}$ 1638 1639 1640 1641 1642 \end{cfa} 1643 \end{lrbox} 1644 1645 \begin{cquote} 1646 \subfloat[Waiting Thread]{\label{f:WaitingThread}\usebox\myboxA} 1647 \hspace{2\parindentlnth} 1648 \subfloat[Signalling Thread]{\label{f:SignallingThread}\usebox\myboxB} 1649 \hspace{2\parindentlnth} 1650 \subfloat[Other Waiting Thread]{\label{f:SignallingThread}\usebox\myboxC} 1651 \end{cquote} 1652 \caption{Barging Prevention} 1653 \label{f:BargingPrevention} 1654 \end{figure} 1655 1656 The obvious solution to the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred. 1657 It can be argued that that moment is when the last lock is no longer needed, because this semantics fits most closely to the behaviour of single-monitor scheduling. 1658 This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from multiple objects to a single group of objects, effectively making the existing single-monitor semantic viable by simply changing monitors to monitor groups. 1659 This solution releases the monitors once every monitor in a group can be released. 1660 However, since some monitors are never released (\eg the monitor of a thread), this interpretation means a group might never be released. 1661 A more interesting interpretation is to transfer the group until all its monitors are released, which means the group is not passed further and a thread can retain its locks. 1662 1663 However, listing \ref{f:int-secret} shows this solution can become much more complicated depending on what is executed while secretly holding B at line \ref{line:secret}, while avoiding the need to transfer ownership of a subset of the condition monitors. 1664 Figure~\ref{f:dependency} shows a slightly different example where a third thread is waiting on monitor @A@, using a different condition variable. 1665 Because the third thread is signalled when secretly holding @B@, the goal becomes unreachable. 1666 Depending on the order of signals (listing \ref{f:dependency} line \ref{line:signal-ab} and \ref{line:signal-a}) two cases can happen: 1667 1668 \begin{comment} 1669 \paragraph{Case 1: thread $\alpha$ goes first.} In this case, the problem is that monitor @A@ needs to be passed to thread $\beta$ when thread $\alpha$ is done with it. 1670 \paragraph{Case 2: thread $\beta$ goes first.} In this case, the problem is that monitor @B@ needs to be retained and passed to thread $\alpha$ along with monitor @A@, which can be done directly or possibly using thread $\beta$ as an intermediate. 1671 \\ 1672 1673 Note that ordering is not determined by a race condition but by whether signalled threads are enqueued in FIFO or FILO order. 1674 However, regardless of the answer, users can move line \ref{line:signal-a} before line \ref{line:signal-ab} and get the reverse effect for listing \ref{f:dependency}. 1675 1676 In both cases, the threads need to be able to distinguish, on a per monitor basis, which ones need to be released and which ones need to be transferred, which means knowing when to release a group becomes complex and inefficient (see next section) and therefore effectively precludes this approach. 1677 1678 1679 \subsubsection{Dependency graphs} 1680 1681 \begin{figure} 1682 \begin{multicols}{3} 1683 Thread $\alpha$ 1684 \begin{cfa}[numbers=left, firstnumber=1] 1685 acquire A 1686 acquire A & B 1687 wait A & B 1688 release A & B 1689 release A 1690 \end{cfa} 1691 \columnbreak 1692 Thread $\gamma$ 1693 \begin{cfa}[numbers=left, firstnumber=6, escapechar=|] 1694 acquire A 1695 acquire A & B 1696 |\label{line:signal-ab}|signal A & B 1697 |\label{line:release-ab}|release A & B 1698 |\label{line:signal-a}|signal A 1699 |\label{line:release-a}|release A 1700 \end{cfa} 1701 \columnbreak 1702 Thread $\beta$ 1703 \begin{cfa}[numbers=left, firstnumber=12, escapechar=|] 1704 acquire A 1705 wait A 1706 |\label{line:release-aa}|release A 1707 \end{cfa} 1708 \end{multicols} 1709 \begin{cfa}[caption={Pseudo-code for the three thread example.},label={f:dependency}] 1710 \end{cfa} 1711 \begin{center} 1712 \input{dependency} 1713 \end{center} 1714 \caption{Dependency graph of the statements in listing \ref{f:dependency}} 1715 \label{fig:dependency} 1716 \end{figure} 1717 1718 In listing \ref{f:int-bulk-cfa}, there is a solution that satisfies both barging prevention and mutual exclusion. 1719 If ownership of both monitors is transferred to the waiter when the signaller releases @A & B@ and then the waiter transfers back ownership of @A@ back to the signaller when it releases it, then the problem is solved (@B@ is no longer in use at this point). 1720 Dynamically finding the correct order is therefore the second possible solution. 1721 The problem is effectively resolving a dependency graph of ownership requirements. 1722 Here even the simplest of code snippets requires two transfers and has a super-linear complexity. 1723 This complexity can be seen in listing \ref{f:explosion}, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions. 1724 Furthermore, the presence of multiple solutions for ownership transfer can cause deadlock problems if a specific solution is not consistently picked; In the same way that multiple lock acquiring order can cause deadlocks. 1725 \begin{figure} 1726 \begin{multicols}{2} 1727 \begin{cfa} 1728 acquire A 1729 acquire B 1730 acquire C 1731 wait A & B & C 1732 release C 1733 release B 1734 release A 1735 \end{cfa} 1736 1737 \columnbreak 1738 1739 \begin{cfa} 1740 acquire A 1741 acquire B 1742 acquire C 1743 signal A & B & C 1744 release C 1745 release B 1746 release A 1747 \end{cfa} 1748 \end{multicols} 1749 \begin{cfa}[caption={Extension to three monitors of listing \ref{f:int-bulk-cfa}},label={f:explosion}] 1750 \end{cfa} 1751 \end{figure} 1752 1753 Given the three threads example in listing \ref{f:dependency}, figure \ref{fig:dependency} shows the corresponding dependency graph that results, where every node is a statement of one of the three threads, and the arrows the dependency of that statement (\eg $\alpha1$ must happen before $\alpha2$). 1754 The extra challenge is that this dependency graph is effectively post-mortem, but the runtime system needs to be able to build and solve these graphs as the dependencies unfold. 1755 Resolving dependency graphs being a complex and expensive endeavour, this solution is not the preferred one. 1756 1757 \subsubsection{Partial Signalling} \label{partial-sig} 1758 \end{comment} 1759 1760 Finally, the solution that is chosen for \CFA is to use partial signalling. 1761 Again using listing \ref{f:int-bulk-cfa}, the partial signalling solution transfers ownership of monitor @B@ at lines \ref{line:signal1} to the waiter but does not wake the waiting thread since it is still using monitor @A@. 1762 Only when it reaches line \ref{line:lastRelease} does it actually wake up the waiting thread. 1763 This solution has the benefit that complexity is encapsulated into only two actions: passing monitors to the next owner when they should be released and conditionally waking threads if all conditions are met. 1764 This solution has a much simpler implementation than a dependency graph solving algorithms, which is why it was chosen. 1765 Furthermore, after being fully implemented, this solution does not appear to have any significant downsides. 1766 1767 Using partial signalling, listing \ref{f:dependency} can be solved easily: 1768 \begin{itemize} 1769 \item When thread $\gamma$ reaches line \ref{line:release-ab} it transfers monitor @B@ to thread $\alpha$ and continues to hold monitor @A@. 1770 \item When thread $\gamma$ reaches line \ref{line:release-a} it transfers monitor @A@ to thread $\beta$ and wakes it up. 1771 \item When thread $\beta$ reaches line \ref{line:release-aa} it transfers monitor @A@ to thread $\alpha$ and wakes it up. 1772 \end{itemize} 1773 1774 1775 \subsection{Signalling: Now or Later} 1988 Threads calling excluded functions block outside of (external to) the monitor on the calling queue, versus blocking on condition queues inside of (internal to) the monitor. 1989 Figure~\ref{f:RWExt} shows a readers/writer lock written using external scheduling, where a waiting reader detects a writer using the resource and restricts further calls until the writer exits by calling @EndWrite@. 1990 The writer does a similar action for each reader or writer using the resource. 1991 Note, no new calls to @StarRead@/@StartWrite@ may occur when waiting for the call to @EndRead@/@EndWrite@. 1992 External scheduling allows waiting for events from other threads while restricting unrelated events, that would otherwise have to wait on conditions in the monitor. 1993 The mechnaism can be done in terms of control flow, \eg Ada @accept@ or \uC @_Accept@, or in terms of data, \eg Go @select@ on channels. 1994 While both mechanisms have strengths and weaknesses, this project uses the control-flow mechanism to be consistent with other language features. 1995 % Two challenges specific to \CFA for external scheduling are loose object-definitions (see Section~\ref{s:LooseObjectDefinitions}) and multiple-monitor functions (see Section~\ref{s:Multi-MonitorScheduling}). 1996 1997 Figure~\ref{f:DatingService} shows a dating service demonstrating non-blocking and blocking signalling. 1998 The dating service matches girl and boy threads with matching compatibility codes so they can exchange phone numbers. 1999 A thread blocks until an appropriate partner arrives. 2000 The complexity is exchanging phone numbers in the monitor because of the mutual-exclusion property. 2001 For signal scheduling, the @exchange@ condition is necessary to block the thread finding the match, while the matcher unblocks to take the opposite number, post its phone number, and unblock the partner. 2002 For signal-block scheduling, the implicit urgent-queue replaces the explict @exchange@-condition and @signal_block@ puts the finding thread on the urgent condition and unblocks the matcher. 2003 The dating service is an example of a monitor that cannot be written using external scheduling because it requires knowledge of calling parameters to make scheduling decisions, and parameters of waiting threads are unavailable; 2004 as well, an arriving thread may not find a partner and must wait, which requires a condition variable, and condition variables imply internal scheduling. 2005 Furthermore, barging corrupts the dating service during an exchange because a barger may also match and change the phone numbers, invalidating the previous exchange phone number. 2006 Putting loops around the @wait@s does not correct the problem; 2007 the simple solution must be restructured to account for barging. 1776 2008 1777 2009 \begin{figure} … … 1784 2016 int GirlPhNo, BoyPhNo; 1785 2017 condition Girls[CCodes], Boys[CCodes]; 1786 condition exchange;2018 `condition exchange;` 1787 2019 }; 1788 2020 int girl( DS & mutex ds, int phNo, int ccode ) { … … 1790 2022 wait( Girls[ccode] ); 1791 2023 GirlPhNo = phNo; 1792 exchange.signal();2024 `signal( exchange );` 1793 2025 } else { 1794 2026 GirlPhNo = phNo; 1795 signal( Boys[ccode] );1796 exchange.wait();1797 } // if2027 `signal( Boys[ccode] );` 2028 `wait( exchange );` 2029 } 1798 2030 return BoyPhNo; 1799 2031 } … … 1820 2052 } else { 1821 2053 GirlPhNo = phNo; // make phone number available 1822 signal_block( Boys[ccode] );// restart boy2054 `signal_block( Boys[ccode] );` // restart boy 1823 2055 1824 2056 } // if … … 1834 2066 \qquad 1835 2067 \subfloat[\lstinline@signal_block@]{\label{f:DatingSignalBlock}\usebox\myboxB} 1836 \caption{Dating service .}1837 \label{f:Dating service}2068 \caption{Dating service} 2069 \label{f:DatingService} 1838 2070 \end{figure} 1839 2071 1840 An important note is that, until now, signalling a monitor was a delayed operation. 1841 The ownership of the monitor is transferred only when the monitor would have otherwise been released, not at the point of the @signal@ statement. 1842 However, in some cases, it may be more convenient for users to immediately transfer ownership to the thread that is waiting for cooperation, which is achieved using the @signal_block@ routine. 1843 1844 The example in table \ref{tbl:datingservice} highlights the difference in behaviour. 1845 As mentioned, @signal@ only transfers ownership once the current critical section exits; this behaviour requires additional synchronization when a two-way handshake is needed. 1846 To avoid this explicit synchronization, the @condition@ type offers the @signal_block@ routine, which handles the two-way handshake as shown in the example. 1847 This feature removes the need for a second condition variables and simplifies programming. 1848 Like every other monitor semantic, @signal_block@ uses barging prevention, which means mutual-exclusion is baton-passed both on the front end and the back end of the call to @signal_block@, meaning no other thread can acquire the monitor either before or after the call. 1849 1850 % ====================================================================== 1851 % ====================================================================== 1852 \section{External scheduling} \label{extsched} 1853 % ====================================================================== 1854 % ====================================================================== 1855 An alternative to internal scheduling is external scheduling (see Table~\ref{tbl:sched}). 1856 1857 \begin{comment} 1858 \begin{table} 1859 \begin{tabular}{|c|c|c|} 1860 Internal Scheduling & External Scheduling & Go\\ 1861 \hline 1862 \begin{uC++}[tabsize=3] 1863 _Monitor Semaphore { 1864 condition c; 1865 bool inUse; 1866 public: 1867 void P() { 1868 if(inUse) 1869 wait(c); 1870 inUse = true; 1871 } 1872 void V() { 1873 inUse = false; 1874 signal(c); 1875 } 1876 } 1877 \end{uC++}&\begin{uC++}[tabsize=3] 1878 _Monitor Semaphore { 1879 1880 bool inUse; 1881 public: 1882 void P() { 1883 if(inUse) 1884 _Accept(V); 1885 inUse = true; 1886 } 1887 void V() { 1888 inUse = false; 1889 1890 } 1891 } 1892 \end{uC++}&\begin{Go}[tabsize=3] 1893 type MySem struct { 1894 inUse bool 1895 c chan bool 1896 } 1897 1898 // acquire 1899 func (s MySem) P() { 1900 if s.inUse { 1901 select { 1902 case <-s.c: 1903 } 1904 } 1905 s.inUse = true 1906 } 1907 1908 // release 1909 func (s MySem) V() { 1910 s.inUse = false 1911 1912 // This actually deadlocks 1913 // when single thread 1914 s.c <- false 1915 } 1916 \end{Go} 2072 In summation, for internal scheduling, non-blocking signalling (as in the producer/consumer example) is used when the signaller is providing the cooperation for a waiting thread; 2073 the signaller enters the monitor and changes state, detects a waiting threads that can use the state, performs a non-blocking signal on the condition queue for the waiting thread, and exits the monitor to run concurrently. 2074 The waiter unblocks next from the urgent queue, uses/takes the state, and exits the monitor. 2075 Blocking signal is the reverse, where the waiter is providing the cooperation for the signalling thread; 2076 the signaller enters the monitor, detects a waiting thread providing the necessary state, performs a blocking signal to place it on the urgent queue and unblock the waiter. 2077 The waiter changes state and exits the monitor, and the signaller unblocks next from the urgent queue to use/take the state. 2078 2079 Both internal and external scheduling extend to multiple monitors in a natural way. 2080 \begin{cquote} 2081 \begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}} 2082 \begin{cfa} 2083 monitor M { `condition e`; ... }; 2084 void foo( M & mutex m1, M & mutex m2 ) { 2085 ... wait( `e` ); ... // wait( e, m1, m2 ) 2086 ... wait( `e, m1` ); ... 2087 ... wait( `e, m2` ); ... 2088 } 2089 \end{cfa} 2090 & 2091 \begin{cfa} 2092 void rtn$\(_1\)$( M & mutex m1, M & mutex m2 ); 2093 void rtn$\(_2\)$( M & mutex m1 ); 2094 void bar( M & mutex m1, M & mutex m2 ) { 2095 ... waitfor( `rtn` ); ... // $\LstCommentStyle{waitfor( rtn\(_1\), m1, m2 )}$ 2096 ... waitfor( `rtn, m1` ); ... // $\LstCommentStyle{waitfor( rtn\(_2\), m1 )}$ 2097 } 2098 \end{cfa} 1917 2099 \end{tabular} 1918 \caption{Different forms of scheduling.} 1919 \label{tbl:sched} 1920 \end{table} 1921 \end{comment} 1922 1923 This method is more constrained and explicit, which helps users reduce the non-deterministic nature of concurrency. 1924 Indeed, as the following examples demonstrate, external scheduling allows users to wait for events from other threads without the concern of unrelated events occurring. 1925 External scheduling can generally be done either in terms of control flow (\eg Ada with @accept@, \uC with @_Accept@) or in terms of data (\eg Go with channels). 1926 Of course, both of these paradigms have their own strengths and weaknesses, but for this project, control-flow semantics was chosen to stay consistent with the rest of the languages semantics. 1927 Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multiple-monitor routines. 1928 The previous example shows a simple use @_Accept@ versus @wait@/@signal@ and its advantages. 1929 Note that while other languages often use @accept@/@select@ as the core external scheduling keyword, \CFA uses @waitfor@ to prevent name collisions with existing socket \textbf{api}s. 1930 1931 For the @P@ member above using internal scheduling, the call to @wait@ only guarantees that @V@ is the last routine to access the monitor, allowing a third routine, say @isInUse()@, acquire mutual exclusion several times while routine @P@ is waiting. 1932 On the other hand, external scheduling guarantees that while routine @P@ is waiting, no other routine than @V@ can acquire the monitor. 1933 1934 % ====================================================================== 1935 % ====================================================================== 1936 \subsection{Loose Object Definitions} 1937 % ====================================================================== 1938 % ====================================================================== 1939 In \uC, a monitor class declaration includes an exhaustive list of monitor operations. 1940 Since \CFA is not object oriented, monitors become both more difficult to implement and less clear for a user: 1941 1942 \begin{cfa} 1943 monitor A {}; 1944 1945 void f(A & mutex a); 1946 void g(A & mutex a) { 1947 waitfor(f); // Obvious which f() to wait for 1948 } 1949 1950 void f(A & mutex a, int); // New different F added in scope 1951 void h(A & mutex a) { 1952 waitfor(f); // Less obvious which f() to wait for 1953 } 1954 \end{cfa} 1955 1956 Furthermore, external scheduling is an example where implementation constraints become visible from the interface. 1957 Here is the cfa-code for the entering phase of a monitor: 1958 \begin{center} 1959 \begin{tabular}{l} 1960 \begin{cfa} 1961 if monitor is free 1962 enter 1963 elif already own the monitor 1964 continue 1965 elif monitor accepts me 1966 enter 1967 else 1968 block 1969 \end{cfa} 1970 \end{tabular} 1971 \end{center} 1972 For the first two conditions, it is easy to implement a check that can evaluate the condition in a few instructions. 1973 However, a fast check for @monitor accepts me@ is much harder to implement depending on the constraints put on the monitors. 1974 Indeed, monitors are often expressed as an entry queue and some acceptor queue as in Figure~\ref{fig:ClassicalMonitor}. 2100 \end{cquote} 2101 For @wait( e )@, the default semantics is to atomically block the signaller and release all acquired mutex parameters, \ie @wait( e, m1, m2 )@. 2102 To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @wait( e, m1 )@. 2103 Wait cannot statically verifies the released monitors are the acquired mutex-parameters without disallowing separately compiled helper functions calling @wait@. 2104 While \CC supports bulk locking, @wait@ only accepts a single lock for a condition variable, so bulk locking with condition variables is asymmetric. 2105 Finally, a signaller, 2106 \begin{cfa} 2107 void baz( M & mutex m1, M & mutex m2 ) { 2108 ... signal( e ); ... 2109 } 2110 \end{cfa} 2111 must have acquired at least the same locks as the waiting thread signalled from a condition queue to allow the locks to be passed, and hence, prevent barging. 2112 2113 Similarly, for @waitfor( rtn )@, the default semantics is to atomically block the acceptor and release all acquired mutex parameters, \ie @waitfor( rtn, m1, m2 )@. 2114 To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @waitfor( rtn, m1 )@. 2115 @waitfor@ does statically verify the monitor types passed are the same as the acquired mutex-parameters of the given function or function pointer, hence the function (pointer) prototype must be accessible. 2116 % When an overloaded function appears in an @waitfor@ statement, calls to any function with that name are accepted. 2117 % The rationale is that members with the same name should perform a similar function, and therefore, all should be eligible to accept a call. 2118 Overloaded functions can be disambiguated using a cast 2119 \begin{cfa} 2120 void rtn( M & mutex m ); 2121 `int` rtn( M & mutex m ); 2122 waitfor( (`int` (*)( M & mutex ))rtn, m ); 2123 \end{cfa} 2124 2125 The ability to release a subset of acquired monitors can result in a \newterm{nested monitor}~\cite{Lister77} deadlock. 2126 \begin{cfa} 2127 void foo( M & mutex m1, M & mutex m2 ) { 2128 ... wait( `e, m1` ); ... $\C{// release m1, keeping m2 acquired )}$ 2129 void bar( M & mutex m1, M & mutex m2 ) { $\C{// must acquire m1 and m2 )}$ 2130 ... signal( `e` ); ... 2131 \end{cfa} 2132 The @wait@ only releases @m1@ so the signalling thread cannot acquire @m1@ and @m2@ to enter @bar@ and @signal@ the condition. 2133 While deadlock can occur with multiple/nesting acquisition, this is a consequence of locks, and by extension monitors, not being perfectly composable. 2134 2135 2136 2137 \subsection{\texorpdfstring{Extended \protect\lstinline@waitfor@}{Extended waitfor}} 2138 2139 Figure~\ref{f:ExtendedWaitfor} shows the extended form of the @waitfor@ statement to conditionally accept one of a group of mutex functions, with an optional statement to be performed \emph{after} the mutex function finishes. 2140 For a @waitfor@ clause to be executed, its @when@ must be true and an outstanding call to its corresponding member(s) must exist. 2141 The \emph{conditional-expression} of a @when@ may call a function, but the function must not block or context switch. 2142 If there are multiple acceptable mutex calls, selection occurs top-to-bottom (prioritized) among the @waitfor@ clauses, whereas some programming languages with similar mechanisms accept nondeterministically for this case, \eg Go \lstinline[morekeywords=select]@select@. 2143 If some accept guards are true and there are no outstanding calls to these members, the acceptor is blocked until a call to one of these members is made. 2144 If there is a @timeout@ clause, it provides an upper bound on waiting. 2145 If all the accept guards are false, the statement does nothing, unless there is a terminating @else@ clause with a true guard, which is executed instead. 2146 Hence, the terminating @else@ clause allows a conditional attempt to accept a call without blocking. 2147 If both @timeout@ and @else@ clause are present, the @else@ must be conditional, or the @timeout@ is never triggered. 2148 There is also a traditional future wait queue (not shown) (\eg Microsoft (@WaitForMultipleObjects@)), to wait for a specified number of future elements in the queue. 1975 2149 1976 2150 \begin{figure} 1977 2151 \centering 1978 \subfloat[Classical Monitor] { 1979 \label{fig:ClassicalMonitor} 1980 {\resizebox{0.45\textwidth}{!}{\input{monitor}}} 1981 }% subfloat 1982 \qquad 1983 \subfloat[bulk acquire Monitor] { 1984 \label{fig:BulkMonitor} 1985 {\resizebox{0.45\textwidth}{!}{\input{ext_monitor}}} 1986 }% subfloat 1987 \caption{External Scheduling Monitor} 2152 \begin{cfa} 2153 `when` ( $\emph{conditional-expression}$ ) $\C{// optional guard}$ 2154 waitfor( $\emph{mutex-member-name}$ ) $\emph{statement}$ $\C{// action after call}$ 2155 `or` `when` ( $\emph{conditional-expression}$ ) $\C{// any number of functions}$ 2156 waitfor( $\emph{mutex-member-name}$ ) $\emph{statement}$ 2157 `or` ... 2158 `when` ( $\emph{conditional-expression}$ ) $\C{// optional guard}$ 2159 `timeout` $\emph{statement}$ $\C{// optional terminating timeout clause}$ 2160 `when` ( $\emph{conditional-expression}$ ) $\C{// optional guard}$ 2161 `else` $\emph{statement}$ $\C{// optional terminating clause}$ 2162 \end{cfa} 2163 \caption{Extended \protect\lstinline@waitfor@} 2164 \label{f:ExtendedWaitfor} 1988 2165 \end{figure} 1989 2166 1990 There are other alternatives to these pictures, but in the case of the left picture, implementing a fast accept check is relatively easy. 1991 Restricted to a fixed number of mutex members, N, the accept check reduces to updating a bitmask when the acceptor queue changes, a check that executes in a single instruction even with a fairly large number (\eg 128) of mutex members. 1992 This approach requires a unique dense ordering of routines with an upper-bound and that ordering must be consistent across translation units. 1993 For OO languages these constraints are common, since objects only offer adding member routines consistently across translation units via inheritance. 1994 However, in \CFA users can extend objects with mutex routines that are only visible in certain translation unit. 1995 This means that establishing a program-wide dense-ordering among mutex routines can only be done in the program linking phase, and still could have issues when using dynamically shared objects. 1996 1997 The alternative is to alter the implementation as in Figure~\ref{fig:BulkMonitor}. 1998 Here, the mutex routine called is associated with a thread on the entry queue while a list of acceptable routines is kept separate. 1999 Generating a mask dynamically means that the storage for the mask information can vary between calls to @waitfor@, allowing for more flexibility and extensions. 2000 Storing an array of accepted routine pointers replaces the single instruction bitmask comparison with dereferencing a pointer followed by a linear search. 2001 Furthermore, supporting nested external scheduling (\eg listing \ref{f:nest-ext}) may now require additional searches for the @waitfor@ statement to check if a routine is already queued. 2167 Note, a group of conditional @waitfor@ clauses is \emph{not} the same as a group of @if@ statements, \eg: 2168 \begin{cfa} 2169 if ( C1 ) waitfor( mem1 ); when ( C1 ) waitfor( mem1 ); 2170 else if ( C2 ) waitfor( mem2 ); or when ( C2 ) waitfor( mem2 ); 2171 \end{cfa} 2172 The left example only accepts @mem1@ if @C1@ is true or only @mem2@ if @C2@ is true. 2173 The right example accepts either @mem1@ or @mem2@ if @C1@ and @C2@ are true. 2174 2175 An interesting use of @waitfor@ is accepting the @mutex@ destructor to know when an object is deallocated, \eg assume the bounded buffer is restructred from a monitor to a thread with the following @main@. 2176 \begin{cfa} 2177 void main( Buffer(T) & buffer ) with(buffer) { 2178 for () { 2179 `waitfor( ^?{}, buffer )` break; 2180 or when ( count != 20 ) waitfor( insert, buffer ) { ... } 2181 or when ( count != 0 ) waitfor( remove, buffer ) { ... } 2182 } 2183 // clean up 2184 } 2185 \end{cfa} 2186 When the program main deallocates the buffer, it first calls the buffer's destructor, which is accepted, the destructor runs, and the buffer is deallocated. 2187 However, the buffer thread cannot continue after the destructor call because the object is gone; 2188 hence, clean up in @main@ cannot occur, which means destructors for local objects are not run. 2189 To make this useful capability work, the semantics for accepting the destructor is the same as @signal@, \ie the destructor call is placed on urgent and the acceptor continues execution, which ends the loop, cleans up, and the thread terminates. 2190 Then, the destructor caller unblocks from urgent to deallocate the object. 2191 Accepting the destructor is the idiomatic way in \CFA to terminate a thread performing direct communication. 2192 2193 2194 \subsection{Bulk Barging Prevention} 2195 2196 Figure~\ref{f:BulkBargingPrevention} shows \CFA code where bulk acquire adds complexity to the internal-signalling semantics. 2197 The complexity begins at the end of the inner @mutex@ statement, where the semantics of internal scheduling need to be extended for multiple monitors. 2198 The problem is that bulk acquire is used in the inner @mutex@ statement where one of the monitors is already acquired. 2199 When the signalling thread reaches the end of the inner @mutex@ statement, it should transfer ownership of @m1@ and @m2@ to the waiting threads to prevent barging into the outer @mutex@ statement by another thread. 2200 However, both the signalling and waiting threads W1 and W2 need some subset of monitors @m1@ and @m2@. 2201 \begin{cquote} 2202 condition c: (order 1) W2(@m2@), W1(@m1@,@m2@)\ \ \ or\ \ \ (order 2) W1(@m1@,@m2@), W2(@m2@) \\ 2203 S: acq. @m1@ $\rightarrow$ acq. @m1,m2@ $\rightarrow$ @signal(c)@ $\rightarrow$ rel. @m2@ $\rightarrow$ pass @m2@ unblock W2 (order 2) $\rightarrow$ rel. @m1@ $\rightarrow$ pass @m1,m2@ unblock W1 \\ 2204 \hspace*{2.75in}$\rightarrow$ rel. @m1@ $\rightarrow$ pass @m1,m2@ unblock W1 (order 1) 2205 \end{cquote} 2002 2206 2003 2207 \begin{figure} 2004 \begin{cfa}[caption={Example of nested external scheduling},label={f:nest-ext}] 2005 monitor M {}; 2006 void foo( M & mutex a ) {} 2007 void bar( M & mutex b ) { 2008 // Nested in the waitfor(bar, c) call 2009 waitfor(foo, b); 2010 } 2011 void baz( M & mutex c ) { 2012 waitfor(bar, c); 2013 } 2014 2015 \end{cfa} 2208 \newbox\myboxA 2209 \begin{lrbox}{\myboxA} 2210 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 2211 monitor M m1, m2; 2212 condition c; 2213 mutex( m1 ) { // $\LstCommentStyle{\color{red}outer}$ 2214 ... 2215 mutex( m1, m2 ) { // $\LstCommentStyle{\color{red}inner}$ 2216 ... `signal( c )`; ... 2217 // m1, m2 still acquired 2218 } // $\LstCommentStyle{\color{red}release m2}$ 2219 // m1 acquired 2220 } // release m1 2221 \end{cfa} 2222 \end{lrbox} 2223 2224 \newbox\myboxB 2225 \begin{lrbox}{\myboxB} 2226 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 2227 2228 2229 mutex( m1 ) { 2230 ... 2231 mutex( m1, m2 ) { 2232 ... `wait( c )`; // release m1, m2 2233 // m1, m2 reacquired 2234 } // $\LstCommentStyle{\color{red}release m2}$ 2235 // m1 acquired 2236 } // release m1 2237 \end{cfa} 2238 \end{lrbox} 2239 2240 \newbox\myboxC 2241 \begin{lrbox}{\myboxC} 2242 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 2243 2244 2245 mutex( m2 ) { 2246 ... `wait( c )`; // release m2 2247 // m2 reacquired 2248 } // $\LstCommentStyle{\color{red}release m2}$ 2249 2250 2251 2252 2253 \end{cfa} 2254 \end{lrbox} 2255 2256 \begin{cquote} 2257 \subfloat[Signalling Thread (S)]{\label{f:SignallingThread}\usebox\myboxA} 2258 \hspace{3\parindentlnth} 2259 \subfloat[Waiting Thread (W1)]{\label{f:WaitingThread}\usebox\myboxB} 2260 \hspace{2\parindentlnth} 2261 \subfloat[Waiting Thread (W2)]{\label{f:OtherWaitingThread}\usebox\myboxC} 2262 \end{cquote} 2263 \caption{Bulk Barging Prevention} 2264 \label{f:BulkBargingPrevention} 2016 2265 \end{figure} 2017 2266 2018 Note that in the right picture, tasks need to always keep track of the monitors associated with mutex routines, and the routine mask needs to have both a routine pointer and a set of monitors, as is discussed in the next section. 2019 These details are omitted from the picture for the sake of simplicity. 2020 2021 At this point, a decision must be made between flexibility and performance. 2022 Many design decisions in \CFA achieve both flexibility and performance, for example polymorphic routines add significant flexibility but inlining them means the optimizer can easily remove any runtime cost. 2023 Here, however, the cost of flexibility cannot be trivially removed. 2024 In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be hard to write. 2025 This decision is based on the assumption that writing fast but inflexible locks is closer to a solved problem than writing locks that are as flexible as external scheduling in \CFA. 2026 2027 % ====================================================================== 2028 % ====================================================================== 2267 One scheduling solution is for the signaller S to keep ownership of all locks until the last lock is ready to be transferred, because this semantics fits most closely to the behaviour of single-monitor scheduling. 2268 However, this solution is inefficient if W2 waited first and can be immediate passed @m2@ when released, while S retains @m1@ until completion of the outer mutex statement. 2269 If W1 waited first, the signaller must retain @m1@ amd @m2@ until completion of the outer mutex statement and then pass both to W1. 2270 % Furthermore, there is an execution sequence where the signaller always finds waiter W2, and hence, waiter W1 starves. 2271 To support this efficient semantics (and prevent barging), the implementation maintains a list of monitors acquired for each blocked thread. 2272 When a signaller exits or waits in a monitor function/statement, the front waiter on urgent is unblocked if all its monitors are released. 2273 Implementing a fast subset check for the necessary released monitors is important. 2274 % The benefit is encapsulating complexity into only two actions: passing monitors to the next owner when they should be released and conditionally waking threads if all conditions are met. 2275 2276 2277 \subsection{Loose Object Definitions} 2278 \label{s:LooseObjectDefinitions} 2279 2280 In an object-oriented programming language, a class includes an exhaustive list of operations. 2281 A new class can add members via static inheritance but the subclass still has an exhaustive list of operations. 2282 (Dynamic member adding, \eg JavaScript~\cite{JavaScript}, is not considered.) 2283 In the object-oriented scenario, the type and all its operators are always present at compilation (even separate compilation), so it is possible to number the operations in a bit mask and use an $O(1)$ compare with a similar bit mask created for the operations specified in a @waitfor@. 2284 2285 However, in \CFA, monitor functions can be statically added/removed in translation units, making a fast subset check difficult. 2286 \begin{cfa} 2287 monitor M { ... }; // common type, included in .h file 2288 translation unit 1 2289 void `f`( M & mutex m ); 2290 void g( M & mutex m ) { waitfor( `f`, m ); } 2291 translation unit 2 2292 void `f`( M & mutex m ); $\C{// replacing f and g for type M in this translation unit}$ 2293 void `g`( M & mutex m ); 2294 void h( M & mutex m ) { waitfor( `f`, m ) or waitfor( `g`, m ); } $\C{// extending type M in this translation unit}$ 2295 \end{cfa} 2296 The @waitfor@ statements in each translation unit cannot form a unique bit-mask because the monitor type does not carry that information. 2297 Hence, function pointers are used to identify the functions listed in the @waitfor@ statement, stored in a variable-sized array. 2298 Then, the same implementation approach used for the urgent stack is used for the calling queue. 2299 Each caller has a list of monitors acquired, and the @waitfor@ statement performs a (usually short) linear search matching functions in the @waitfor@ list with called functions, and then verifying the associated mutex locks can be transfers. 2300 (A possible way to construct a dense mapping is at link or load-time.) 2301 2302 2029 2303 \subsection{Multi-Monitor Scheduling} 2030 % ====================================================================== 2031 % ====================================================================== 2032 2033 External scheduling, like internal scheduling, becomes significantly more complex when introducing multi-monitor syntax. 2034 Even in the simplest possible case, some new semantics needs to be established: 2035 \begin{cfa} 2036 monitor M {}; 2037 2038 void f(M & mutex a); 2039 2040 void g(M & mutex b, M & mutex c) { 2041 waitfor(f); // two monitors M => unknown which to pass to f(M & mutex) 2042 } 2043 \end{cfa} 2044 The obvious solution is to specify the correct monitor as follows: 2045 2046 \begin{cfa} 2047 monitor M {}; 2048 2049 void f(M & mutex a); 2050 2051 void g(M & mutex a, M & mutex b) { 2052 // wait for call to f with argument b 2053 waitfor(f, b); 2054 } 2055 \end{cfa} 2056 This syntax is unambiguous. 2057 Both locks are acquired and kept by @g@. 2058 When routine @f@ is called, the lock for monitor @b@ is temporarily transferred from @g@ to @f@ (while @g@ still holds lock @a@). 2059 This behaviour can be extended to the multi-monitor @waitfor@ statement as follows. 2060 2061 \begin{cfa} 2062 monitor M {}; 2063 2064 void f(M & mutex a, M & mutex b); 2065 2066 void g(M & mutex a, M & mutex b) { 2067 // wait for call to f with arguments a and b 2068 waitfor(f, a, b); 2069 } 2070 \end{cfa} 2071 2072 Note that the set of monitors passed to the @waitfor@ statement must be entirely contained in the set of monitors already acquired in the routine. @waitfor@ used in any other context is undefined behaviour. 2073 2074 An important behaviour to note is when a set of monitors only match partially: 2075 2076 \begin{cfa} 2077 mutex struct A {}; 2078 2079 mutex struct B {}; 2080 2081 void g(A & mutex a, B & mutex b) { 2082 waitfor(f, a, b); 2083 } 2084 2085 A a1, a2; 2086 B b; 2087 2088 void foo() { 2089 g(a1, b); // block on accept 2090 } 2091 2092 void bar() { 2093 f(a2, b); // fulfill cooperation 2094 } 2095 \end{cfa} 2096 While the equivalent can happen when using internal scheduling, the fact that conditions are specific to a set of monitors means that users have to use two different condition variables. 2097 In both cases, partially matching monitor sets does not wakeup the waiting thread. 2098 It is also important to note that in the case of external scheduling the order of parameters is irrelevant; @waitfor(f,a,b)@ and @waitfor(f,b,a)@ are indistinguishable waiting condition. 2099 2100 % ====================================================================== 2101 % ====================================================================== 2102 \subsection{\protect\lstinline|waitfor| Semantics} 2103 % ====================================================================== 2104 % ====================================================================== 2105 2106 Syntactically, the @waitfor@ statement takes a routine identifier and a set of monitors. 2107 While the set of monitors can be any list of expressions, the routine name is more restricted because the compiler validates at compile time the validity of the routine type and the parameters used with the @waitfor@ statement. 2108 It checks that the set of monitors passed in matches the requirements for a routine call. 2109 Figure~\ref{f:waitfor} shows various usages of the waitfor statement and which are acceptable. 2110 The choice of the routine type is made ignoring any non-@mutex@ parameter. 2111 One limitation of the current implementation is that it does not handle overloading, but overloading is possible. 2304 \label{s:Multi-MonitorScheduling} 2305 2306 External scheduling, like internal scheduling, becomes significantly more complex for multi-monitor semantics. 2307 Even in the simplest case, new semantics need to be established. 2308 \begin{cfa} 2309 monitor M { ... }; 2310 void f( M & mutex m1 ); 2311 void g( M & mutex m1, M & mutex m2 ) { `waitfor( f );` } $\C{// pass m1 or m2 to f?}$ 2312 \end{cfa} 2313 The solution is for the programmer to disambiguate: 2314 \begin{cfa} 2315 waitfor( f, `m2` ); $\C{// wait for call to f with argument m2}$ 2316 \end{cfa} 2317 Both locks are acquired by function @g@, so when function @f@ is called, the lock for monitor @m2@ is passed from @g@ to @f@, while @g@ still holds lock @m1@. 2318 This behaviour can be extended to the multi-monitor @waitfor@ statement. 2319 \begin{cfa} 2320 monitor M { ... }; 2321 void f( M & mutex m1, M & mutex m2 ); 2322 void g( M & mutex m1, M & mutex m2 ) { waitfor( f, `m1, m2` ); $\C{// wait for call to f with arguments m1 and m2}$ 2323 \end{cfa} 2324 Again, the set of monitors passed to the @waitfor@ statement must be entirely contained in the set of monitors already acquired by the accepting function. 2325 Also, the order of the monitors in a @waitfor@ statement is unimportant. 2326 2327 Figure~\ref{f:UnmatchedMutexSets} shows an example where, for internal and external scheduling with multiple monitors, a signalling or accepting thread must match exactly, \ie partial matching results in waiting. 2328 For both examples, the set of monitors is disjoint so unblocking is impossible. 2329 2112 2330 \begin{figure} 2113 \begin{cfa}[caption={Various correct and incorrect uses of the waitfor statement},label={f:waitfor}] 2114 monitor A{}; 2115 monitor B{}; 2116 2117 void f1( A & mutex ); 2118 void f2( A & mutex, B & mutex ); 2119 void f3( A & mutex, int ); 2120 void f4( A & mutex, int ); 2121 void f4( A & mutex, double ); 2122 2123 void foo( A & mutex a1, A & mutex a2, B & mutex b1, B & b2 ) { 2124 A * ap = & a1; 2125 void (*fp)( A & mutex ) = f1; 2126 2127 waitfor(f1, a1); // Correct : 1 monitor case 2128 waitfor(f2, a1, b1); // Correct : 2 monitor case 2129 waitfor(f3, a1); // Correct : non-mutex arguments are ignored 2130 waitfor(f1, *ap); // Correct : expression as argument 2131 2132 waitfor(f1, a1, b1); // Incorrect : Too many mutex arguments 2133 waitfor(f2, a1); // Incorrect : Too few mutex arguments 2134 waitfor(f2, a1, a2); // Incorrect : Mutex arguments don't match 2135 waitfor(f1, 1); // Incorrect : 1 not a mutex argument 2136 waitfor(f9, a1); // Incorrect : f9 routine does not exist 2137 waitfor(*fp, a1 ); // Incorrect : fp not an identifier 2138 waitfor(f4, a1); // Incorrect : f4 ambiguous 2139 2140 waitfor(f2, a1, b2); // Undefined behaviour : b2 not mutex 2141 } 2142 \end{cfa} 2331 \centering 2332 \begin{lrbox}{\myboxA} 2333 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 2334 monitor M1 {} m11, m12; 2335 monitor M2 {} m2; 2336 condition c; 2337 void f( M1 & mutex m1, M2 & mutex m2 ) { 2338 signal( c ); 2339 } 2340 void g( M1 & mutex m1, M2 & mutex m2 ) { 2341 wait( c ); 2342 } 2343 g( `m11`, m2 ); // block on wait 2344 f( `m12`, m2 ); // cannot fulfil 2345 \end{cfa} 2346 \end{lrbox} 2347 2348 \begin{lrbox}{\myboxB} 2349 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 2350 monitor M1 {} m11, m12; 2351 monitor M2 {} m2; 2352 2353 void f( M1 & mutex m1, M2 & mutex m2 ) { 2354 2355 } 2356 void g( M1 & mutex m1, M2 & mutex m2 ) { 2357 waitfor( f, m1, m2 ); 2358 } 2359 g( `m11`, m2 ); // block on accept 2360 f( `m12`, m2 ); // cannot fulfil 2361 \end{cfa} 2362 \end{lrbox} 2363 \subfloat[Internal scheduling]{\label{f:InternalScheduling}\usebox\myboxA} 2364 \hspace{3pt} 2365 \vrule 2366 \hspace{3pt} 2367 \subfloat[External scheduling]{\label{f:ExternalScheduling}\usebox\myboxB} 2368 \caption{Unmatched \protect\lstinline@mutex@ sets} 2369 \label{f:UnmatchedMutexSets} 2143 2370 \end{figure} 2144 2371 2145 Finally, for added flexibility, \CFA supports constructing a complex @waitfor@ statement using the @or@, @timeout@ and @else@. 2146 Indeed, multiple @waitfor@ clauses can be chained together using @or@; this chain forms a single statement that uses baton pass to any routine that fits one of the routine+monitor set passed in. 2147 To enable users to tell which accepted routine executed, @waitfor@s are followed by a statement (including the null statement @;@) or a compound statement, which is executed after the clause is triggered. 2148 A @waitfor@ chain can also be followed by a @timeout@, to signify an upper bound on the wait, or an @else@, to signify that the call should be non-blocking, which checks for a matching routine call already arrived and otherwise continues. 2149 Any and all of these clauses can be preceded by a @when@ condition to dynamically toggle the accept clauses on or off based on some current state. 2150 Figure~\ref{f:waitfor2} demonstrates several complex masks and some incorrect ones. 2372 2373 \subsection{\texorpdfstring{\protect\lstinline@mutex@ Threads}{mutex Threads}} 2374 2375 Threads in \CFA can also be monitors to allow \emph{direct communication} among threads, \ie threads can have mutex functions that are called by other threads. 2376 Hence, all monitor features are available when using threads. 2377 Figure~\ref{f:DirectCommunication} shows a comparison of direct call communication in \CFA with direct channel communication in Go. 2378 (Ada provides a similar mechanism to the \CFA direct communication.) 2379 The program main in both programs communicates directly with the other thread versus indirect communication where two threads interact through a passive monitor. 2380 Both direct and indirection thread communication are valuable tools in structuring concurrent programs. 2151 2381 2152 2382 \begin{figure} 2153 \lstset{language=CFA,deletedelim=**[is][]{`}{`}} 2154 \begin{cfa} 2155 monitor A{}; 2156 2157 void f1( A & mutex ); 2158 void f2( A & mutex ); 2159 2160 void foo( A & mutex a, bool b, int t ) { 2161 waitfor(f1, a); $\C{// Correct : blocking case}$ 2162 2163 waitfor(f1, a) { $\C{// Correct : block with statement}$ 2164 sout | "f1" | endl; 2383 \centering 2384 \begin{lrbox}{\myboxA} 2385 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 2386 2387 struct Msg { int i, j; }; 2388 thread GoRtn { int i; float f; Msg m; }; 2389 void mem1( GoRtn & mutex gortn, int i ) { gortn.i = i; } 2390 void mem2( GoRtn & mutex gortn, float f ) { gortn.f = f; } 2391 void mem3( GoRtn & mutex gortn, Msg m ) { gortn.m = m; } 2392 void ^?{}( GoRtn & mutex ) {} 2393 2394 void main( GoRtn & gortn ) with( gortn ) { // thread starts 2395 2396 for () { 2397 2398 `waitfor( mem1, gortn )` sout | i; // wait for calls 2399 or `waitfor( mem2, gortn )` sout | f; 2400 or `waitfor( mem3, gortn )` sout | m.i | m.j; 2401 or `waitfor( ^?{}, gortn )` break; 2402 2165 2403 } 2166 waitfor(f1, a) { $\C{// Correct : block waiting for f1 or f2}$ 2167 sout | "f1" | endl; 2168 } or waitfor(f2, a) { 2169 sout | "f2" | endl; 2404 2405 } 2406 int main() { 2407 GoRtn gortn; $\C[2.0in]{// start thread}$ 2408 `mem1( gortn, 0 );` $\C{// different calls}\CRT$ 2409 `mem2( gortn, 2.5 );` 2410 `mem3( gortn, (Msg){1, 2} );` 2411 2412 2413 } // wait for completion 2414 \end{cfa} 2415 \end{lrbox} 2416 2417 \begin{lrbox}{\myboxB} 2418 \begin{Go}[aboveskip=0pt,belowskip=0pt] 2419 func main() { 2420 type Msg struct{ i, j int } 2421 2422 ch1 := make( chan int ) 2423 ch2 := make( chan float32 ) 2424 ch3 := make( chan Msg ) 2425 hand := make( chan string ) 2426 shake := make( chan string ) 2427 gortn := func() { $\C[1.5in]{// thread starts}$ 2428 var i int; var f float32; var m Msg 2429 L: for { 2430 select { $\C{// wait for messages}$ 2431 case `i = <- ch1`: fmt.Println( i ) 2432 case `f = <- ch2`: fmt.Println( f ) 2433 case `m = <- ch3`: fmt.Println( m ) 2434 case `<- hand`: break L $\C{// sentinel}$ 2435 } 2436 } 2437 `shake <- "SHAKE"` $\C{// completion}$ 2170 2438 } 2171 waitfor(f1, a); or else; $\C{// Correct : non-blocking case}$ 2172 2173 waitfor(f1, a) { $\C{// Correct : non-blocking case}$ 2174 sout | "blocked" | endl; 2175 } or else { 2176 sout | "didn't block" | endl; 2439 2440 go gortn() $\C{// start thread}$ 2441 `ch1 <- 0` $\C{// different messages}$ 2442 `ch2 <- 2.5` 2443 `ch3 <- Msg{1, 2}` 2444 `hand <- "HAND"` $\C{// sentinel value}$ 2445 `<- shake` $\C{// wait for completion}\CRT$ 2446 } 2447 \end{Go} 2448 \end{lrbox} 2449 2450 \subfloat[\CFA]{\label{f:CFAwaitfor}\usebox\myboxA} 2451 \hspace{3pt} 2452 \vrule 2453 \hspace{3pt} 2454 \subfloat[Go]{\label{f:Gochannel}\usebox\myboxB} 2455 \caption{Direct communication} 2456 \label{f:DirectCommunication} 2457 \end{figure} 2458 2459 \begin{comment} 2460 The following shows an example of two threads directly calling each other and accepting calls from each other in a cycle. 2461 \begin{cfa} 2462 \end{cfa} 2463 \vspace{-0.8\baselineskip} 2464 \begin{cquote} 2465 \begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}} 2466 \begin{cfa} 2467 thread Ping {} pi; 2468 void ping( Ping & mutex ) {} 2469 void main( Ping & pi ) { 2470 for ( 10 ) { 2471 `waitfor( ping, pi );` 2472 `pong( po );` 2177 2473 } 2178 waitfor(f1, a) { $\C{// Correct : block at most 10 seconds}$ 2179 sout | "blocked" | endl; 2180 } or timeout( 10`s) { 2181 sout | "didn't block" | endl; 2474 } 2475 int main() {} 2476 \end{cfa} 2477 & 2478 \begin{cfa} 2479 thread Pong {} po; 2480 void pong( Pong & mutex ) {} 2481 void main( Pong & po ) { 2482 for ( 10 ) { 2483 `ping( pi );` 2484 `waitfor( pong, po );` 2182 2485 } 2183 // Correct : block only if b == true if b == false, don't even make the call 2184 when(b) waitfor(f1, a); 2185 2186 // Correct : block only if b == true if b == false, make non-blocking call 2187 waitfor(f1, a); or when(!b) else; 2188 2189 // Correct : block only of t > 1 2190 waitfor(f1, a); or when(t > 1) timeout(t); or else; 2191 2192 // Incorrect : timeout clause is dead code 2193 waitfor(f1, a); or timeout(t); or else; 2194 2195 // Incorrect : order must be waitfor [or waitfor... [or timeout] [or else]] 2196 timeout(t); or waitfor(f1, a); or else; 2197 } 2198 \end{cfa} 2199 \caption{Correct and incorrect uses of the or, else, and timeout clause around a waitfor statement} 2200 \label{f:waitfor2} 2201 \end{figure} 2202 2203 % ====================================================================== 2204 % ====================================================================== 2205 \subsection{Waiting For The Destructor} 2206 % ====================================================================== 2207 % ====================================================================== 2208 An interesting use for the @waitfor@ statement is destructor semantics. 2209 Indeed, the @waitfor@ statement can accept any @mutex@ routine, which includes the destructor (see section \ref{data}). 2210 However, with the semantics discussed until now, waiting for the destructor does not make any sense, since using an object after its destructor is called is undefined behaviour. 2211 The simplest approach is to disallow @waitfor@ on a destructor. 2212 However, a more expressive approach is to flip ordering of execution when waiting for the destructor, meaning that waiting for the destructor allows the destructor to run after the current @mutex@ routine, similarly to how a condition is signalled. 2213 \begin{figure} 2214 \begin{cfa}[caption={Example of an executor which executes action in series until the destructor is called.},label={f:dtor-order}] 2215 monitor Executer {}; 2216 struct Action; 2217 2218 void ^?{} (Executer & mutex this); 2219 void execute(Executer & mutex this, const Action & ); 2220 void run (Executer & mutex this) { 2221 while(true) { 2222 waitfor(execute, this); 2223 or waitfor(^?{} , this) { 2224 break; 2225 } 2226 } 2227 } 2228 \end{cfa} 2229 \end{figure} 2230 For example, listing \ref{f:dtor-order} shows an example of an executor with an infinite loop, which waits for the destructor to break out of this loop. 2231 Switching the semantic meaning introduces an idiomatic way to terminate a task and/or wait for its termination via destruction. 2232 2233 2234 % ###### # ###### # # # ####### # ### ##### # # 2235 % # # # # # # # # # # # # # # # ## ## 2236 % # # # # # # # # # # # # # # # # # # 2237 % ###### # # ###### # # # # ##### # # ##### # # # 2238 % # ####### # # ####### # # # # # # # # 2239 % # # # # # # # # # # # # # # # # 2240 % # # # # # # # ####### ####### ####### ####### ### ##### # # 2241 \section{Parallelism} 2242 Historically, computer performance was about processor speeds and instruction counts. 2243 However, with heat dissipation being a direct consequence of speed increase, parallelism has become the new source for increased performance~\cite{Sutter05, Sutter05b}. 2244 In this decade, it is no longer reasonable to create a high-performance application without caring about parallelism. 2245 Indeed, parallelism is an important aspect of performance and more specifically throughput and hardware utilization. 2246 The lowest-level approach of parallelism is to use \textbf{kthread} in combination with semantics like @fork@, @join@, \etc. 2247 However, since these have significant costs and limitations, \textbf{kthread} are now mostly used as an implementation tool rather than a user oriented one. 2248 There are several alternatives to solve these issues that all have strengths and weaknesses. 2249 While there are many variations of the presented paradigms, most of these variations do not actually change the guarantees or the semantics, they simply move costs in order to achieve better performance for certain workloads. 2250 2251 \section{Paradigms} 2252 \subsection{User-Level Threads} 2253 A direct improvement on the \textbf{kthread} approach is to use \textbf{uthread}. 2254 These threads offer most of the same features that the operating system already provides but can be used on a much larger scale. 2255 This approach is the most powerful solution as it allows all the features of multithreading, while removing several of the more expensive costs of kernel threads. 2256 The downside is that almost none of the low-level threading problems are hidden; users still have to think about data races, deadlocks and synchronization issues. 2257 These issues can be somewhat alleviated by a concurrency toolkit with strong guarantees, but the parallelism toolkit offers very little to reduce complexity in itself. 2258 2259 Examples of languages that support \textbf{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}. 2260 2261 \subsection{Fibers : User-Level Threads Without Preemption} \label{fibers} 2262 A popular variant of \textbf{uthread} is what is often referred to as \textbf{fiber}. 2263 However, \textbf{fiber} do not present meaningful semantic differences with \textbf{uthread}. 2264 The significant difference between \textbf{uthread} and \textbf{fiber} is the lack of \textbf{preemption} in the latter. 2265 Advocates of \textbf{fiber} list their high performance and ease of implementation as major strengths, but the performance difference between \textbf{uthread} and \textbf{fiber} is controversial, and the ease of implementation, while true, is a weak argument in the context of language design. 2266 Therefore this proposal largely ignores fibers. 2267 2268 An example of a language that uses fibers is Go~\cite{Go} 2269 2270 \subsection{Jobs and Thread Pools} 2271 An approach on the opposite end of the spectrum is to base parallelism on \textbf{pool}. 2272 Indeed, \textbf{pool} offer limited flexibility but at the benefit of a simpler user interface. 2273 In \textbf{pool} based systems, users express parallelism as units of work, called jobs, and a dependency graph (either explicit or implicit) that ties them together. 2274 This approach means users need not worry about concurrency but significantly limit the interaction that can occur among jobs. 2275 Indeed, any \textbf{job} that blocks also block the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. 2276 It can be argued that a solution to this problem is to use more workers than available cores. 2277 However, unless the number of jobs and the number of workers are comparable, having a significant number of blocked jobs always results in idles cores. 2278 2279 The gold standard of this implementation is Intel's TBB library~\cite{TBB}. 2280 2281 \subsection{Paradigm Performance} 2282 While the choice between the three paradigms listed above may have significant performance implications, it is difficult to pin down the performance implications of choosing a model at the language level. 2283 Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. 2284 Having a large amount of mostly independent units of work to execute almost guarantees equivalent performance across paradigms and that the \textbf{pool}-based system has the best efficiency thanks to the lower memory overhead (\ie no thread stack per job). 2285 However, interactions among jobs can easily exacerbate contention. 2286 User-level threads allow fine-grain context switching, which results in better resource utilization, but a context switch is more expensive and the extra control means users need to tweak more variables to get the desired performance. 2287 Finally, if the units of uninterrupted work are large, enough the paradigm choice is largely amortized by the actual work done. 2288 2289 \section{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel} 2290 A \textbf{cfacluster} is a group of \textbf{kthread} executed in isolation. \textbf{uthread} are scheduled on the \textbf{kthread} of a given \textbf{cfacluster}, allowing organization between \textbf{uthread} and \textbf{kthread}. 2291 It is important that \textbf{kthread} belonging to a same \textbf{cfacluster} have homogeneous settings, otherwise migrating a \textbf{uthread} from one \textbf{kthread} to the other can cause issues. 2292 A \textbf{cfacluster} also offers a pluggable scheduler that can optimize the workload generated by the \textbf{uthread}. 2293 2294 \textbf{cfacluster} have not been fully implemented in the context of this paper. 2295 Currently \CFA only supports one \textbf{cfacluster}, the initial one. 2296 2297 \subsection{Future Work: Machine Setup}\label{machine} 2298 While this was not done in the context of this paper, another important aspect of clusters is affinity. 2299 While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heterogeneous setups. 2300 For example, a system using \textbf{numa} configurations may benefit from users being able to tie clusters and/or kernel threads to certain CPU cores. 2301 OS support for CPU affinity is now common~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx}, which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity. 2302 2303 \subsection{Paradigms}\label{cfaparadigms} 2304 Given these building blocks, it is possible to reproduce all three of the popular paradigms. 2305 Indeed, \textbf{uthread} is the default paradigm in \CFA. 2306 However, disabling \textbf{preemption} on a cluster means threads effectively become fibers. 2307 Since several \textbf{cfacluster} with different scheduling policy can coexist in the same application, this allows \textbf{fiber} and \textbf{uthread} to coexist in the runtime of an application. 2308 Finally, it is possible to build executors for thread pools from \textbf{uthread} or \textbf{fiber}, which includes specialized jobs like actors~\cite{Actors}. 2309 2310 2311 2312 \section{Behind the Scenes} 2313 There are several challenges specific to \CFA when implementing concurrency. 2314 These challenges are a direct result of bulk acquire and loose object definitions. 2315 These two constraints are the root cause of most design decisions in the implementation. 2316 Furthermore, to avoid contention from dynamically allocating memory in a concurrent environment, the internal-scheduling design is (almost) entirely free of mallocs. 2317 This approach avoids the chicken and egg problem~\cite{Chicken} of having a memory allocator that relies on the threading system and a threading system that relies on the runtime. 2318 This extra goal means that memory management is a constant concern in the design of the system. 2319 2320 The main memory concern for concurrency is queues. 2321 All blocking operations are made by parking threads onto queues and all queues are designed with intrusive nodes, where each node has pre-allocated link fields for chaining, to avoid the need for memory allocation. 2322 Since several concurrency operations can use an unbound amount of memory (depending on bulk acquire), statically defining information in the intrusive fields of threads is insufficient.The only way to use a variable amount of memory without requiring memory allocation is to pre-allocate large buffers of memory eagerly and store the information in these buffers. 2323 Conveniently, the call stack fits that description and is easy to use, which is why it is used heavily in the implementation of internal scheduling, particularly variable-length arrays. 2324 Since stack allocation is based on scopes, the first step of the implementation is to identify the scopes that are available to store the information, and which of these can have a variable-length array. 2325 The threads and the condition both have a fixed amount of memory, while @mutex@ routines and blocking calls allow for an unbound amount, within the stack size. 2326 2327 Note that since the major contributions of this paper are extending monitor semantics to bulk acquire and loose object definitions, any challenges that are not resulting of these characteristics of \CFA are considered as solved problems and therefore not discussed. 2328 2329 % ====================================================================== 2330 % ====================================================================== 2331 \section{Mutex Routines} 2332 % ====================================================================== 2333 % ====================================================================== 2334 2335 The first step towards the monitor implementation is simple @mutex@ routines. 2336 In the single monitor case, mutual-exclusion is done using the entry/exit procedure in listing \ref{f:entry1}. 2337 The entry/exit procedures do not have to be extended to support multiple monitors. 2338 Indeed it is sufficient to enter/leave monitors one-by-one as long as the order is correct to prevent deadlock~\cite{Havender68}. 2339 In \CFA, ordering of monitor acquisition relies on memory ordering. 2340 This approach is sufficient because all objects are guaranteed to have distinct non-overlapping memory layouts and mutual-exclusion for a monitor is only defined for its lifetime, meaning that destroying a monitor while it is acquired is undefined behaviour. 2341 When a mutex call is made, the concerned monitors are aggregated into a variable-length pointer array and sorted based on pointer values. 2342 This array persists for the entire duration of the mutual-exclusion and its ordering reused extensively. 2343 \begin{figure} 2344 \begin{multicols}{2} 2345 Entry 2346 \begin{cfa} 2347 if monitor is free 2348 enter 2349 elif already own the monitor 2350 continue 2351 else 2352 block 2353 increment recursions 2354 \end{cfa} 2355 \columnbreak 2356 Exit 2357 \begin{cfa} 2358 decrement recursion 2359 if recursion == 0 2360 if entry queue not empty 2361 wake-up thread 2362 \end{cfa} 2363 \end{multicols} 2364 \begin{cfa}[caption={Initial entry and exit routine for monitors},label={f:entry1}] 2365 \end{cfa} 2366 \end{figure} 2367 2368 \subsection{Details: Interaction with polymorphism} 2369 Depending on the choice of semantics for when monitor locks are acquired, interaction between monitors and \CFA's concept of polymorphism can be more complex to support. 2370 However, it is shown that entry-point locking solves most of the issues. 2371 2372 First of all, interaction between @otype@ polymorphism (see Section~\ref{s:ParametricPolymorphism}) and monitors is impossible since monitors do not support copying. 2373 Therefore, the main question is how to support @dtype@ polymorphism. 2374 It is important to present the difference between the two acquiring options: \textbf{callsite-locking} and entry-point locking, \ie acquiring the monitors before making a mutex routine-call or as the first operation of the mutex routine-call. 2375 For example: 2486 } 2487 2488 \end{cfa} 2489 \end{tabular} 2490 \end{cquote} 2491 % \lstMakeShortInline@% 2492 % \caption{Threads ping/pong using external scheduling} 2493 % \label{f:pingpong} 2494 % \end{figure} 2495 Note, the ping/pong threads are globally declared, @pi@/@po@, and hence, start (and possibly complete) before the program main starts. 2496 \end{comment} 2497 2498 2499 \subsection{Execution Properties} 2500 2501 Table~\ref{t:ObjectPropertyComposition} shows how the \CFA high-level constructs cover 3 fundamental execution properties: thread, stateful function, and mutual exclusion. 2502 Case 1 is a basic object, with none of the new execution properties. 2503 Case 2 allows @mutex@ calls to Case 1 to protect shared data. 2504 Case 3 allows stateful functions to suspend/resume but restricts operations because the state is stackless. 2505 Case 4 allows @mutex@ calls to Case 3 to protect shared data. 2506 Cases 5 and 6 are the same as 3 and 4 without restriction because the state is stackful. 2507 Cases 7 and 8 are rejected because a thread cannot execute without a stackful state in a preemptive environment when context switching from the signal handler. 2508 Cases 9 and 10 have a stackful thread without and with @mutex@ calls. 2509 For situations where threads do not require direct communication, case 9 provides faster creation/destruction by eliminating @mutex@ setup. 2510 2376 2511 \begin{table} 2377 \begin{center} 2378 \begin{tabular}{|c|c|c|} 2379 Mutex & \textbf{callsite-locking} & \textbf{entry-point-locking} \\ 2380 call & cfa-code & cfa-code \\ 2512 \caption{Object property composition} 2513 \centering 2514 \label{t:ObjectPropertyComposition} 2515 \renewcommand{\arraystretch}{1.25} 2516 %\setlength{\tabcolsep}{5pt} 2517 \begin{tabular}{c|c||l|l} 2518 \multicolumn{2}{c||}{object properties} & \multicolumn{2}{c}{mutual exclusion} \\ 2381 2519 \hline 2382 \begin{cfa}[tabsize=3] 2383 void foo(monitor& mutex a){ 2384 2385 // Do Work 2386 //... 2387 2388 } 2389 2390 void main() { 2391 monitor a; 2392 2393 foo(a); 2394 2395 } 2396 \end{cfa} & \begin{cfa}[tabsize=3] 2397 foo(& a) { 2398 2399 // Do Work 2400 //... 2401 2402 } 2403 2404 main() { 2405 monitor a; 2406 acquire(a); 2407 foo(a); 2408 release(a); 2409 } 2410 \end{cfa} & \begin{cfa}[tabsize=3] 2411 foo(& a) { 2412 acquire(a); 2413 // Do Work 2414 //... 2415 release(a); 2416 } 2417 2418 main() { 2419 monitor a; 2420 2421 foo(a); 2422 2423 } 2424 \end{cfa} 2425 \end{tabular} 2426 \end{center} 2427 \caption{Call-site vs entry-point locking for mutex calls} 2428 \label{tbl:locking-site} 2429 \end{table} 2430 2431 Note the @mutex@ keyword relies on the type system, which means that in cases where a generic monitor-routine is desired, writing the mutex routine is possible with the proper trait, \eg: 2432 \begin{cfa} 2433 // Incorrect: T may not be monitor 2434 forall(dtype T) 2435 void foo(T * mutex t); 2436 2437 // Correct: this routine only works on monitors (any monitor) 2438 forall(dtype T | is_monitor(T)) 2439 void bar(T * mutex t)); 2440 \end{cfa} 2441 2442 Both entry point and \textbf{callsite-locking} are feasible implementations. 2443 The current \CFA implementation uses entry-point locking because it requires less work when using \textbf{raii}, effectively transferring the burden of implementation to object construction/destruction. 2444 It is harder to use \textbf{raii} for call-site locking, as it does not necessarily have an existing scope that matches exactly the scope of the mutual exclusion, \ie the routine body. 2445 For example, the monitor call can appear in the middle of an expression. 2446 Furthermore, entry-point locking requires less code generation since any useful routine is called multiple times but there is only one entry point for many call sites. 2447 2448 % ====================================================================== 2449 % ====================================================================== 2450 \section{Threading} \label{impl:thread} 2451 % ====================================================================== 2452 % ====================================================================== 2453 2454 Figure \ref{fig:system1} shows a high-level picture if the \CFA runtime system in regards to concurrency. 2455 Each component of the picture is explained in detail in the flowing sections. 2456 2457 \begin{figure} 2458 \begin{center} 2459 {\resizebox{\textwidth}{!}{\input{system.pstex_t}}} 2460 \end{center} 2461 \caption{Overview of the entire system} 2462 \label{fig:system1} 2463 \end{figure} 2464 2465 \subsection{Processors} 2466 Parallelism in \CFA is built around using processors to specify how much parallelism is desired. \CFA processors are object wrappers around kernel threads, specifically @pthread@s in the current implementation of \CFA. 2467 Indeed, any parallelism must go through operating-system libraries. 2468 However, \textbf{uthread} are still the main source of concurrency, processors are simply the underlying source of parallelism. 2469 Indeed, processor \textbf{kthread} simply fetch a \textbf{uthread} from the scheduler and run it; they are effectively executers for user-threads. 2470 The main benefit of this approach is that it offers a well-defined boundary between kernel code and user code, for example, kernel thread quiescing, scheduling and interrupt handling. 2471 Processors internally use coroutines to take advantage of the existing context-switching semantics. 2472 2473 \subsection{Stack Management} 2474 One of the challenges of this system is to reduce the footprint as much as possible. 2475 Specifically, all @pthread@s created also have a stack created with them, which should be used as much as possible. 2476 Normally, coroutines also create their own stack to run on, however, in the case of the coroutines used for processors, these coroutines run directly on the \textbf{kthread} stack, effectively stealing the processor stack. 2477 The exception to this rule is the Main Processor, \ie the initial \textbf{kthread} that is given to any program. 2478 In order to respect C user expectations, the stack of the initial kernel thread, the main stack of the program, is used by the main user thread rather than the main processor, which can grow very large. 2479 2480 \subsection{Context Switching} 2481 As mentioned in section \ref{coroutine}, coroutines are a stepping stone for implementing threading, because they share the same mechanism for context-switching between different stacks. 2482 To improve performance and simplicity, context-switching is implemented using the following assumption: all context-switches happen inside a specific routine call. 2483 This assumption means that the context-switch only has to copy the callee-saved registers onto the stack and then switch the stack registers with the ones of the target coroutine/thread. 2484 Note that the instruction pointer can be left untouched since the context-switch is always inside the same routine 2485 Threads, however, do not context-switch between each other directly. 2486 They context-switch to the scheduler. 2487 This method is called a 2-step context-switch and has the advantage of having a clear distinction between user code and the kernel where scheduling and other system operations happen. 2488 Obviously, this doubles the context-switch cost because threads must context-switch to an intermediate stack. 2489 The alternative 1-step context-switch uses the stack of the ``from'' thread to schedule and then context-switches directly to the ``to'' thread. 2490 However, the performance of the 2-step context-switch is still superior to a @pthread_yield@ (see section \ref{results}). 2491 Additionally, for users in need for optimal performance, it is important to note that having a 2-step context-switch as the default does not prevent \CFA from offering a 1-step context-switch (akin to the Microsoft @SwitchToFiber@~\cite{switchToWindows} routine). 2492 This option is not currently present in \CFA, but the changes required to add it are strictly additive. 2493 2494 \subsection{Preemption} \label{preemption} 2495 Finally, an important aspect for any complete threading system is preemption. 2496 As mentioned in section \ref{basics}, preemption introduces an extra degree of uncertainty, which enables users to have multiple threads interleave transparently, rather than having to cooperate among threads for proper scheduling and CPU distribution. 2497 Indeed, preemption is desirable because it adds a degree of isolation among threads. 2498 In a fully cooperative system, any thread that runs a long loop can starve other threads, while in a preemptive system, starvation can still occur but it does not rely on every thread having to yield or block on a regular basis, which reduces significantly a programmer burden. 2499 Obviously, preemption is not optimal for every workload. 2500 However any preemptive system can become a cooperative system by making the time slices extremely large. 2501 Therefore, \CFA uses a preemptive threading system. 2502 2503 Preemption in \CFA\footnote{Note that the implementation of preemption is strongly tied with the underlying threading system. 2504 For this reason, only the Linux implementation is cover, \CFA does not run on Windows at the time of writting} is based on kernel timers, which are used to run a discrete-event simulation. 2505 Every processor keeps track of the current time and registers an expiration time with the preemption system. 2506 When the preemption system receives a change in preemption, it inserts the time in a sorted order and sets a kernel timer for the closest one, effectively stepping through preemption events on each signal sent by the timer. 2507 These timers use the Linux signal {\tt SIGALRM}, which is delivered to the process rather than the kernel-thread. 2508 This results in an implementation problem, because when delivering signals to a process, the kernel can deliver the signal to any kernel thread for which the signal is not blocked, \ie: 2509 \begin{quote} 2510 A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked. 2511 If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which to deliver the signal. 2512 SIGNAL(7) - Linux Programmer's Manual 2513 \end{quote} 2514 For the sake of simplicity, and in order to prevent the case of having two threads receiving alarms simultaneously, \CFA programs block the {\tt SIGALRM} signal on every kernel thread except one. 2515 2516 Now because of how involuntary context-switches are handled, the kernel thread handling {\tt SIGALRM} cannot also be a processor thread. 2517 Hence, involuntary context-switching is done by sending signal {\tt SIGUSR1} to the corresponding proces\-sor and having the thread yield from inside the signal handler. 2518 This approach effectively context-switches away from the signal handler back to the kernel and the signal handler frame is eventually unwound when the thread is scheduled again. 2519 As a result, a signal handler can start on one kernel thread and terminate on a second kernel thread (but the same user thread). 2520 It is important to note that signal handlers save and restore signal masks because user-thread migration can cause a signal mask to migrate from one kernel thread to another. 2521 This behaviour is only a problem if all kernel threads, among which a user thread can migrate, differ in terms of signal masks\footnote{Sadly, official POSIX documentation is silent on what distinguishes ``async-signal-safe'' routines from other routines}. 2522 However, since the kernel thread handling preemption requires a different signal mask, executing user threads on the kernel-alarm thread can cause deadlocks. 2523 For this reason, the alarm thread is in a tight loop around a system call to @sigwaitinfo@, requiring very little CPU time for preemption. 2524 One final detail about the alarm thread is how to wake it when additional communication is required (\eg on thread termination). 2525 This unblocking is also done using {\tt SIGALRM}, but sent through the @pthread_sigqueue@. 2526 Indeed, @sigwait@ can differentiate signals sent from @pthread_sigqueue@ from signals sent from alarms or the kernel. 2527 2528 \subsection{Scheduler} 2529 Finally, an aspect that was not mentioned yet is the scheduling algorithm. 2530 Currently, the \CFA scheduler uses a single ready queue for all processors, which is the simplest approach to scheduling. 2531 Further discussion on scheduling is present in section \ref{futur:sched}. 2532 2533 % ====================================================================== 2534 % ====================================================================== 2535 \section{Internal Scheduling} \label{impl:intsched} 2536 % ====================================================================== 2537 % ====================================================================== 2538 The following figure is the traditional illustration of a monitor (repeated from page~\pageref{fig:ClassicalMonitor} for convenience): 2539 2540 \begin{figure} 2541 \begin{center} 2542 {\resizebox{0.4\textwidth}{!}{\input{monitor}}} 2543 \end{center} 2544 \caption{Traditional illustration of a monitor} 2545 \end{figure} 2546 2547 This picture has several components, the two most important being the entry queue and the AS-stack. 2548 The entry queue is an (almost) FIFO list where threads waiting to enter are parked, while the acceptor/signaller (AS) stack is a FILO list used for threads that have been signalled or otherwise marked as running next. 2549 2550 For \CFA, this picture does not have support for blocking multiple monitors on a single condition. 2551 To support bulk acquire two changes to this picture are required. 2552 First, it is no longer helpful to attach the condition to \emph{a single} monitor. 2553 Secondly, the thread waiting on the condition has to be separated across multiple monitors, seen in figure \ref{fig:monitor_cfa}. 2554 2555 \begin{figure} 2556 \begin{center} 2557 {\resizebox{0.8\textwidth}{!}{\input{int_monitor}}} 2558 \end{center} 2559 \caption{Illustration of \CFA Monitor} 2560 \label{fig:monitor_cfa} 2561 \end{figure} 2562 2563 This picture and the proper entry and leave algorithms (see listing \ref{f:entry2}) is the fundamental implementation of internal scheduling. 2564 Note that when a thread is moved from the condition to the AS-stack, it is conceptually split into N pieces, where N is the number of monitors specified in the parameter list. 2565 The thread is woken up when all the pieces have popped from the AS-stacks and made active. 2566 In this picture, the threads are split into halves but this is only because there are two monitors. 2567 For a specific signalling operation every monitor needs a piece of thread on its AS-stack. 2568 2569 \begin{figure} 2570 \begin{multicols}{2} 2571 Entry 2572 \begin{cfa} 2573 if monitor is free 2574 enter 2575 elif already own the monitor 2576 continue 2577 else 2578 block 2579 increment recursion 2580 2581 \end{cfa} 2582 \columnbreak 2583 Exit 2584 \begin{cfa} 2585 decrement recursion 2586 if recursion == 0 2587 if signal_stack not empty 2588 set_owner to thread 2589 if all monitors ready 2590 wake-up thread 2591 2592 if entry queue not empty 2593 wake-up thread 2594 \end{cfa} 2595 \end{multicols} 2596 \begin{cfa}[caption={Entry and exit routine for monitors with internal scheduling},label={f:entry2}] 2597 \end{cfa} 2598 \end{figure} 2599 2600 The solution discussed in \ref{s:InternalScheduling} can be seen in the exit routine of listing \ref{f:entry2}. 2601 Basically, the solution boils down to having a separate data structure for the condition queue and the AS-stack, and unconditionally transferring ownership of the monitors but only unblocking the thread when the last monitor has transferred ownership. 2602 This solution is deadlock safe as well as preventing any potential barging. 2603 The data structures used for the AS-stack are reused extensively for external scheduling, but in the case of internal scheduling, the data is allocated using variable-length arrays on the call stack of the @wait@ and @signal_block@ routines. 2604 2605 \begin{figure} 2606 \begin{center} 2607 {\resizebox{0.8\textwidth}{!}{\input{monitor_structs.pstex_t}}} 2608 \end{center} 2609 \caption{Data structures involved in internal/external scheduling} 2610 \label{fig:structs} 2611 \end{figure} 2612 2613 Figure \ref{fig:structs} shows a high-level representation of these data structures. 2614 The main idea behind them is that, a thread cannot contain an arbitrary number of intrusive ``next'' pointers for linking onto monitors. 2615 The @condition node@ is the data structure that is queued onto a condition variable and, when signalled, the condition queue is popped and each @condition criterion@ is moved to the AS-stack. 2616 Once all the criteria have been popped from their respective AS-stacks, the thread is woken up, which is what is shown in listing \ref{f:entry2}. 2617 2618 % ====================================================================== 2619 % ====================================================================== 2620 \section{External Scheduling} 2621 % ====================================================================== 2622 % ====================================================================== 2623 Similarly to internal scheduling, external scheduling for multiple monitors relies on the idea that waiting-thread queues are no longer specific to a single monitor, as mentioned in section \ref{extsched}. 2624 For internal scheduling, these queues are part of condition variables, which are still unique for a given scheduling operation (\ie no signal statement uses multiple conditions). 2625 However, in the case of external scheduling, there is no equivalent object which is associated with @waitfor@ statements. 2626 This absence means the queues holding the waiting threads must be stored inside at least one of the monitors that is acquired. 2627 These monitors being the only objects that have sufficient lifetime and are available on both sides of the @waitfor@ statement. 2628 This requires an algorithm to choose which monitor holds the relevant queue. 2629 It is also important that said algorithm be independent of the order in which users list parameters. 2630 The proposed algorithm is to fall back on monitor lock ordering (sorting by address) and specify that the monitor that is acquired first is the one with the relevant waiting queue. 2631 This assumes that the lock acquiring order is static for the lifetime of all concerned objects but that is a reasonable constraint. 2632 2633 This algorithm choice has two consequences: 2634 \begin{itemize} 2635 \item The queue of the monitor with the lowest address is no longer a true FIFO queue because threads can be moved to the front of the queue. 2636 These queues need to contain a set of monitors for each of the waiting threads. 2637 Therefore, another thread whose set contains the same lowest address monitor but different lower priority monitors may arrive first but enter the critical section after a thread with the correct pairing. 2638 \item The queue of the lowest priority monitor is both required and potentially unused. 2639 Indeed, since it is not known at compile time which monitor is the monitor which has the lowest address, every monitor needs to have the correct queues even though it is possible that some queues go unused for the entire duration of the program, for example if a monitor is only used in a specific pair. 2640 \end{itemize} 2641 Therefore, the following modifications need to be made to support external scheduling: 2642 \begin{itemize} 2643 \item The threads waiting on the entry queue need to keep track of which routine they are trying to enter, and using which set of monitors. 2644 The @mutex@ routine already has all the required information on its stack, so the thread only needs to keep a pointer to that information. 2645 \item The monitors need to keep a mask of acceptable routines. 2646 This mask contains for each acceptable routine, a routine pointer and an array of monitors to go with it. 2647 It also needs storage to keep track of which routine was accepted. 2648 Since this information is not specific to any monitor, the monitors actually contain a pointer to an integer on the stack of the waiting thread. 2649 Note that if a thread has acquired two monitors but executes a @waitfor@ with only one monitor as a parameter, setting the mask of acceptable routines to both monitors will not cause any problems since the extra monitor will not change ownership regardless. 2650 This becomes relevant when @when@ clauses affect the number of monitors passed to a @waitfor@ statement. 2651 \item The entry/exit routines need to be updated as shown in listing \ref{f:entry3}. 2652 \end{itemize} 2653 2654 \subsection{External Scheduling - Destructors} 2655 Finally, to support the ordering inversion of destructors, the code generation needs to be modified to use a special entry routine. 2656 This routine is needed because of the storage requirements of the call order inversion. 2657 Indeed, when waiting for the destructors, storage is needed for the waiting context and the lifetime of said storage needs to outlive the waiting operation it is needed for. 2658 For regular @waitfor@ statements, the call stack of the routine itself matches this requirement but it is no longer the case when waiting for the destructor since it is pushed on to the AS-stack for later. 2659 The @waitfor@ semantics can then be adjusted correspondingly, as seen in listing \ref{f:entry-dtor} 2660 2661 \begin{figure} 2662 \begin{multicols}{2} 2663 Entry 2664 \begin{cfa} 2665 if monitor is free 2666 enter 2667 elif already own the monitor 2668 continue 2669 elif matches waitfor mask 2670 push criteria to AS-stack 2671 continue 2672 else 2673 block 2674 increment recursion 2675 \end{cfa} 2676 \columnbreak 2677 Exit 2678 \begin{cfa} 2679 decrement recursion 2680 if recursion == 0 2681 if signal_stack not empty 2682 set_owner to thread 2683 if all monitors ready 2684 wake-up thread 2685 endif 2686 endif 2687 2688 if entry queue not empty 2689 wake-up thread 2690 endif 2691 \end{cfa} 2692 \end{multicols} 2693 \begin{cfa}[caption={Entry and exit routine for monitors with internal scheduling and external scheduling},label={f:entry3}] 2694 \end{cfa} 2695 \end{figure} 2696 2697 \begin{figure} 2698 \begin{multicols}{2} 2699 Destructor Entry 2700 \begin{cfa} 2701 if monitor is free 2702 enter 2703 elif already own the monitor 2704 increment recursion 2705 return 2706 create wait context 2707 if matches waitfor mask 2708 reset mask 2709 push self to AS-stack 2710 baton pass 2711 else 2712 wait 2713 increment recursion 2714 \end{cfa} 2715 \columnbreak 2716 Waitfor 2717 \begin{cfa} 2718 if matching thread is already there 2719 if found destructor 2720 push destructor to AS-stack 2721 unlock all monitors 2722 else 2723 push self to AS-stack 2724 baton pass 2725 endif 2726 return 2727 endif 2728 if non-blocking 2729 Unlock all monitors 2730 Return 2731 endif 2732 2733 push self to AS-stack 2734 set waitfor mask 2735 block 2736 return 2737 \end{cfa} 2738 \end{multicols} 2739 \begin{cfa}[caption={Pseudo code for the \protect\lstinline|waitfor| routine and the \protect\lstinline|mutex| entry routine for destructors},label={f:entry-dtor}] 2740 \end{cfa} 2741 \end{figure} 2742 2743 2744 % ====================================================================== 2745 % ====================================================================== 2746 \section{Putting It All Together} 2747 % ====================================================================== 2748 % ====================================================================== 2749 2750 2751 \section{Threads As Monitors} 2752 As it was subtly alluded in section \ref{threads}, @thread@s in \CFA are in fact monitors, which means that all monitor features are available when using threads. 2753 For example, here is a very simple two thread pipeline that could be used for a simulator of a game engine: 2754 \begin{figure} 2755 \begin{cfa}[caption={Toy simulator using \protect\lstinline|thread|s and \protect\lstinline|monitor|s.},label={f:engine-v1}] 2756 // Visualization declaration 2757 thread Renderer {} renderer; 2758 Frame * simulate( Simulator & this ); 2759 2760 // Simulation declaration 2761 thread Simulator{} simulator; 2762 void render( Renderer & this ); 2763 2764 // Blocking call used as communication 2765 void draw( Renderer & mutex this, Frame * frame ); 2766 2767 // Simulation loop 2768 void main( Simulator & this ) { 2769 while( true ) { 2770 Frame * frame = simulate( this ); 2771 draw( renderer, frame ); 2772 } 2773 } 2774 2775 // Rendering loop 2776 void main( Renderer & this ) { 2777 while( true ) { 2778 waitfor( draw, this ); 2779 render( this ); 2780 } 2781 } 2782 \end{cfa} 2783 \end{figure} 2784 One of the obvious complaints of the previous code snippet (other than its toy-like simplicity) is that it does not handle exit conditions and just goes on forever. 2785 Luckily, the monitor semantics can also be used to clearly enforce a shutdown order in a concise manner: 2786 \begin{figure} 2787 \begin{cfa}[caption={Same toy simulator with proper termination condition.},label={f:engine-v2}] 2788 // Visualization declaration 2789 thread Renderer {} renderer; 2790 Frame * simulate( Simulator & this ); 2791 2792 // Simulation declaration 2793 thread Simulator{} simulator; 2794 void render( Renderer & this ); 2795 2796 // Blocking call used as communication 2797 void draw( Renderer & mutex this, Frame * frame ); 2798 2799 // Simulation loop 2800 void main( Simulator & this ) { 2801 while( true ) { 2802 Frame * frame = simulate( this ); 2803 draw( renderer, frame ); 2804 2805 // Exit main loop after the last frame 2806 if( frame->is_last ) break; 2807 } 2808 } 2809 2810 // Rendering loop 2811 void main( Renderer & this ) { 2812 while( true ) { 2813 waitfor( draw, this ); 2814 or waitfor( ^?{}, this ) { 2815 // Add an exit condition 2816 break; 2817 } 2818 2819 render( this ); 2820 } 2821 } 2822 2823 // Call destructor for simulator once simulator finishes 2824 // Call destructor for renderer to signify shutdown 2825 \end{cfa} 2826 \end{figure} 2827 2828 \section{Fibers \& Threads} 2829 As mentioned in section \ref{preemption}, \CFA uses preemptive threads by default but can use fibers on demand. 2830 Currently, using fibers is done by adding the following line of code to the program~: 2831 \begin{cfa} 2832 unsigned int default_preemption() { 2833 return 0; 2834 } 2835 \end{cfa} 2836 This routine is called by the kernel to fetch the default preemption rate, where 0 signifies an infinite time-slice, \ie no preemption. 2837 However, once clusters are fully implemented, it will be possible to create fibers and \textbf{uthread} in the same system, as in listing \ref{f:fiber-uthread} 2838 \begin{figure} 2839 \lstset{language=CFA,deletedelim=**[is][]{`}{`}} 2840 \begin{cfa}[caption={Using fibers and \textbf{uthread} side-by-side in \CFA},label={f:fiber-uthread}] 2841 // Cluster forward declaration 2842 struct cluster; 2843 2844 // Processor forward declaration 2845 struct processor; 2846 2847 // Construct clusters with a preemption rate 2848 void ?{}(cluster& this, unsigned int rate); 2849 // Construct processor and add it to cluster 2850 void ?{}(processor& this, cluster& cluster); 2851 // Construct thread and schedule it on cluster 2852 void ?{}(thread& this, cluster& cluster); 2853 2854 // Declare two clusters 2855 cluster thread_cluster = { 10`ms }; // Preempt every 10 ms 2856 cluster fibers_cluster = { 0 }; // Never preempt 2857 2858 // Construct 4 processors 2859 processor processors[4] = { 2860 //2 for the thread cluster 2861 thread_cluster; 2862 thread_cluster; 2863 //2 for the fibers cluster 2864 fibers_cluster; 2865 fibers_cluster; 2866 }; 2867 2868 // Declares thread 2869 thread UThread {}; 2870 void ?{}(UThread& this) { 2871 // Construct underlying thread to automatically 2872 // be scheduled on the thread cluster 2873 (this){ thread_cluster } 2874 } 2875 2876 void main(UThread & this); 2877 2878 // Declares fibers 2879 thread Fiber {}; 2880 void ?{}(Fiber& this) { 2881 // Construct underlying thread to automatically 2882 // be scheduled on the fiber cluster 2883 (this.__thread){ fibers_cluster } 2884 } 2885 2886 void main(Fiber & this); 2887 \end{cfa} 2888 \end{figure} 2889 2890 2891 % ====================================================================== 2892 % ====================================================================== 2893 \section{Performance Results} \label{results} 2894 % ====================================================================== 2895 % ====================================================================== 2896 \section{Machine Setup} 2897 Table \ref{tab:machine} shows the characteristics of the machine used to run the benchmarks. 2898 All tests were made on this machine. 2899 \begin{table} 2900 \begin{center} 2901 \begin{tabular}{| l | r | l | r |} 2902 \hline 2903 Architecture & x86\_64 & NUMA node(s) & 8 \\ 2904 \hline 2905 CPU op-mode(s) & 32-bit, 64-bit & Model name & AMD Opteron\texttrademark Processor 6380 \\ 2906 \hline 2907 Byte Order & Little Endian & CPU Freq & 2.5\si{\giga\hertz} \\ 2908 \hline 2909 CPU(s) & 64 & L1d cache & \SI{16}{\kibi\byte} \\ 2910 \hline 2911 Thread(s) per core & 2 & L1i cache & \SI{64}{\kibi\byte} \\ 2912 \hline 2913 Core(s) per socket & 8 & L2 cache & \SI{2048}{\kibi\byte} \\ 2914 \hline 2915 Socket(s) & 4 & L3 cache & \SI{6144}{\kibi\byte} \\ 2520 thread & stateful & \multicolumn{1}{c|}{No} & \multicolumn{1}{c}{Yes} \\ 2916 2521 \hline 2917 2522 \hline 2918 Operating system & Ubuntu 16.04.3 LTS & Kernel & Linux 4.4-97-generic\\2523 No & No & \textbf{1}\ \ \ aggregate type & \textbf{2}\ \ \ @monitor@ aggregate type \\ 2919 2524 \hline 2920 Compiler & GCC 6.3 & Translator & CFA 1\\2525 No & Yes (stackless) & \textbf{3}\ \ \ @generator@ & \textbf{4}\ \ \ @monitor@ @generator@ \\ 2921 2526 \hline 2922 Java version & OpenJDK-9 & Go version & 1.9.2\\2527 No & Yes (stackful) & \textbf{5}\ \ \ @coroutine@ & \textbf{6}\ \ \ @monitor@ @coroutine@ \\ 2923 2528 \hline 2529 Yes & No / Yes (stackless) & \textbf{7}\ \ \ {\color{red}rejected} & \textbf{8}\ \ \ {\color{red}rejected} \\ 2530 \hline 2531 Yes & Yes (stackful) & \textbf{9}\ \ \ @thread@ & \textbf{10}\ \ @monitor@ @thread@ \\ 2924 2532 \end{tabular} 2925 \end{center}2926 \caption{Machine setup used for the tests}2927 \label{tab:machine}2928 2533 \end{table} 2929 2534 2930 \section{Micro Benchmarks} 2931 All benchmarks are run using the same harness to produce the results, seen as the @BENCH()@ macro in the following examples. 2932 This macro uses the following logic to benchmark the code: 2933 \begin{cfa} 2934 #define BENCH(run, result) \ 2935 before = gettime(); \ 2936 run; \ 2937 after = gettime(); \ 2938 result = (after - before) / N; 2939 \end{cfa} 2940 The method used to get time is @clock_gettime(CLOCK_THREAD_CPUTIME_ID);@. 2941 Each benchmark is using many iterations of a simple call to measure the cost of the call. 2942 The specific number of iterations depends on the specific benchmark. 2943 2944 \subsection{Context-Switching} 2945 The first interesting benchmark is to measure how long context-switches take. 2946 The simplest approach to do this is to yield on a thread, which executes a 2-step context switch. 2947 Yielding causes the thread to context-switch to the scheduler and back, more precisely: from the \textbf{uthread} to the \textbf{kthread} then from the \textbf{kthread} back to the same \textbf{uthread} (or a different one in the general case). 2948 In order to make the comparison fair, coroutines also execute a 2-step context-switch by resuming another coroutine which does nothing but suspending in a tight loop, which is a resume/suspend cycle instead of a yield. 2949 Figure~\ref{f:ctx-switch} shows the code for coroutines and threads with the results in table \ref{tab:ctx-switch}. 2950 All omitted tests are functionally identical to one of these tests. 2951 The difference between coroutines and threads can be attributed to the cost of scheduling. 2535 2536 \subsection{Low-level Locks} 2537 2538 For completeness and efficiency, \CFA provides a standard set of low-level locks: recursive mutex, condition, semaphore, barrier, \etc, and atomic instructions: @fetchAssign@, @fetchAdd@, @testSet@, @compareSet@, \etc. 2539 Some of these low-level mechanism are used in the \CFA runtime, but we strongly advocate using high-level mechanisms whenever possible. 2540 2541 2542 % \section{Parallelism} 2543 % \label{s:Parallelism} 2544 % 2545 % Historically, computer performance was about processor speeds. 2546 % However, with heat dissipation being a direct consequence of speed increase, parallelism is the new source for increased performance~\cite{Sutter05, Sutter05b}. 2547 % Therefore, high-performance applications must care about parallelism, which requires concurrency. 2548 % The lowest-level approach of parallelism is to use \newterm{kernel threads} in combination with semantics like @fork@, @join@, \etc. 2549 % However, kernel threads are better as an implementation tool because of complexity and higher cost. 2550 % Therefore, different abstractions are often layered onto kernel threads to simplify them, \eg pthreads. 2551 % 2552 % 2553 % \subsection{User Threads} 2554 % 2555 % A direct improvement on kernel threads is user threads, \eg Erlang~\cite{Erlang} and \uC~\cite{uC++book}. 2556 % This approach provides an interface that matches the language paradigms, gives more control over concurrency by the language runtime, and an abstract (and portable) interface to the underlying kernel threads across operating systems. 2557 % In many cases, user threads can be used on a much larger scale (100,000 threads). 2558 % Like kernel threads, user threads support preemption, which maximizes nondeterminism, but increases the potential for concurrency errors: race, livelock, starvation, and deadlock. 2559 % \CFA adopts user-threads to provide more flexibility and a low-cost mechanism to build any other concurrency approach, \eg thread pools and actors~\cite{Actors}. 2560 % 2561 % A variant of user thread is \newterm{fibres}, which removes preemption, \eg Go~\cite{Go} @goroutine@s. 2562 % Like functional programming, which removes mutation and its associated problems, removing preemption from concurrency reduces nondeterminism, making race and deadlock errors more difficult to generate. 2563 % However, preemption is necessary for fairness and to reduce tail-latency. 2564 % For concurrency that relies on spinning, if all cores spin the system is livelocked, whereas preemption breaks the livelock. 2565 2566 2567 \begin{comment} 2568 \subsection{Thread Pools} 2569 2570 In contrast to direct threading is indirect \newterm{thread pools}, \eg Java @executor@, where small jobs (work units) are inserted into a work pool for execution. 2571 If the jobs are dependent, \ie interact, there is an implicit/explicit dependency graph that ties them together. 2572 While removing direct concurrency, and hence the amount of context switching, thread pools significantly limit the interaction that can occur among jobs. 2573 Indeed, jobs should not block because that also blocks the underlying thread, which effectively means the CPU utilization, and therefore throughput, suffers. 2574 While it is possible to tune the thread pool with sufficient threads, it becomes difficult to obtain high throughput and good core utilization as job interaction increases. 2575 As well, concurrency errors return, which threads pools are suppose to mitigate. 2576 2952 2577 \begin{figure} 2578 \centering 2579 \begin{tabular}{@{}l|l@{}} 2580 \begin{cfa} 2581 struct Adder { 2582 int * row, cols; 2583 }; 2584 int operator()() { 2585 subtotal = 0; 2586 for ( int c = 0; c < cols; c += 1 ) 2587 subtotal += row[c]; 2588 return subtotal; 2589 } 2590 void ?{}( Adder * adder, int row[$\,$], int cols, int & subtotal ) { 2591 adder.[rows, cols, subtotal] = [rows, cols, subtotal]; 2592 } 2593 2594 2595 2596 2597 \end{cfa} 2598 & 2599 \begin{cfa} 2600 int main() { 2601 const int rows = 10, cols = 10; 2602 int matrix[rows][cols], subtotals[rows], total = 0; 2603 // read matrix 2604 Executor executor( 4 ); // kernel threads 2605 Adder * adders[rows]; 2606 for ( r; rows ) { // send off work for executor 2607 adders[r] = new( matrix[r], cols, &subtotal[r] ); 2608 executor.send( *adders[r] ); 2609 } 2610 for ( r; rows ) { // wait for results 2611 delete( adders[r] ); 2612 total += subtotals[r]; 2613 } 2614 sout | total; 2615 } 2616 \end{cfa} 2617 \end{tabular} 2618 \caption{Executor} 2619 \end{figure} 2620 \end{comment} 2621 2622 2623 \section{Runtime Structure} 2624 \label{s:CFARuntimeStructure} 2625 2626 Figure~\ref{f:RunTimeStructure} illustrates the runtime structure of a \CFA program. 2627 In addition to the new kinds of objects introduced by \CFA, there are two more runtime entities used to control parallel execution: cluster and (virtual) processor. 2628 An executing thread is illustrated by its containment in a processor. 2629 2630 \begin{figure} 2631 \centering 2632 \input{RunTimeStructure} 2633 \caption{\CFA Runtime structure} 2634 \label{f:RunTimeStructure} 2635 \end{figure} 2636 2637 2638 \subsection{Cluster} 2639 \label{s:RuntimeStructureCluster} 2640 2641 A \newterm{cluster} is a collection of threads and virtual processors (abstract kernel-thread) that execute the (user) threads from its own ready queue (like an OS executing kernel threads). 2642 The purpose of a cluster is to control the amount of parallelism that is possible among threads, plus scheduling and other execution defaults. 2643 The default cluster-scheduler is single-queue multi-server, which provides automatic load-balancing of threads on processors. 2644 However, the design allows changing the scheduler, \eg multi-queue multi-server with work-stealing/sharing across the virtual processors. 2645 If several clusters exist, both threads and virtual processors, can be explicitly migrated from one cluster to another. 2646 No automatic load balancing among clusters is performed by \CFA. 2647 2648 When a \CFA program begins execution, it creates a user cluster with a single processor and a special processor to handle preemption that does not execute user threads. 2649 The user cluster is created to contain the application user-threads. 2650 Having all threads execute on the one cluster often maximizes utilization of processors, which minimizes runtime. 2651 However, because of limitations of scheduling requirements (real-time), NUMA architecture, heterogeneous hardware, or issues with the underlying operating system, multiple clusters are sometimes necessary. 2652 2653 2654 \subsection{Virtual Processor} 2655 \label{s:RuntimeStructureProcessor} 2656 2657 A virtual processor is implemented by a kernel thread (\eg UNIX process), which are scheduled for execution on a hardware processor by the underlying operating system. 2658 Programs may use more virtual processors than hardware processors. 2659 On a multiprocessor, kernel threads are distributed across the hardware processors resulting in virtual processors executing in parallel. 2660 (It is possible to use affinity to lock a virtual processor onto a particular hardware processor~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx}, which is used when caching issues occur or for heterogeneous hardware processors.) 2661 The \CFA runtime attempts to block unused processors and unblock processors as the system load increases; 2662 balancing the workload with processors is difficult because it requires future knowledge, \ie what will the applicaton workload do next. 2663 Preemption occurs on virtual processors rather than user threads, via operating-system interrupts. 2664 Thus virtual processors execute user threads, where preemption frequency applies to a virtual processor, so preemption occurs randomly across the executed user threads. 2665 Turning off preemption transforms user threads into fibres. 2666 2667 2668 \begin{comment} 2669 \section{Implementation} 2670 \label{s:Implementation} 2671 2672 A primary implementation challenge is avoiding contention from dynamically allocating memory because of bulk acquire, \eg the internal-scheduling design is (almost) free of allocations. 2673 All blocking operations are made by parking threads onto queues, therefore all queues are designed with intrusive nodes, where each node has preallocated link fields for chaining. 2674 Furthermore, several bulk-acquire operations need a variable amount of memory. 2675 This storage is allocated at the base of a thread's stack before blocking, which means programmers must add a small amount of extra space for stacks. 2676 2677 In \CFA, ordering of monitor acquisition relies on memory ordering to prevent deadlock~\cite{Havender68}, because all objects have distinct non-overlapping memory layouts, and mutual-exclusion for a monitor is only defined for its lifetime. 2678 When a mutex call is made, pointers to the concerned monitors are aggregated into a variable-length array and sorted. 2679 This array persists for the entire duration of the mutual exclusion and is used extensively for synchronization operations. 2680 2681 To improve performance and simplicity, context switching occurs inside a function call, so only callee-saved registers are copied onto the stack and then the stack register is switched; 2682 the corresponding registers are then restored for the other context. 2683 Note, the instruction pointer is untouched since the context switch is always inside the same function. 2684 Experimental results (not presented) for a stackless or stackful scheduler (1 versus 2 context switches) (see Section~\ref{s:Concurrency}) show the performance is virtually equivalent, because both approaches are dominated by locking to prevent a race condition. 2685 2686 All kernel threads (@pthreads@) created a stack. 2687 Each \CFA virtual processor is implemented as a coroutine and these coroutines run directly on the kernel-thread stack, effectively stealing this stack. 2688 The exception to this rule is the program main, \ie the initial kernel thread that is given to any program. 2689 In order to respect C expectations, the stack of the initial kernel thread is used by program main rather than the main processor, allowing it to grow dynamically as in a normal C program. 2690 \end{comment} 2691 2692 2693 \subsection{Preemption} 2694 2695 Nondeterministic preemption provides fairness from long-running threads, and forces concurrent programmers to write more robust programs, rather than relying on code between cooperative scheduling to be atomic. 2696 This atomic reliance can fail on multi-core machines, because execution across cores is nondeterministic. 2697 A different reason for not supporting preemption is that it significantly complicates the runtime system, \eg Microsoft runtime does not support interrupts and on Linux systems, interrupts are complex (see below). 2698 Preemption is normally handled by setting a countdown timer on each virtual processor. 2699 When the timer expires, an interrupt is delivered, and the interrupt handler resets the countdown timer, and if the virtual processor is executing in user code, the signal handler performs a user-level context-switch, or if executing in the language runtime kernel, the preemption is ignored or rolled forward to the point where the runtime kernel context switches back to user code. 2700 Multiple signal handlers may be pending. 2701 When control eventually switches back to the signal handler, it returns normally, and execution continues in the interrupted user thread, even though the return from the signal handler may be on a different kernel thread than the one where the signal is delivered. 2702 The only issue with this approach is that signal masks from one kernel thread may be restored on another as part of returning from the signal handler; 2703 therefore, the same signal mask is required for all virtual processors in a cluster. 2704 Because preemption frequency is usually long (1 millisecond) performance cost is negligible. 2705 2706 Linux switched a decade ago from specific to arbitrary process signal-delivery for applications with multiple kernel threads. 2707 \begin{cquote} 2708 A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked. 2709 If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which it will deliver the signal. 2710 SIGNAL(7) - Linux Programmer's Manual 2711 \end{cquote} 2712 Hence, the timer-expiry signal, which is generated \emph{externally} by the Linux kernel to an application, is delivered to any of its Linux subprocesses (kernel threads). 2713 To ensure each virtual processor receives a preemption signal, a discrete-event simulation is run on a special virtual processor, and only it sets and receives timer events. 2714 Virtual processors register an expiration time with the discrete-event simulator, which is inserted in sorted order. 2715 The simulation sets the countdown timer to the value at the head of the event list, and when the timer expires, all events less than or equal to the current time are processed. 2716 Processing a preemption event sends an \emph{internal} @SIGUSR1@ signal to the registered virtual processor, which is always delivered to that processor. 2717 2718 2719 \subsection{Debug Kernel} 2720 2721 There are two versions of the \CFA runtime kernel: debug and non-debug. 2722 The debugging version has many runtime checks and internal assertions, \eg stack (non-writable) guard page, and checks for stack overflow whenever context switches occur among coroutines and threads, which catches most stack overflows. 2723 After a program is debugged, the non-debugging version can be used to significantly decrease space and increase performance. 2724 2725 2726 \section{Performance} 2727 \label{s:Performance} 2728 2729 To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0. 2730 For comparison, the package must be multi-processor (M:N), which excludes libdill/libmil~\cite{libdill} (M:1)), and use a shared-memory programming model, \eg not message passing. 2731 The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \CFA/\uC are compiled with gcc 6.5. 2732 2733 All benchmarks are run using the following harness. (The Java harness is augmented to circumvent JIT issues.) 2734 \begin{cfa} 2735 unsigned int N = 10_000_000; 2736 #define BENCH( `run` ) Time before = getTimeNsec(); `run;` Duration result = (getTimeNsec() - before) / N; 2737 \end{cfa} 2738 The method used to get time is @clock_gettime( CLOCK_REALTIME )@. 2739 Each benchmark is performed @N@ times, where @N@ varies depending on the benchmark; 2740 the total time is divided by @N@ to obtain the average time for a benchmark. 2741 Each benchmark experiment is run 31 times. 2742 All omitted tests for other languages are functionally identical to the \CFA tests and available online~\cite{CforallBenchMarks}. 2743 % tar --exclude=.deps --exclude=Makefile --exclude=Makefile.in --exclude=c.c --exclude=cxx.cpp --exclude=fetch_add.c -cvhf benchmark.tar benchmark 2744 2745 \paragraph{Object Creation} 2746 2747 Object creation is measured by creating/deleting the specific kind of concurrent object. 2748 Figure~\ref{f:creation} shows the code for \CFA, with results in Table~\ref{tab:creation}. 2749 The only note here is that the call stacks of \CFA coroutines are lazily created, therefore without priming the coroutine to force stack creation, the creation cost is artificially low. 2750 2953 2751 \begin{multicols}{2} 2954 \CFA Coroutines 2955 \begin{cfa} 2956 coroutine GreatSuspender {}; 2957 void main(GreatSuspender& this) { 2958 while(true) { suspend(); } 2959 } 2752 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 2753 \begin{cfa} 2754 @thread@ MyThread {}; 2755 void @main@( MyThread & ) {} 2960 2756 int main() { 2961 GreatSuspender s; 2962 resume(s); 2757 BENCH( for ( N ) { @MyThread m;@ } ) 2758 sout | result`ns; 2759 } 2760 \end{cfa} 2761 \captionof{figure}{\CFA object-creation benchmark} 2762 \label{f:creation} 2763 2764 \columnbreak 2765 2766 \vspace*{-16pt} 2767 \captionof{table}{Object creation comparison (nanoseconds)} 2768 \label{tab:creation} 2769 2770 \begin{tabular}[t]{@{}r*{3}{D{.}{.}{5.2}}@{}} 2771 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 2772 \CFA Coroutine Lazy & 13.2 & 13.1 & 0.44 \\ 2773 \CFA Coroutine Eager & 531.3 & 536.0 & 26.54 \\ 2774 \CFA Thread & 2074.9 & 2066.5 & 170.76 \\ 2775 \uC Coroutine & 89.6 & 90.5 & 1.83 \\ 2776 \uC Thread & 528.2 & 528.5 & 4.94 \\ 2777 Goroutine & 4068.0 & 4113.1 & 414.55 \\ 2778 Java Thread & 103848.5 & 104295.4 & 2637.57 \\ 2779 Pthreads & 33112.6 & 33127.1 & 165.90 2780 \end{tabular} 2781 \end{multicols} 2782 2783 2784 \paragraph{Context-Switching} 2785 2786 In procedural programming, the cost of a function call is important as modularization (refactoring) increases. 2787 (In many cases, a compiler inlines function calls to eliminate this cost.) 2788 Similarly, when modularization extends to coroutines/tasks, the time for a context switch becomes a relevant factor. 2789 The coroutine test is from resumer to suspender and from suspender to resumer, which is two context switches. 2790 The thread test is using yield to enter and return from the runtime kernel, which is two context switches. 2791 The difference in performance between coroutine and thread context-switch is the cost of scheduling for threads, whereas coroutines are self-scheduling. 2792 Figure~\ref{f:ctx-switch} only shows the \CFA code for coroutines/threads (other systems are similar) with all results in Table~\ref{tab:ctx-switch}. 2793 2794 \begin{multicols}{2} 2795 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 2796 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 2797 @coroutine@ C {} c; 2798 void main( C & ) { for ( ;; ) { @suspend;@ } } 2799 int main() { // coroutine test 2800 BENCH( for ( N ) { @resume( c );@ } ) 2801 sout | result`ns; 2802 } 2803 int main() { // task test 2804 BENCH( for ( N ) { @yield();@ } ) 2805 sout | result`ns; 2806 } 2807 \end{cfa} 2808 \captionof{figure}{\CFA context-switch benchmark} 2809 \label{f:ctx-switch} 2810 2811 \columnbreak 2812 2813 \vspace*{-16pt} 2814 \captionof{table}{Context switch comparison (nanoseconds)} 2815 \label{tab:ctx-switch} 2816 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}} 2817 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 2818 C function & 1.8 & 1.8 & 0.01 \\ 2819 \CFA generator & 2.4 & 2.2 & 0.25 \\ 2820 \CFA Coroutine & 36.2 & 36.2 & 0.25 \\ 2821 \CFA Thread & 93.2 & 93.5 & 2.09 \\ 2822 \uC Coroutine & 52.0 & 52.1 & 0.51 \\ 2823 \uC Thread & 96.2 & 96.3 & 0.58 \\ 2824 Goroutine & 141.0 & 141.3 & 3.39 \\ 2825 Java Thread & 374.0 & 375.8 & 10.38 \\ 2826 Pthreads Thread & 361.0 & 365.3 & 13.19 2827 \end{tabular} 2828 \end{multicols} 2829 2830 2831 \paragraph{Mutual-Exclusion} 2832 2833 Uncontented mutual exclusion, which frequently occurs, is measured by entering/leaving a critical section. 2834 For monitors, entering and leaving a monitor function is measured. 2835 To put the results in context, the cost of entering a non-inline function and the cost of acquiring and releasing a @pthread_mutex@ lock is also measured. 2836 Figure~\ref{f:mutex} shows the code for \CFA with all results in Table~\ref{tab:mutex}. 2837 Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects. 2838 2839 \begin{multicols}{2} 2840 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 2841 \begin{cfa} 2842 @monitor@ M {} m1/*, m2, m3, m4*/; 2843 void __attribute__((noinline)) 2844 do_call( M & @mutex m/*, m2, m3, m4*/@ ) {} 2845 int main() { 2963 2846 BENCH( 2964 for(size_t i=0; i<n; i++) { 2965 resume(s); 2966 }, 2967 result 2847 for( N ) do_call( m1/*, m2, m3, m4*/ ); 2968 2848 ) 2969 printf("%llu\n", result); 2970 } 2971 \end{cfa} 2849 sout | result`ns; 2850 } 2851 \end{cfa} 2852 \captionof{figure}{\CFA acquire/release mutex benchmark} 2853 \label{f:mutex} 2854 2972 2855 \columnbreak 2973 \CFA Threads 2974 \begin{cfa} 2975 2976 2977 2978 2979 int main() { 2980 2981 2982 BENCH( 2983 for(size_t i=0; i<n; i++) { 2984 yield(); 2985 }, 2986 result 2987 ) 2988 printf("%llu\n", result); 2989 } 2990 \end{cfa} 2856 2857 \vspace*{-16pt} 2858 \captionof{table}{Mutex comparison (nanoseconds)} 2859 \label{tab:mutex} 2860 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}} 2861 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 2862 test and test-and-test lock & 19.1 & 18.9 & 0.40 \\ 2863 \CFA @mutex@ function, 1 arg. & 45.9 & 46.6 & 1.45 \\ 2864 \CFA @mutex@ function, 2 arg. & 105.0 & 104.7 & 3.08 \\ 2865 \CFA @mutex@ function, 4 arg. & 165.0 & 167.6 & 5.65 \\ 2866 \uC @monitor@ member rtn. & 54.0 & 53.7 & 0.82 \\ 2867 Java synchronized method & 31.0 & 31.1 & 0.50 \\ 2868 Pthreads Mutex Lock & 33.6 & 32.6 & 1.14 2869 \end{tabular} 2991 2870 \end{multicols} 2992 \begin{cfa}[caption={\CFA benchmark code used to measure context-switches for coroutines and threads.},label={f:ctx-switch}] 2993 \end{cfa} 2994 \end{figure} 2995 2996 \begin{table} 2997 \begin{center} 2998 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |} 2999 \cline{2-4} 3000 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\ 3001 \hline 3002 Kernel Thread & 241.5 & 243.86 & 5.08 \\ 3003 \CFA Coroutine & 38 & 38 & 0 \\ 3004 \CFA Thread & 103 & 102.96 & 2.96 \\ 3005 \uC Coroutine & 46 & 45.86 & 0.35 \\ 3006 \uC Thread & 98 & 99.11 & 1.42 \\ 3007 Goroutine & 150 & 149.96 & 3.16 \\ 3008 Java Thread & 289 & 290.68 & 8.72 \\ 3009 \hline 3010 \end{tabular} 3011 \end{center} 3012 \caption{Context Switch comparison. 3013 All numbers are in nanoseconds(\si{\nano\second})} 3014 \label{tab:ctx-switch} 3015 \end{table} 3016 3017 \subsection{Mutual-Exclusion} 3018 The next interesting benchmark is to measure the overhead to enter/leave a critical-section. 3019 For monitors, the simplest approach is to measure how long it takes to enter and leave a monitor routine. 3020 Figure~\ref{f:mutex} shows the code for \CFA. 3021 To put the results in context, the cost of entering a non-inline routine and the cost of acquiring and releasing a @pthread_mutex@ lock is also measured. 3022 The results can be shown in table \ref{tab:mutex}. 3023 3024 \begin{figure} 3025 \begin{cfa}[caption={\CFA benchmark code used to measure mutex routines.},label={f:mutex}] 3026 monitor M {}; 3027 void __attribute__((noinline)) call( M & mutex m /*, m2, m3, m4*/ ) {} 3028 3029 int main() { 3030 M m/*, m2, m3, m4*/; 3031 BENCH( 3032 for(size_t i=0; i<n; i++) { 3033 call(m/*, m2, m3, m4*/); 3034 }, 3035 result 3036 ) 3037 printf("%llu\n", result); 3038 } 3039 \end{cfa} 3040 \end{figure} 3041 3042 \begin{table} 3043 \begin{center} 3044 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |} 3045 \cline{2-4} 3046 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\ 3047 \hline 3048 C routine & 2 & 2 & 0 \\ 3049 FetchAdd + FetchSub & 26 & 26 & 0 \\ 3050 Pthreads Mutex Lock & 31 & 31.86 & 0.99 \\ 3051 \uC @monitor@ member routine & 30 & 30 & 0 \\ 3052 \CFA @mutex@ routine, 1 argument & 41 & 41.57 & 0.9 \\ 3053 \CFA @mutex@ routine, 2 argument & 76 & 76.96 & 1.57 \\ 3054 \CFA @mutex@ routine, 4 argument & 145 & 146.68 & 3.85 \\ 3055 Java synchronized routine & 27 & 28.57 & 2.6 \\ 3056 \hline 3057 \end{tabular} 3058 \end{center} 3059 \caption{Mutex routine comparison. 3060 All numbers are in nanoseconds(\si{\nano\second})} 3061 \label{tab:mutex} 3062 \end{table} 3063 3064 \subsection{Internal Scheduling} 3065 The internal-scheduling benchmark measures the cost of waiting on and signalling a condition variable. 3066 Figure~\ref{f:int-sched} shows the code for \CFA, with results table \ref{tab:int-sched}. 3067 As with all other benchmarks, all omitted tests are functionally identical to one of these tests. 3068 3069 \begin{figure} 3070 \begin{cfa}[caption={Benchmark code for internal scheduling},label={f:int-sched}] 2871 2872 2873 \paragraph{External Scheduling} 2874 2875 External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement. 2876 Figure~\ref{f:ext-sched} shows the code for \CFA, with results in Table~\ref{tab:ext-sched}. 2877 Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects. 2878 2879 \begin{multicols}{2} 2880 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 2881 \vspace*{-16pt} 2882 \begin{cfa} 3071 2883 volatile int go = 0; 3072 condition c; 3073 monitor M {}; 3074 M m1; 3075 3076 void __attribute__((noinline)) do_call( M & mutex a1 ) { signal(c); } 3077 2884 @monitor@ M {} m; 3078 2885 thread T {}; 3079 void ^?{}( T & mutex this ) {} 3080 void main( T & this ) { 3081 while(go == 0) { yield(); } 3082 while(go == 1) { do_call(m1); } 3083 } 3084 int __attribute__((noinline)) do_wait( M & mutex a1 ) { 3085 go = 1; 3086 BENCH( 3087 for(size_t i=0; i<n; i++) { 3088 wait(c); 3089 }, 3090 result 3091 ) 3092 printf("%llu\n", result); 3093 go = 0; 3094 return 0; 2886 void __attribute__((noinline)) 2887 do_call( M & @mutex@ ) {} 2888 void main( T & ) { 2889 while ( go == 0 ) { yield(); } 2890 while ( go == 1 ) { do_call( m ); } 2891 } 2892 int __attribute__((noinline)) 2893 do_wait( M & @mutex@ m ) { 2894 go = 1; // continue other thread 2895 BENCH( for ( N ) { @waitfor( do_call, m );@ } ) 2896 go = 0; // stop other thread 2897 sout | result`ns; 3095 2898 } 3096 2899 int main() { 3097 2900 T t; 3098 return do_wait(m1); 3099 } 3100 \end{cfa} 3101 \end{figure} 3102 3103 \begin{table} 3104 \begin{center} 3105 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |} 3106 \cline{2-4} 3107 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\ 3108 \hline 3109 Pthreads Condition Variable & 5902.5 & 6093.29 & 714.78 \\ 3110 \uC @signal@ & 322 & 323 & 3.36 \\ 3111 \CFA @signal@, 1 @monitor@ & 352.5 & 353.11 & 3.66 \\ 3112 \CFA @signal@, 2 @monitor@ & 430 & 430.29 & 8.97 \\ 3113 \CFA @signal@, 4 @monitor@ & 594.5 & 606.57 & 18.33 \\ 3114 Java @notify@ & 13831.5 & 15698.21 & 4782.3 \\ 3115 \hline 2901 do_wait( m ); 2902 } 2903 \end{cfa} 2904 \captionof{figure}{\CFA external-scheduling benchmark} 2905 \label{f:ext-sched} 2906 2907 \columnbreak 2908 2909 \vspace*{-16pt} 2910 \captionof{table}{External-scheduling comparison (nanoseconds)} 2911 \label{tab:ext-sched} 2912 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}} 2913 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 2914 \CFA @waitfor@, 1 @monitor@ & 376.4 & 376.8 & 7.63 \\ 2915 \CFA @waitfor@, 2 @monitor@ & 491.4 & 492.0 & 13.31 \\ 2916 \CFA @waitfor@, 4 @monitor@ & 681.0 & 681.7 & 19.10 \\ 2917 \uC @_Accept@ & 331.1 & 331.4 & 2.66 3116 2918 \end{tabular} 3117 \end{ center}3118 \caption{Internal scheduling comparison. 3119 All numbers are in nanoseconds(\si{\nano\second})} 3120 \ label{tab:int-sched}3121 \end{table} 3122 3123 \subsection{External Scheduling} 3124 The Internal scheduling benchmark measures the cost of the @waitfor@ statement (@_Accept@ in \uC).3125 Figure~\ref{f:ext-sched} shows the code for \CFA, with results in table \ref{tab:ext-sched}.3126 As with all other benchmarks, all omitted tests are functionally identical to one of these tests. 3127 3128 \ begin{figure}3129 \begin{cfa} [caption={Benchmark code for external scheduling},label={f:ext-sched}]2919 \end{multicols} 2920 2921 2922 \paragraph{Internal Scheduling} 2923 2924 Internal scheduling is measured using a cycle of two threads signalling and waiting. 2925 Figure~\ref{f:int-sched} shows the code for \CFA, with results in Table~\ref{tab:int-sched}. 2926 Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects. 2927 Java scheduling is significantly greater because the benchmark explicitly creates multiple thread in order to prevent the JIT from making the program sequential, \ie removing all locking. 2928 2929 \begin{multicols}{2} 2930 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 2931 \begin{cfa} 3130 2932 volatile int go = 0; 3131 monitor M {}; 3132 M m1; 2933 @monitor@ M { @condition c;@ } m; 2934 void __attribute__((noinline)) 2935 do_call( M & @mutex@ a1 ) { @signal( c );@ } 3133 2936 thread T {}; 3134 3135 void __attribute__((noinline)) do_call( M & mutex a1 ) {}3136 3137 void ^?{}( T & mutex this ) {}3138 2937 void main( T & this ) { 3139 while(go == 0) { yield(); } 3140 while(go == 1) { do_call(m1); } 3141 } 3142 int __attribute__((noinline)) do_wait( M & mutex a1 ) { 3143 go = 1; 3144 BENCH( 3145 for(size_t i=0; i<n; i++) { 3146 waitfor(call, a1); 3147 }, 3148 result 3149 ) 3150 printf("%llu\n", result); 3151 go = 0; 3152 return 0; 2938 while ( go == 0 ) { yield(); } 2939 while ( go == 1 ) { do_call( m ); } 2940 } 2941 int __attribute__((noinline)) 2942 do_wait( M & mutex m ) with(m) { 2943 go = 1; // continue other thread 2944 BENCH( for ( N ) { @wait( c );@ } ); 2945 go = 0; // stop other thread 2946 sout | result`ns; 3153 2947 } 3154 2948 int main() { 3155 2949 T t; 3156 return do_wait(m1); 3157 } 3158 \end{cfa} 3159 \end{figure} 3160 3161 \begin{table} 3162 \begin{center} 3163 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |} 3164 \cline{2-4} 3165 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\ 3166 \hline 3167 \uC @Accept@ & 350 & 350.61 & 3.11 \\ 3168 \CFA @waitfor@, 1 @monitor@ & 358.5 & 358.36 & 3.82 \\ 3169 \CFA @waitfor@, 2 @monitor@ & 422 & 426.79 & 7.95 \\ 3170 \CFA @waitfor@, 4 @monitor@ & 579.5 & 585.46 & 11.25 \\ 3171 \hline 2950 do_wait( m ); 2951 } 2952 \end{cfa} 2953 \captionof{figure}{\CFA Internal-scheduling benchmark} 2954 \label{f:int-sched} 2955 2956 \columnbreak 2957 2958 \vspace*{-16pt} 2959 \captionof{table}{Internal-scheduling comparison (nanoseconds)} 2960 \label{tab:int-sched} 2961 \bigskip 2962 2963 \begin{tabular}{@{}r*{3}{D{.}{.}{5.2}}@{}} 2964 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 2965 \CFA @signal@, 1 @monitor@ & 372.6 & 374.3 & 14.17 \\ 2966 \CFA @signal@, 2 @monitor@ & 492.7 & 494.1 & 12.99 \\ 2967 \CFA @signal@, 4 @monitor@ & 749.4 & 750.4 & 24.74 \\ 2968 \uC @signal@ & 320.5 & 321.0 & 3.36 \\ 2969 Java @notify@ & 10160.5 & 10169.4 & 267.71 \\ 2970 Pthreads Cond. Variable & 4949.6 & 5065.2 & 363 3172 2971 \end{tabular} 3173 \end{center} 3174 \caption{External scheduling comparison. 3175 All numbers are in nanoseconds(\si{\nano\second})} 3176 \label{tab:ext-sched} 3177 \end{table} 3178 3179 3180 \subsection{Object Creation} 3181 Finally, the last benchmark measures the cost of creation for concurrent objects. 3182 Figure~\ref{f:creation} shows the code for @pthread@s and \CFA threads, with results shown in table \ref{tab:creation}. 3183 As with all other benchmarks, all omitted tests are functionally identical to one of these tests. 3184 The only note here is that the call stacks of \CFA coroutines are lazily created, therefore without priming the coroutine, the creation cost is very low. 3185 3186 \begin{figure} 3187 \begin{center} 3188 @pthread@ 3189 \begin{cfa} 3190 int main() { 3191 BENCH( 3192 for(size_t i=0; i<n; i++) { 3193 pthread_t thread; 3194 if(pthread_create(&thread,NULL,foo,NULL)<0) { 3195 perror( "failure" ); 3196 return 1; 3197 } 3198 3199 if(pthread_join(thread, NULL)<0) { 3200 perror( "failure" ); 3201 return 1; 3202 } 3203 }, 3204 result 3205 ) 3206 printf("%llu\n", result); 3207 } 3208 \end{cfa} 3209 3210 3211 3212 \CFA Threads 3213 \begin{cfa} 3214 int main() { 3215 BENCH( 3216 for(size_t i=0; i<n; i++) { 3217 MyThread m; 3218 }, 3219 result 3220 ) 3221 printf("%llu\n", result); 3222 } 3223 \end{cfa} 3224 \end{center} 3225 \caption{Benchmark code for \protect\lstinline|pthread|s and \CFA to measure object creation} 3226 \label{f:creation} 3227 \end{figure} 3228 3229 \begin{table} 3230 \begin{center} 3231 \begin{tabular}{| l | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] | S[table-format=5.2,table-number-alignment=right] |} 3232 \cline{2-4} 3233 \multicolumn{1}{c |}{} & \multicolumn{1}{c |}{ Median } &\multicolumn{1}{c |}{ Average } & \multicolumn{1}{c |}{ Standard Deviation} \\ 3234 \hline 3235 Pthreads & 26996 & 26984.71 & 156.6 \\ 3236 \CFA Coroutine Lazy & 6 & 5.71 & 0.45 \\ 3237 \CFA Coroutine Eager & 708 & 706.68 & 4.82 \\ 3238 \CFA Thread & 1173.5 & 1176.18 & 15.18 \\ 3239 \uC Coroutine & 109 & 107.46 & 1.74 \\ 3240 \uC Thread & 526 & 530.89 & 9.73 \\ 3241 Goroutine & 2520.5 & 2530.93 & 61,56 \\ 3242 Java Thread & 91114.5 & 92272.79 & 961.58 \\ 3243 \hline 3244 \end{tabular} 3245 \end{center} 3246 \caption{Creation comparison. 3247 All numbers are in nanoseconds(\si{\nano\second}).} 3248 \label{tab:creation} 3249 \end{table} 3250 2972 \end{multicols} 3251 2973 3252 2974 3253 2975 \section{Conclusion} 3254 This paper has achieved a minimal concurrency \textbf{api} that is simple, efficient and usable as the basis for higher-level features. 3255 The approach presented is based on a lightweight thread-system for parallelism, which sits on top of clusters of processors. 3256 This M:N model is judged to be both more efficient and allow more flexibility for users. 3257 Furthermore, this document introduces monitors as the main concurrency tool for users. 3258 This paper also offers a novel approach allowing multiple monitors to be accessed simultaneously without running into the Nested Monitor Problem~\cite{Lister77}. 3259 It also offers a full implementation of the concurrency runtime written entirely in \CFA, effectively the largest \CFA code base to date. 3260 3261 3262 % ====================================================================== 3263 % ====================================================================== 2976 2977 Advanced control-flow will always be difficult, especially when there is temporal ordering and nondeterminism. 2978 However, many systems exacerbate the difficulty through their presentation mechanisms. 2979 This paper shows it is possible to present a hierarchy of control-flow features, generator, coroutine, thread, and monitor, providing an integrated set of high-level, efficient, and maintainable control-flow features. 2980 Eliminated from \CFA are spurious wakeup and barging, which are nonintuitive and lead to errors, and having to work with a bewildering set of low-level locks and acquisition techniques. 2981 \CFA high-level race-free monitors and tasks provide the core mechanisms for mutual exclusion and synchronization, without having to resort to magic qualifiers like @volatile@/@atomic@. 2982 Extending these mechanisms to handle high-level deadlock-free bulk acquire across both mutual exclusion and synchronization is a unique contribution. 2983 The \CFA runtime provides concurrency based on a preemptive M:N user-level threading-system, executing in clusters, which encapsulate scheduling of work on multiple kernel threads providing parallelism. 2984 The M:N model is judged to be efficient and provide greater flexibility than a 1:1 threading model. 2985 These concepts and the \CFA runtime-system are written in the \CFA language, extensively leveraging the \CFA type-system, which demonstrates the expressiveness of the \CFA language. 2986 Performance comparisons with other concurrent systems/languages show the \CFA approach is competitive across all low-level operations, which translates directly into good performance in well-written concurrent applications. 2987 C programmers should feel comfortable using these mechanisms for developing complex control-flow in applications, with the ability to obtain maximum available performance by selecting mechanisms at the appropriate level of need. 2988 2989 3264 2990 \section{Future Work} 3265 % ====================================================================== 3266 % ====================================================================== 3267 3268 \subsection{Performance} \label{futur:perf} 3269 This paper presents a first implementation of the \CFA concurrency runtime. 3270 Therefore, there is still significant work to improve performance. 3271 Many of the data structures and algorithms may change in the future to more efficient versions. 3272 For example, the number of monitors in a single bulk acquire is only bound by the stack size, this is probably unnecessarily generous. 3273 It may be possible that limiting the number helps increase performance. 3274 However, it is not obvious that the benefit would be significant. 3275 3276 \subsection{Flexible Scheduling} \label{futur:sched} 2991 2992 While control flow in \CFA has a strong start, development is still underway to complete a number of missing features. 2993 2994 \paragraph{Flexible Scheduling} 2995 \label{futur:sched} 2996 3277 2997 An important part of concurrency is scheduling. 3278 2998 Different scheduling algorithms can affect performance (both in terms of average and variation). 3279 2999 However, no single scheduler is optimal for all workloads and therefore there is value in being able to change the scheduler for given programs. 3280 One solution is to offer various tweaking options to users, allowing the scheduler to be adjusted to the requirements of the workload. 3281 However, in order to be truly flexible, it would be interesting to allow users to add arbitrary data and arbitrary scheduling algorithms. 3282 For example, a web server could attach Type-of-Service information to threads and have a ``ToS aware'' scheduling algorithm tailored to this specific web server. 3283 This path of flexible schedulers will be explored for \CFA. 3284 3285 \subsection{Non-Blocking I/O} \label{futur:nbio} 3286 While most of the parallelism tools are aimed at data parallelism and control-flow parallelism, many modern workloads are not bound on computation but on IO operations, a common case being web servers and XaaS (anything as a service). 3287 These types of workloads often require significant engineering around amortizing costs of blocking IO operations. 3288 At its core, non-blocking I/O is an operating system level feature that allows queuing IO operations (\eg network operations) and registering for notifications instead of waiting for requests to complete. 3289 In this context, the role of the language makes Non-Blocking IO easily available and with low overhead. 3290 The current trend is to use asynchronous programming using tools like callbacks and/or futures and promises, which can be seen in frameworks like Node.js~\cite{NodeJs} for JavaScript, Spring MVC~\cite{SpringMVC} for Java and Django~\cite{Django} for Python. 3291 However, while these are valid solutions, they lead to code that is harder to read and maintain because it is much less linear. 3292 3293 \subsection{Other Concurrency Tools} \label{futur:tools} 3294 While monitors offer a flexible and powerful concurrent core for \CFA, other concurrency tools are also necessary for a complete multi-paradigm concurrency package. 3295 Examples of such tools can include simple locks and condition variables, futures and promises~\cite{promises}, executors and actors. 3296 These additional features are useful when monitors offer a level of abstraction that is inadequate for certain tasks. 3297 3298 \subsection{Implicit Threading} \label{futur:implcit} 3299 Simpler applications can benefit greatly from having implicit parallelism. 3300 That is, parallelism that does not rely on the user to write concurrency. 3301 This type of parallelism can be achieved both at the language level and at the library level. 3302 The canonical example of implicit parallelism is parallel for loops, which are the simplest example of a divide and conquer algorithms~\cite{uC++book}. 3303 Table \ref{f:parfor} shows three different code examples that accomplish point-wise sums of large arrays. 3304 Note that none of these examples explicitly declare any concurrency or parallelism objects. 3305 3306 \begin{table} 3307 \begin{center} 3308 \begin{tabular}[t]{|c|c|c|} 3309 Sequential & Library Parallel & Language Parallel \\ 3310 \begin{cfa}[tabsize=3] 3311 void big_sum( 3312 int* a, int* b, 3313 int* o, 3314 size_t len) 3315 { 3316 for( 3317 int i = 0; 3318 i < len; 3319 ++i ) 3320 { 3321 o[i]=a[i]+b[i]; 3322 } 3323 } 3324 3325 3326 3327 3328 3329 int* a[10000]; 3330 int* b[10000]; 3331 int* c[10000]; 3332 //... fill in a & b 3333 big_sum(a,b,c,10000); 3334 \end{cfa} &\begin{cfa}[tabsize=3] 3335 void big_sum( 3336 int* a, int* b, 3337 int* o, 3338 size_t len) 3339 { 3340 range ar(a, a+len); 3341 range br(b, b+len); 3342 range or(o, o+len); 3343 parfor( ai, bi, oi, 3344 []( int* ai, 3345 int* bi, 3346 int* oi) 3347 { 3348 oi=ai+bi; 3349 }); 3350 } 3351 3352 3353 int* a[10000]; 3354 int* b[10000]; 3355 int* c[10000]; 3356 //... fill in a & b 3357 big_sum(a,b,c,10000); 3358 \end{cfa}&\begin{cfa}[tabsize=3] 3359 void big_sum( 3360 int* a, int* b, 3361 int* o, 3362 size_t len) 3363 { 3364 parfor (ai,bi,oi) 3365 in (a, b, o ) 3366 { 3367 oi = ai + bi; 3368 } 3369 } 3370 3371 3372 3373 3374 3375 3376 3377 int* a[10000]; 3378 int* b[10000]; 3379 int* c[10000]; 3380 //... fill in a & b 3381 big_sum(a,b,c,10000); 3382 \end{cfa} 3383 \end{tabular} 3384 \end{center} 3385 \caption{For loop to sum numbers: Sequential, using library parallelism and language parallelism.} 3386 \label{f:parfor} 3387 \end{table} 3388 3389 Implicit parallelism is a restrictive solution and therefore has its limitations. 3390 However, it is a quick and simple approach to parallelism, which may very well be sufficient for smaller applications and reduces the amount of boilerplate needed to start benefiting from parallelism in modern CPUs. 3391 3392 3393 % A C K N O W L E D G E M E N T S 3394 % ------------------------------- 3000 One solution is to offer various tuning options, allowing the scheduler to be adjusted to the requirements of the workload. 3001 However, to be truly flexible, a pluggable scheduler is necessary. 3002 Currently, the \CFA pluggable scheduler is too simple to handle complex scheduling, \eg quality of service and real-time, where the scheduler must interact with mutex objects to deal with issues like priority inversion~\cite{Buhr00b}. 3003 3004 \paragraph{Non-Blocking I/O} 3005 \label{futur:nbio} 3006 3007 Many modern workloads are not bound by computation but IO operations, a common case being web servers and XaaS~\cite{XaaS} (anything as a service). 3008 These types of workloads require significant engineering to amortizing costs of blocking IO-operations. 3009 At its core, non-blocking I/O is an operating-system level feature queuing IO operations, \eg network operations, and registering for notifications instead of waiting for requests to complete. 3010 Current trends use asynchronous programming like callbacks, futures, and/or promises, \eg Node.js~\cite{NodeJs} for JavaScript, Spring MVC~\cite{SpringMVC} for Java, and Django~\cite{Django} for Python. 3011 However, these solutions lead to code that is hard to create, read and maintain. 3012 A better approach is to tie non-blocking I/O into the concurrency system to provide ease of use with low overhead, \eg thread-per-connection web-services. 3013 A non-blocking I/O library is currently under development for \CFA. 3014 3015 \paragraph{Other Concurrency Tools} 3016 \label{futur:tools} 3017 3018 While monitors offer flexible and powerful concurrency for \CFA, other concurrency tools are also necessary for a complete multi-paradigm concurrency package. 3019 Examples of such tools can include futures and promises~\cite{promises}, executors and actors. 3020 These additional features are useful for applications that can be constructed without shared data and direct blocking. 3021 As well, new \CFA extensions should make it possible to create a uniform interface for virtually all mutual exclusion, including monitors and low-level locks. 3022 3023 \paragraph{Implicit Threading} 3024 \label{futur:implcit} 3025 3026 Basic concurrent (embarrassingly parallel) applications can benefit greatly from implicit concurrency, where sequential programs are converted to concurrent, possibly with some help from pragmas to guide the conversion. 3027 This type of concurrency can be achieved both at the language level and at the library level. 3028 The canonical example of implicit concurrency is concurrent nested @for@ loops, which are amenable to divide and conquer algorithms~\cite{uC++book}. 3029 The \CFA language features should make it possible to develop a reasonable number of implicit concurrency mechanism to solve basic HPC data-concurrency problems. 3030 However, implicit concurrency is a restrictive solution with significant limitations, so it can never replace explicit concurrent programming. 3031 3032 3395 3033 \section{Acknowledgements} 3396 3034 3397 Thanks to Aaron Moss, Rob Schluntz and Andrew Beach for their work on the \CFA project as well as all the discussions which helped concretize the ideas in this paper. 3398 Partial funding was supplied by the Natural Sciences and Engineering Research Council of Canada and a corporate partnership with Huawei Ltd. 3399 3400 3401 % B I B L I O G R A P H Y 3402 % ----------------------------- 3403 %\bibliographystyle{plain} 3035 The authors would like to recognize the design assistance of Aaron Moss, Rob Schluntz, Andrew Beach and Michael Brooks on the features described in this paper. 3036 Funding for this project has been provided by Huawei Ltd.\ (\url{http://www.huawei.com}). %, and Peter Buhr is partially funded by the Natural Sciences and Engineering Research Council of Canada. 3037 3038 {% 3039 \fontsize{9bp}{12bp}\selectfont% 3404 3040 \bibliography{pl,local} 3405 3041 }% 3406 3042 3407 3043 \end{document} -
doc/papers/concurrency/annex/local.bib
r7951100 rb067d9b 46 46 title = {Thread Building Blocks}, 47 47 howpublished= {Intel, \url{https://www.threadingbuildingblocks.org}}, 48 note = {Accessed: 2018-3},48 optnote = {Accessed: 2018-3}, 49 49 } 50 50 … … 66 66 } 67 67 68 @ article{BankTransfer,68 @misc{BankTransfer, 69 69 key = {Bank Transfer}, 70 70 keywords = {Bank Transfer}, 71 71 title = {Bank Account Transfer Problem}, 72 publisher = {Wiki Wiki Web}, 73 address = {http://wiki.c2.com}, 72 howpublished = {Wiki Wiki Web, \url{http://wiki.c2.com/?BankAccountTransferProblem}}, 74 73 year = 2010 75 74 } -
doc/papers/concurrency/figures/ext_monitor.fig
r7951100 rb067d9b 8 8 -2 9 9 1200 2 10 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3150.000 3450.000 3150 3150 2850 3450 3150 375011 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3150.000 4350.000 3150 4050 2850 4350 3150 465012 6 5850 1950 6150 225013 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 2100 105 105 6000 2100 6105 220514 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 2160 d\00110 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1500.000 3600.000 1500 3300 1200 3600 1500 3900 11 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1500.000 4500.000 1500 4200 1200 4500 1500 4800 12 6 4200 2100 4500 2400 13 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 2250 105 105 4350 2250 4455 2355 14 4 1 -1 0 0 0 10 0.0000 2 105 90 4350 2310 d\001 15 15 -6 16 6 5100 2100 5400 240017 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 2250 105 105 5250 2250 5355 225018 4 1 -1 0 0 0 10 0.0000 2 105 120 5250 2295 X\00116 6 4200 1800 4500 2100 17 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 1950 105 105 4350 1950 4455 2055 18 4 1 -1 0 0 0 10 0.0000 2 105 90 4350 2010 b\001 19 19 -6 20 6 5100 1800 5400 2100 21 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 1950 105 105 5250 1950 5355 1950 22 4 1 -1 0 0 0 10 0.0000 2 105 120 5250 2010 Y\001 20 6 1420 5595 5625 5805 21 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 1500 5700 80 80 1500 5700 1580 5780 22 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 2850 5700 105 105 2850 5700 2955 5805 23 1 3 0 1 -1 -1 0 0 4 0.000 1 0.0000 4350 5700 105 105 4350 5700 4455 5805 24 4 0 -1 0 0 0 12 0.0000 2 135 1035 3075 5775 blocked task\001 25 4 0 -1 0 0 0 12 0.0000 2 135 870 1650 5775 active task\001 26 4 0 -1 0 0 0 12 0.0000 2 135 1050 4575 5775 routine mask\001 23 27 -6 24 6 5850 1650 6150 1950 25 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 1800 105 105 6000 1800 6105 1905 26 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 1860 b\001 28 6 3450 1950 3750 2550 29 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 3600 2100 105 105 3600 2100 3705 2100 30 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 31 3450 1950 3750 1950 3750 2550 3450 2550 3450 1950 32 4 1 4 0 0 0 10 0.0000 2 105 120 3600 2160 Y\001 27 33 -6 28 6 3070 5445 7275 5655 29 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3150 5550 80 80 3150 5550 3230 5630 30 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4500 5550 105 105 4500 5550 4605 5655 31 1 3 0 1 -1 -1 0 0 4 0.000 1 0.0000 6000 5550 105 105 6000 5550 6105 5655 32 4 0 -1 0 0 0 12 0.0000 2 135 1035 4725 5625 blocked task\001 33 4 0 -1 0 0 0 12 0.0000 2 135 870 3300 5625 active task\001 34 4 0 -1 0 0 0 12 0.0000 2 135 1050 6225 5625 routine mask\001 34 6 3450 2250 3750 2550 35 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 3600 2400 105 105 3600 2400 3705 2400 36 4 1 4 0 0 0 10 0.0000 2 105 120 3600 2445 X\001 35 37 -6 36 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3300 3600 105 105 3300 3600 3405 370537 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3600 3600 105 105 3600 3600 3705 370538 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6600 3900 105 105 6600 3900 6705 400539 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6900 3900 105 105 6900 3900 7005 400540 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 2700 105 105 6000 2700 6105 280541 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 2400 105 105 6000 2400 6105 250542 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 5100 4575 80 80 5100 4575 5180 465538 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 1650 3750 105 105 1650 3750 1755 3855 39 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 1950 3750 105 105 1950 3750 2055 3855 40 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4950 4050 105 105 4950 4050 5055 4155 41 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 5250 4050 105 105 5250 4050 5355 4155 42 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 2850 105 105 4350 2850 4455 2955 43 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 2550 105 105 4350 2550 4455 2655 44 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3450 4725 80 80 3450 4725 3530 4805 43 45 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 44 4050 2925 5475 2925 5475 3225 4050 3225 4050 292546 2400 3075 3825 3075 3825 3375 2400 3375 2400 3075 45 47 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 46 3150 3750 3750 3750 3750 4050 3150 405048 1500 3900 2100 3900 2100 4200 1500 4200 47 49 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3 48 3150 3450 3750 3450 3900 367550 1500 3600 2100 3600 2250 3825 49 51 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 50 3750 3150 3600 337552 2100 3300 1950 3525 51 53 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3 52 3150 4350 3750 4350 3900 457554 1500 4500 2100 4500 2250 4725 53 55 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 54 3750 4050 3600 427556 2100 4200 1950 4425 55 57 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 56 3150 4650 3750 4650 3750 4950 4950 495058 1500 4800 2100 4800 2100 5100 3300 5100 57 59 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 58 6450 3750 6300 397560 4800 3900 4650 4125 59 61 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 60 4950 4950 5175 510062 3300 5100 3525 5250 61 63 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 9 62 5250 4950 6450 4950 6450 4050 7050 4050 7050 3750 6450 375063 6450 2850 6150 2850 6150 165064 3600 5100 4800 5100 4800 4200 5400 4200 5400 3900 4800 3900 65 4800 3000 4500 3000 4500 1800 64 66 2 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5 65 5850 4200 5850 3300 4350 3300 4350 4200 5850 420066 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1267 4200 4350 4200 3450 2700 3450 2700 4350 4200 4350 68 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 67 69 1 1 1.00 60.00 120.00 68 7 1 1.00 60.00 120.00 69 5250 3150 5250 2400 70 3600 3225 3600 2550 71 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 72 4050 3000 4500 3150 70 73 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 71 3150 3150 3750 3150 3750 2850 5700 2850 5700 1650 72 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 73 5700 2850 6150 3000 74 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 75 5100 1800 5400 1800 5400 2400 5100 2400 5100 1800 76 4 1 -1 0 0 0 10 0.0000 2 75 75 6000 2745 a\001 77 4 1 -1 0 0 0 10 0.0000 2 75 75 6000 2445 c\001 78 4 1 -1 0 0 0 12 0.0000 2 135 315 5100 5325 exit\001 79 4 1 -1 0 0 0 12 0.0000 2 135 135 3300 3075 A\001 80 4 1 -1 0 0 0 12 0.0000 2 135 795 3300 4875 condition\001 81 4 1 -1 0 0 0 12 0.0000 2 135 135 3300 5100 B\001 82 4 0 -1 0 0 0 12 0.0000 2 135 420 6600 3675 stack\001 83 4 0 -1 0 0 0 12 0.0000 2 180 750 6600 3225 acceptor/\001 84 4 0 -1 0 0 0 12 0.0000 2 180 750 6600 3450 signalled\001 85 4 1 -1 0 0 0 12 0.0000 2 135 795 3300 2850 condition\001 86 4 1 -1 0 0 0 12 0.0000 2 165 420 6000 1350 entry\001 87 4 1 -1 0 0 0 12 0.0000 2 135 495 6000 1575 queue\001 88 4 0 -1 0 0 0 12 0.0000 2 135 525 6300 2400 arrival\001 89 4 0 -1 0 0 0 12 0.0000 2 135 630 6300 2175 order of\001 90 4 1 -1 0 0 0 12 0.0000 2 135 525 5100 3675 shared\001 91 4 1 -1 0 0 0 12 0.0000 2 135 735 5100 3975 variables\001 92 4 0 0 50 -1 0 11 0.0000 2 165 855 4275 3150 Acceptables\001 93 4 0 0 50 -1 0 11 0.0000 2 120 165 5775 2700 W\001 94 4 0 0 50 -1 0 11 0.0000 2 120 135 5775 2400 X\001 95 4 0 0 50 -1 0 11 0.0000 2 120 105 5775 2100 Z\001 96 4 0 0 50 -1 0 11 0.0000 2 120 135 5775 1800 Y\001 74 1500 3300 2100 3300 2100 3000 4050 3000 4050 1800 75 4 1 -1 0 0 0 10 0.0000 2 75 75 4350 2895 a\001 76 4 1 -1 0 0 0 10 0.0000 2 75 75 4350 2595 c\001 77 4 1 -1 0 0 0 12 0.0000 2 135 315 3450 5475 exit\001 78 4 1 -1 0 0 0 12 0.0000 2 135 135 1650 3225 A\001 79 4 1 -1 0 0 0 12 0.0000 2 135 795 1650 5025 condition\001 80 4 1 -1 0 0 0 12 0.0000 2 135 135 1650 5250 B\001 81 4 0 -1 0 0 0 12 0.0000 2 135 420 4950 3825 stack\001 82 4 0 -1 0 0 0 12 0.0000 2 180 750 4950 3375 acceptor/\001 83 4 0 -1 0 0 0 12 0.0000 2 180 750 4950 3600 signalled\001 84 4 1 -1 0 0 0 12 0.0000 2 135 795 1650 3000 condition\001 85 4 0 -1 0 0 0 12 0.0000 2 135 525 4650 2550 arrival\001 86 4 0 -1 0 0 0 12 0.0000 2 135 630 4650 2325 order of\001 87 4 1 -1 0 0 0 12 0.0000 2 135 525 3450 3825 shared\001 88 4 1 -1 0 0 0 12 0.0000 2 135 735 3450 4125 variables\001 89 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 2025 X\001 90 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 2325 Y\001 91 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 2625 Y\001 92 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 2925 X\001 93 4 0 -1 0 0 3 12 0.0000 2 150 540 4950 4425 urgent\001 94 4 1 0 50 -1 0 11 0.0000 2 165 600 3075 3300 accepted\001 95 4 1 -1 0 0 0 12 0.0000 2 165 960 4275 1725 entry queue\001 -
doc/papers/concurrency/figures/monitor.fig
r7951100 rb067d9b 8 8 -2 9 9 1200 2 10 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1500.000 2700.000 1500 2400 1200 2700 1500 3000 11 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1500.000 3600.000 1500 3300 1200 3600 1500 3900 12 6 4200 1200 4500 1500 13 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 1350 105 105 4350 1350 4455 1455 14 4 1 -1 0 0 0 10 0.0000 2 105 90 4350 1410 d\001 10 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1500.000 3300.000 1500 3000 1200 3300 1500 3600 11 5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 1500.000 4200.000 1500 3900 1200 4200 1500 4500 12 6 1350 5250 5325 5550 13 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 1500 5400 80 80 1500 5400 1580 5480 14 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 2850 5400 105 105 2850 5400 2955 5505 15 1 3 0 1 -1 -1 0 0 4 0.000 1 0.0000 4350 5400 105 105 4350 5400 4455 5505 16 4 0 -1 0 0 0 12 0.0000 2 180 765 4575 5475 duplicate\001 17 4 0 -1 0 0 0 12 0.0000 2 135 1035 3075 5475 blocked task\001 18 4 0 -1 0 0 0 12 0.0000 2 135 870 1650 5475 active task\001 15 19 -6 16 6 4200 900 4500 120017 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 1 050 105 105 4350 1050 4455 115518 4 1 -1 0 0 0 10 0.0000 2 105 90 4350 1110 b\00120 6 4200 1800 4500 2100 21 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 1950 105 105 4350 1950 4455 2055 22 4 1 -1 0 0 0 10 0.0000 2 105 90 4350 2010 d\001 19 23 -6 20 6 2400 1500 2700 180021 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 2550 1650 105 105 2550 1650 2655 165022 4 1 -1 0 0 0 10 0.0000 2 105 90 2550 1710 b\00124 6 4200 1500 4500 1800 25 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 1650 105 105 4350 1650 4455 1755 26 4 1 -1 0 0 0 10 0.0000 2 105 90 4350 1710 b\001 23 27 -6 24 6 2400 1800 2700 2100 25 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 2550 1950 105 105 2550 1950 2655 1950 26 4 1 -1 0 0 0 10 0.0000 2 75 75 2550 1995 a\001 27 -6 28 6 3300 1500 3600 1800 29 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 3450 1650 105 105 3450 1650 3555 1650 30 4 1 -1 0 0 0 10 0.0000 2 105 90 3450 1710 d\001 31 -6 32 6 1350 4650 5325 4950 33 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 1500 4800 80 80 1500 4800 1580 4880 34 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 2850 4800 105 105 2850 4800 2955 4905 35 1 3 0 1 -1 -1 0 0 4 0.000 1 0.0000 4350 4800 105 105 4350 4800 4455 4905 36 4 0 -1 0 0 0 12 0.0000 2 180 765 4575 4875 duplicate\001 37 4 0 -1 0 0 0 12 0.0000 2 135 1035 3075 4875 blocked task\001 38 4 0 -1 0 0 0 12 0.0000 2 135 870 1650 4875 active task\001 39 -6 40 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 1650 2850 105 105 1650 2850 1755 2955 41 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 1950 2850 105 105 1950 2850 2055 2955 42 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4950 3150 105 105 4950 3150 5055 3255 43 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 5250 3150 105 105 5250 3150 5355 3255 44 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 1950 105 105 4350 1950 4455 2055 45 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 1650 105 105 4350 1650 4455 1755 46 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3450 3825 80 80 3450 3825 3530 3905 47 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 3450 1950 105 105 3450 1950 3555 1950 28 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 1650 3450 105 105 1650 3450 1755 3555 29 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 1950 3450 105 105 1950 3450 2055 3555 30 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4950 3750 105 105 4950 3750 5055 3855 31 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 5250 3750 105 105 5250 3750 5355 3855 32 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3450 4425 80 80 3450 4425 3530 4505 33 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 2550 105 105 4350 2550 4455 2655 34 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4350 2250 105 105 4350 2250 4455 2355 35 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 5 36 1500 3000 2100 3000 2100 2700 2400 2700 2400 2100 37 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 38 1500 3600 2100 3600 2100 3900 1500 3900 39 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3 40 1500 3300 2100 3300 2250 3525 48 41 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 49 2400 2100 2625 2250 42 2100 3000 1950 3225 43 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3 44 1500 4200 2100 4200 2250 4425 50 45 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 51 3300 2100 3525 2250 46 2100 3900 1950 4125 47 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 48 1500 4500 2100 4500 2100 4800 3300 4800 52 49 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 53 4200 2100 4425 2250 54 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 5 55 1500 2400 2100 2400 2100 2100 2400 2100 2400 1500 50 4800 3600 4650 3825 51 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 52 3300 4800 3525 4950 53 2 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5 54 4200 4050 4200 3150 2700 3150 2700 4050 4200 4050 56 55 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 57 1500 3000 2100 3000 2100 3300 1500 3300 58 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3 59 1500 2700 2100 2700 2250 2925 60 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 61 2100 2400 1950 2625 62 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3 63 1500 3600 2100 3600 2250 3825 64 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 65 2100 3300 1950 3525 66 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 67 1500 3900 2100 3900 2100 4200 3300 4200 68 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 69 4800 3000 4650 3225 70 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 71 3300 4200 3525 4350 72 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 73 3600 1500 3600 2100 4200 2100 4200 900 74 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 75 2700 1500 2700 2100 3300 2100 3300 1500 56 3600 2100 3600 2700 4050 2700 4050 1500 76 57 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 9 77 3600 4200 4800 4200 4800 3300 5400 3300 5400 3000 4800 3000 78 4800 2100 4500 2100 4500 900 79 2 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5 80 4200 3450 4200 2550 2700 2550 2700 3450 4200 3450 81 4 1 -1 0 0 0 10 0.0000 2 75 75 4350 1995 a\001 82 4 1 -1 0 0 0 10 0.0000 2 75 75 4350 1695 c\001 83 4 1 -1 0 0 0 12 0.0000 2 135 315 3450 4575 exit\001 84 4 1 -1 0 0 0 12 0.0000 2 135 135 1650 2325 A\001 85 4 1 -1 0 0 0 12 0.0000 2 135 795 1650 4125 condition\001 86 4 1 -1 0 0 0 12 0.0000 2 135 135 1650 4350 B\001 87 4 0 -1 0 0 0 12 0.0000 2 135 420 4950 2925 stack\001 88 4 0 -1 0 0 0 12 0.0000 2 180 750 4950 2475 acceptor/\001 89 4 0 -1 0 0 0 12 0.0000 2 180 750 4950 2700 signalled\001 90 4 1 -1 0 0 0 12 0.0000 2 135 795 1650 2100 condition\001 91 4 1 -1 0 0 0 12 0.0000 2 135 135 2550 1425 X\001 92 4 1 -1 0 0 0 12 0.0000 2 135 135 3450 1425 Y\001 93 4 1 -1 0 0 0 12 0.0000 2 165 420 4350 600 entry\001 94 4 1 -1 0 0 0 12 0.0000 2 135 495 4350 825 queue\001 95 4 0 -1 0 0 0 12 0.0000 2 135 525 4650 1650 arrival\001 96 4 0 -1 0 0 0 12 0.0000 2 135 630 4650 1425 order of\001 97 4 1 -1 0 0 0 12 0.0000 2 135 525 3450 2925 shared\001 98 4 1 -1 0 0 0 12 0.0000 2 135 735 3450 3225 variables\001 99 4 1 -1 0 0 0 12 0.0000 2 120 510 3000 975 mutex\001 100 4 1 -1 0 0 0 10 0.0000 2 75 75 3450 1995 c\001 101 4 1 -1 0 0 0 12 0.0000 2 135 570 3000 1200 queues\001 58 3600 4800 4800 4800 4800 3900 5400 3900 5400 3600 4800 3600 59 4800 2700 4500 2700 4500 1500 60 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 61 4050 2700 4500 2850 62 4 1 -1 0 0 0 12 0.0000 2 135 315 3450 5175 exit\001 63 4 1 -1 0 0 0 12 0.0000 2 135 795 1650 4725 condition\001 64 4 1 -1 0 0 0 12 0.0000 2 135 135 1650 4950 B\001 65 4 0 -1 0 0 0 12 0.0000 2 135 420 4950 3525 stack\001 66 4 0 -1 0 0 0 12 0.0000 2 180 750 4950 3075 acceptor/\001 67 4 0 -1 0 0 0 12 0.0000 2 180 750 4950 3300 signalled\001 68 4 1 -1 0 0 0 12 0.0000 2 135 525 3450 3525 shared\001 69 4 1 -1 0 0 0 12 0.0000 2 135 735 3450 3825 variables\001 70 4 0 -1 0 0 3 12 0.0000 2 150 540 4950 4125 urgent\001 71 4 1 -1 0 0 0 10 0.0000 2 75 75 4350 2595 a\001 72 4 1 -1 0 0 0 10 0.0000 2 75 75 4350 2295 c\001 73 4 0 -1 0 0 0 12 0.0000 2 135 525 4650 2250 arrival\001 74 4 0 -1 0 0 0 12 0.0000 2 135 630 4650 2025 order of\001 75 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 1725 X\001 76 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 2025 Y\001 77 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 2325 Y\001 78 4 0 4 50 -1 0 11 0.0000 2 120 135 4075 2625 X\001 79 4 1 -1 0 0 0 12 0.0000 2 165 960 4275 1425 entry queue\001 -
doc/papers/general/.gitignore
r7951100 rb067d9b 4 4 *.ps 5 5 6 Paper.tex.plain7 6 mail 8 7 Paper.out.ps -
doc/papers/general/Makefile
r7951100 rb067d9b 4 4 Figures = figures 5 5 Macros = ../AMA/AMA-stix/ama 6 TeXLIB = .:${Macros}:${Build}: ../../bibliography:6 TeXLIB = .:${Macros}:${Build}: 7 7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 8 BibTeX = BIBINPUTS= ${TeXLIB}&& export BIBINPUTS && bibtex8 BibTeX = BIBINPUTS=../../bibliography: && export BIBINPUTS && bibtex 9 9 10 10 MAKEFLAGS = --no-print-directory # --silent … … 46 46 47 47 Paper.zip : 48 zip -x general/.gitignore -x general/"*AMA*" -x general/Paper.out.ps -x general/Paper.tex.plain -x general/evaluation.zip -x general/mail -x general/response -x general/test.c -x general/evaluation.zip -x general/Paper.tex.plain -x general/Paper.ps -x general/Paper.pdf -x general/"*build*" -x general/evaluation/.gitignore -x general/evaluation/timing.xlsx -r Paper.zip general 48 zip -x general/.gitignore -x general/Paper.out.ps -x general/Paper.tex.plain -x -x general/WileyNJD-AMA.bst general/"*evaluation*" -x general/evaluation.zip \ 49 -x general/mail -x general/response -x general/test.c -x general/Paper.ps -x general/"*build*" -r Paper.zip general pl.bib 49 50 50 51 evaluation.zip : 51 zip -x evaluation/.gitignore -x evaluation/timing.xlsx -x evaluation/timing.dat -r evaluation.zip evaluation52 zip -x evaluation/.gitignore -x evaluation/timing.xlsx -x evaluation/timing.dat -r evaluation.zip evaluation 52 53 53 54 # File Dependencies # … … 59 60 dvips ${Build}/$< -o $@ 60 61 61 ${BASE}.dvi : Makefile ${B uild} ${BASE}.out.ps WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \62 ../../bibliography/pl.bib 62 ${BASE}.dvi : Makefile ${BASE}.out.ps ${Macros}/WileyNJD-v2.cls WileyNJD-AMA.bst ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 63 ../../bibliography/pl.bib | ${Build} 63 64 # Must have *.aux file containing citations for bibtex 64 65 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi … … 75 76 mkdir -p ${Build} 76 77 77 ${BASE}.out.ps : ${Build}78 ${BASE}.out.ps : | ${Build} 78 79 ln -fs ${Build}/Paper.out.ps . 79 80 … … 84 85 gnuplot -e Build="'${Build}/'" evaluation/timing.gp 85 86 86 %.tex : %.fig ${Build}87 %.tex : %.fig | ${Build} 87 88 fig2dev -L eepic $< > ${Build}/$@ 88 89 89 %.ps : %.fig ${Build}90 %.ps : %.fig | ${Build} 90 91 fig2dev -L ps $< > ${Build}/$@ 91 92 92 %.pstex : %.fig ${Build}93 %.pstex : %.fig | ${Build} 93 94 fig2dev -L pstex $< > ${Build}/$@ 94 95 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t -
doc/papers/general/Paper.tex
r7951100 rb067d9b 1 1 \documentclass[AMA,STIX1COL]{WileyNJD-v2} 2 \setlength\typewidth{170mm} 3 \setlength\textwidth{170mm} 2 4 3 5 \articletype{RESEARCH ARTICLE}% 4 6 5 \received{26 April 2016} 6 \revised{6 June 2016} 7 \accepted{6 June 2016} 8 7 \received{12 March 2018} 8 \revised{8 May 2018} 9 \accepted{28 June 2018} 10 11 \setlength\typewidth{168mm} 12 \setlength\textwidth{168mm} 9 13 \raggedbottom 10 14 … … 187 191 } 188 192 189 \title{\texorpdfstring{\protect\CFA : Adding Modern Programming Language Features to C}{Cforall : Adding Modern Programming Language Features to C}}193 \title{\texorpdfstring{\protect\CFA : Adding modern programming language features to C}{Cforall : Adding modern programming language features to C}} 190 194 191 195 \author[1]{Aaron Moss} 192 196 \author[1]{Robert Schluntz} 193 \author[1]{Peter A. Buhr *}197 \author[1]{Peter A. Buhr} 194 198 \authormark{MOSS \textsc{et al}} 195 199 196 \address[1]{\orgdiv{Cheriton School of Computer Science}, \orgname{University of Waterloo}, \orgaddress{\state{Waterloo, O N}, \country{Canada}}}197 198 \corres{ *Peter A. Buhr, Cheriton School of Computer Science, University of Waterloo, 200 University Avenue West, Waterloo, ON,N2L 3G1, Canada. \email{pabuhr{\char`\@}uwaterloo.ca}}200 \address[1]{\orgdiv{Cheriton School of Computer Science}, \orgname{University of Waterloo}, \orgaddress{\state{Waterloo, Ontario}, \country{Canada}}} 201 202 \corres{Peter A. Buhr, Cheriton School of Computer Science, University of Waterloo, 200 University Avenue West, Waterloo, ON N2L 3G1, Canada. \email{pabuhr{\char`\@}uwaterloo.ca}} 199 203 200 204 \fundingInfo{Natural Sciences and Engineering Research Council of Canada} 201 205 202 206 \abstract[Summary]{ 203 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from hobby projects to commercial operating-systems. 204 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 205 Nevertheless, C, first standardized almost forty years ago, lacks many features that make programming in more modern languages safer and more productive. 206 207 The goal of the \CFA project (pronounced ``C-for-all'') is to create an extension of C that provides modern safety and productivity features while still ensuring strong backwards compatibility with C and its programmers. 208 Prior projects have attempted similar goals but failed to honour C programming-style; 209 for instance, adding object-oriented or functional programming with garbage collection is a non-starter for many C developers. 210 Specifically, \CFA is designed to have an orthogonal feature-set based closely on the C programming paradigm, so that \CFA features can be added \emph{incrementally} to existing C code-bases, and C programmers can learn \CFA extensions on an as-needed basis, preserving investment in existing code and programmers. 211 This paper presents a quick tour of \CFA features showing how their design avoids shortcomings of similar features in C and other C-like languages. 212 Finally, experimental results are presented to validate several of the new features. 207 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from hobby projects to commercial operating systems. 208 This installation base and the programmers producing it represent a massive software engineering investment spanning decades and likely to continue for decades more. 209 Nevertheless, C, which was first standardized almost 30 years ago, lacks many features that make programming in more modern languages safer and more productive. 210 The goal of the \CFA project (pronounced ``C for all'') is to create an extension of C that provides modern safety and productivity features while still ensuring strong backward compatibility with C and its programmers. 211 Prior projects have attempted similar goals but failed to honor the C programming style; 212 for instance, adding object-oriented or functional programming with garbage collection is a nonstarter for many C developers. 213 Specifically, \CFA is designed to have an orthogonal feature set based closely on the C programming paradigm, so that \CFA features can be added \emph{incrementally} to existing C code bases, and C programmers can learn \CFA extensions on an as-needed basis, preserving investment in existing code and programmers. 214 This paper presents a quick tour of \CFA features, showing how their design avoids shortcomings of similar features in C and other C-like languages. 215 Experimental results are presented to validate several of the new features. 213 216 }% 214 217 215 \keywords{ generic types, tuple types, variadic types, polymorphic functions, C, Cforall}218 \keywords{C, Cforall, generic types, polymorphic functions, tuple types, variadic types} 216 219 217 220 218 221 \begin{document} 219 \linenumbers % comment out to turn off line numbering222 %\linenumbers % comment out to turn off line numbering 220 223 221 224 \maketitle 222 225 223 226 227 \vspace*{-10pt} 224 228 \section{Introduction} 225 229 226 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from hobby projects to commercial operating -systems.227 This installation base and the programmers producing it represent a massive software -engineering investment spanning decades and likely to continue for decades more.228 The TIOBE ~\cite{TIOBE} ranks the top 5 most \emph{popular} programming languages as: Java 15\%, \Textbf{C 12\%}, \Textbf{\CC 5.5\%},Python 5\%, \Csharp 4.5\% = 42\%, where the next 50 languages are less than 4\% each with a long tail.229 The top 3 rankings over the past 30 years are:230 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from hobby projects to commercial operating systems. 231 This installation base and the programmers producing it represent a massive software engineering investment spanning decades and likely to continue for decades more. 232 The TIOBE index~\cite{TIOBE} ranks the top five most \emph{popular} programming languages as Java 15\%, \Textbf{C 12\%}, \Textbf{\CC 5.5\%}, and Python 5\%, \Csharp 4.5\% = 42\%, where the next 50 languages are less than 4\% each with a long tail. 233 The top three rankings over the past 30 years are as follows. 230 234 \begin{center} 231 235 \setlength{\tabcolsep}{10pt} 232 \lstDeleteShortInline@% 233 \begin{tabular}{@{}rccccccc@{}} 234 & 2018 & 2013 & 2008 & 2003 & 1998 & 1993 & 1988 \\ \hline 235 Java & 1 & 2 & 1 & 1 & 18 & - & - \\ 236 \fontsize{9bp}{11bp}\selectfont 237 \lstDeleteShortInline@% 238 \begin{tabular}{@{}cccccccc@{}} 239 & 2018 & 2013 & 2008 & 2003 & 1998 & 1993 & 1988 \\ 240 Java & 1 & 2 & 1 & 1 & 18 & -- & -- \\ 236 241 \Textbf{C}& \Textbf{2} & \Textbf{1} & \Textbf{2} & \Textbf{2} & \Textbf{1} & \Textbf{1} & \Textbf{1} \\ 237 242 \CC & 3 & 4 & 3 & 3 & 2 & 2 & 5 \\ … … 241 246 Love it or hate it, C is extremely popular, highly used, and one of the few systems languages. 242 247 In many cases, \CC is often used solely as a better C. 243 Nevertheless, C, first standardized almost fortyyears ago~\cite{ANSI89:C}, lacks many features that make programming in more modern languages safer and more productive.244 245 \CFA (pronounced ``C -for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that adds modern language-features to C, while maintaining source and runtime compatibility in the familiar C programming model.246 The four key design goals for \CFA~\cite{Bilson03} are :247 (1) The behaviour of standard C code must remain the same when translated by a \CFA compiler as when translated by a C compiler;248 (2) Standard C code must be as fast and as small when translated by a \CFA compiler as when translated by a C compiler;249 (3) \CFA code must be at least as portable as standard C code;250 (4) Extensions introduced by \CFA must be translated in the most efficient way possible.251 These goals ensure existing C code-bases can be convertedto \CFA incrementally with minimal effort, and C programmers can productively generate \CFA code without training beyond the features being used.252 \CC is used similarly , but has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.253 254 All language sfeatures discussed in this paper are working, except some advanced exception-handling features.255 Not discussed in this paper are the integrated concurrency -constructs and user-level threading-library~\cite{Delisle18}.248 Nevertheless, C, which was first standardized almost 30 years ago~\cite{ANSI89:C}, lacks many features that make programming in more modern languages safer and more productive. 249 250 \CFA (pronounced ``C for all'' and written \CFA or Cforall) is an evolutionary extension of the C programming language that adds modern language features to C, while maintaining source and runtime compatibility in the familiar C programming model. 251 The four key design goals for \CFA~\cite{Bilson03} are as follows: 252 (1) the behavior of standard C code must remain the same when translated by a \CFA compiler as when translated by a C compiler; 253 (2) the standard C code must be as fast and as small when translated by a \CFA compiler as when translated by a C compiler; 254 (3) the \CFA code must be at least as portable as standard C code; 255 (4) extensions introduced by \CFA must be translated in the most efficient way possible. 256 These goals ensure that the existing C code bases can be converted into \CFA incrementally with minimal effort, and C programmers can productively generate \CFA code without training beyond the features being used. 257 \CC is used similarly but has the disadvantages of multiple legacy design choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project. 258 259 All language features discussed in this paper are working, except some advanced exception-handling features. 260 Not discussed in this paper are the integrated concurrency constructs and user-level threading library~\cite{Delisle18}. 256 261 \CFA is an \emph{open-source} project implemented as a source-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3). 257 Ultimately, a compiler is necessary for advanced features and optimal performance.258 262 % @plg2[9]% cd cfa-cc/src; cloc ArgTweak CodeGen CodeTools Common Concurrency ControlStruct Designators GenPoly InitTweak MakeLibCfa.cc MakeLibCfa.h Parser ResolvExpr SymTab SynTree Tuples driver prelude main.cc 259 263 % ------------------------------------------------------------------------------- … … 270 274 % SUM: 223 8203 8263 46479 271 275 % ------------------------------------------------------------------------------- 272 The \CFA translator is 200+ files and 46,000+ lines of code written in C/\CC. 273 Starting with a translator versus a compiler makes it easier and faster to generate and debug C object-code rather than intermediate, assembler or machine code. 274 The translator design is based on the \emph{visitor pattern}, allowing multiple passes over the abstract code-tree, which works well for incrementally adding new feature through additional visitor passes. 275 At the heart of the translator is the type resolver, which handles the polymorphic function/type overload-resolution. 276 The \CFA translator is 200+ files and 46\,000+ lines of code written in C/\CC. 277 A translator versus a compiler makes it easier and faster to generate and debug the C object code rather than the intermediate, assembler, or machine code; 278 ultimately, a compiler is necessary for advanced features and optimal performance. 279 % The translator design is based on the \emph{visitor pattern}, allowing multiple passes over the abstract code-tree, which works well for incrementally adding new feature through additional visitor passes. 280 Two key translator components are expression analysis, determining expression validity and what operations are required for its implementation, and code generation, dealing with multiple forms of overloading, polymorphism, and multiple return values by converting them into the C code for a C compiler that supports none of these features. 281 Details of these components are available in chapters 2 and 3 in the work of Bilson~\cite{Bilson03} and form the base for the current \CFA translator. 276 282 % @plg2[8]% cd cfa-cc/src; cloc libcfa 277 283 % ------------------------------------------------------------------------------- … … 288 294 % SUM: 100 1895 2785 11763 289 295 % ------------------------------------------------------------------------------- 290 The \CFA runtime system is 100+ files and 11 ,000+ lines of code, written in \CFA.296 The \CFA runtime system is 100+ files and 11\,000+ lines of code, written in \CFA. 291 297 Currently, the \CFA runtime is the largest \emph{user} of \CFA providing a vehicle to test the language features and implementation. 292 298 % @plg2[6]% cd cfa-cc/src; cloc tests examples benchmark … … 305 311 % SUM: 290 13175 3400 27776 306 312 % ------------------------------------------------------------------------------- 307 The \CFA tests are 290+ files and 27,000+ lines of code. 308 The tests illustrate syntactic and semantic features in \CFA, plus a growing number of runtime benchmarks. 309 The tests check for correctness and are used for daily regression testing of 3800+ commits. 310 311 Finally, it is impossible to describe a programming language without usages before definitions. 312 Therefore, syntax and semantics appear before explanations, and related work (Section~\ref{s:RelatedWork}) is deferred until \CFA is presented; 313 hence, patience is necessary until details are discussed. 314 315 313 % The \CFA tests are 290+ files and 27,000+ lines of code. 314 % The tests illustrate syntactic and semantic features in \CFA, plus a growing number of runtime benchmarks. 315 % The tests check for correctness and are used for daily regression testing of 3800+ commits. 316 317 Finally, it is impossible to describe a programming language without usage before definition. 318 Therefore, syntax and semantics appear before explanations; 319 hence, patience is necessary until sufficient details are presented and discussed. 320 Similarly, a detailed comparison with other programming languages is postponed until Section~\ref{s:RelatedWork}. 321 322 323 \vspace*{-6pt} 316 324 \section{Polymorphic Functions} 317 325 318 \CFA introduces both ad -hoc and parametric polymorphism to C, with a design originally formalized by Ditchfield~\cite{Ditchfield92},and first implemented by Bilson~\cite{Bilson03}.319 Shortcomings are identified in existing approaches to generic and variadic data types in C-like languages and how these shortcomings are avoided in \CFA.320 Specifically, the solution is both reusable and type -checked, as well as conforming to the design goals of \CFA with ergonomic use of existing C abstractions.326 \CFA introduces both ad hoc and parametric polymorphism to C, with a design originally formalized by Ditchfield~\cite{Ditchfield92} and first implemented by Bilson~\cite{Bilson03}. 327 Shortcomings are identified in the existing approaches to generic and variadic data types in C-like languages and how these shortcomings are avoided in \CFA. 328 Specifically, the solution is both reusable and type checked, as well as conforming to the design goals of \CFA with ergonomic use of existing C abstractions. 321 329 The new constructs are empirically compared with C and \CC approaches via performance experiments in Section~\ref{sec:eval}. 322 330 323 331 324 \subsection{Name Overloading} 332 \vspace*{-6pt} 333 \subsection{Name overloading} 325 334 \label{s:NameOverloading} 326 335 327 336 \begin{quote} 328 There are only two hard things in Computer Science: cache invalidation and \emph{naming things} --Phil Karlton337 ``There are only two hard things in Computer Science: cache invalidation and \emph{naming things}.''---Phil Karlton 329 338 \end{quote} 330 339 \vspace{-9pt} 331 C already has a limited form of ad -hoc polymorphism in its basic arithmetic operators, which apply to a variety of different types using identical syntax.340 C already has a limited form of ad hoc polymorphism in its basic arithmetic operators, which apply to a variety of different types using identical syntax. 332 341 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable; 333 342 Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C. 334 343 Code generation for these overloaded functions and variables is implemented by the usual approach of mangling the identifier names to include a representation of their type, while \CFA decides which overload to apply based on the same ``usual arithmetic conversions'' used in C to disambiguate operator overloads. 335 As an example: 344 345 \newpage 336 346 \begin{cfa} 337 347 int max = 2147483647; $\C[4in]{// (1)}$ … … 339 349 int max( int a, int b ) { return a < b ? b : a; } $\C{// (3)}$ 340 350 double max( double a, double b ) { return a < b ? b : a; } $\C{// (4)}\CRT$ 341 max( 7, -max ); $\C {// uses (3) and (1), by matching int from constant 7}$351 max( 7, -max ); $\C[3in]{// uses (3) and (1), by matching int from constant 7}$ 342 352 max( max, 3.14 ); $\C{// uses (4) and (2), by matching double from constant 3.14}$ 343 353 max( max, -max ); $\C{// ERROR, ambiguous}$ 344 int m = max( max, -max ); $\C{// uses (3) and (1) twice, by matching return type} $354 int m = max( max, -max ); $\C{// uses (3) and (1) twice, by matching return type}\CRT$ 345 355 \end{cfa} 346 356 … … 348 358 In some cases, hundreds of names can be reduced to tens, resulting in a significant cognitive reduction. 349 359 In the above, the name @max@ has a consistent meaning, and a programmer only needs to remember the single concept: maximum. 350 To prevent significant ambiguities, \CFA uses the return type in selecting overloads, \eg in the assignment to @m@, the compiler use @m@'s type to unambiguously select the most appropriate call to function @max@ (as does Ada).360 To prevent significant ambiguities, \CFA uses the return type in selecting overloads, \eg in the assignment to @m@, the compiler uses @m@'s type to unambiguously select the most appropriate call to function @max@ (as does Ada). 351 361 As is shown later, there are a number of situations where \CFA takes advantage of available type information to disambiguate, where other programming languages generate ambiguities. 352 362 353 \Celeven added @_Generic@ expressions ~\cite[\S~6.5.1.1]{C11}, which is used with preprocessor macros to provide ad-hoc polymorphism;363 \Celeven added @_Generic@ expressions (see section~6.5.1.1 of the ISO/IEC 9899~\cite{C11}), which is used with preprocessor macros to provide ad hoc polymorphism; 354 364 however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading. 355 The macro wrapping the generic expression imposes some limitations; 356 \eg, it cannot implement the example above, because the variables @max@ are ambiguous with the functions @max@. 365 The macro wrapping the generic expression imposes some limitations, for instance, it cannot implement the example above, because the variables @max@ are ambiguous with the functions @max@. 357 366 Ergonomic limitations of @_Generic@ include the necessity to put a fixed list of supported types in a single place and manually dispatch to appropriate overloads, as well as possible namespace pollution from the dispatch functions, which must all have distinct names. 358 \CFA supports @_Generic@ expressions for backward s compatibility, but it is an unnecessary mechanism. \TODO{actually implement that}367 \CFA supports @_Generic@ expressions for backward compatibility, but it is an unnecessary mechanism. 359 368 360 369 % http://fanf.livejournal.com/144696.html … … 363 372 364 373 365 \subsection{\texorpdfstring{\protect\lstinline{forall} Functions}{forall Functions}} 374 \vspace*{-10pt} 375 \subsection{\texorpdfstring{\protect\lstinline{forall} functions}{forall functions}} 366 376 \label{sec:poly-fns} 367 377 368 The signature feature of \CFA is parametric-polymorphic functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a @forall@ clause (giving the language its name) :378 The signature feature of \CFA is parametric-polymorphic functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a @forall@ clause (giving the language its name). 369 379 \begin{cfa} 370 380 `forall( otype T )` T identity( T val ) { return val; } … … 373 383 This @identity@ function can be applied to any complete \newterm{object type} (or @otype@). 374 384 The type variable @T@ is transformed into a set of additional implicit parameters encoding sufficient information about @T@ to create and return a variable of that type. 375 The \CFA implementation passes the size and alignment of the type represented by an @otype@ parameter, as well as an assignment operator, constructor, copy constructor and destructor.376 If this extra information is not needed, \egfor a pointer, the type parameter can be declared as a \newterm{data type} (or @dtype@).377 378 In \CFA, the polymorphic runtime -cost is spread over each polymorphic call, because more arguments are passed to polymorphic functions;379 the experiments in Section~\ref{sec:eval} show this overhead is similar to \CC virtual -function calls.380 A design advantage is that, unlike \CC template -functions, \CFA polymorphic-functions are compatible with C \emph{separate compilation}, preventing compilation and code bloat.381 382 Since bare polymorphic -types provide a restricted set of available operations, \CFA provides a \newterm{type assertion}~\cite[pp.~37-44]{Alphard} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable.383 For example, the function @twice@ can be defined using the \CFA syntax for operator overloading :385 The \CFA implementation passes the size and alignment of the type represented by an @otype@ parameter, as well as an assignment operator, constructor, copy constructor, and destructor. 386 If this extra information is not needed, for instance, for a pointer, the type parameter can be declared as a \newterm{data type} (or @dtype@). 387 388 In \CFA, the polymorphic runtime cost is spread over each polymorphic call, because more arguments are passed to polymorphic functions; 389 the experiments in Section~\ref{sec:eval} show this overhead is similar to \CC virtual function calls. 390 A design advantage is that, unlike \CC template functions, \CFA polymorphic functions are compatible with C \emph{separate compilation}, preventing compilation and code bloat. 391 392 Since bare polymorphic types provide a restricted set of available operations, \CFA provides a \newterm{type assertion}~\cite[pp.~37-44]{Alphard} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type variable. 393 For example, the function @twice@ can be defined using the \CFA syntax for operator overloading. 384 394 \begin{cfa} 385 395 forall( otype T `| { T ?+?(T, T); }` ) T twice( T x ) { return x `+` x; } $\C{// ? denotes operands}$ 386 396 int val = twice( twice( 3.7 ) ); $\C{// val == 14}$ 387 397 \end{cfa} 388 which works for any type @T@ with a matching addition operator. 389 The polymorphism is achieved by creating a wrapper function for calling @+@ with @T@ bound to @double@, then passing this function to the first call of @twice@. 390 There is now the option of using the same @twice@ and converting the result to @int@ on assignment, or creating another @twice@ with type parameter @T@ bound to @int@ because \CFA uses the return type~\cite{Cormack81,Baker82,Ada} in its type analysis. 391 The first approach has a late conversion from @double@ to @int@ on the final assignment, while the second has an early conversion to @int@. 392 \CFA minimizes the number of conversions and their potential to lose information, so it selects the first approach, which corresponds with C-programmer intuition. 398 This works for any type @T@ with a matching addition operator. 399 The polymorphism is achieved by creating a wrapper function for calling @+@ with the @T@ bound to @double@ and then passing this function to the first call of @twice@. 400 There is now the option of using the same @twice@ and converting the result into @int@ on assignment or creating another @twice@ with the type parameter @T@ bound to @int@ because \CFA uses the return type~\cite{Cormack81,Baker82,Ada} in its type analysis. 401 The first approach has a late conversion from @double@ to @int@ on the final assignment, whereas the second has an early conversion to @int@. 402 \CFA minimizes the number of conversions and their potential to lose information; 403 hence, it selects the first approach, which corresponds with C programmer intuition. 393 404 394 405 Crucial to the design of a new programming language are the libraries to access thousands of external software features. 395 Like \CC, \CFA inherits a massive compatible library -base, where other programming languages must rewrite or provide fragile inter-language communication with C.396 A simple example is leveraging the existing type-unsafe (@void *@) C @bsearch@ to binary search a sorted float array :406 Like \CC, \CFA inherits a massive compatible library base, where other programming languages must rewrite or provide fragile interlanguage communication with C. 407 A simple example is leveraging the existing type-unsafe (@void *@) C @bsearch@ to binary search a sorted float array. 397 408 \begin{cfa} 398 409 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, … … 404 415 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); $\C{// search sorted array}$ 405 416 \end{cfa} 406 which can be augmented simply with generalized, type-safe, \CFA-overloaded wrappers: 417 This can be augmented simply with generalized, type-safe, \CFA-overloaded wrappers. 407 418 \begin{cfa} 408 419 forall( otype T | { int ?<?( T, T ); } ) T * bsearch( T key, const T * arr, size_t size ) { … … 418 429 \end{cfa} 419 430 The nested function @comp@ provides the hidden interface from typed \CFA to untyped (@void *@) C, plus the cast of the result. 420 Providing a hidden @comp@ function in \CC is awkward as lambdas do not use C calling-conventions and template declarations cannot appear at block scope. 421 As well, an alternate kind of return is made available: position versus pointer to found element. 422 \CC's type-system cannot disambiguate between the two versions of @bsearch@ because it does not use the return type in overload resolution, nor can \CC separately compile a template @bsearch@. 431 % FIX 432 Providing a hidden @comp@ function in \CC is awkward as lambdas do not use C calling conventions and template declarations cannot appear in block scope. 433 In addition, an alternate kind of return is made available: position versus pointer to found element. 434 \CC's type system cannot disambiguate between the two versions of @bsearch@ because it does not use the return type in overload resolution, nor can \CC separately compile a template @bsearch@. 423 435 424 436 \CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations (see Section~\ref{sec:libraries}). … … 430 442 \end{cfa} 431 443 432 Call -site inferencing and nested functions provide a localized form of inheritance.444 Call site inferencing and nested functions provide a localized form of inheritance. 433 445 For example, the \CFA @qsort@ only sorts in ascending order using @<@. 434 However, it is trivial to locally change this behavio ur:446 However, it is trivial to locally change this behavior. 435 447 \begin{cfa} 436 448 forall( otype T | { int ?<?( T, T ); } ) void qsort( const T * arr, size_t size ) { /* use C qsort */ } 437 449 int main() { 438 int ?<?( double x, double y ) { return x `>` y; } $\C{// locally override behavio ur}$450 int ?<?( double x, double y ) { return x `>` y; } $\C{// locally override behavior}$ 439 451 qsort( vals, 10 ); $\C{// descending sort}$ 440 452 } 441 453 \end{cfa} 442 454 The local version of @?<?@ performs @?>?@ overriding the built-in @?<?@ so it is passed to @qsort@. 443 Hence, programmers can easily form local environments, adding and modifying appropriate functions, to maximize reuse of other existing functions and types.444 445 To reduce duplication, it is possible to distribute a group of @forall@ (and storage-class qualifiers) over functions/types, s o each block declaration is prefixed by the group (see example in Appendix~\ref{s:CforallStack}).455 Therefore, programmers can easily form local environments, adding and modifying appropriate functions, to maximize the reuse of other existing functions and types. 456 457 To reduce duplication, it is possible to distribute a group of @forall@ (and storage-class qualifiers) over functions/types, such that each block declaration is prefixed by the group (see the example in Appendix~\ref{s:CforallStack}). 446 458 \begin{cfa} 447 459 forall( otype `T` ) { $\C{// distribution block, add forall qualifier to declarations}$ … … 454 466 455 467 456 \vspace*{-2pt}457 468 \subsection{Traits} 458 469 459 \CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration: 460 470 \CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration. 461 471 \begin{cquote} 462 472 \lstDeleteShortInline@% … … 485 495 \end{cquote} 486 496 487 Note ,the @sumable@ trait does not include a copy constructor needed for the right side of @?+=?@ and return;488 it is provided by @otype@, which is syntactic sugar for the following trait :497 Note that the @sumable@ trait does not include a copy constructor needed for the right side of @?+=?@ and return; 498 it is provided by @otype@, which is syntactic sugar for the following trait. 489 499 \begin{cfa} 490 500 trait otype( dtype T | sized(T) ) { // sized is a pseudo-trait for types with known size and alignment … … 495 505 }; 496 506 \end{cfa} 497 Given the information provided for an @otype@, variables of polymorphic type can be treated as if they were a complete type: stack -allocatable, default or copy-initialized, assigned, and deleted.498 499 In summation, the \CFA type -system uses \newterm{nominal typing} for concrete types, matching with the C type-system, and \newterm{structural typing} for polymorphic types.507 Given the information provided for an @otype@, variables of polymorphic type can be treated as if they were a complete type: stack allocatable, default or copy initialized, assigned, and deleted. 508 509 In summation, the \CFA type system uses \newterm{nominal typing} for concrete types, matching with the C type system, and \newterm{structural typing} for polymorphic types. 500 510 Hence, trait names play no part in type equivalence; 501 511 the names are simply macros for a list of polymorphic assertions, which are expanded at usage sites. 502 Nevertheless, trait names form a logical subtype -hierarchy with @dtype@ at the top, where traits often contain overlapping assertions, \eg operator @+@.503 Traits are used like interfaces in Java or abstract base -classes in \CC, but without the nominal inheritance-relationships.504 Instead, each polymorphic function (or generic type) defines the structural type needed for its execution (polymorphic type -key), and this key is fulfilled at each call site from the lexical environment, which is similar toGo~\cite{Go} interfaces.505 Hence, new lexical scopes and nested functions are used extensively to create local subtypes, as in the @qsort@ example, without having to manage a nominal -inheritance hierarchy.512 Nevertheless, trait names form a logical subtype hierarchy with @dtype@ at the top, where traits often contain overlapping assertions, \eg operator @+@. 513 Traits are used like interfaces in Java or abstract base classes in \CC, but without the nominal inheritance relationships. 514 Instead, each polymorphic function (or generic type) defines the structural type needed for its execution (polymorphic type key), and this key is fulfilled at each call site from the lexical environment, which is similar to the Go~\cite{Go} interfaces. 515 Hence, new lexical scopes and nested functions are used extensively to create local subtypes, as in the @qsort@ example, without having to manage a nominal inheritance hierarchy. 506 516 % (Nominal inheritance can be approximated with traits using marker variables or functions, as is done in Go.) 507 517 … … 534 544 535 545 A significant shortcoming of standard C is the lack of reusable type-safe abstractions for generic data structures and algorithms. 536 Broadly speaking, there are three approaches to implement abstract data -structures in C.537 One approach is to write bespoke data -structures for each context in which they are needed.538 While this approach is flexible and supports integration with the C type -checker and tooling, it is also tedious and error-prone, especially for more complex data structures.539 A second approach is to use @void *@-based polymorphism, \eg the C standard -library functions @bsearch@ and @qsort@, which allowreuse of code with common functionality.540 However, basing all polymorphism on @void *@ eliminates the type -checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that is not otherwiseneeded.541 A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type -checked, but errors may be difficult to interpret.546 Broadly speaking, there are three approaches to implement abstract data structures in C. 547 One approach is to write bespoke data structures for each context in which they are needed. 548 While this approach is flexible and supports integration with the C type checker and tooling, it is also tedious and error prone, especially for more complex data structures. 549 A second approach is to use @void *@-based polymorphism, \eg the C standard library functions @bsearch@ and @qsort@, which allow for the reuse of code with common functionality. 550 However, basing all polymorphism on @void *@ eliminates the type checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that is otherwise not needed. 551 A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type checked, but errors may be difficult to interpret. 542 552 Furthermore, writing and using preprocessor macros is unnatural and inflexible. 543 553 544 \CC, Java, and other languages use \newterm{generic types} to produce type-safe abstract data -types.545 \CFA generic types integrate efficiently and naturally with the existing polymorphic functions, while retaining backward scompatibility with C and providing separate compilation.554 \CC, Java, and other languages use \newterm{generic types} to produce type-safe abstract data types. 555 \CFA generic types integrate efficiently and naturally with the existing polymorphic functions, while retaining backward compatibility with C and providing separate compilation. 546 556 However, for known concrete parameters, the generic-type definition can be inlined, like \CC templates. 547 557 548 A generic type can be declared by placing a @forall@ specifier on a @struct@ or @union@ declaration , and instantiated using a parenthesized list of types after the type name:558 A generic type can be declared by placing a @forall@ specifier on a @struct@ or @union@ declaration and instantiated using a parenthesized list of types after the type name. 549 559 \begin{cquote} 550 560 \lstDeleteShortInline@% … … 574 584 575 585 \CFA classifies generic types as either \newterm{concrete} or \newterm{dynamic}. 576 Concrete types have a fixed memory layout regardless of type parameters, wh iledynamic types vary in memory layout depending on their type parameters.586 Concrete types have a fixed memory layout regardless of type parameters, whereas dynamic types vary in memory layout depending on their type parameters. 577 587 A \newterm{dtype-static} type has polymorphic parameters but is still concrete. 578 588 Polymorphic pointers are an example of dtype-static types; 579 given some type variable @T@, @T@ is a polymorphic type, as is @T *@, but @T *@ has a fixed size and can thereforebe represented by @void *@ in code generation.580 581 \CFA generic types also allow checked argument -constraints.582 For example, the following declaration of a sorted set -type ensures the set key supports equality and relational comparison:589 given some type variable @T@, @T@ is a polymorphic type, as is @T *@, but @T *@ has a fixed size and can, therefore, be represented by @void *@ in code generation. 590 591 \CFA generic types also allow checked argument constraints. 592 For example, the following declaration of a sorted set type ensures the set key supports equality and relational comparison. 583 593 \begin{cfa} 584 594 forall( otype Key | { _Bool ?==?(Key, Key); _Bool ?<?(Key, Key); } ) struct sorted_set; … … 586 596 587 597 588 \subsection{Concrete Generic-Types}589 590 The \CFA translator template -expands concrete generic-types into new structure types, affording maximal inlining.591 To enable inter -operation among equivalent instantiations of a generic type, the translator saves the set of instantiations currently in scope and reuses the generated structure declarations where appropriate.592 A function declaration that accepts or returns a concrete generic -type produces a declaration for the instantiated structure in the same scope, which all callers may reuse.593 For example, the concrete instantiation for @pair( const char *, int )@ is :598 \subsection{Concrete generic types} 599 600 The \CFA translator template expands concrete generic types into new structure types, affording maximal inlining. 601 To enable interoperation among equivalent instantiations of a generic type, the translator saves the set of instantiations currently in scope and reuses the generated structure declarations where appropriate. 602 A function declaration that accepts or returns a concrete generic type produces a declaration for the instantiated structure in the same scope, which all callers may reuse. 603 For example, the concrete instantiation for @pair( const char *, int )@ is 594 604 \begin{cfa} 595 605 struct _pair_conc0 { … … 598 608 \end{cfa} 599 609 600 A concrete generic -type with dtype-static parameters is also expanded to a structure type, but this type is used for all matching instantiations.601 In the above example, the @pair( F *, T * )@ parameter to @value@ is such a type; its expansion is below and it is used as the type of the variables @q@ and @r@ as well, with casts for member access where appropriate:610 A concrete generic type with dtype-static parameters is also expanded to a structure type, but this type is used for all matching instantiations. 611 In the above example, the @pair( F *, T * )@ parameter to @value@ is such a type; its expansion is below, and it is used as the type of the variables @q@ and @r@ as well, with casts for member access where appropriate. 602 612 \begin{cfa} 603 613 struct _pair_conc1 { … … 607 617 608 618 609 \subsection{Dynamic Generic-Types} 610 611 Though \CFA implements concrete generic-types efficiently, it also has a fully general system for dynamic generic types. 612 As mentioned in Section~\ref{sec:poly-fns}, @otype@ function parameters (in fact all @sized@ polymorphic parameters) come with implicit size and alignment parameters provided by the caller. 613 Dynamic generic-types also have an \newterm{offset array} containing structure-member offsets. 614 A dynamic generic-@union@ needs no such offset array, as all members are at offset 0, but size and alignment are still necessary. 615 Access to members of a dynamic structure is provided at runtime via base-displacement addressing with the structure pointer and the member offset (similar to the @offsetof@ macro), moving a compile-time offset calculation to runtime. 619 \subsection{Dynamic generic types} 620 621 Though \CFA implements concrete generic types efficiently, it also has a fully general system for dynamic generic types. 622 As mentioned in Section~\ref{sec:poly-fns}, @otype@ function parameters (in fact, all @sized@ polymorphic parameters) come with implicit size and alignment parameters provided by the caller. 623 Dynamic generic types also have an \newterm{offset array} containing structure-member offsets. 624 A dynamic generic @union@ needs no such offset array, as all members are at offset 0, but size and alignment are still necessary. 625 Access to members of a dynamic structure is provided at runtime via base displacement addressing 626 % FIX 627 using the structure pointer and the member offset (similar to the @offsetof@ macro), moving a compile-time offset calculation to runtime. 616 628 617 629 The offset arrays are statically generated where possible. 618 If a dynamic generic -type is declared to be passed or returned by value from a polymorphic function, the translator can safely assume the generic type is complete (\ie has a known layout) at any call-site, and the offset array is passed from the caller;630 If a dynamic generic type is declared to be passed or returned by value from a polymorphic function, the translator can safely assume that the generic type is complete (\ie has a known layout) at any call site, and the offset array is passed from the caller; 619 631 if the generic type is concrete at the call site, the elements of this offset array can even be statically generated using the C @offsetof@ macro. 620 As an example, the body of the second @value@ function is implemented as :632 As an example, the body of the second @value@ function is implemented as 621 633 \begin{cfa} 622 634 _assign_T( _retval, p + _offsetof_pair[1] ); $\C{// return *p.second}$ 623 635 \end{cfa} 624 @_assign_T@ is passed in as an implicit parameter from @otype T@, and takes two @T *@ (@void *@ in the generated code), a destination and a source; @_retval@ is the pointer to a caller-allocated buffer for the return value, the usual \CFA method to handle dynamically-sized return types. 625 @_offsetof_pair@ is the offset array passed into @value@; this array is generated at the call site as: 636 \newpage 637 \noindent 638 Here, @_assign_T@ is passed in as an implicit parameter from @otype T@, and takes two @T *@ (@void *@ in the generated code), a destination and a source, and @_retval@ is the pointer to a caller-allocated buffer for the return value, the usual \CFA method to handle dynamically sized return types. 639 @_offsetof_pair@ is the offset array passed into @value@; 640 this array is generated at the call site as 626 641 \begin{cfa} 627 642 size_t _offsetof_pair[] = { offsetof( _pair_conc0, first ), offsetof( _pair_conc0, second ) } 628 643 \end{cfa} 629 644 630 In some cases the offset arrays cannot be statically generated.631 For instance, modularity is generally provided in C by including an opaque forward -declaration of a structure and associated accessor and mutator functions in a header file, with the actual implementations in a separately-compiled @.c@ file.632 \CFA supports this pattern for generic types, but the caller does not know the actual layout or size of the dynamic generic -type,and only holds it by a pointer.645 In some cases, the offset arrays cannot be statically generated. 646 For instance, modularity is generally provided in C by including an opaque forward declaration of a structure and associated accessor and mutator functions in a header file, with the actual implementations in a separately compiled @.c@ file. 647 \CFA supports this pattern for generic types, but the caller does not know the actual layout or size of the dynamic generic type and only holds it by a pointer. 633 648 The \CFA translator automatically generates \newterm{layout functions} for cases where the size, alignment, and offset array of a generic struct cannot be passed into a function from that function's caller. 634 649 These layout functions take as arguments pointers to size and alignment variables and a caller-allocated array of member offsets, as well as the size and alignment of all @sized@ parameters to the generic structure (un@sized@ parameters are forbidden from being used in a context that affects layout). … … 640 655 Whether a type is concrete, dtype-static, or dynamic is decided solely on the @forall@'s type parameters. 641 656 This design allows opaque forward declarations of generic types, \eg @forall(otype T)@ @struct Box@ -- like in C, all uses of @Box(T)@ can be separately compiled, and callers from other translation units know the proper calling conventions to use. 642 If the definition of a structure type is included in deciding whether a generic type is dynamic or concrete, some further types may be recognized as dtype-static (\eg @forall(otype T)@ @struct unique_ptr { T * p }@ does not depend on @T@ for its layout, but the existence of an @otype@ parameter means that it \emph{could}.), but preserving separate compilation (and the associated C compatibility) in the existing design is judged to be an appropriate trade-off. 657 If the definition of a structure type is included in deciding whether a generic type is dynamic or concrete, some further types may be recognized as dtype-static (\eg @forall(otype T)@ @struct unique_ptr { T * p }@ does not depend on @T@ for its layout, but the existence of an @otype@ parameter means that it \emph{could}.); 658 however, preserving separate compilation (and the associated C compatibility) in the existing design is judged to be an appropriate trade-off. 643 659 644 660 … … 653 669 } 654 670 \end{cfa} 655 Since @pair( T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the members of both pairs and the arguments to the comparison function match in type. 656 657 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \newterm{tag-structures}. 658 Sometimes information is only used for type-checking and can be omitted at runtime, \eg: 671 Since @pair( T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@; 672 hence, the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type checked to ensure members of both pairs and arguments to the comparison function match in type. 673 674 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \newterm{tag structures}. 675 Sometimes, information is only used for type checking and can be omitted at runtime. 659 676 \begin{cquote} 660 677 \lstDeleteShortInline@% … … 675 692 half_marathon; 676 693 scalar(litres) two_pools = pool + pool; 677 `marathon + pool;` // ERROR, mismatched types694 `marathon + pool;` // ERROR, mismatched types 678 695 \end{cfa} 679 696 \end{tabular} 680 697 \lstMakeShortInline@% 681 698 \end{cquote} 682 @scalar@ is a dtype-static type, so all uses have a single structure definition, containing @unsigned long@, and can share the same implementations of common functions like @?+?@. 699 Here, @scalar@ is a dtype-static type; 700 hence, all uses have a single structure definition, containing @unsigned long@, and can share the same implementations of common functions like @?+?@. 683 701 These implementations may even be separately compiled, unlike \CC template functions. 684 However, the \CFA type -checker ensures matching types are used by all calls to @?+?@, preventing nonsensical computations like adding a length to a volume.702 However, the \CFA type checker ensures matching types are used by all calls to @?+?@, preventing nonsensical computations like adding a length to a volume. 685 703 686 704 … … 688 706 \label{sec:tuples} 689 707 690 In many languages, functions can return at mostone value;708 In many languages, functions can return, at most, one value; 691 709 however, many operations have multiple outcomes, some exceptional. 692 710 Consider C's @div@ and @remquo@ functions, which return the quotient and remainder for a division of integer and float values, respectively. … … 699 717 double r = remquo( 13.5, 5.2, &q ); $\C{// return remainder, alias quotient}$ 700 718 \end{cfa} 701 @div@ aggregates the quotient/remainder in a structure, while@remquo@ aliases a parameter to an argument.719 Here, @div@ aggregates the quotient/remainder in a structure, whereas @remquo@ aliases a parameter to an argument. 702 720 Both approaches are awkward. 703 Alternatively, a programming language can directly support returning multiple values, \eg in \CFA: 721 % FIX 722 Alternatively, a programming language can directly support returning multiple values, \eg \CFA provides the following. 704 723 \begin{cfa} 705 724 [ int, int ] div( int num, int den ); $\C{// return two integers}$ … … 712 731 This approach is straightforward to understand and use; 713 732 therefore, why do few programming languages support this obvious feature or provide it awkwardly? 714 To answer, there are complex consequences that cascade through multiple aspects of the language, especially the type -system.715 This section show these consequences and how \CFA handles them.733 To answer, there are complex consequences that cascade through multiple aspects of the language, especially the type system. 734 This section shows these consequences and how \CFA handles them. 716 735 717 736 718 737 \subsection{Tuple Expressions} 719 738 720 The addition of multiple-return-value functions (MRVF ) are \emph{useless} without a syntax for accepting multiple values at the call-site.739 The addition of multiple-return-value functions (MRVFs) is \emph{useless} without a syntax for accepting multiple values at the call site. 721 740 The simplest mechanism for capturing the return values is variable assignment, allowing the values to be retrieved directly. 722 741 As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \newterm{tuple}. 723 742 724 However, functions also use \newterm{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVF ), \eg:743 However, functions also use \newterm{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVFs), \eg, \CFA provides the following. 725 744 \begin{cfa} 726 745 printf( "%d %d\n", div( 13, 5 ) ); $\C{// return values seperated into arguments}$ 727 746 \end{cfa} 728 747 Here, the values returned by @div@ are composed with the call to @printf@ by flattening the tuple into separate arguments. 729 However, the \CFA type-system must support significantly more complex composition :748 However, the \CFA type-system must support significantly more complex composition. 730 749 \begin{cfa} 731 750 [ int, int ] foo$\(_1\)$( int ); $\C{// overloaded foo functions}$ … … 734 753 `bar`( foo( 3 ), foo( 3 ) ); 735 754 \end{cfa} 736 The type-resolver only has the tuple return-types to resolve the call to @bar@ as the @foo@ parameters are identical, which involves unifying the possible @foo@ functions with @bar@'s parameter list. 737 No combination of @foo@s are an exact match with @bar@'s parameters, so the resolver applies C conversions. 755 The type resolver only has the tuple return types to resolve the call to @bar@ as the @foo@ parameters are identical, which involves unifying the possible @foo@ functions with @bar@'s parameter list. 756 No combination of @foo@s is an exact match with @bar@'s parameters; 757 thus, the resolver applies C conversions. 758 % FIX 738 759 The minimal cost is @bar( foo@$_1$@( 3 ), foo@$_2$@( 3 ) )@, giving (@int@, {\color{ForestGreen}@int@}, @double@) to (@int@, {\color{ForestGreen}@double@}, @double@) with one {\color{ForestGreen}safe} (widening) conversion from @int@ to @double@ versus ({\color{red}@double@}, {\color{ForestGreen}@int@}, {\color{ForestGreen}@int@}) to ({\color{red}@int@}, {\color{ForestGreen}@double@}, {\color{ForestGreen}@double@}) with one {\color{red}unsafe} (narrowing) conversion from @double@ to @int@ and two safe conversions. 739 760 740 761 741 \subsection{Tuple Variables}762 \subsection{Tuple variables} 742 763 743 764 An important observation from function composition is that new variable names are not required to initialize parameters from an MRVF. 744 \CFA also allows declaration of tuple variables that can be initialized from an MRVF, since it can be awkward to declare multiple variables of different types, \eg: 765 \CFA also allows declaration of tuple variables that can be initialized from an MRVF, since it can be awkward to declare multiple variables of different types. 766 \newpage 745 767 \begin{cfa} 746 768 [ int, int ] qr = div( 13, 5 ); $\C{// tuple-variable declaration and initialization}$ 747 769 [ double, double ] qr = div( 13.5, 5.2 ); 748 770 \end{cfa} 749 where the tuple variable-name serves the same purpose as the parameter name(s).771 Here, the tuple variable name serves the same purpose as the parameter name(s). 750 772 Tuple variables can be composed of any types, except for array types, since array sizes are generally unknown in C. 751 773 752 One way to access the tuple -variable components is with assignment or composition:774 One way to access the tuple variable components is with assignment or composition. 753 775 \begin{cfa} 754 776 [ q, r ] = qr; $\C{// access tuple-variable components}$ 755 777 printf( "%d %d\n", qr ); 756 778 \end{cfa} 757 \CFA also supports \newterm{tuple indexing} to access single components of a tuple expression :779 \CFA also supports \newterm{tuple indexing} to access single components of a tuple expression. 758 780 \begin{cfa} 759 781 [int, int] * p = &qr; $\C{// tuple pointer}$ … … 766 788 767 789 768 \subsection{Flattening and Restructuring}790 \subsection{Flattening and restructuring} 769 791 770 792 In function call contexts, tuples support implicit flattening and restructuring conversions. 771 793 Tuple flattening recursively expands a tuple into the list of its basic components. 772 Tuple structuring packages a list of expressions into a value of tuple type , \eg:794 Tuple structuring packages a list of expressions into a value of tuple type. 773 795 \begin{cfa} 774 796 int f( int, int ); … … 781 803 h( x, y ); $\C{// flatten and structure}$ 782 804 \end{cfa} 783 In the call to @f@, @x@ is implicitly flattened so the components of @x@ are passed as t he two arguments.805 In the call to @f@, @x@ is implicitly flattened so the components of @x@ are passed as two arguments. 784 806 In the call to @g@, the values @y@ and @10@ are structured into a single argument of type @[int, int]@ to match the parameter type of @g@. 785 807 Finally, in the call to @h@, @x@ is flattened to yield an argument list of length 3, of which the first component of @x@ is passed as the first parameter of @h@, and the second component of @x@ and @y@ are structured into the second argument of type @[int, int]@. 786 The flexible structure of tuples permits a simple and expressive function call syntax to work seamlessly with both SRVF and MRVF, and with any number of arguments of arbitrarily complex structure. 787 788 789 \subsection{Tuple Assignment} 790 808 The flexible structure of tuples permits a simple and expressive function call syntax to work seamlessly with both SRVFs and MRVFs with any number of arguments of arbitrarily complex structure. 809 810 811 \subsection{Tuple assignment} 812 813 \enlargethispage{-10pt} 791 814 An assignment where the left side is a tuple type is called \newterm{tuple assignment}. 792 There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non -tuple type, called \newterm{multiple} and \newterm{mass assignment}, respectively.815 There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a nontuple type, called \newterm{multiple} and \newterm{mass assignment}, respectively. 793 816 \begin{cfa} 794 817 int x = 10; … … 800 823 [y, x] = 3.14; $\C{// mass assignment}$ 801 824 \end{cfa} 802 Both kinds of tuple assignment have parallel semantics, so that each value on the left and right side is evaluated before any assignments occur.825 Both kinds of tuple assignment have parallel semantics, so that each value on the left and right sides is evaluated before any assignments occur. 803 826 As a result, it is possible to swap the values in two variables without explicitly creating any temporary variables or calling a function, \eg, @[x, y] = [y, x]@. 804 827 This semantics means mass assignment differs from C cascading assignment (\eg @a = b = c@) in that conversions are applied in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment. 805 For example, @[y, x] = 3.14@ performs the assignments @y = 3.14@ and @x = 3.14@, yielding @y == 3.14@ and @x == 3@; 806 whereas, C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@. 828 For example, @[y, x] = 3.14@ performs the assignments @y = 3.14@ and @x = 3.14@, yielding @y == 3.14@ and @x == 3@, whereas C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@. 807 829 Finally, tuple assignment is an expression where the result type is the type of the left-hand side of the assignment, just like all other assignment expressions in C. 808 This example shows mass, multiple, and cascading assignment used in one expression :830 This example shows mass, multiple, and cascading assignment used in one expression. 809 831 \begin{cfa} 810 832 [void] f( [int, int] ); … … 813 835 814 836 815 \subsection{Member Access}816 817 It is also possible to access multiple members from a single expression using a \newterm{member -access}.818 The result is a single tuple-valued expression whose type is the tuple of the types of the members , \eg:837 \subsection{Member access} 838 839 It is also possible to access multiple members from a single expression using a \newterm{member access}. 840 The result is a single tuple-valued expression whose type is the tuple of the types of the members. 819 841 \begin{cfa} 820 842 struct S { int x; double y; char * z; } s; … … 830 852 [int, int, int] y = x.[2, 0, 2]; $\C{// duplicate: [y.0, y.1, y.2] = [x.2, x.0.x.2]}$ 831 853 \end{cfa} 832 It is also possible for a member access to contain other member accesses , \eg:854 It is also possible for a member access to contain other member accesses. 833 855 \begin{cfa} 834 856 struct A { double i; int j; }; … … 897 919 898 920 Tuples also integrate with \CFA polymorphism as a kind of generic type. 899 Due to the implicit flattening and structuring conversions involved in argument passing, @otype@ and @dtype@ parameters are restricted to matching only with non -tuple types, \eg:921 Due to the implicit flattening and structuring conversions involved in argument passing, @otype@ and @dtype@ parameters are restricted to matching only with nontuple types. 900 922 \begin{cfa} 901 923 forall( otype T, dtype U ) void f( T x, U * y ); 902 924 f( [5, "hello"] ); 903 925 \end{cfa} 904 where@[5, "hello"]@ is flattened, giving argument list @5, "hello"@, and @T@ binds to @int@ and @U@ binds to @const char@.926 Here, @[5, "hello"]@ is flattened, giving argument list @5, "hello"@, and @T@ binds to @int@ and @U@ binds to @const char@. 905 927 Tuples, however, may contain polymorphic components. 906 928 For example, a plus operator can be written to sum two triples. … … 920 942 g( 5, 10.21 ); 921 943 \end{cfa} 944 \newpage 922 945 Hence, function parameter and return lists are flattened for the purposes of type unification allowing the example to pass expression resolution. 923 946 This relaxation is possible by extending the thunk scheme described by Bilson~\cite{Bilson03}. … … 930 953 931 954 932 \subsection{Variadic Tuples}955 \subsection{Variadic tuples} 933 956 \label{sec:variadic-tuples} 934 957 935 To define variadic functions, \CFA adds a new kind of type parameter, @ttype@ (tuple type).936 Matching against a @ttype@ parameter consumes all remaining argument components and packages them into a tuple, binding to the resulting tuple of types.937 In a given parameter list, there must be at mostone @ttype@ parameter that occurs last, which matches normal variadic semantics, with a strong feeling of similarity to \CCeleven variadic templates.958 To define variadic functions, \CFA adds a new kind of type parameter, \ie @ttype@ (tuple type). 959 Matching against a @ttype@ parameter consumes all the remaining argument components and packages them into a tuple, binding to the resulting tuple of types. 960 In a given parameter list, there must be, at most, one @ttype@ parameter that occurs last, which matches normal variadic semantics, with a strong feeling of similarity to \CCeleven variadic templates. 938 961 As such, @ttype@ variables are also called \newterm{argument packs}. 939 962 … … 941 964 Since nothing is known about a parameter pack by default, assertion parameters are key to doing anything meaningful. 942 965 Unlike variadic templates, @ttype@ polymorphic functions can be separately compiled. 943 For example, a generalized @sum@ function:966 For example, the following is a generalized @sum@ function. 944 967 \begin{cfa} 945 968 int sum$\(_0\)$() { return 0; } … … 950 973 \end{cfa} 951 974 Since @sum@\(_0\) does not accept any arguments, it is not a valid candidate function for the call @sum(10, 20, 30)@. 952 In order to call @sum@\(_1\), @10@ is matched with @x@, and the argument resolution moves on to the argument pack @rest@, which consumes the remainder of the argument list and @Params@ is bound to @[20, 30]@.975 In order to call @sum@\(_1\), @10@ is matched with @x@, and the argument resolution moves on to the argument pack @rest@, which consumes the remainder of the argument list, and @Params@ is bound to @[20, 30]@. 953 976 The process continues until @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion. 954 977 Effectively, this algorithm traces as @sum(10, 20, 30)@ $\rightarrow$ @10 + sum(20, 30)@ $\rightarrow$ @10 + (20 + sum(30))@ $\rightarrow$ @10 + (20 + (30 + sum()))@ $\rightarrow$ @10 + (20 + (30 + 0))@. 955 978 956 It is reasonable to take the @sum@ function a step further to enforce a minimum number of arguments :979 It is reasonable to take the @sum@ function a step further to enforce a minimum number of arguments. 957 980 \begin{cfa} 958 981 int sum( int x, int y ) { return x + y; } … … 961 984 } 962 985 \end{cfa} 963 One more step permits the summation of any sumable type with all arguments of the same type :986 One more step permits the summation of any sumable type with all arguments of the same type. 964 987 \begin{cfa} 965 988 trait sumable( otype T ) { … … 990 1013 This example showcases a variadic-template-like decomposition of the provided argument list. 991 1014 The individual @print@ functions allow printing a single element of a type. 992 The polymorphic @print@ allows printing any list of types, where aseach individual type has a @print@ function.1015 The polymorphic @print@ allows printing any list of types, where each individual type has a @print@ function. 993 1016 The individual print functions can be used to build up more complicated @print@ functions, such as @S@, which cannot be done with @printf@ in C. 994 1017 This mechanism is used to seamlessly print tuples in the \CFA I/O library (see Section~\ref{s:IOLibrary}). 995 1018 996 1019 Finally, it is possible to use @ttype@ polymorphism to provide arbitrary argument forwarding functions. 997 For example, it is possible to write @new@ as a library function :1020 For example, it is possible to write @new@ as a library function. 998 1021 \begin{cfa} 999 1022 forall( otype R, otype S ) void ?{}( pair(R, S) *, R, S ); … … 1004 1027 \end{cfa} 1005 1028 The @new@ function provides the combination of type-safe @malloc@ with a \CFA constructor call, making it impossible to forget constructing dynamically allocated objects. 1006 This function provides the type -safety of @new@ in \CC, without the need to specify the allocated type again, thanksto return-type inference.1029 This function provides the type safety of @new@ in \CC, without the need to specify the allocated type again, due to return-type inference. 1007 1030 1008 1031 … … 1010 1033 1011 1034 Tuples are implemented in the \CFA translator via a transformation into \newterm{generic types}. 1012 For each $N$, the first time an $N$-tuple is seen in a scope a generic type with $N$ type parameters is generated, \eg: 1035 For each $N$, the first time an $N$-tuple is seen in a scope, a generic type with $N$ type parameters is generated. 1036 For example, the following 1013 1037 \begin{cfa} 1014 1038 [int, int] f() { … … 1017 1041 } 1018 1042 \end{cfa} 1019 is transformed into :1043 is transformed into 1020 1044 \begin{cfa} 1021 1045 forall( dtype T0, dtype T1 | sized(T0) | sized(T1) ) struct _tuple2 { … … 1083 1107 1084 1108 The various kinds of tuple assignment, constructors, and destructors generate GNU C statement expressions. 1085 A variable is generated to store the value produced by a statement expression, since its members may need to be constructed with a non -trivial constructor and it may need to be referred to multiple time, \eg in a unique expression.1109 A variable is generated to store the value produced by a statement expression, since its members may need to be constructed with a nontrivial constructor and it may need to be referred to multiple time, \eg in a unique expression. 1086 1110 The use of statement expressions allows the translator to arbitrarily generate additional temporary variables as needed, but binds the implementation to a non-standard extension of the C language. 1087 1111 However, there are other places where the \CFA translator makes use of GNU C extensions, such as its use of nested functions, so this restriction is not new. … … 1091 1115 \section{Control Structures} 1092 1116 1093 \CFA identifies inconsistent, problematic, and missing control structures in C, a ndextends, modifies, and adds control structures to increase functionality and safety.1094 1095 1096 \subsection{\texorpdfstring{\protect\lstinline {if} Statement}{if Statement}}1097 1098 The @if@ expression allows declarations, similar to @for@ declaration expression:1117 \CFA identifies inconsistent, problematic, and missing control structures in C, as well as extends, modifies, and adds control structures to increase functionality and safety. 1118 1119 1120 \subsection{\texorpdfstring{\protect\lstinline@if@ statement}{if statement}} 1121 1122 The @if@ expression allows declarations, similar to the @for@ declaration expression. 1099 1123 \begin{cfa} 1100 1124 if ( int x = f() ) ... $\C{// x != 0}$ … … 1103 1127 \end{cfa} 1104 1128 Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the @if@ expression, and the results are combined using the logical @&&@ operator.\footnote{\CC only provides a single declaration always compared not equal to 0.} 1105 The scope of the declaration(s) is local to the @if@ statement but exist within both the ``then'' and ``else'' clauses.1106 1107 1108 \subsection{\texorpdfstring{\protect\lstinline {switch} Statement}{switch Statement}}1129 The scope of the declaration(s) is local to the @if@ statement but exists within both the ``then'' and ``else'' clauses. 1130 1131 1132 \subsection{\texorpdfstring{\protect\lstinline@switch@ statement}{switch statement}} 1109 1133 1110 1134 There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses. 1111 1135 1112 C has no shorthand for specifying a list of case values, whether the list is non -contiguous or contiguous\footnote{C provides this mechanism via fall through.}.1113 \CFA provides a shorthand for a non -contiguous list:1136 C has no shorthand for specifying a list of case values, whether the list is noncontiguous or contiguous\footnote{C provides this mechanism via fall through.}. 1137 \CFA provides a shorthand for a noncontiguous list: 1114 1138 \begin{cquote} 1115 1139 \lstDeleteShortInline@% … … 1126 1150 \lstMakeShortInline@% 1127 1151 \end{cquote} 1128 for a contiguous list:\footnote{gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, as a space is required after a number, otherwise the first period is a decimal point.} 1152 for a contiguous list:\footnote{gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, as a space is required after a number; 1153 otherwise, the first period is a decimal point.} 1129 1154 \begin{cquote} 1130 1155 \lstDeleteShortInline@% … … 1157 1182 } 1158 1183 \end{cfa} 1159 \CFA precludes this form of transfer \emph{into} a control structure because it causes undefined behaviour, especially with respect to missed initialization, and provides very limited functionality.1160 1161 C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in undefined behaviour:1184 \CFA precludes this form of transfer \emph{into} a control structure because it causes an undefined behavior, especially with respect to missed initialization, and provides very limited functionality. 1185 1186 C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in an undefined behavior. 1162 1187 \begin{cfa} 1163 1188 switch ( x ) { … … 1176 1201 1177 1202 C @switch@ provides multiple entry points into the statement body, but once an entry point is selected, control continues across \emph{all} @case@ clauses until the end of the @switch@ body, called \newterm{fall through}; 1178 @case@ clauses are made disjoint by the @break@ statement. 1203 @case@ clauses are made disjoint by the @break@ 1204 \newpage 1205 \noindent 1206 statement. 1179 1207 While fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in errors from missing @break@ statements. 1180 For backward s compatibility, \CFA provides a \emph{new} control structure,@choose@, which mimics @switch@, but reverses the meaning of fall through (see Figure~\ref{f:ChooseSwitchStatements}), similar to Go.1208 For backward compatibility, \CFA provides a \emph{new} control structure, \ie @choose@, which mimics @switch@, but reverses the meaning of fall through (see Figure~\ref{f:ChooseSwitchStatements}), similar to Go. 1181 1209 1182 1210 \begin{figure} 1183 1211 \centering 1212 \fontsize{9bp}{11bp}\selectfont 1184 1213 \lstDeleteShortInline@% 1185 1214 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} … … 1218 1247 \end{tabular} 1219 1248 \lstMakeShortInline@% 1220 \caption{\lstinline|choose| versus \lstinline|switch| Statements}1249 \caption{\lstinline|choose| versus \lstinline|switch| statements} 1221 1250 \label{f:ChooseSwitchStatements} 1251 \vspace*{-11pt} 1222 1252 \end{figure} 1223 1253 1224 Finally, Figure~\ref{f:FallthroughStatement} shows @fallthrough@ may appear in contexts other than terminating a @case@ clause , and have an explicit transfer label allowing separate cases but common final-code for a set of cases.1254 Finally, Figure~\ref{f:FallthroughStatement} shows @fallthrough@ may appear in contexts other than terminating a @case@ clause and have an explicit transfer label allowing separate cases but common final code for a set of cases. 1225 1255 The target label must be below the @fallthrough@ and may not be nested in a control structure, \ie @fallthrough@ cannot form a loop, and the target label must be at the same or higher level as the containing @case@ clause and located at the same level as a @case@ clause; 1226 1256 the target label may be case @default@, but only associated with the current @switch@/@choose@ statement. … … 1228 1258 \begin{figure} 1229 1259 \centering 1260 \fontsize{9bp}{11bp}\selectfont 1230 1261 \lstDeleteShortInline@% 1231 1262 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} … … 1256 1287 \end{tabular} 1257 1288 \lstMakeShortInline@% 1258 \caption{\lstinline|fallthrough| Statement}1289 \caption{\lstinline|fallthrough| statement} 1259 1290 \label{f:FallthroughStatement} 1291 \vspace*{-11pt} 1260 1292 \end{figure} 1261 1293 1262 1294 1263 \subsection{\texorpdfstring{Labelled \protect\lstinline{continue} / \protect\lstinline{break}}{Labelled continue / break}} 1295 \vspace*{-8pt} 1296 \subsection{\texorpdfstring{Labeled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labeled continue / break}} 1264 1297 1265 1298 While C provides @continue@ and @break@ statements for altering control flow, both are restricted to one level of nesting for a particular control structure. 1266 Unfortunately, this restriction forces programmers to use @goto@ to achieve the equivalent control -flow for more than one level of nesting.1267 To prevent having to switch to the @goto@, \CFA extends the @continue@ and @break@ with a target label to support static multi-level exit~\cite{Buhr85}, as in Java.1299 Unfortunately, this restriction forces programmers to use @goto@ to achieve the equivalent control flow for more than one level of nesting. 1300 To prevent having to switch to the @goto@, \CFA extends @continue@ and @break@ with a target label to support static multilevel exit~\cite{Buhr85}, as in Java. 1268 1301 For both @continue@ and @break@, the target label must be directly associated with a @for@, @while@ or @do@ statement; 1269 1302 for @break@, the target label can also be associated with a @switch@, @if@ or compound (@{}@) statement. 1270 Figure~\ref{f:MultiLevelExit} shows @continue@ and @break@ indicating the specific control structure ,and the corresponding C program using only @goto@ and labels.1271 The innermost loop has 7 exit points, which cause continuation or termination of one or more of the 7 nested control-structures.1303 Figure~\ref{f:MultiLevelExit} shows @continue@ and @break@ indicating the specific control structure and the corresponding C program using only @goto@ and labels. 1304 The innermost loop has seven exit points, which cause a continuation or termination of one or more of the seven nested control structures. 1272 1305 1273 1306 \begin{figure} 1307 \fontsize{9bp}{11bp}\selectfont 1274 1308 \lstDeleteShortInline@% 1275 1309 \begin{tabular}{@{\hspace{\parindentlnth}}l|@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}} … … 1336 1370 \end{tabular} 1337 1371 \lstMakeShortInline@% 1338 \caption{Multi -level Exit}1372 \caption{Multilevel exit} 1339 1373 \label{f:MultiLevelExit} 1374 \vspace*{-5pt} 1340 1375 \end{figure} 1341 1376 1342 With respect to safety, both label led @continue@ and @break@ are a @goto@ restricted in the following ways:1343 \begin{ itemize}1377 With respect to safety, both labeled @continue@ and @break@ are @goto@ restricted in the following ways. 1378 \begin{list}{$\bullet$}{\topsep=4pt\itemsep=0pt\parsep=0pt} 1344 1379 \item 1345 1380 They cannot create a loop, which means only the looping constructs cause looping. … … 1347 1382 \item 1348 1383 They cannot branch into a control structure. 1349 This restriction prevents missing declarations and/or initializations at the start of a control structure resulting in undefined behaviour. 1350 \end{itemize} 1351 The advantage of the labelled @continue@/@break@ is allowing static multi-level exits without having to use the @goto@ statement, and tying control flow to the target control structure rather than an arbitrary point in a program. 1352 Furthermore, the location of the label at the \emph{beginning} of the target control structure informs the reader (eye candy) that complex control-flow is occurring in the body of the control structure. 1384 This restriction prevents missing declarations and/or initializations at the start of a control structure resulting in an undefined behavior. 1385 \end{list} 1386 The advantage of the labeled @continue@/@break@ is allowing static multilevel exits without having to use the @goto@ statement and tying control flow to the target control structure rather than an arbitrary point in a program. 1387 Furthermore, the location of the label at the \emph{beginning} of the target control structure informs the reader (eye candy) that complex control flow is 1388 occurring in the body of the control structure. 1353 1389 With @goto@, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader. 1354 Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting existing constructs.1390 Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting the existing constructs. 1355 1391 Otherwise, the implicit targets of the current @continue@ and @break@, \ie the closest enclosing loop or @switch@, change as certain constructs are added or removed. 1356 1392 1357 1393 1358 \subsection{Exception Handling} 1359 1360 The following framework for \CFA exception-handling is in place, excluding some runtime type-information and virtual functions. 1394 \vspace*{-5pt} 1395 \subsection{Exception handling} 1396 1397 The following framework for \CFA exception handling is in place, excluding some runtime type information and virtual functions. 1361 1398 \CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling})~\cite{Buhr92b,Buhr00a}. 1362 Both mechanisms provide dynamic call to a handler using dynamic name -lookup, where fix-up has dynamic return and recovery has static return from the handler.1399 Both mechanisms provide dynamic call to a handler using dynamic name lookup, where fix-up has dynamic return and recovery has static return from the handler. 1363 1400 \CFA restricts exception types to those defined by aggregate type @exception@. 1364 1401 The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@). 1365 If @resume@ or @throw@ ha ve no exception type, it is a reresume/rethrow, meaning the currentlyexception continues propagation.1402 If @resume@ or @throw@ has no exception type, it is a reresume/rethrow, which means that the current exception continues propagation. 1366 1403 If there is no current exception, the reresume/rethrow results in a runtime error. 1367 1404 1368 1405 \begin{figure} 1406 \fontsize{9bp}{11bp}\selectfont 1407 \lstDeleteShortInline@% 1369 1408 \begin{cquote} 1370 \lstDeleteShortInline@%1371 1409 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 1372 1410 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{Resumption}} & \multicolumn{1}{c@{}}{\textbf{Termination}} \\ … … 1399 1437 \end{cfa} 1400 1438 \end{tabular} 1401 \lstMakeShortInline@%1402 1439 \end{cquote} 1403 \caption{\CFA Exception Handling} 1440 \lstMakeShortInline@% 1441 \caption{\CFA exception handling} 1404 1442 \label{f:CFAExceptionHandling} 1443 \vspace*{-5pt} 1405 1444 \end{figure} 1406 1445 1407 The set of exception types in a list of catch clause may include both a resumption and termination handler:1446 The set of exception types in a list of catch clauses may include both a resumption and a termination handler. 1408 1447 \begin{cfa} 1409 1448 try { … … 1419 1458 The termination handler is available because the resumption propagation did not unwind the stack. 1420 1459 1421 An additional feature is conditional matching in a catch clause :1460 An additional feature is conditional matching in a catch clause. 1422 1461 \begin{cfa} 1423 1462 try { … … 1428 1467 catch ( IOError err ) { ... } $\C{// handler error from other files}$ 1429 1468 \end{cfa} 1430 where the throw inserts the failing file-handle into the I/O exception.1431 Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible. .1432 1433 The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise} :1469 Here, the throw inserts the failing file handle into the I/O exception. 1470 Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible. 1471 1472 The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}. 1434 1473 \begin{cfa} 1435 1474 resume( $\emph{exception-type}$, $\emph{alternate-stack}$ ) … … 1439 1478 Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handler returns. 1440 1479 1441 To facilitate nonlocal raise, \CFA provides dynamic enabling and disabling of nonlocal exception -propagation.1442 The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks:1480 To facilitate nonlocal raise, \CFA provides dynamic enabling and disabling of nonlocal exception propagation. 1481 The constructs for controlling propagation of nonlocal exceptions are the @enable@ and @disable@ blocks. 1443 1482 \begin{cquote} 1444 1483 \lstDeleteShortInline@% … … 1446 1485 \begin{cfa} 1447 1486 enable $\emph{exception-type-list}$ { 1448 // allow non -local raise1487 // allow nonlocal raise 1449 1488 } 1450 1489 \end{cfa} … … 1452 1491 \begin{cfa} 1453 1492 disable $\emph{exception-type-list}$ { 1454 // disallow non -local raise1493 // disallow nonlocal raise 1455 1494 } 1456 1495 \end{cfa} … … 1460 1499 The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively. 1461 1500 Specifying no exception type is shorthand for specifying all exception types. 1462 Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state. 1463 Coroutines and tasks start with non-local exceptions disabled, allowing handlers to be put in place, before non-local exceptions are explicitly enabled. 1501 Both @enable@ and @disable@ blocks can be nested; 1502 turning propagation on/off on entry and on exit, the specified exception types are restored to their prior state. 1503 Coroutines and tasks start with nonlocal exceptions disabled, allowing handlers to be put in place, before nonlocal exceptions are explicitly enabled. 1464 1504 \begin{cfa} 1465 1505 void main( mytask & t ) { $\C{// thread starts here}$ 1466 // non -local exceptions disabled1467 try { $\C{// establish handles for non -local exceptions}$1468 enable { $\C{// allow non -local exception delivery}$1506 // nonlocal exceptions disabled 1507 try { $\C{// establish handles for nonlocal exceptions}$ 1508 enable { $\C{// allow nonlocal exception delivery}$ 1469 1509 // task body 1470 1510 } … … 1474 1514 \end{cfa} 1475 1515 1476 Finally, \CFA provides a Java like @finally@ clause after the catch clauses:1516 Finally, \CFA provides a Java-like @finally@ clause after the catch clauses. 1477 1517 \begin{cfa} 1478 1518 try { … … 1483 1523 } 1484 1524 \end{cfa} 1485 The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.1525 The finally clause is always executed, \ie, if the try block ends normally or if an exception is raised. 1486 1526 If an exception is raised and caught, the handler is run before the finally clause. 1487 1527 Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated. 1488 Mimicking the @finally@ clause with mechanisms like R AII is non-trivial when there are multiple types and local accesses.1489 1490 1491 \subsection{\texorpdfstring{\protect\lstinline{with} Statement}{with Statement}}1528 Mimicking the @finally@ clause with mechanisms like Resource Aquisition Is Initialization (RAII) is nontrivial when there are multiple types and local accesses. 1529 1530 1531 \subsection{\texorpdfstring{\protect\lstinline{with} statement}{with statement}} 1492 1532 \label{s:WithStatement} 1493 1533 1494 Heterogeneous data isoften aggregated into a structure/union.1495 To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate member-qualification by opening a scope containing the member identifiers.1534 Heterogeneous data are often aggregated into a structure/union. 1535 To reduce syntactic noise, \CFA provides a @with@ statement (see section~4.F in the Pascal User Manual and Report~\cite{Pascal}) to elide aggregate member qualification by opening a scope containing the member identifiers. 1496 1536 \begin{cquote} 1497 1537 \vspace*{-\baselineskip}%??? … … 1521 1561 Object-oriented programming languages only provide implicit qualification for the receiver. 1522 1562 1523 In detail, the @with@ statement has the form :1563 In detail, the @with@ statement has the form 1524 1564 \begin{cfa} 1525 1565 $\emph{with-statement}$: … … 1527 1567 \end{cfa} 1528 1568 and may appear as the body of a function or nested within a function body. 1529 Each expression in the expression -list provides a type and object.1569 Each expression in the expression list provides a type and object. 1530 1570 The type must be an aggregate type. 1531 1571 (Enumerations are already opened.) 1532 The object is the implicit qualifier for the open structure -members.1572 The object is the implicit qualifier for the open structure members. 1533 1573 1534 1574 All expressions in the expression list are open in parallel within the compound statement, which is different from Pascal, which nests the openings from left to right. 1535 The difference between parallel and nesting occurs for members with the same name and type :1575 The difference between parallel and nesting occurs for members with the same name and type. 1536 1576 \begin{cfa} 1537 1577 struct S { int `i`; int j; double m; } s, w; $\C{// member i has same type in structure types S and T}$ … … 1547 1587 } 1548 1588 \end{cfa} 1549 For parallel semantics, both @s.i@ and @t.i@ are visible , so@i@ is ambiguous without qualification;1550 for nested semantics, @t.i@ hides @s.i@ , so@i@ implies @t.i@.1589 For parallel semantics, both @s.i@ and @t.i@ are visible and, therefore, @i@ is ambiguous without qualification; 1590 for nested semantics, @t.i@ hides @s.i@ and, therefore, @i@ implies @t.i@. 1551 1591 \CFA's ability to overload variables means members with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates. 1552 1592 Qualification or a cast is used to disambiguate. 1553 1593 1554 There is an interesting problem between parameters and the function -body @with@, \eg:1594 There is an interesting problem between parameters and the function body @with@. 1555 1595 \begin{cfa} 1556 1596 void ?{}( S & s, int i ) with ( s ) { $\C{// constructor}$ … … 1558 1598 } 1559 1599 \end{cfa} 1560 Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the function -body @with@.1561 To solve this problem, parameters are treated like an initialized aggregate :1600 Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the function body @with@. 1601 To solve this problem, parameters are treated like an initialized aggregate 1562 1602 \begin{cfa} 1563 1603 struct Params { … … 1566 1606 } params; 1567 1607 \end{cfa} 1568 and implicitly opened \emph{after} a function-body open, to give them higher priority: 1608 \newpage 1609 and implicitly opened \emph{after} a function body open, to give them higher priority 1569 1610 \begin{cfa} 1570 1611 void ?{}( S & s, int `i` ) with ( s ) `{` `with( $\emph{\color{red}params}$ )` { … … 1572 1613 } `}` 1573 1614 \end{cfa} 1574 Finally, a cast may be used to disambiguate among overload variables in a @with@ expression :1615 Finally, a cast may be used to disambiguate among overload variables in a @with@ expression 1575 1616 \begin{cfa} 1576 1617 with ( w ) { ... } $\C{// ambiguous, same name and no context}$ 1577 1618 with ( (S)w ) { ... } $\C{// unambiguous, cast}$ 1578 1619 \end{cfa} 1579 and @with@ expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate :1620 and @with@ expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate 1580 1621 \begin{cfa} 1581 1622 struct S { int i, j; } sv; … … 1601 1642 \CFA attempts to correct and add to C declarations, while ensuring \CFA subjectively ``feels like'' C. 1602 1643 An important part of this subjective feel is maintaining C's syntax and procedural paradigm, as opposed to functional and object-oriented approaches in other systems languages such as \CC and Rust. 1603 Maintaining the C approach means that C coding -patterns remain not only useable but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development.1644 Maintaining the C approach means that C coding patterns remain not only useable but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development. 1604 1645 Nevertheless, some features from other approaches are undeniably convenient; 1605 1646 \CFA attempts to adapt these features to the C paradigm. 1606 1647 1607 1648 1608 \subsection{Alternative Declaration Syntax}1649 \subsection{Alternative declaration syntax} 1609 1650 1610 1651 C declaration syntax is notoriously confusing and error prone. 1611 For example, many C programmers are confused by a declaration as simple as :1652 For example, many C programmers are confused by a declaration as simple as the following. 1612 1653 \begin{cquote} 1613 1654 \lstDeleteShortInline@% … … 1621 1662 \lstMakeShortInline@% 1622 1663 \end{cquote} 1623 Is this an array of 5 pointers to integers or a pointer to an array of 5integers?1664 Is this an array of five pointers to integers or a pointer to an array of five integers? 1624 1665 If there is any doubt, it implies productivity and safety issues even for basic programs. 1625 1666 Another example of confusion results from the fact that a function name and its parameters are embedded within the return type, mimicking the way the return value is used at the function's call site. 1626 For example, a function returning a pointer to an array of integers is defined and used in the following way :1667 For example, a function returning a pointer to an array of integers is defined and used in the following way. 1627 1668 \begin{cfa} 1628 1669 int `(*`f`())[`5`]` {...}; $\C{// definition}$ … … 1632 1673 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice. 1633 1674 1634 \CFA provides its own type, variable and function declarations, using a different syntax~\cite[pp.~856--859]{Buhr94a}. 1635 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right. 1675 \newpage 1676 \CFA provides its own type, variable, and function declarations, using a different syntax~\cite[pp.~856--859]{Buhr94a}. 1677 The new declarations place qualifiers to the left of the base type, whereas C declarations place qualifiers to the right. 1636 1678 The qualifiers have the same meaning but are ordered left to right to specify a variable's type. 1637 1679 \begin{cquote} … … 1659 1701 \lstMakeShortInline@% 1660 1702 \end{cquote} 1661 The only exception is bit-field specification, which always appear to the right of the base type.1703 The only exception is bit-field specification, which always appears to the right of the base type. 1662 1704 % Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a function parameter. 1663 1705 However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list. 1664 For instance, variables @x@ and @y@ of type pointer to integer are defined in \CFA as follows:1706 For instance, variables @x@ and @y@ of type pointer to integer are defined in \CFA as 1665 1707 \begin{cquote} 1666 1708 \lstDeleteShortInline@% … … 1725 1767 \end{comment} 1726 1768 1727 All specifiers (@extern@, @static@, \etc) and qualifiers (@const@, @volatile@, \etc) are used in the normal way with the new declarations and also appear left to right , \eg:1769 All specifiers (@extern@, @static@, \etc) and qualifiers (@const@, @volatile@, \etc) are used in the normal way with the new declarations and also appear left to right. 1728 1770 \begin{cquote} 1729 1771 \lstDeleteShortInline@% 1730 1772 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{\hspace{2\parindentlnth}}l@{}} 1731 1773 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{C}} \\ 1732 \begin{cfa} 1774 \begin{cfa}[basicstyle=\linespread{0.9}\fontsize{9bp}{12bp}\selectfont\sf] 1733 1775 extern const * const int x; 1734 1776 static const * [5] const int y; 1735 1777 \end{cfa} 1736 1778 & 1737 \begin{cfa} 1779 \begin{cfa}[basicstyle=\linespread{0.9}\fontsize{9bp}{12bp}\selectfont\sf] 1738 1780 int extern const * const x; 1739 1781 static const int (* const y)[5] 1740 1782 \end{cfa} 1741 1783 & 1742 \begin{cfa} 1784 \begin{cfa}[basicstyle=\linespread{0.9}\fontsize{9bp}{12bp}\selectfont\sf] 1743 1785 // external const pointer to const int 1744 1786 // internal const pointer to array of 5 const int … … 1748 1790 \end{cquote} 1749 1791 Specifiers must appear at the start of a \CFA function declaration\footnote{\label{StorageClassSpecifier} 1750 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature .~\cite[\S~6.11.5(1)]{C11}}.1792 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature (see section~6.11.5(1) in ISO/IEC 9899~\cite{C11}).}. 1751 1793 1752 1794 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-function @sizeof@: … … 1769 1811 1770 1812 The syntax of the new function-prototype declaration follows directly from the new function-definition syntax; 1771 a s well, parameter names are optional, \eg:1813 also, parameter names are optional. 1772 1814 \begin{cfa} 1773 1815 [ int x ] f ( /* void */ ); $\C[2.5in]{// returning int with no parameters}$ … … 1777 1819 [ * int, int ] j ( int ); $\C{// returning pointer to int and int with int parameter}$ 1778 1820 \end{cfa} 1779 This syntax allows a prototype declaration to be created by cutting and pasting source text from the function-definition header (or vice versa).1780 Like C, it is possible to declare multiple function -prototypes in a single declaration, where the return type is distributed across \emph{all} function names in the declaration list, \eg:1821 This syntax allows a prototype declaration to be created by cutting and pasting the source text from the function-definition header (or vice versa). 1822 Like C, it is possible to declare multiple function prototypes in a single declaration, where the return type is distributed across \emph{all} function names in the declaration list. 1781 1823 \begin{cquote} 1782 1824 \lstDeleteShortInline@% … … 1793 1835 \lstMakeShortInline@% 1794 1836 \end{cquote} 1795 where\CFA allows the last function in the list to define its body.1796 1797 The syntax for pointers to \CFA functions specifies the pointer name on the right , \eg:1837 Here, \CFA allows the last function in the list to define its body. 1838 1839 The syntax for pointers to \CFA functions specifies the pointer name on the right. 1798 1840 \begin{cfa} 1799 1841 * [ int x ] () fp; $\C{// pointer to function returning int with no parameters}$ … … 1802 1844 * [ * int, int ] ( int ) jp; $\C{// pointer to function returning pointer to int and int with int parameter}\CRT$ 1803 1845 \end{cfa} 1804 Note, the name of the function pointer is specified last, as for other variable declarations. 1805 1806 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. 1807 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style. 1808 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems. 1846 \newpage 1847 \noindent 1848 Note that the name of the function pointer is specified last, as for other variable declarations. 1849 1850 Finally, new \CFA declarations may appear together with C declarations in the same program block but cannot be mixed within a specific declaration. 1851 Therefore, a programmer has the option of either continuing to use traditional C declarations or taking advantage of the new style. 1852 Clearly, both styles need to be supported for some time due to existing C-style header files, particularly for UNIX-like systems. 1809 1853 1810 1854 … … 1814 1858 All variables in C have an \newterm{address}, a \newterm{value}, and a \newterm{type}; 1815 1859 at the position in the program's memory denoted by the address, there exists a sequence of bits (the value), with the length and semantic meaning of this bit sequence defined by the type. 1816 The C type -system does not always track the relationship between a value and its address;1817 a value that does not have a corresponding address is called a \newterm{rvalue} (for ``right-hand value''), while a value that does have an address is called a\newterm{lvalue} (for ``left-hand value'').1818 For example, in @int x; x = 42;@ the variable expression @x@ on the left-hand -side of the assignment is a lvalue, while the constant expression @42@ on the right-hand-side of the assignment is arvalue.1819 Despite the nomenclature of ``left-hand'' and ``right-hand'', an expression's classification as lvalue or rvalue is entirely dependent on whether it has an address or not; in imperative programming, the address of a value is used for both reading and writing (mutating) a value, and as such, lvalues can be convertedto rvalues and read from, but rvalues cannot be mutated because they lack a location to store the updated value.1860 The C type system does not always track the relationship between a value and its address; 1861 a value that does not have a corresponding address is called an \newterm{rvalue} (for ``right-hand value''), whereas a value that does have an address is called an \newterm{lvalue} (for ``left-hand value''). 1862 For example, in @int x; x = 42;@ the variable expression @x@ on the left-hand side of the assignment is an lvalue, whereas the constant expression @42@ on the right-hand side of the assignment is an rvalue. 1863 Despite the nomenclature of ``left-hand'' and ``right-hand'', an expression's classification as an lvalue or an rvalue is entirely dependent on whether it has an address or not; in imperative programming, the address of a value is used for both reading and writing (mutating) a value, and as such, lvalues can be converted into rvalues and read from, but rvalues cannot be mutated because they lack a location to store the updated value. 1820 1864 1821 1865 Within a lexical scope, lvalue expressions have an \newterm{address interpretation} for writing a value or a \newterm{value interpretation} to read a value. 1822 For example, in @x = y@, @x@ has an address interpretation, wh ile@y@ has a value interpretation.1866 For example, in @x = y@, @x@ has an address interpretation, whereas @y@ has a value interpretation. 1823 1867 While this duality of interpretation is useful, C lacks a direct mechanism to pass lvalues between contexts, instead relying on \newterm{pointer types} to serve a similar purpose. 1824 1868 In C, for any type @T@ there is a pointer type @T *@, the value of which is the address of a value of type @T@. 1825 A pointer rvalue can be explicitly \newterm{dereferenced} to the pointed-to lvalue with the dereference operator @*?@, while the rvalue representing the address of a lvalue can be obtained with the address-of operator @&?@. 1826 1869 A pointer rvalue can be explicitly \newterm{dereferenced} to the pointed-to lvalue with the dereference operator @*?@, whereas the rvalue representing the address of an lvalue can be obtained with the address-of operator @&?@. 1827 1870 \begin{cfa} 1828 1871 int x = 1, y = 2, * p1, * p2, ** p3; … … 1832 1875 *p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15); 1833 1876 \end{cfa} 1834 1835 1877 Unfortunately, the dereference and address-of operators introduce a great deal of syntactic noise when dealing with pointed-to values rather than pointers, as well as the potential for subtle bugs because of pointer arithmetic. 1836 1878 For both brevity and clarity, it is desirable for the compiler to figure out how to elide the dereference operators in a complex expression such as the assignment to @*p2@ above. 1837 However, since C defines a number of forms of \newterm{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a programmer may write one when they mean the other ,and precluding any simple algorithm for elision of dereference operators.1879 However, since C defines a number of forms of \newterm{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a programmer may write one when they mean the other and precluding any simple algorithm for elision of dereference operators. 1838 1880 To solve these problems, \CFA introduces reference types @T &@; 1839 a @T &@ has exactly the same value as a @T *@, but where the @T *@ takes the address interpretation by default, a @T &@ takes the value interpretation by default, as below: 1840 1881 a @T &@ has exactly the same value as a @T *@, but where the @T *@ takes the address interpretation by default, a @T &@ takes the value interpretation by default, as below. 1841 1882 \begin{cfa} 1842 1883 int x = 1, y = 2, & r1, & r2, && r3; … … 1846 1887 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); $\C{// implicit dereferencing}$ 1847 1888 \end{cfa} 1848 1849 1889 Except for auto-dereferencing by the compiler, this reference example is exactly the same as the previous pointer example. 1850 Hence, a reference behaves like a variable name -- an lvalue expression which is interpreted as a value --but also has the type system track the address of that value.1851 One way to conceptualize a reference is via a rewrite rule, where the compiler inserts a dereference operator before the reference variable for each reference qualifier in the reference variable declaration , so the previous example implicitly acts like:1852 1890 Hence, a reference behaves like a variable name---an lvalue expression that is interpreted as a value---but also has the type system track the address of that value. 1891 One way to conceptualize a reference is via a rewrite rule, where the compiler inserts a dereference operator before the reference variable for each reference qualifier in the reference variable declaration; 1892 thus, the previous example implicitly acts like the following. 1853 1893 \begin{cfa} 1854 1894 `*`r2 = ((`*`r1 + `*`r2) * (`**`r3 - `*`r1)) / (`**`r3 - 15); 1855 1895 \end{cfa} 1856 1857 1896 References in \CFA are similar to those in \CC, with important improvements, which can be seen in the example above. 1858 1897 Firstly, \CFA does not forbid references to references. 1859 This provides a much more orthogonal design for library implementors, obviating the need for workarounds such as @std::reference_wrapper@.1898 This provides a much more orthogonal design for library \mbox{implementors}, obviating the need for workarounds such as @std::reference_wrapper@. 1860 1899 Secondly, \CFA references are rebindable, whereas \CC references have a fixed address. 1861 Rebinding allows \CFA references to be default -initialized (\eg to a null pointer\footnote{1862 While effort has been made into non-null reference checking in \CC and Java, the exercise seems moot for any non -managed languages (C/\CC), given that it only handles one of many different error situations, \eg using a pointer after its storage is deleted.}) and point to different addresses throughout their lifetime, like pointers.1900 Rebinding allows \CFA references to be default initialized (\eg to a null pointer\footnote{ 1901 While effort has been made into non-null reference checking in \CC and Java, the exercise seems moot for any nonmanaged languages (C/\CC), given that it only handles one of many different error situations, \eg using a pointer after its storage is deleted.}) and point to different addresses throughout their lifetime, like pointers. 1863 1902 Rebinding is accomplished by extending the existing syntax and semantics of the address-of operator in C. 1864 1903 1865 In C, the address of a lvalue is always a rvalue, as in general that address is not stored anywhere in memory,and does not itself have an address.1866 In \CFA, the address of a @T &@ is a lvalue @T *@, as the address of the underlying @T@ is stored in the reference,and can thus be mutated there.1904 In C, the address of an lvalue is always an rvalue, as, in general, that address is not stored anywhere in memory and does not itself have an address. 1905 In \CFA, the address of a @T &@ is an lvalue @T *@, as the address of the underlying @T@ is stored in the reference and can thus be mutated there. 1867 1906 The result of this rule is that any reference can be rebound using the existing pointer assignment semantics by assigning a compatible pointer into the address of the reference, \eg @&r1 = &x;@ above. 1868 1907 This rebinding occurs to an arbitrary depth of reference nesting; 1869 1908 loosely speaking, nested address-of operators produce a nested lvalue pointer up to the depth of the reference. 1870 1909 These explicit address-of operators can be thought of as ``cancelling out'' the implicit dereference operators, \eg @(&`*`)r1 = &x@ or @(&(&`*`)`*`)r3 = &(&`*`)r1@ or even @(&`*`)r2 = (&`*`)`*`r3@ for @&r2 = &r3@. 1871 More precisely: 1910 The precise rules are 1872 1911 \begin{itemize} 1873 1912 \item 1874 if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) then @&R@ has type {@T `*`&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols). 1875 1913 If @R@ is an rvalue of type @T &@$_1\cdots$ @&@$_r$, where $r \ge 1$ references (@&@ symbols), than @&R@ has type @T `*`&@$_{\color{red}2}\cdots$ @&@$_{\color{red}r}$, \ie @T@ pointer with $r-1$ references (@&@ symbols). 1876 1914 \item 1877 if @L@ is an lvalue of type {@T &@$_1 \cdots$@ &@$_l$} where $l \ge 0$ references (@&@ symbols) then @&L@ has type {@T `*`&@$_{\color{red}1} \cdots$@ &@$_{\color{red}l}$}, \\\ie @T@ pointer with $l$ references (@&@ symbols).1915 If @L@ is an lvalue of type @T &@$_1\cdots$ @&@$_l$, where $l \ge 0$ references (@&@ symbols), than @&L@ has type @T `*`&@$_{\color{red}1}\cdots$ @&@$_{\color{red}l}$, \ie @T@ pointer with $l$ references (@&@ symbols). 1878 1916 \end{itemize} 1879 Since pointers and references share the same internal representation, code using either is equally performant; in fact the \CFA compiler converts references to pointers internally, and the choice between them is made solely on convenience, \eg many pointer or value accesses. 1917 Since pointers and references share the same internal representation, code using either is equally performant; 1918 in fact, the \CFA compiler converts references into pointers internally, and the choice between them is made solely on convenience, \eg many pointer or value accesses. 1880 1919 1881 1920 By analogy to pointers, \CFA references also allow cv-qualifiers such as @const@: … … 1892 1931 There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, and return/temporary binding. 1893 1932 In each of these contexts, the address-of operator on the target lvalue is elided. 1894 The syntactic motivation is clearest when considering overloaded operator -assignment, \eg @int ?+=?(int &, int)@; given @int x, y@, the expected call syntax is @x += y@, not @&x += y@.1895 1896 More generally, this initialization of references from lvalues rather than pointers is an instance of a ``lvalue-to-reference'' conversion rather than an elision of the address-of operator;1933 The syntactic motivation is clearest when considering overloaded operator assignment, \eg @int ?+=?(int &, int)@; given @int x, y@, the expected call syntax is @x += y@, not @&x += y@. 1934 1935 More generally, this initialization of references from lvalues rather than pointers is an instance of an ``lvalue-to-reference'' conversion rather than an elision of the address-of operator; 1897 1936 this conversion is used in any context in \CFA where an implicit conversion is allowed. 1898 Similarly, use of athe value pointed to by a reference in an rvalue context can be thought of as a ``reference-to-rvalue'' conversion, and \CFA also includes a qualifier-adding ``reference-to-reference'' conversion, analogous to the @T *@ to @const T *@ conversion in standard C.1899 The final reference conversion included in \CFA is ``rvalue-to-reference'' conversion, implemented by means of an implicit temporary.1937 Similarly, use of the value pointed to by a reference in an rvalue context can be thought of as a ``reference-to-rvalue'' conversion, and \CFA also includes a qualifier-adding ``reference-to-reference'' conversion, analogous to the @T *@ to @const T *@ conversion in standard C. 1938 The final reference conversion included in \CFA is an ``rvalue-to-reference'' conversion, implemented by means of an implicit temporary. 1900 1939 When an rvalue is used to initialize a reference, it is instead used to initialize a hidden temporary value with the same lexical scope as the reference, and the reference is initialized to the address of this temporary. 1901 1940 \begin{cfa} … … 1905 1944 f( 3, x + y, (S){ 1.0, 7.0 }, (int [3]){ 1, 2, 3 } ); $\C{// pass rvalue to lvalue \(\Rightarrow\) implicit temporary}$ 1906 1945 \end{cfa} 1907 This allows complex values to be succinctly and efficiently passed to functions, without the syntactic overhead of explicit definition of a temporary variable or the runtime cost of pass-by-value. 1908 \CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \newterm{const poisoning} problem~\cite{Taylor10}, in which addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers. 1909 1910 1911 \subsection{Type Nesting} 1912 1913 Nested types provide a mechanism to organize associated types and refactor a subset of members into a named aggregate (\eg sub-aggregates @name@, @address@, @department@, within aggregate @employe@). 1914 Java nested types are dynamic (apply to objects), \CC are static (apply to the \lstinline[language=C++]@class@), and C hoists (refactors) nested types into the enclosing scope, meaning there is no need for type qualification. 1915 Since \CFA in not object-oriented, adopting dynamic scoping does not make sense; 1916 instead \CFA adopts \CC static nesting, using the member-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@'' (see Figure~\ref{f:TypeNestingQualification}). 1946 This allows complex values to be succinctly and efficiently passed to functions, without the syntactic overhead of the explicit definition of a temporary variable or the runtime cost of pass-by-value. 1947 \CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \newterm{const poisoning} problem~\cite{Taylor10}, in which the addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers. 1948 1949 1950 \subsection{Type nesting} 1951 1952 Nested types provide a mechanism to organize associated types and refactor a subset of members into a named aggregate (\eg subaggregates @name@, @address@, @department@, within aggregate @employe@). 1953 Java nested types are dynamic (apply to objects), \CC are static (apply to the \lstinline[language=C++]@class@), and C hoists (refactors) nested types into the enclosing scope, which means there is no need for type qualification. 1954 Since \CFA in not object oriented, adopting dynamic scoping does not make sense; 1955 instead, \CFA adopts \CC static nesting, using the member-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@'' (see Figure~\ref{f:TypeNestingQualification}). 1956 In the C left example, types @C@, @U@ and @T@ are implicitly hoisted outside of type @S@ into the containing block scope. 1957 In the \CFA right example, the types are not hoisted and accessible. 1958 1917 1959 \begin{figure} 1918 1960 \centering 1961 \fontsize{9bp}{11bp}\selectfont\sf 1919 1962 \lstDeleteShortInline@% 1920 1963 \begin{tabular}{@{}l@{\hspace{3em}}l|l@{}} … … 1978 2021 \end{tabular} 1979 2022 \lstMakeShortInline@% 1980 \caption{Type Nesting / Qualification}2023 \caption{Type nesting / qualification} 1981 2024 \label{f:TypeNestingQualification} 2025 \vspace*{-8pt} 1982 2026 \end{figure} 1983 In the C left example, types @C@, @U@ and @T@ are implicitly hoisted outside of type @S@ into the containing block scope. 1984 In the \CFA right example, the types are not hoisted and accessible. 1985 1986 1987 \subsection{Constructors and Destructors} 2027 2028 2029 \vspace*{-8pt} 2030 \subsection{Constructors and destructors} 1988 2031 \label{s:ConstructorsDestructors} 1989 2032 1990 One of the strengths (and weaknesses) of C is memory-management control, allowing resource release to be precisely specified versus unknown release with garbage-collected memory -management.2033 One of the strengths (and weaknesses) of C is memory-management control, allowing resource release to be precisely specified versus unknown release with garbage-collected memory management. 1991 2034 However, this manual approach is verbose, and it is useful to manage resources other than memory (\eg file handles) using the same mechanism as memory. 1992 \CC addresses these issues using R esource Aquisition Is Initialization (RAII), implemented by means of \newterm{constructor} and \newterm{destructor} functions;2035 \CC addresses these issues using RAII, implemented by means of \newterm{constructor} and \newterm{destructor} functions; 1993 2036 \CFA adopts constructors and destructors (and @finally@) to facilitate RAII. 1994 While constructors and destructors are a common feature of object-oriented programming -languages, they are an independent capability allowing \CFA to adopt them while retaining a procedural paradigm.1995 Specifically, \CFA constructors and destructors are denoted by name and first parameter -type versus name and nesting in an aggregate type.2037 While constructors and destructors are a common feature of object-oriented programming languages, they are an independent capability allowing \CFA to adopt them while retaining a procedural paradigm. 2038 Specifically, \CFA constructors and destructors are denoted by name and first parameter type versus name and nesting in an aggregate type. 1996 2039 Constructor calls seamlessly integrate with existing C initialization syntax, providing a simple and familiar syntax to C programmers and allowing constructor calls to be inserted into legacy C code with minimal code changes. 1997 2040 … … 2002 2045 The constructor and destructor have return type @void@, and the first parameter is a reference to the object type to be constructed or destructed. 2003 2046 While the first parameter is informally called the @this@ parameter, as in object-oriented languages, any variable name may be used. 2004 Both constructors and destructors allow additional parameters after the @this@ parameter for specifying values for initialization/de -initialization\footnote{2005 Destruction parameters are useful for specifying storage-management actions, such as de -initialize but not deallocate.}.2006 \begin{cfa} 2047 Both constructors and destructors allow additional parameters after the @this@ parameter for specifying values for initialization/deinitialization\footnote{ 2048 Destruction parameters are useful for specifying storage-management actions, such as deinitialize but not deallocate.}. 2049 \begin{cfa}[basicstyle=\linespread{0.9}\fontsize{9bp}{11bp}\selectfont\sf] 2007 2050 struct VLA { int size, * data; }; $\C{// variable length array of integers}$ 2008 2051 void ?{}( VLA & vla ) with ( vla ) { size = 10; data = alloc( size ); } $\C{// default constructor}$ … … 2013 2056 \end{cfa} 2014 2057 @VLA@ is a \newterm{managed type}\footnote{ 2015 A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non -trivial constructor or destructor, or with a member of a managed type.2058 A managed type affects the runtime environment versus a self-contained type.}: a type requiring a nontrivial constructor or destructor, or with a member of a managed type. 2016 2059 A managed type is implicitly constructed at allocation and destructed at deallocation to ensure proper interaction with runtime resources, in this case, the @data@ array in the heap. 2017 For details of the code-generation placement of implicit constructor and destructor calls among complex executable statements see~\cite[\S~2.2]{Schluntz17}.2018 2019 \CFA also provides syntax for \newterm{initialization} and \newterm{copy} :2060 For details of the code-generation placement of implicit constructor and destructor calls among complex executable statements, see section~2.2 in the work of Schlintz~\cite{Schluntz17}. 2061 2062 \CFA also provides syntax for \newterm{initialization} and \newterm{copy}. 2020 2063 \begin{cfa} 2021 2064 void ?{}( VLA & vla, int size, char fill = '\0' ) { $\C{// initialization}$ … … 2026 2069 } 2027 2070 \end{cfa} 2028 (Note ,the example is purposely simplified using shallow-copy semantics.)2029 An initialization constructor -call has the same syntax as a C initializer, except the initialization values are passed as arguments to a matching constructor (number and type of paremeters).2071 (Note that the example is purposely simplified using shallow-copy semantics.) 2072 An initialization constructor call has the same syntax as a C initializer, except that the initialization values are passed as arguments to a matching constructor (number and type of parameters). 2030 2073 \begin{cfa} 2031 2074 VLA va = `{` 20, 0 `}`, * arr = alloc()`{` 5, 0 `}`; 2032 2075 \end{cfa} 2033 Note , the use of a \newterm{constructor expression} to initialize the storage from the dynamic storage-allocation.2076 Note the use of a \newterm{constructor expression} to initialize the storage from the dynamic storage allocation. 2034 2077 Like \CC, the copy constructor has two parameters, the second of which is a value parameter with the same type as the first parameter; 2035 2078 appropriate care is taken to not recursively call the copy constructor when initializing the second parameter. … … 2037 2080 \CFA constructors may be explicitly called, like Java, and destructors may be explicitly called, like \CC. 2038 2081 Explicit calls to constructors double as a \CC-style \emph{placement syntax}, useful for construction of members in user-defined constructors and reuse of existing storage allocations. 2039 Like the other operators in \CFA, there is a concise syntax for constructor/destructor function calls :2082 Like the other operators in \CFA, there is a concise syntax for constructor/destructor function calls. 2040 2083 \begin{cfa} 2041 2084 { … … 2053 2096 To provide a uniform type interface for @otype@ polymorphism, the \CFA compiler automatically generates a default constructor, copy constructor, assignment operator, and destructor for all types. 2054 2097 These default functions can be overridden by user-generated versions. 2055 For compatibility with the standard behavio ur of C, the default constructor and destructor for all basic, pointer, and reference types do nothing, whilethe copy constructor and assignment operator are bitwise copies;2056 if default zero -initialization is desired, the default constructors can be overridden.2098 For compatibility with the standard behavior of C, the default constructor and destructor for all basic, pointer, and reference types do nothing, whereas the copy constructor and assignment operator are bitwise copies; 2099 if default zero initialization is desired, the default constructors can be overridden. 2057 2100 For user-generated types, the four functions are also automatically generated. 2058 2101 @enum@ types are handled the same as their underlying integral type, and unions are also bitwise copied and no-op initialized and destructed. 2059 2102 For compatibility with C, a copy constructor from the first union member type is also defined. 2060 For @struct@ types, each of the four functions areimplicitly defined to call their corresponding functions on each member of the struct.2061 To better simulate the behavio ur of C initializers, a set of \newterm{member constructors} is also generated for structures.2062 A constructor is generated for each non -empty prefix of a structure's member-list to copy-construct the members passed as parameters and default-construct the remaining members.2103 For @struct@ types, each of the four functions is implicitly defined to call their corresponding functions on each member of the struct. 2104 To better simulate the behavior of C initializers, a set of \newterm{member constructors} is also generated for structures. 2105 A constructor is generated for each nonempty prefix of a structure's member list to copy-construct the members passed as parameters and default-construct the remaining members. 2063 2106 To allow users to limit the set of constructors available for a type, when a user declares any constructor or destructor, the corresponding generated function and all member constructors for that type are hidden from expression resolution; 2064 similarly, the generated default constructor is hidden upon declaration of any constructor.2107 similarly, the generated default constructor is hidden upon the declaration of any constructor. 2065 2108 These semantics closely mirror the rule for implicit declaration of constructors in \CC\cite[p.~186]{ANSI98:C++}. 2066 2109 2067 In some circumstance programmers may not wish to have implicit constructor and destructor generation and calls. 2068 In these cases, \CFA provides the initialization syntax \lstinline|S x `@=` {}|, and the object becomes unmanaged, so implicit constructor and destructor calls are not generated. 2110 In some circumstance, programmers may not wish to have implicit constructor and destructor generation and calls. 2111 In these cases, \CFA provides the initialization syntax \lstinline|S x `@=` {}|, and the object becomes unmanaged; 2112 hence, implicit \mbox{constructor} and destructor calls are not generated. 2069 2113 Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg \lstinline|VLA a @= { 0, 0x0 }|, with the usual C initialization semantics. 2070 2114 The same syntax can be used in a compound literal, \eg \lstinline|a = (VLA)`@`{ 0, 0x0 }|, to create a C-style literal. 2071 The point of \lstinline|@=| is to provide a migration path from legacy C code to \CFA, by providing a mechanism to incrementally convert to implicit initialization.2115 The point of \lstinline|@=| is to provide a migration path from legacy C code to \CFA, by providing a mechanism to incrementally convert into implicit initialization. 2072 2116 2073 2117 … … 2077 2121 \section{Literals} 2078 2122 2079 C already includes limited polymorphism for literals -- @0@ can be either an integer or a pointer literal, depending on context, whilethe syntactic forms of literals of the various integer and float types are very similar, differing from each other only in suffix.2080 In keeping with the general \CFA approach of adding features while respecting the ``C -style'' of doing things, C's polymorphic constants and typed literal syntax are extended to interoperate with user-defined types, while maintaining a backwards-compatible semantics.2123 C already includes limited polymorphism for literals---@0@ can be either an integer or a pointer literal, depending on context, whereas the syntactic forms of literals of the various integer and float types are very similar, differing from each other only in suffix. 2124 In keeping with the general \CFA approach of adding features while respecting the ``C style'' of doing things, C's polymorphic constants and typed literal syntax are extended to interoperate with user-defined types, while maintaining a backward-compatible semantics. 2081 2125 2082 2126 A simple example is allowing the underscore, as in Ada, to separate prefixes, digits, and suffixes in all \CFA constants, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@, where the underscore is also the standard separator in C identifiers. 2083 \CC uses a single quote as a separator but it is restricted among digits, precluding its use in the literal prefix or suffix, \eg @0x1.ffff@@`'@@ffffp128l@, and causes problems with most IDEs, which must be extended to deal with this alternate use of the single quote.2127 \CC uses a single quote as a separator, but it is restricted among digits, precluding its use in the literal prefix or suffix, \eg @0x1.ffff@@`'@@ffffp128l@, and causes problems with most integrated development environments (IDEs), which must be extended to deal with this alternate use of the single quote. 2084 2128 2085 2129 … … 2124 2168 2125 2169 In C, @0@ has the special property that it is the only ``false'' value; 2126 by the standard, any value that compares equal to @0@ is false, wh ileany value that compares unequal to @0@ is true.2127 As such, an expression @x@ in any boolean context (such as the condition of an @if@ or @while@ statement, or the arguments to @&&@, @||@, or @?:@\,) can be rewritten as @x != 0@ without changing its semantics.2170 by the standard, any value that compares equal to @0@ is false, whereas any value that compares unequal to @0@ is true. 2171 As such, an expression @x@ in any Boolean context (such as the condition of an @if@ or @while@ statement, or the arguments to @&&@, @||@, or @?:@\,) can be rewritten as @x != 0@ without changing its semantics. 2128 2172 Operator overloading in \CFA provides a natural means to implement this truth-value comparison for arbitrary types, but the C type system is not precise enough to distinguish an equality comparison with @0@ from an equality comparison with an arbitrary integer or pointer. 2129 2173 To provide this precision, \CFA introduces a new type @zero_t@ as the type of literal @0@ (somewhat analagous to @nullptr_t@ and @nullptr@ in \CCeleven); … … 2131 2175 With this addition, \CFA rewrites @if (x)@ and similar expressions to @if ( (x) != 0 )@ or the appropriate analogue, and any type @T@ is ``truthy'' by defining an operator overload @int ?!=?( T, zero_t )@. 2132 2176 \CC makes types truthy by adding a conversion to @bool@; 2133 prior to the addition of explicit cast operators in \CCeleven, this approach had the pitfall of making truthy types transitively convert ableto any numeric type;2177 prior to the addition of explicit cast operators in \CCeleven, this approach had the pitfall of making truthy types transitively convertible into any numeric type; 2134 2178 \CFA avoids this issue. 2135 2179 … … 2142 2186 2143 2187 2144 \subsection{User Literals}2188 \subsection{User literals} 2145 2189 2146 2190 For readability, it is useful to associate units to scale literals, \eg weight (stone, pound, kilogram) or time (seconds, minutes, hours). 2147 The left of Figure~\ref{f:UserLiteral} shows the \CFA alternative call -syntax (postfix: literal argument before function name), using the backquote, to convert basic literals into user literals.2191 The left of Figure~\ref{f:UserLiteral} shows the \CFA alternative call syntax (postfix: literal argument before function name), using the backquote, to convert basic literals into user literals. 2148 2192 The backquote is a small character, making the unit (function name) predominate. 2149 For examples, the multi -precision integer-type in Section~\ref{s:MultiPrecisionIntegers} has user literals:2193 For examples, the multiprecision integer type in Section~\ref{s:MultiPrecisionIntegers} has the following user literals. 2150 2194 {\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}} 2151 2195 \begin{cfa} … … 2153 2197 y = "12345678901234567890123456789"|`mp| + "12345678901234567890123456789"|`mp|; 2154 2198 \end{cfa} 2155 Because \CFA uses a standard function, all types and literals are applicable, as well as overloading and conversions, where @?`@ denotes a postfix-function name and @`@ denotes a postfix-function call.2199 Because \CFA uses a standard function, all types and literals are applicable, as well as overloading and conversions, where @?`@ denotes a postfix-function name and @`@ denotes a postfix-function call. 2156 2200 }% 2157 2201 \begin{cquote} … … 2195 2239 \end{cquote} 2196 2240 2197 The right of Figure~\ref{f:UserLiteral} shows the equivalent \CC version using the underscore for the call -syntax.2241 The right of Figure~\ref{f:UserLiteral} shows the equivalent \CC version using the underscore for the call syntax. 2198 2242 However, \CC restricts the types, \eg @unsigned long long int@ and @long double@ to represent integral and floating literals. 2199 2243 After which, user literals must match (no conversions); … … 2202 2246 \begin{figure} 2203 2247 \centering 2248 \fontsize{9bp}{11bp}\selectfont 2204 2249 \lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}} 2205 2250 \lstDeleteShortInline@% … … 2257 2302 \end{tabular} 2258 2303 \lstMakeShortInline@% 2259 \caption{User Literal}2304 \caption{User literal} 2260 2305 \label{f:UserLiteral} 2261 2306 \end{figure} … … 2265 2310 \label{sec:libraries} 2266 2311 2267 As stated in Section~\ref{sec:poly-fns}, \CFA inherits a large corpus of library code, where other programming languages must rewrite or provide fragile inter -language communication with C.2312 As stated in Section~\ref{sec:poly-fns}, \CFA inherits a large corpus of library code, where other programming languages must rewrite or provide fragile interlanguage communication with C. 2268 2313 \CFA has replacement libraries condensing hundreds of existing C names into tens of \CFA overloaded names, all without rewriting the actual computations. 2269 In many cases, the interface is an inline wrapper providing overloading during compilation but zero cost at runtime.2314 In many cases, the interface is an inline wrapper providing overloading during compilation but of zero cost at runtime. 2270 2315 The following sections give a glimpse of the interface reduction to many C libraries. 2271 2316 In many cases, @signed@/@unsigned@ @char@, @short@, and @_Complex@ functions are available (but not shown) to ensure expression computations remain in a single type, as conversions can distort results. … … 2275 2320 2276 2321 C library @limits.h@ provides lower and upper bound constants for the basic types. 2277 \CFA name overloading is used to condense these typed constants , \eg:2322 \CFA name overloading is used to condense these typed constants. 2278 2323 \begin{cquote} 2279 2324 \lstDeleteShortInline@% … … 2294 2339 \lstMakeShortInline@% 2295 2340 \end{cquote} 2296 The result is a significant reduction in names to access typed constants , \eg:2341 The result is a significant reduction in names to access typed constants. 2297 2342 \begin{cquote} 2298 2343 \lstDeleteShortInline@% … … 2320 2365 2321 2366 C library @math.h@ provides many mathematical functions. 2322 \CFA function overloading is used to condense these mathematical functions , \eg:2367 \CFA function overloading is used to condense these mathematical functions. 2323 2368 \begin{cquote} 2324 2369 \lstDeleteShortInline@% … … 2339 2384 \lstMakeShortInline@% 2340 2385 \end{cquote} 2341 The result is a significant reduction in names to access math functions , \eg:2386 The result is a significant reduction in names to access math functions. 2342 2387 \begin{cquote} 2343 2388 \lstDeleteShortInline@% … … 2358 2403 \lstMakeShortInline@% 2359 2404 \end{cquote} 2360 While \Celeven has type-generic math ~\cite[\S~7.25]{C11}in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a function name with a single set of floating type(s).2405 While \Celeven has type-generic math (see section~7.25 of the ISO/IEC 9899\cite{C11}) in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a function name with a single set of floating type(s). 2361 2406 For example, it is impossible to overload @atan@ for both one and two arguments; 2362 instead the names @atan@ and @atan2@ are required (see Section~\ref{s:NameOverloading}).2363 The key observation is that only a restricted set of type-generic macros areprovided for a limited set of function names, which do not generalize across the type system, as in \CFA.2407 instead, the names @atan@ and @atan2@ are required (see Section~\ref{s:NameOverloading}). 2408 The key observation is that only a restricted set of type-generic macros is provided for a limited set of function names, which do not generalize across the type system, as in \CFA. 2364 2409 2365 2410 … … 2367 2412 2368 2413 C library @stdlib.h@ provides many general functions. 2369 \CFA function overloading is used to condense these utility functions , \eg:2414 \CFA function overloading is used to condense these utility functions. 2370 2415 \begin{cquote} 2371 2416 \lstDeleteShortInline@% … … 2386 2431 \lstMakeShortInline@% 2387 2432 \end{cquote} 2388 The result is a significant reduction in names to access utility functions, \eg:2433 The result is a significant reduction in names to access the utility functions. 2389 2434 \begin{cquote} 2390 2435 \lstDeleteShortInline@% … … 2405 2450 \lstMakeShortInline@% 2406 2451 \end{cquote} 2407 In addit on, there are polymorphic functions, like @min@ and @max@, that work on any type with operators@?<?@ or @?>?@.2452 In addition, there are polymorphic functions, like @min@ and @max@, that work on any type with operator @?<?@ or @?>?@. 2408 2453 2409 2454 The following shows one example where \CFA \emph{extends} an existing standard C interface to reduce complexity and provide safety. 2410 C/\Celeven provide a number of complex and overlapping storage-management operation to support the following capabilities:2411 \begin{ description}%[topsep=3pt,itemsep=2pt,parsep=0pt]2455 C/\Celeven provide a number of complex and overlapping storage-management operations to support the following capabilities. 2456 \begin{list}{}{\itemsep=0pt\parsep=0pt\labelwidth=0pt\leftmargin\parindent\itemindent-\leftmargin\let\makelabel\descriptionlabel} 2412 2457 \item[fill] 2413 2458 an allocation with a specified character. 2414 2459 \item[resize] 2415 2460 an existing allocation to decrease or increase its size. 2416 In either case, new storage may or may not be allocated and, if there is a new allocation, as much data from the existing allocation iscopied.2461 In either case, new storage may or may not be allocated, and if there is a new allocation, as much data from the existing allocation are copied. 2417 2462 For an increase in storage size, new storage after the copied data may be filled. 2463 \newpage 2418 2464 \item[align] 2419 2465 an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes. … … 2421 2467 allocation with a specified number of elements. 2422 2468 An array may be filled, resized, or aligned. 2423 \end{ description}2424 Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation -functions and how all the capabilities can be combined into two \CFA functions.2425 \CFA storage-management functions extend the C equivalents by overloading, providing shallow type -safety, and removing the need to specify the base allocation-size.2426 Figure~\ref{f:StorageAllocation} contrasts \CFA and C storage -allocation performing the same operations with the same type safety.2469 \end{list} 2470 Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation functions and how all the capabilities can be combined into two \CFA functions. 2471 \CFA storage-management functions extend the C equivalents by overloading, providing shallow type safety, and removing the need to specify the base allocation size. 2472 Figure~\ref{f:StorageAllocation} contrasts \CFA and C storage allocation performing the same operations with the same type safety. 2427 2473 2428 2474 \begin{table} 2429 \caption{Storage- Management Operations}2475 \caption{Storage-management operations} 2430 2476 \label{t:StorageManagementOperations} 2431 2477 \centering 2432 2478 \lstDeleteShortInline@% 2433 2479 \lstMakeShortInline~% 2434 \begin{tabular}{@{}r|r|l|l|l|l@{}} 2435 \multicolumn{1}{c}{}& & \multicolumn{1}{c|}{fill} & resize & align & array \\ 2436 \hline 2480 \begin{tabular}{@{}rrllll@{}} 2481 \multicolumn{1}{c}{}& & \multicolumn{1}{c}{fill} & resize & align & array \\ 2437 2482 C & ~malloc~ & no & no & no & no \\ 2438 2483 & ~calloc~ & yes (0 only) & no & no & yes \\ … … 2440 2485 & ~memalign~ & no & no & yes & no \\ 2441 2486 & ~posix_memalign~ & no & no & yes & no \\ 2442 \hline2443 2487 C11 & ~aligned_alloc~ & no & no & yes & no \\ 2444 \hline2445 2488 \CFA & ~alloc~ & yes/copy & no/yes & no & yes \\ 2446 2489 & ~align_alloc~ & yes & no & yes & yes \\ … … 2452 2495 \begin{figure} 2453 2496 \centering 2497 \fontsize{9bp}{11bp}\selectfont 2454 2498 \begin{cfa}[aboveskip=0pt,xleftmargin=0pt] 2455 2499 size_t dim = 10; $\C{// array dimension}$ … … 2489 2533 \end{tabular} 2490 2534 \lstMakeShortInline@% 2491 \caption{\CFA versus C Storage-Allocation}2535 \caption{\CFA versus C storage allocation} 2492 2536 \label{f:StorageAllocation} 2493 2537 \end{figure} 2494 2538 2495 2539 Variadic @new@ (see Section~\ref{sec:variadic-tuples}) cannot support the same overloading because extra parameters are for initialization. 2496 Hence, there are @new@ and @anew@ functions for single and array variables, and the fill value is the arguments to the constructor , \eg:2540 Hence, there are @new@ and @anew@ functions for single and array variables, and the fill value is the arguments to the constructor. 2497 2541 \begin{cfa} 2498 2542 struct S { int i, j; }; … … 2501 2545 S * as = anew( dim, 2, 3 ); $\C{// each array element initialized to 2, 3}$ 2502 2546 \end{cfa} 2503 Note ,\CC can only initialize array elements via the default constructor.2504 2505 Finally, the \CFA memory -allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap.2547 Note that \CC can only initialize array elements via the default constructor. 2548 2549 Finally, the \CFA memory allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap. 2506 2550 When a @realloc@ is performed, the sticky properties are respected, so that new storage is correctly aligned and initialized with the fill character. 2507 2551 … … 2510 2554 \label{s:IOLibrary} 2511 2555 2512 The goal of \CFA I/O is to simplify the common cases, while fully supporting polymorphism and user defined types in a consistent way.2556 The goal of \CFA I/O is to simplify the common cases, while fully supporting polymorphism and user-defined types in a consistent way. 2513 2557 The approach combines ideas from \CC and Python. 2514 2558 The \CFA header file for the I/O library is @fstream@. … … 2539 2583 \lstMakeShortInline@% 2540 2584 \end{cquote} 2541 The \CFA form has half the characters of the \CC form ,and is similar to Python I/O with respect to implicit separators.2585 The \CFA form has half the characters of the \CC form and is similar to Python I/O with respect to implicit separators. 2542 2586 Similar simplification occurs for tuple I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''. 2543 2587 \begin{cfa} … … 2572 2616 \lstMakeShortInline@% 2573 2617 \end{cquote} 2574 There is a weak similarity between the \CFA logical-or operator and the Shell pipe -operator for moving data, where data flows in the correct direction for input butthe opposite direction for output.2618 There is a weak similarity between the \CFA logical-or operator and the Shell pipe operator for moving data, where data flow in the correct direction for input but in the opposite direction for output. 2575 2619 \begin{comment} 2576 2620 The implicit separator character (space/blank) is a separator not a terminator. … … 2593 2637 \end{itemize} 2594 2638 \end{comment} 2595 There are functions to set and get the separator string ,and manipulators to toggle separation on and off in the middle of output.2596 2597 2598 \subsection{Multi -precision Integers}2639 There are functions to set and get the separator string and manipulators to toggle separation on and off in the middle of output. 2640 2641 2642 \subsection{Multiprecision integers} 2599 2643 \label{s:MultiPrecisionIntegers} 2600 2644 2601 \CFA has an interface to the G MP multi-precision signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.2602 The \CFA interface wraps GMP functions into operator functions to make programming with multi -precision integers identical to using fixed-sized integers.2603 The \CFA type name for multi -precision signed-integers is @Int@ and the header file is @gmp@.2604 Figure~\ref{f:GMPInterface} shows a multi -precision factorial-program contrasting the GMP interface in \CFA and C.2605 2606 \begin{figure} 2645 \CFA has an interface to the GNU multiple precision (GMP) signed integers~\cite{GMP}, similar to the \CC interface provided by GMP. 2646 The \CFA interface wraps GMP functions into operator functions to make programming with multiprecision integers identical to using fixed-sized integers. 2647 The \CFA type name for multiprecision signed integers is @Int@ and the header file is @gmp@. 2648 Figure~\ref{f:GMPInterface} shows a multiprecision factorial program contrasting the GMP interface in \CFA and C. 2649 2650 \begin{figure}[b] 2607 2651 \centering 2652 \fontsize{9bp}{11bp}\selectfont 2608 2653 \lstDeleteShortInline@% 2609 2654 \begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}} … … 2636 2681 \end{tabular} 2637 2682 \lstMakeShortInline@% 2638 \caption{GMP Interface \CFA versus C}2683 \caption{GMP interface \CFA versus C} 2639 2684 \label{f:GMPInterface} 2640 2685 \end{figure} 2641 2686 2642 2687 2688 \vspace{-4pt} 2643 2689 \section{Polymorphism Evaluation} 2644 2690 \label{sec:eval} … … 2649 2695 % Though \CFA provides significant added functionality over C, these features have a low runtime penalty. 2650 2696 % In fact, it is shown that \CFA's generic programming can enable faster runtime execution than idiomatic @void *@-based C code. 2651 The experiment is a set of generic-stack micro -benchmarks~\cite{CFAStackEvaluation} in C, \CFA, and \CC (see implementations in Appendix~\ref{sec:BenchmarkStackImplementations}).2697 The experiment is a set of generic-stack microbenchmarks~\cite{CFAStackEvaluation} in C, \CFA, and \CC (see implementations in Appendix~\ref{sec:BenchmarkStackImplementations}). 2652 2698 Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks should show little runtime variance, differing only in length and clarity of source code. 2653 2699 A more illustrative comparison measures the costs of idiomatic usage of each language's features. 2654 Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked -list.2700 Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked list. 2655 2701 The benchmark test is similar for the other languages. 2656 2702 The experiment uses element types @int@ and @pair(short, char)@, and pushes $N=40M$ elements on a generic stack, copies the stack, clears one of the stacks, and finds the maximum value in the other stack. 2657 2703 2658 2704 \begin{figure} 2705 \fontsize{9bp}{11bp}\selectfont 2659 2706 \begin{cfa}[xleftmargin=3\parindentlnth,aboveskip=0pt,belowskip=0pt] 2660 2707 int main() { … … 2676 2723 } 2677 2724 \end{cfa} 2678 \caption{\protect\CFA Benchmark Test}2725 \caption{\protect\CFA benchmark test} 2679 2726 \label{fig:BenchmarkTest} 2727 \vspace*{-10pt} 2680 2728 \end{figure} 2681 2729 2682 The structure of each benchmark implemented is :C with @void *@-based polymorphism, \CFA with parametric polymorphism, \CC with templates, and \CC using only class inheritance for polymorphism, called \CCV.2730 The structure of each benchmark implemented is C with @void *@-based polymorphism, \CFA with parametric polymorphism, \CC with templates, and \CC using only class inheritance for polymorphism, called \CCV. 2683 2731 The \CCV variant illustrates an alternative object-oriented idiom where all objects inherit from a base @object@ class, mimicking a Java-like interface; 2684 hence runtime checks are necessary to safely down-cast objects.2685 The most notable difference among the implementations is in memory layout of generic types: \CFA and \CC inline the stack and pair elements into corresponding list and pair nodes, wh ile C and \CCV lack such a capability and instead must store generic objects via pointers to separately-allocated objects.2686 Note , the C benchmark uses unchecked casts as C has no runtime mechanism to perform such checks, while \CFA and \CC provide type-safety statically.2732 hence, runtime checks are necessary to safely downcast objects. 2733 The most notable difference among the implementations is in memory layout of generic types: \CFA and \CC inline the stack and pair elements into corresponding list and pair nodes, whereas C and \CCV lack such capability and, instead, must store generic objects via pointers to separately allocated objects. 2734 Note that the C benchmark uses unchecked casts as C has no runtime mechanism to perform such checks, whereas \CFA and \CC provide type safety statically. 2687 2735 2688 2736 Figure~\ref{fig:eval} and Table~\ref{tab:eval} show the results of running the benchmark in Figure~\ref{fig:BenchmarkTest} and its C, \CC, and \CCV equivalents. 2689 The graph plots the median of 5consecutive runs of each program, with an initial warm-up run omitted.2737 The graph plots the median of five consecutive runs of each program, with an initial warm-up run omitted. 2690 2738 All code is compiled at \texttt{-O2} by gcc or g++ 6.4.0, with all \CC code compiled as \CCfourteen. 2691 2739 The benchmarks are run on an Ubuntu 16.04 workstation with 16 GB of RAM and a 6-core AMD FX-6300 CPU with 3.5 GHz maximum clock frequency. … … 2693 2741 \begin{figure} 2694 2742 \centering 2695 \ input{timing}2696 \caption{Benchmark Timing Results (smaller is better)}2743 \resizebox{0.7\textwidth}{!}{\input{timing}} 2744 \caption{Benchmark timing results (smaller is better)} 2697 2745 \label{fig:eval} 2746 \vspace*{-10pt} 2698 2747 \end{figure} 2699 2748 2700 2749 \begin{table} 2750 \vspace*{-10pt} 2701 2751 \caption{Properties of benchmark code} 2702 2752 \label{tab:eval} 2703 2753 \centering 2754 \vspace*{-4pt} 2704 2755 \newcommand{\CT}[1]{\multicolumn{1}{c}{#1}} 2705 \begin{tabular}{ rrrrr}2706 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV} \\ \hline2707 maximum memory usage (MB) & 10 ,001 & 2,502 & 2,503 & 11,253 \\2756 \begin{tabular}{lrrrr} 2757 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV} \\ 2758 maximum memory usage (MB) & 10\,001 & 2\,502 & 2\,503 & 11\,253 \\ 2708 2759 source code size (lines) & 201 & 191 & 125 & 294 \\ 2709 2760 redundant type annotations (lines) & 27 & 0 & 2 & 16 \\ 2710 2761 binary size (KB) & 14 & 257 & 14 & 37 \\ 2711 2762 \end{tabular} 2763 \vspace*{-16pt} 2712 2764 \end{table} 2713 2765 2714 The C and \CCV variants are generally the slowest with the largest memory footprint, because of their less-efficient memory layout and the pointer-indirection necessary to implement generic types; 2766 \enlargethispage{-10pt} 2767 The C and \CCV variants are generally the slowest with the largest memory footprint, due to their less-efficient memory layout and the pointer indirection necessary to implement generic types; 2715 2768 this inefficiency is exacerbated by the second level of generic types in the pair benchmarks. 2716 By contrast, the \CFA and \CC variants run in roughly equivalent time for both the integer and pair because of equivalent storage layout, with the inlined libraries (\ie no separate compilation) and greater maturity of the \CC compiler contributing to its lead.2717 \CCV is slower than C largely due to the cost of runtime type -checking of down-casts (implemented with @dynamic_cast@);2769 By contrast, the \CFA and \CC variants run in roughly equivalent time for both the integer and pair because of the equivalent storage layout, with the inlined libraries (\ie no separate compilation) and greater maturity of the \CC compiler contributing to its lead. 2770 \CCV is slower than C largely due to the cost of runtime type checking of downcasts (implemented with @dynamic_cast@). 2718 2771 The outlier for \CFA, pop @pair@, results from the complexity of the generated-C polymorphic code. 2719 2772 The gcc compiler is unable to optimize some dead code and condense nested calls; … … 2721 2774 Finally, the binary size for \CFA is larger because of static linking with the \CFA libraries. 2722 2775 2723 \CFA is also competitive in terms of source code size, measured as a proxy for programmer effort. The line counts in Table~\ref{tab:eval} include implementations of @pair@ and @stack@ types for all four languages for purposes of direct comparison, though it should be noted that \CFA and \CC have pre-written data structures in their standard libraries that programmers would generally use instead. Use of these standard library types has minimal impact on the performance benchmarks, but shrinks the \CFA and \CC benchmarks to 39 and 42 lines, respectively.2776 \CFA is also competitive in terms of source code size, measured as a proxy for programmer effort. The line counts in Table~\ref{tab:eval} include implementations of @pair@ and @stack@ types for all four languages for purposes of direct comparison, although it should be noted that \CFA and \CC have prewritten data structures in their standard libraries that programmers would generally use instead. Use of these standard library types has minimal impact on the performance benchmarks, but shrinks the \CFA and \CC benchmarks to 39 and 42 lines, respectively. 2724 2777 The difference between the \CFA and \CC line counts is primarily declaration duplication to implement separate compilation; a header-only \CFA library would be similar in length to the \CC version. 2725 On the other hand, C does not have a generic collections -library in its standard distribution, resulting in frequent reimplementation of such collection types by C programmers.2726 \CCV does not use the \CC standard template library by construction , and in factincludes the definition of @object@ and wrapper classes for @char@, @short@, and @int@ in its line count, which inflates this count somewhat, as an actual object-oriented language would include these in the standard library;2778 On the other hand, C does not have a generic collections library in its standard distribution, resulting in frequent reimplementation of such collection types by C programmers. 2779 \CCV does not use the \CC standard template library by construction and, in fact, includes the definition of @object@ and wrapper classes for @char@, @short@, and @int@ in its line count, which inflates this count somewhat, as an actual object-oriented language would include these in the standard library; 2727 2780 with their omission, the \CCV line count is similar to C. 2728 2781 We justify the given line count by noting that many object-oriented languages do not allow implementing new interfaces on library types without subclassing or wrapper types, which may be similarly verbose. 2729 2782 2730 Line -count is a fairly rough measure of code complexity;2731 another important factor is how much type information the programmer must specify manually, especially where that information is not compiler -checked.2732 Such unchecked type information produces a heavier documentation burden and increased potential for runtime bugs ,and is much less common in \CFA than C, with its manually specified function pointer arguments and format codes, or \CCV, with its extensive use of un-type-checked downcasts, \eg @object@ to @integer@ when popping a stack.2783 Line count is a fairly rough measure of code complexity; 2784 another important factor is how much type information the programmer must specify manually, especially where that information is not compiler checked. 2785 Such unchecked type information produces a heavier documentation burden and increased potential for runtime bugs and is much less common in \CFA than C, with its manually specified function pointer arguments and format codes, or \CCV, with its extensive use of un-type-checked downcasts, \eg @object@ to @integer@ when popping a stack. 2733 2786 To quantify this manual typing, the ``redundant type annotations'' line in Table~\ref{tab:eval} counts the number of lines on which the type of a known variable is respecified, either as a format specifier, explicit downcast, type-specific function, or by name in a @sizeof@, struct literal, or @new@ expression. 2734 The \CC benchmark uses two redundant type annotations to create a new stack nodes, wh ilethe C and \CCV benchmarks have several such annotations spread throughout their code.2787 The \CC benchmark uses two redundant type annotations to create a new stack nodes, whereas the C and \CCV benchmarks have several such annotations spread throughout their code. 2735 2788 The \CFA benchmark is able to eliminate all redundant type annotations through use of the polymorphic @alloc@ function discussed in Section~\ref{sec:libraries}. 2736 2789 2737 We conjecture these results scale across most generic data-types as the underlying polymorphism implement is constant. 2738 2739 2790 We conjecture that these results scale across most generic data types as the underlying polymorphism implement is constant. 2791 2792 2793 \vspace*{-8pt} 2740 2794 \section{Related Work} 2741 2795 \label{s:RelatedWork} … … 2753 2807 \CC provides three disjoint polymorphic extensions to C: overloading, inheritance, and templates. 2754 2808 The overloading is restricted because resolution does not use the return type, inheritance requires learning object-oriented programming and coping with a restricted nominal-inheritance hierarchy, templates cannot be separately compiled resulting in compilation/code bloat and poor error messages, and determining how these mechanisms interact and which to use is confusing. 2755 In contrast, \CFA has a single facility for polymorphic code supporting type-safe separate -compilation of polymorphic functions and generic (opaque) types, which uniformly leverage the C procedural paradigm.2809 In contrast, \CFA has a single facility for polymorphic code supporting type-safe separate compilation of polymorphic functions and generic (opaque) types, which uniformly leverage the C procedural paradigm. 2756 2810 The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed type properties. 2757 Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specifythe requirements of a generic function beyond compilation errors during template expansion;2811 Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way of specifying the requirements of a generic function beyond compilation errors during template expansion; 2758 2812 furthermore, \CC concepts are restricted to template polymorphism. 2759 2813 2760 2814 Cyclone~\cite{Grossman06} also provides capabilities for polymorphic functions and existential types, similar to \CFA's @forall@ functions and generic types. 2761 Cyclone existential types can include function pointers in a construct similar to a virtual function -table, but these pointers must be explicitly initialized at some point in the code,a tedious and potentially error-prone process.2815 Cyclone existential types can include function pointers in a construct similar to a virtual function table, but these pointers must be explicitly initialized at some point in the code, which is a tedious and potentially error-prone process. 2762 2816 Furthermore, Cyclone's polymorphic functions and types are restricted to abstraction over types with the same layout and calling convention as @void *@, \ie only pointer types and @int@. 2763 2817 In \CFA terms, all Cyclone polymorphism must be dtype-static. 2764 2818 While the Cyclone design provides the efficiency benefits discussed in Section~\ref{sec:generic-apps} for dtype-static polymorphism, it is more restrictive than \CFA's general model. 2765 Smith and Volpano~\cite{Smith98} present Polymorphic C, an ML dialect with polymorphic functions, C-like syntax, and pointer types; it lacks many of C's features, however, most notably structure types, and so is not a practical C replacement. 2819 Smith and Volpano~\cite{Smith98} present Polymorphic C, an ML dialect with polymorphic functions, C-like syntax, and pointer types; 2820 it lacks many of C's features, most notably structure types, and hence, is not a practical C replacement. 2766 2821 2767 2822 Objective-C~\cite{obj-c-book} is an industrially successful extension to C. 2768 However, Objective-C is a radical departure from C, using an object-oriented model with message -passing.2823 However, Objective-C is a radical departure from C, using an object-oriented model with message passing. 2769 2824 Objective-C did not support type-checked generics until recently \cite{xcode7}, historically using less-efficient runtime checking of object types. 2770 The GObject~\cite{GObject} framework also adds object-oriented programming with runtime type-checking and reference-counting garbage -collection to C;2771 these features are more intrusive additions than those provided by \CFA, in addition to the runtime overhead of reference -counting.2772 Vala~\cite{Vala} compiles to GObject-based C, adding the burden of learning a separate language syntax to the aforementioned demerits of GObject as a modernization path for existing C code -bases.2773 Java~\cite{Java8} included generic types in Java~5, which are type -checked at compilation and type-erased at runtime, similar to \CFA's.2774 However, in Java, each object carries its own table of method pointers, wh ile\CFA passes the method pointers separately to maintain a C-compatible layout.2825 The GObject~\cite{GObject} framework also adds object-oriented programming with runtime type-checking and reference-counting garbage collection to C; 2826 these features are more intrusive additions than those provided by \CFA, in addition to the runtime overhead of reference counting. 2827 Vala~\cite{Vala} compiles to GObject-based C, adding the burden of learning a separate language syntax to the aforementioned demerits of GObject as a modernization path for existing C code bases. 2828 Java~\cite{Java8} included generic types in Java~5, which are type checked at compilation and type erased at runtime, similar to \CFA's. 2829 However, in Java, each object carries its own table of method pointers, whereas \CFA passes the method pointers separately to maintain a C-compatible layout. 2775 2830 Java is also a garbage-collected, object-oriented language, with the associated resource usage and C-interoperability burdens. 2776 2831 2777 D~\cite{D}, Go, and Rust~\cite{Rust} are modern , compiled languages with abstraction features similar to \CFA traits, \emph{interfaces} in D and Goand \emph{traits} in Rust.2832 D~\cite{D}, Go, and Rust~\cite{Rust} are modern compiled languages with abstraction features similar to \CFA traits, \emph{interfaces} in D and Go, and \emph{traits} in Rust. 2778 2833 However, each language represents a significant departure from C in terms of language model, and none has the same level of compatibility with C as \CFA. 2779 2834 D and Go are garbage-collected languages, imposing the associated runtime overhead. 2780 2835 The necessity of accounting for data transfer between managed runtimes and the unmanaged C runtime complicates foreign-function interfaces to C. 2781 2836 Furthermore, while generic types and functions are available in Go, they are limited to a small fixed set provided by the compiler, with no language facility to define more. 2782 D restricts garbage collection to its own heap by default, wh ile Rust is not garbage-collected, and thushas a lighter-weight runtime more interoperable with C.2837 D restricts garbage collection to its own heap by default, whereas Rust is not garbage collected and, thus, has a lighter-weight runtime more interoperable with C. 2783 2838 Rust also possesses much more powerful abstraction capabilities for writing generic code than Go. 2784 On the other hand, Rust's borrow -checker provides strong safety guarantees but is complex and difficult to learn and imposes a distinctly idiomatic programming style.2839 On the other hand, Rust's borrow checker provides strong safety guarantees but is complex and difficult to learn and imposes a distinctly idiomatic programming style. 2785 2840 \CFA, with its more modest safety features, allows direct ports of C code while maintaining the idiomatic style of the original source. 2786 2841 2787 2842 2788 \subsection{Tuples/Variadics} 2789 2843 \vspace*{-18pt} 2844 \subsection{Tuples/variadics} 2845 2846 \vspace*{-5pt} 2790 2847 Many programming languages have some form of tuple construct and/or variadic functions, \eg SETL, C, KW-C, \CC, D, Go, Java, ML, and Scala. 2791 2848 SETL~\cite{SETL} is a high-level mathematical programming language, with tuples being one of the primary data types. 2792 2849 Tuples in SETL allow subscripting, dynamic expansion, and multiple assignment. 2793 C provides variadic functions through @va_list@ objects, but the programmer is responsible for managing the number of arguments and their types, so the mechanism is type unsafe. 2850 C provides variadic functions through @va_list@ objects, but the programmer is responsible for managing the number of arguments and their types; 2851 thus, the mechanism is type unsafe. 2794 2852 KW-C~\cite{Buhr94a}, a predecessor of \CFA, introduced tuples to C as an extension of the C syntax, taking much of its inspiration from SETL. 2795 2853 The main contributions of that work were adding MRVF, tuple mass and multiple assignment, and record-member access. 2796 \CCeleven introduced @std::tuple@ as a library variadic template structure.2854 \CCeleven introduced @std::tuple@ as a library variadic-template structure. 2797 2855 Tuples are a generalization of @std::pair@, in that they allow for arbitrary length, fixed-size aggregation of heterogeneous values. 2798 2856 Operations include @std::get<N>@ to extract values, @std::tie@ to create a tuple of references used for assignment, and lexicographic comparisons. 2799 \CCseventeen proposes \emph{structured bindings}~\cite{Sutter15} to eliminate pre -declaring variables anduse of @std::tie@ for binding the results.2800 This extension requires the use of @auto@ to infer the types of the new variables , so complicated expressions with a non-obvious type must be documented with some other mechanism.2857 \CCseventeen proposes \emph{structured bindings}~\cite{Sutter15} to eliminate predeclaring variables and the use of @std::tie@ for binding the results. 2858 This extension requires the use of @auto@ to infer the types of the new variables; hence, complicated expressions with a nonobvious type must be documented with some other mechanism. 2801 2859 Furthermore, structured bindings are not a full replacement for @std::tie@, as it always declares new variables. 2802 2860 Like \CC, D provides tuples through a library variadic-template structure. 2803 2861 Go does not have tuples but supports MRVF. 2804 Java's variadic functions appear similar to C's but are type -safe using homogeneous arrays, which are less useful than \CFA's heterogeneously-typed variadic functions.2862 Java's variadic functions appear similar to C's but are type safe using homogeneous arrays, which are less useful than \CFA's heterogeneously typed variadic functions. 2805 2863 Tuples are a fundamental abstraction in most functional programming languages, such as Standard ML~\cite{sml}, Haskell, and Scala~\cite{Scala}, which decompose tuples using pattern matching. 2806 2864 2807 2865 2866 \vspace*{-18pt} 2808 2867 \subsection{C Extensions} 2809 2868 2810 \CC is the best known C-based language, and is similar to \CFA in that both are extensions to C with source and runtime backwards compatibility. 2811 Specific difference between \CFA and \CC have been identified in prior sections, with a final observation that \CFA has equal or fewer tokens to express the same notion in many cases. 2869 \vspace*{-5pt} 2870 \CC is the best known C-based language and is similar to \CFA in that both are extensions to C with source and runtime backward compatibility. 2871 Specific differences between \CFA and \CC have been identified in prior sections, with a final observation that \CFA has equal or fewer tokens to express the same notion in many cases. 2812 2872 The key difference in design philosophies is that \CFA is easier for C programmers to understand by maintaining a procedural paradigm and avoiding complex interactions among extensions. 2813 2873 \CC, on the other hand, has multiple overlapping features (such as the three forms of polymorphism), many of which have complex interactions with its object-oriented design. 2814 As a result, \CC has a steep learning curve for even experienced C programmers, especially when attempting to maintain performance equivalent to C legacy -code.2815 2816 There are several other C extension -languages with less usage and even more dramatic changes than \CC.2817 Objective-Cand Cyclone are two other extensions to C with different design goals than \CFA, as discussed above.2874 As a result, \CC has a steep learning curve for even experienced C programmers, especially when attempting to maintain performance equivalent to C legacy code. 2875 2876 There are several other C extension languages with less usage and even more dramatic changes than \CC. 2877 \mbox{Objective-C} and Cyclone are two other extensions to C with different design goals than \CFA, as discussed above. 2818 2878 Other languages extend C with more focused features. 2819 2879 $\mu$\CC~\cite{uC++book}, CUDA~\cite{Nickolls08}, ispc~\cite{Pharr12}, and Sierra~\cite{Leissa14} add concurrent or data-parallel primitives to C or \CC; 2820 data-parallel features have not yet been added to \CFA, but are easily incorporated within its design, wh ileconcurrency primitives similar to those in $\mu$\CC have already been added~\cite{Delisle18}.2821 Finally, CCured~\cite{Necula02} and Ironclad \CC~\cite{DeLozier13} attempt to provide a more memory-safe C by annotating pointer types with garbage collection information; type-checked polymorphism in \CFA covers several of C's memory-safety issues, but more aggressive approaches such as annotating all pointer types with their nullability or requiring runtime garbage collection are contradictory to \CFA's backward scompatibility goals.2880 data-parallel features have not yet been added to \CFA, but are easily incorporated within its design, whereas concurrency primitives similar to those in $\mu$\CC have already been added~\cite{Delisle18}. 2881 Finally, CCured~\cite{Necula02} and Ironclad \CC~\cite{DeLozier13} attempt to provide a more memory-safe C by annotating pointer types with garbage collection information; type-checked polymorphism in \CFA covers several of C's memory-safety issues, but more aggressive approaches such as annotating all pointer types with their nullability or requiring runtime garbage collection are contradictory to \CFA's backward compatibility goals. 2822 2882 2823 2883 2824 2884 \section{Conclusion and Future Work} 2825 2885 2826 The goal of \CFA is to provide an evolutionary pathway for large C development -environments to be more productive and safer, while respecting the talent and skill of C programmers.2827 While other programming languages purport to be a better C, they are in factnew and interesting languages in their own right, but not C extensions.2828 The purpose of this paper is to introduce \CFA, and showcase language features that illustrate the \CFA type -system and approaches taken to achieve the goal of evolutionary C extension.2829 The contributions are a powerful type -system using parametric polymorphism and overloading, generic types, tuples, advanced control structures, and extended declarations, which all have complex interactions.2886 The goal of \CFA is to provide an evolutionary pathway for large C development environments to be more productive and safer, while respecting the talent and skill of C programmers. 2887 While other programming languages purport to be a better C, they are, in fact, new and interesting languages in their own right, but not C extensions. 2888 The purpose of this paper is to introduce \CFA, and showcase language features that illustrate the \CFA type system and approaches taken to achieve the goal of evolutionary C extension. 2889 The contributions are a powerful type system using parametric polymorphism and overloading, generic types, tuples, advanced control structures, and extended declarations, which all have complex interactions. 2830 2890 The work is a challenging design, engineering, and implementation exercise. 2831 2891 On the surface, the project may appear as a rehash of similar mechanisms in \CC. 2832 2892 However, every \CFA feature is different than its \CC counterpart, often with extended functionality, better integration with C and its programmers, and always supporting separate compilation. 2833 All of these new features are being used by the \CFA development -team to build the \CFA runtime-system.2893 All of these new features are being used by the \CFA development team to build the \CFA runtime system. 2834 2894 Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable. 2835 2895 2836 While all examples in the paper compile and run, a public beta-release of \CFA will take 6--8 months to reduce compilation time, provide better debugging, and add a few more libraries. 2837 There is also new work on a number of \CFA features, including arrays with size, runtime type-information, virtual functions, user-defined conversions, and modules. 2838 While \CFA polymorphic functions use dynamic virtual-dispatch with low runtime overhead (see Section~\ref{sec:eval}), it is not as low as \CC template-inlining. 2839 Hence it may be beneficial to provide a mechanism for performance-sensitive code. 2840 Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types (\CC template specialization). 2841 These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code-bloat. 2842 In general, we believe separate compilation, producing smaller code, works well with loaded hardware-caches, which may offset the benefit of larger inlined-code. 2896 While all examples in the paper compile and run, there are ongoing efforts to reduce compilation time, provide better debugging, and add more libraries; 2897 when this work is complete in early 2019, a public beta release will be available at \url{https://github.com/cforall/cforall}. 2898 There is also new work on a number of \CFA features, including arrays with size, runtime type information, virtual functions, user-defined conversions, and modules. 2899 While \CFA polymorphic functions use dynamic virtual dispatch with low runtime overhead (see Section~\ref{sec:eval}), it is not as low as \CC template inlining. 2900 Hence, it may be beneficial to provide a mechanism for performance-sensitive code. 2901 Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function definitions to instantiate a specialized version for some set of types (\CC template specialization). 2902 These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code bloat. 2903 In general, we believe separate compilation, producing smaller code, works well with loaded hardware caches, which may offset the benefit of larger inlined code. 2843 2904 2844 2905 2845 2906 \section{Acknowledgments} 2846 2907 2847 The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, Thierry Delisle, Andrew Beach and Brice Dobry on the features described in this paper,and thank Magnus Madsen for feedback on the writing.2848 Funding for this project has been provided by Huawei Ltd.\ (\url{http://www.huawei.com}), and Aaron Moss and Peter Buhr are partially funded by the Natural Sciences and Engineering Research Council of Canada.2908 The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, Thierry Delisle, Andrew Beach, and Brice Dobry on the features described in this paper and thank Magnus Madsen for feedback on the writing. 2909 Funding for this project was provided by Huawei Ltd (\url{http://www.huawei.com}), and Aaron Moss and Peter Buhr were partially funded by the Natural Sciences and Engineering Research Council of Canada. 2849 2910 2850 2911 {% 2851 2912 \fontsize{9bp}{12bp}\selectfont% 2913 \vspace*{-3pt} 2852 2914 \bibliography{pl} 2853 2915 }% … … 2928 2990 2929 2991 2992 \enlargethispage{1000pt} 2930 2993 \subsection{\CFA} 2931 2994 \label{s:CforallStack} … … 2994 3057 2995 3058 3059 \newpage 2996 3060 \subsection{\CC} 2997 3061 -
doc/proposals/ctordtor/Makefile
r7951100 rb067d9b 1 ## Define the appropriateconfiguration variables.1 ## Define the configuration variables. 2 2 3 MACROS = ../../LaTeXmacros 4 BIB = ../../bibliography 3 Build = build 4 Figures = figures 5 Macros = ../../LaTeXmacros 6 Bib = ../../bibliography 5 7 6 TeXLIB = .:$ (MACROS):$(MACROS)/listings:$(MACROS)/enumitem:$(BIB)/:7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error 8 TeXLIB = .:${Macros}:${MACROS}/listings:${MACROS}/enumitem:${Bib}/: 9 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 8 10 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 11 12 MAKEFLAGS = --no-print-directory # --silent 13 VPATH = ${Build} ${Figures} 9 14 10 15 ## Define the text source files. … … 29 34 30 35 DOCUMENT = ctor.pdf 36 BASE = ${basename ${DOCUMENT}} 31 37 32 38 # Directives # 39 40 .PHONY : all clean # not file names 33 41 34 42 all : ${DOCUMENT} 35 43 36 44 clean : 37 rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \ 38 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT} 45 @rm -frv ${DOCUMENT} ${BASE}.ps ${Build} 39 46 40 47 # File Dependencies # 41 48 42 ${DOCUMENT} : ${ basename ${DOCUMENT}}.ps49 ${DOCUMENT} : ${BASE}.ps 43 50 ps2pdf $< 44 51 45 ${ basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi46 dvips $ < -o $@52 ${BASE}.ps : ${BASE}.dvi 53 dvips ${Build}/$< -o $@ 47 54 48 ${ basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex\49 $ (MACROS)/common.tex $(MACROS)/indexstyle $(BIB)/cfa.bib55 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 56 ${Macros}/common.tex ${Macros}/indexstyle ${Bib}/pl.bib | ${Build} 50 57 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 51 if [ ! -r ${basename $@}.ind ] ; then touch${basename $@}.ind ; fi58 #if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi 52 59 # Must have *.aux file containing citations for bibtex 53 60 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi 54 -${BibTeX} ${ basename $@}55 # Some citations reference others so run stepsagain to resolve these citations61 -${BibTeX} ${Build}/${basename $@} 62 # Some citations reference others so run again to resolve these citations 56 63 ${LaTeX} ${basename $@}.tex 57 -${BibTeX} ${ basename $@}64 -${BibTeX} ${Build}/${basename $@} 58 65 # Make index from *.aux entries and input index at end of document 59 makeindex -s $(MACROS)/indexstyle ${basename $@}.idx 66 #makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx 67 # Run again to finish citations 60 68 ${LaTeX} ${basename $@}.tex 61 69 # Run again to get index title into table of contents … … 67 75 ## Define the default recipes. 68 76 69 %.tex : %.fig 70 fig2dev -L eepic $< > $@77 ${Build}: 78 mkdir -p ${Build} 71 79 72 %. ps : %.fig73 fig2dev -L ps $< >$@80 %.tex : %.fig | ${Build} 81 fig2dev -L eepic $< > ${Build}/$@ 74 82 75 %.pstex : %.fig 76 fig2dev -L pstex $< > $@ 77 fig2dev -L pstex_t -p $@ $< > $@_t 83 %.ps : %.fig | ${Build} 84 fig2dev -L ps $< > ${Build}/$@ 85 86 %.pstex : %.fig | ${Build} 87 fig2dev -L pstex $< > ${Build}/$@ 88 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t 78 89 79 90 # Local Variables: # -
doc/proposals/ctordtor/ctor.tex
r7951100 rb067d9b 1 % inline code ©...© (copyright symbol) emacs: C-q M-)2 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-.3 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_4 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-"5 % LaTex escape §...§ (section symbol) emacs: C-q M-'6 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^7 % math escape $...$ (dollar symbol)8 9 1 \documentclass[twoside,11pt]{article} 10 2 … … 15 7 \usepackage{textcomp} 16 8 \usepackage[latin1]{inputenc} 9 17 10 \usepackage{fullpage,times,comment} 18 11 \usepackage{epic,eepic} 19 \usepackage{upquote} % switch curled `'" to straight12 \usepackage{upquote} % switch curled `'" to straight 20 13 \usepackage{calc} 21 14 \usepackage{xspace} 22 15 \usepackage{graphicx} 23 \usepackage{varioref} % extended references24 \usepackage{listings} % format program code25 \usepackage[flushmargin]{footmisc} % support label/reference in footnote16 \usepackage{varioref} % extended references 17 \usepackage{listings} % format program code 18 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 26 19 \usepackage{latexsym} % \Box glyph 27 20 \usepackage{mathptmx} % better math font with "times" … … 34 27 \renewcommand{\UrlFont}{\small\sf} 35 28 36 \setlength{\topmargin}{-0.45in} % move running title into header29 \setlength{\topmargin}{-0.45in} % move running title into header 37 30 \setlength{\headsep}{0.25in} 38 31 … … 43 36 44 37 \interfootnotelinepenalty=10000 38 39 \CFAStyle % use default CFA format-style 40 % inline code ©...© (copyright symbol) emacs: C-q M-) 41 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 42 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ 43 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-" 44 % LaTex escape §...§ (section symbol) emacs: C-q M-' 45 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 46 % math escape $...$ (dollar symbol) 47 45 48 46 49 \title{ … … 83 86 \thispagestyle{plain} 84 87 \pagenumbering{arabic} 85 86 88 87 89 -
doc/proposals/flags.md
r7951100 rb067d9b 60 60 ``` 61 61 FunFlags f = some_val(); 62 if ( f ) { sout | "f has some flag(s) set" | endl; }63 if ( f & FOO ) { sout | "f has FOO set" | endl; }62 if ( f ) { sout | "f has some flag(s) set"; } 63 if ( f & FOO ) { sout | "f has FOO set"; } 64 64 f |= FOO; // set FOO 65 65 f -= FOO; // unset FOO … … 88 88 ``` 89 89 FunFlags f = some_val(); 90 if ( f.FOO ) { sout | "f has FOO set" | endl; }90 if ( f.FOO ) { sout | "f has FOO set"; } 91 91 f.FOO = true; // set FOO 92 92 f.FOO = false; // unset FOO -
doc/proposals/tuples/Makefile
r7951100 rb067d9b 1 ## Define the appropriateconfiguration variables.1 ## Define the configuration variables. 2 2 3 MACROS = ../../LaTeXmacros 4 BIB = ../../bibliography 3 Build = build 4 Figures = figures 5 Macros = ../../LaTeXmacros 6 Bib = ../../bibliography 5 7 6 TeXLIB = .:$ (MACROS):$(MACROS)/listings:$(MACROS)/enumitem:$(BIB)/:7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error 8 TeXLIB = .:${Macros}:${MACROS}/listings:${MACROS}/enumitem:${Bib}/: 9 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 8 10 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 11 12 MAKEFLAGS = --no-print-directory --silent # 13 VPATH = ${Build} ${Figures} 9 14 10 15 ## Define the text source files. … … 29 34 30 35 DOCUMENT = tuples.pdf 36 BASE = ${basename ${DOCUMENT}} 31 37 32 38 # Directives # 39 40 .PHONY : all clean # not file names 33 41 34 42 all : ${DOCUMENT} 35 43 36 44 clean : 37 rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \ 38 ${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT} 45 @rm -frv ${DOCUMENT} ${BASE}.ps ${Build} 39 46 40 47 # File Dependencies # 41 48 42 ${DOCUMENT} : ${ basename ${DOCUMENT}}.ps49 ${DOCUMENT} : ${BASE}.ps 43 50 ps2pdf $< 44 51 45 ${ basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi46 dvips $ < -o $@52 ${BASE}.ps : ${BASE}.dvi 53 dvips ${Build}/$< -o $@ 47 54 48 ${ basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex\49 $ (MACROS)/common.tex $(MACROS)/indexstyle $(BIB)/cfa.bib55 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 56 ${Macros}/common.tex ${Macros}/indexstyle ${Bib}/pl.bib | ${Build} 50 57 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 51 if [ ! -r ${basename $@}.ind ] ; then touch${basename $@}.ind ; fi58 #if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi 52 59 # Must have *.aux file containing citations for bibtex 53 60 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi 54 -${BibTeX} ${ basename $@}55 # Some citations reference others so run stepsagain to resolve these citations61 -${BibTeX} ${Build}/${basename $@} 62 # Some citations reference others so run again to resolve these citations 56 63 ${LaTeX} ${basename $@}.tex 57 -${BibTeX} ${ basename $@}64 -${BibTeX} ${Build}/${basename $@} 58 65 # Make index from *.aux entries and input index at end of document 59 makeindex -s $(MACROS)/indexstyle ${basename $@}.idx 66 #makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx 67 # Run again to finish citations 60 68 ${LaTeX} ${basename $@}.tex 61 69 # Run again to get index title into table of contents … … 67 75 ## Define the default recipes. 68 76 69 %.tex : %.fig 70 fig2dev -L eepic $< > $@77 ${Build}: 78 mkdir -p ${Build} 71 79 72 %. ps : %.fig73 fig2dev -L ps $< >$@80 %.tex : %.fig | ${Build} 81 fig2dev -L eepic $< > ${Build}/$@ 74 82 75 %.pstex : %.fig 76 fig2dev -L pstex $< > $@ 77 fig2dev -L pstex_t -p $@ $< > $@_t 83 %.ps : %.fig | ${Build} 84 fig2dev -L ps $< > ${Build}/$@ 85 86 %.pstex : %.fig | ${Build} 87 fig2dev -L pstex $< > ${Build}/$@ 88 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t 78 89 79 90 # Local Variables: # -
doc/proposals/tuples/tuples.tex
r7951100 rb067d9b 1 % inline code ©...© (copyright symbol) emacs: C-q M-)2 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-.3 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_4 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-"5 % LaTex escape §...§ (section symbol) emacs: C-q M-'6 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^7 % math escape $...$ (dollar symbol)8 9 1 \documentclass[twoside,11pt]{article} 10 2 … … 15 7 \usepackage{textcomp} 16 8 \usepackage[latin1]{inputenc} 9 17 10 \usepackage{fullpage,times,comment} 18 11 \usepackage{epic,eepic} 19 \usepackage{upquote} % switch curled `'" to straight12 \usepackage{upquote} % switch curled `'" to straight 20 13 \usepackage{calc} 21 14 \usepackage{xspace} 22 15 \usepackage{graphicx} 23 \usepackage{varioref} % extended references24 \usepackage{listings} % format program code25 \usepackage[flushmargin]{footmisc} % support label/reference in footnote16 \usepackage{varioref} % extended references 17 \usepackage{listings} % format program code 18 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 26 19 \usepackage{latexsym} % \Box glyph 27 20 \usepackage{mathptmx} % better math font with "times" … … 34 27 \renewcommand{\UrlFont}{\small\sf} 35 28 36 \setlength{\topmargin}{-0.45in} % move running title into header29 \setlength{\topmargin}{-0.45in} % move running title into header 37 30 \setlength{\headsep}{0.25in} 38 31 … … 42 35 43 36 \interfootnotelinepenalty=10000 37 38 \CFAStyle % use default CFA format-style 39 % inline code ©...© (copyright symbol) emacs: C-q M-) 40 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 41 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ 42 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-" 43 % LaTex escape §...§ (section symbol) emacs: C-q M-' 44 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 45 % math escape $...$ (dollar symbol) 46 44 47 45 48 \title{ -
doc/proposals/user_conversions.md
r7951100 rb067d9b 5 5 There is also a set of _explicit_ conversions that are only allowed through a 6 6 cast expression. 7 Based on Glen's notes on conversions [1], I propose that safe and unsafe 8 conversions be expressed as constructor variants, though I make explicit 9 (cast) conversions a constructor variant as well rather than a dedicated 10 operator. 7 I propose that safe, unsafe, and explicit (cast) conversions be expressed as 8 constructor variants. 11 9 Throughout this article, I will use the following operator names for 12 10 constructors and conversion functions from `From` to `To`: 13 11 14 void ?{} ( To*, To ); // copy constructor 15 void ?{} ( To*, From ); // explicit constructor 16 void ?{explicit} ( To*, From ); // explicit cast conversion 17 void ?{safe} ( To*, From ); // implicit safe conversion 18 void ?{unsafe} ( To*, From ); // implicit unsafe conversion 19 20 [1] http://plg.uwaterloo.ca/~cforall/Conversions/index.html 21 22 Glen's design made no distinction between constructors and unsafe implicit 12 void ?{} ( To&, To ); // copy constructor 13 void ?{} ( To&, From ); // explicit constructor 14 void ?{explicit} ( To&, From ); // explicit cast conversion 15 void ?{safe} ( To&, From ); // implicit safe conversion 16 void ?{unsafe} ( To&, From ); // implicit unsafe conversion 17 18 It has been suggested that all constructors would define unsafe implicit 23 19 conversions; this is elegant, but interacts poorly with tuples. 24 20 Essentially, without making this distinction, a constructor like the following … … 26 22 multiplying the space of possible interpretations of all functions: 27 23 28 void ?{}( Coord *this, int x, int y );24 void ?{}( Coord& this, int x, int y ); 29 25 30 26 That said, it would certainly be possible to make a multiple-argument implicit … … 32 28 used infrequently: 33 29 34 void ?{unsafe}( Coord *this, int x, int y );30 void ?{unsafe}( Coord& this, int x, int y ); 35 31 36 32 An alternate possibility would be to only count two-arg constructors 37 `void ?{} ( To *, From )` as unsafe conversions; under this semantics, safe and33 `void ?{} ( To&, From )` as unsafe conversions; under this semantics, safe and 38 34 explicit conversions should also have a compiler-enforced restriction to 39 35 ensure that they are two-arg functions (this restriction may be valuable … … 43 39 is convertable to `To`. 44 40 If user-defined conversions are not added to the language, 45 `void ?{} ( To *, From )` may be a suitable representation, relying on41 `void ?{} ( To&, From )` may be a suitable representation, relying on 46 42 conversions on the argument types to account for transitivity. 47 On the other hand, `To*` should perhaps match its target type exactly, so 48 another assertion syntax specific to conversions may be required, e.g. 49 `From -> To`. 43 Since `To&` should be an exact match on `To`, this should put all the implicit 44 conversions on the RHS. 45 On the other hand, under some models (like [1]), implicit conversions are not 46 allowed in assertion parameters, so another assertion syntax specific to 47 conversions may be required, e.g. `From -> To`. 48 It has also been suggested that, for programmer control, no implicit 49 conversions (except, possibly, for polymorphic specialization) should be 50 allowed in resolution of cast operators. 51 52 [1] ../working/assertion_resolution.md 50 53 51 54 ### Constructor Idiom ### … … 53 56 that we can use the full range of Cforall features for conversions, including 54 57 polymorphism. 55 Glen [1] defines a _constructor idiom_ that can be used to create chains of 56 safe conversions without duplicating code; given a type `Safe` which members 57 of another type `From` can be directly converted to, the constructor idiom 58 allows us to write a conversion for any type `To` which `Safe` converts to: 59 60 forall(otype To | { void ?{safe}( To*, Safe ) }) 61 void ?{safe}( To *this, From that ) { 58 In an earlier version of this proposal, Glen Ditchfield defines a 59 _constructor idiom_ that can be used to create chains of safe conversions 60 without duplicating code; given a type `Safe` which members of another type 61 `From` can be directly converted to, the constructor idiom allows us to write 62 a conversion for any type `To` which `Safe` converts to: 63 64 forall(otype To | { void ?{safe}( To&, Safe ) }) 65 void ?{safe}( To& this, From that ) { 62 66 Safe tmp = /* some expression involving that */; 63 *this = tmp; // usesassertion parameter67 this{ tmp }; // initialize from assertion parameter 64 68 } 65 69 … … 67 71 unsafe conversions. 68 72 73 Glen's original suggestion said the copy constructor for `To` should also be 74 accepted as a resolution for `void ?{safe}( To&, Safe )` (`Safe` == `To`), 75 allowing this same code to be used for the single-step conversion as well. 76 This proposal does come at the cost of an extra copy initialization of the 77 target value, though. 78 79 Contrariwise, if a monomorphic conversion from `From` to `Safe` is written, 80 e.g: 81 82 void ?{safe}( Safe& this, From that ) { 83 this{ /* some parameters involving that */ }; 84 } 85 86 Then the code for a transitive conversion from `From` to any `To` type 87 convertable from `Safe` is written: 88 89 forall(otype To | { void ?{safe}( To&, Safe ) }) 90 void ?{safe}( To& this, From that ) { 91 Safe tmp = that; // uses monomorphic conversion 92 this{ tmp }; // initialize from assertion parameter 93 } 94 95 Given the entirely-boilerplate nature of this code, but negative performance 96 implications of the unmodified constructor idiom, it might be fruitful to have 97 transitive and single step conversion operators, and let CFA build the 98 transitive conversions; some possible names: 99 100 void ?{safe} (To&, From); void ?{final safe} (To&, From); // single-step 101 void ?{safe*} (To&, From); void ?{safe} (To&, From); // transitive 102 69 103 What selective non-use of the constructor idiom gives us is the ability to 70 104 define a conversion that may only be the *last* conversion in a chain of such. 71 Constructing a conversion graph able to unambiguously represent the full 72 hierarchy of implicit conversions in C is provably impossible using only 73 single-step conversions with no additional information (see Appendix A), but 74 this mechanism is sufficiently powerful (see [1], though the design there has 75 some minor bugs; the general idea is to use the constructor idiom to define 76 two chains of conversions, one among the signed integral types, another among 77 the unsigned, and to use monomorphic conversions to allow conversions between 78 signed and unsigned integer types). 105 One use for this is to solve the problem that `explicit` conversions were 106 added to C++ for, that of conversions to `bool` chaining to become conversions 107 to any arithmetic type. 108 Another use is to unambiguously represent the full hierarchy of implicit 109 conversions in C by making sign conversions non-transitive, allowing the 110 compiler to resolve e.g. `int -> unsigned long` as 111 `int -> long -> unsigned long` over `int -> unsigned int -> unsigned long`. 112 See [2] for more details. 113 114 [2] ../working/glen_conversions/index.html#usual 79 115 80 116 ### Appendix A: Partial and Total Orders ### … … 153 189 convert from `int` to `unsigned long`, so we just put in a direct conversion 154 190 and make the compiler smart enough to figure out the costs" - this is the 155 approach taken by the existing compi pler, but given that in a user-defined191 approach taken by the existing compiler, but given that in a user-defined 156 192 conversion proposal the users can build an arbitrary graph of conversions, 157 193 this case still needs to be handled. … … 160 196 exists a chain of conversions from `a` to `b` (see Appendix A for description 161 197 of preorders and related constructs). 162 This preorder corresponds roughlyto a more usual type-theoretic concept of198 This preorder roughly corresponds to a more usual type-theoretic concept of 163 199 subtyping ("if I can convert `a` to `b`, `a` is a more specific type than 164 200 `b`"); however, since this graph is arbitrary, it may contain cycles, so if … … 192 228 and so is considered to be the nearer type. 193 229 By transitivity, then, the conversion from `X` to `Y2` should be cheaper than 194 the conversion from `X` to `W`, but in this case the ` X` and `W` are230 the conversion from `X` to `W`, but in this case the `Y2` and `W` are 195 231 incomparable by the conversion preorder, so the tie is broken by the shorter 196 232 path from `X` to `W` in favour of `W`, contradicting the transitivity property -
doc/refrat/Makefile
r7951100 rb067d9b 53 53 dvips ${Build}/$< -o $@ 54 54 55 ${BASE}.dvi : Makefile ${ Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \56 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib 55 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 56 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib | ${Build} 57 57 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 58 58 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi … … 78 78 mkdir -p ${Build} 79 79 80 %.tex : %.fig ${Build}80 %.tex : %.fig | ${Build} 81 81 fig2dev -L eepic $< > ${Build}/$@ 82 82 83 %.ps : %.fig ${Build}83 %.ps : %.fig | ${Build} 84 84 fig2dev -L ps $< > ${Build}/$@ 85 85 86 %.pstex : %.fig ${Build}86 %.pstex : %.fig | ${Build} 87 87 fig2dev -L pstex $< > ${Build}/$@ 88 88 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t -
doc/user/Makefile
r7951100 rb067d9b 4 4 Figures = figures 5 5 Macros = ../LaTeXmacros 6 TeXLIB = .:${Macros}:${Build}: ../bibliography:6 TeXLIB = .:${Macros}:${Build}: 7 7 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build} 8 BibTeX = BIBINPUTS= ${TeXLIB}&& export BIBINPUTS && bibtex8 BibTeX = BIBINPUTS=../bibliography: && export BIBINPUTS && bibtex 9 9 10 10 MAKEFLAGS = --no-print-directory --silent # … … 51 51 # File Dependencies # 52 52 53 build/version: ../../configure | ${Build} 54 ../../configure --version | grep "cfa-cc configure" | grep -oEe "([0-9]+\.)+[0-9]+" > $@ 55 53 56 ${DOCUMENT} : ${BASE}.ps 54 57 ps2pdf $< … … 57 60 dvips ${Build}/$< -o $@ 58 61 59 ${BASE}.dvi : Makefile ${ Build} ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \60 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib 62 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 63 ${Macros}/common.tex ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build} 61 64 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 62 65 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi … … 76 79 ## Define the default recipes. 77 80 78 ${Build} :81 ${Build} : 79 82 mkdir -p ${Build} 80 83 81 %.tex : %.fig ${Build}84 %.tex : %.fig | ${Build} 82 85 fig2dev -L eepic $< > ${Build}/$@ 83 86 84 %.ps : %.fig ${Build}87 %.ps : %.fig | ${Build} 85 88 fig2dev -L ps $< > ${Build}/$@ 86 89 87 %.pstex : %.fig ${Build}90 %.pstex : %.fig | ${Build} 88 91 fig2dev -L pstex $< > ${Build}/$@ 89 92 fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t -
doc/user/user.tex
r7951100 rb067d9b 1 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 %% 2 %% 3 3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 4 %% 5 5 %% The contents of this file are covered under the licence agreement in the 6 6 %% file "LICENCE" distributed with Cforall. 7 %% 8 %% user.tex -- 9 %% 7 %% 8 %% user.tex -- 9 %% 10 10 %% Author : Peter A. Buhr 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : S un May 6 10:33:53 201814 %% Update Count : 3 31913 %% Last Modified On : Sat Jul 13 18:36:18 2019 14 %% Update Count : 3876 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 72 72 73 73 % Names used in the document. 74 \newcommand{\Version}{\input{ ../../version}}74 \newcommand{\Version}{\input{build/version}} 75 75 \newcommand{\Textbf}[2][red]{{\color{#1}{\textbf{#2}}}} 76 76 \newcommand{\Emph}[2][red]{{\color{#1}\textbf{\emph{#2}}}} … … 146 146 \CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving similar performance. 147 147 Like C, \CFA is a statically typed, procedural (non-\Index{object-oriented}) language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible. 148 The primary new features include p arametric-polymorphic routines and types, exceptions, concurrency, and modules.148 The primary new features include polymorphic routines and types, exceptions, concurrency, and modules. 149 149 150 150 One of the main design philosophies of \CFA is to ``\Index{describe not prescribe}'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''. … … 155 155 As well, new programs can be written in \CFA using a combination of C and \CFA features. 156 156 157 \Index*[C++]{\CC{}} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C.158 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, all of which requiressignificant effort and training to incrementally add \CC to a C-based project.157 \Index*[C++]{\CC{}}~\cite{c++:v1} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C. 158 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project. 159 159 In contrast, \CFA has 30 years of hindsight and a clean starting point. 160 160 161 161 Like \Index*[C++]{\CC{}}, there may be both an old and new ways to achieve the same effect. 162 For example, the following programs compare the \CFA, C, and \CC I/O mechanisms, where the programs output the same result.163 \begin{c quote}162 For example, the following programs compare the C, \CFA, and \CC I/O mechanisms, where the programs output the same result. 163 \begin{center} 164 164 \begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}} 165 165 \multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\ … … 178 178 int main( void ) { 179 179 int x = 0, y = 1, z = 2; 180 ®sout | x | y | z | endl;®§\indexc{sout}§180 ®sout | x | y | z;®§\indexc{sout}§ 181 181 } 182 182 \end{cfa} … … 191 191 \end{cfa} 192 192 \end{tabular} 193 \end{c quote}193 \end{center} 194 194 While the \CFA I/O looks similar to the \Index*[C++]{\CC{}} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see~\VRef{s:IOLibrary}). 195 195 196 196 197 \subsection{Background} 197 198 198 199 This document is a programmer reference-manual for the \CFA programming language. 199 The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of each feature.200 The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of features. 200 201 The manual does not teach programming, \ie how to combine the new constructs to build complex programs. 201 A reader should alreadyhave an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented, as well as some experience programming in C/\CC.202 The reader must have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented, as well as some experience programming in C/\CC. 202 203 Implementers should refer to the \CFA Programming Language Specification for details about the language syntax and semantics. 203 204 Changes to the syntax and additional features are expected to be included in later revisions. … … 206 207 \section{Why fix C?} 207 208 208 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems (especially UNIX systems) to hobby projects.209 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from hobby projects to commercial operating-systems. 209 210 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 210 211 Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction. 211 212 For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is usually the only language of choice. 212 The TIOBE index~\cite{TIOBE} for March 2016 showed the following programming-language popularity: \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC{}} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, where the next 50 languages are less than 3\% eachwith a long tail.213 As well, for 30 years, C has been the number 1 and 2 most popular programming language:213 The TIOBE index~\cite{TIOBE} for July 2018 ranks the top five most \emph{popular} programming languages as \Index*{Java} 16\%, C 14\%, \Index*[C++]{\CC{}} 7.5\%, Python 6\%, Visual Basic 4\% = 47.5\%, where the next 50 languages are less than 4\% each, with a long tail. 214 The top 3 rankings over the past 30 years are: 214 215 \begin{center} 215 \setlength{\tabcolsep}{1.5ex} 216 \begin{tabular}{@{}r|c|c|c|c|c|c|c@{}} 217 Ranking & 2016 & 2011 & 2006 & 2001 & 1996 & 1991 & 1986 \\ 218 \hline 219 Java & 1 & 1 & 1 & 3 & 29 & - & - \\ 220 \hline 221 \R{C} & \R{2} & \R{2} & \R{2} & \R{1} & \R{1} & \R{1} & \R{1} \\ 222 \hline 223 \CC & 3 & 3 & 3 & 2 & 2 & 2 & 7 \\ 216 \setlength{\tabcolsep}{10pt} 217 \begin{tabular}{@{}rccccccc@{}} 218 & 2018 & 2013 & 2008 & 2003 & 1998 & 1993 & 1988 \\ \hline 219 Java & 1 & 2 & 1 & 1 & 16 & - & - \\ 220 \R{C} & \R{2} & \R{1} & \R{2} & \R{2} & \R{1} & \R{1} & \R{1} \\ 221 \CC & 3 & 4 & 3 & 3 & 2 & 2 & 5 \\ 224 222 \end{tabular} 225 223 \end{center} 226 224 Hence, C is still an extremely important programming language, with double the usage of \Index*[C++]{\CC{}}; in many cases, \CC is often used solely as a better C. 227 225 Love it or hate it, C has been an important and influential part of computer science for 40 years and its appeal is not diminishing. 228 Unfortunately, C has many problems and omissions that make it an unacceptable programming language for modern needs.226 Nevertheless, C has many problems and omissions that make it an unacceptable programming language for modern needs. 229 227 230 228 As stated, the goal of the \CFA project is to engineer modern language-features into C in an evolutionary rather than revolutionary way. … … 236 234 These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection. 237 235 As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten. 238 These costs can be prohibitive for many companies with a large software-base in C/\CC, and a significant number of programmers require retraining to the new programming language. 239 240 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixes many of the well known C problems while containing modern language-features. 241 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers; 236 These costs can be prohibitive for many companies with a large software-base in C/\CC, and a significant number of programmers require retraining in the new programming language. 237 238 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixes many of the well known C problems while adding modern language-features. 239 To achieve these goals required a significant engineering exercise, where we had to ``think inside the existing C box''. 240 Without these significant extension to C, it is unable to cope with the needs of modern programming problems and programmers; 242 241 as a result, it will fade into disuse. 243 242 Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language. … … 255 254 \begin{lstlisting} 256 255 ®forall( otype T )® T identity( T val ) { return val; } 257 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§256 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§ 258 257 \end{lstlisting} 259 258 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions. … … 283 282 284 283 double key = 5.0, vals[10] = { /* 10 sorted floating values */ }; 285 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§284 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§ 286 285 \end{lstlisting} 287 286 which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers: … … 292 291 293 292 forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) { 294 T * result = bsearch( key, arr, size ); §\C{// call first version}§295 return result ? result - arr : size; } §\C{// pointer subtraction includes sizeof(T)}§296 297 double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§293 T * result = bsearch( key, arr, size ); §\C{// call first version}§ 294 return result ? result - arr : size; } §\C{// pointer subtraction includes sizeof(T)}§ 295 296 double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§ 298 297 int posn = bsearch( 5.0, vals, 10 ); 299 298 \end{lstlisting} … … 307 306 \begin{lstlisting} 308 307 forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 309 int * ip = malloc(); §\C{// select type and size from left-hand side}§308 int * ip = malloc(); §\C{// select type and size from left-hand side}§ 310 309 double * dp = malloc(); 311 310 struct S {...} * sp = malloc(); … … 318 317 Whereas, \CFA wraps each of these routines into ones with the overloaded name ©abs©: 319 318 \begin{cfa} 320 char abs( char );321 ®extern "C" {® int abs( int ); ®}®§\C{// use default C routine for int}§322 long int abs( long int );323 long long int abs( long long int );324 float abs( float );325 double abs( double );326 long double abs( long double );327 float _Complex abs( float _Complex );328 double _Complex abs( double _Complex );329 long double _Complex abs( long double _Complex );319 char ®abs®( char ); 320 extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§ 321 long int ®abs®( long int ); 322 long long int ®abs®( long long int ); 323 float ®abs®( float ); 324 double ®abs®( double ); 325 long double ®abs®( long double ); 326 float _Complex ®abs®( float _Complex ); 327 double _Complex ®abs®( double _Complex ); 328 long double _Complex ®abs®( long double _Complex ); 330 329 \end{cfa} 331 330 The problem is the name clash between the library routine ©abs© and the \CFA names ©abs©. 332 331 Hence, names appearing in an ©extern "C"© block have \newterm*{C linkage}. 333 332 Then overloading polymorphism uses a mechanism called \newterm{name mangling}\index{mangling!name} to create unique names that are different from C names, which are not mangled. 334 Hence, there is the same need as in \CC, to know if a name is a C or \CFA name, so it can be correctly formed.335 There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type .333 Hence, there is the same need, as in \CC, to know if a name is a C or \CFA name, so it can be correctly formed. 334 There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and types. 336 335 337 336 This example strongly illustrates a core idea in \CFA: \emph{the \Index{power of a name}}. … … 350 349 \begin{description} 351 350 \item 352 \Indexc{-std=gnu 99}\index{compilation option!-std=gnu99@{©-std=gnu99©}}353 The 1999C standard plus GNU extensions.354 \item 355 \Indexc[deletekeywords=inline]{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{\lstinline[deletekeywords=inline] @-fgnu89-inline@}}356 Use the traditional GNU semantics for inline routines in C 99mode, which allows inline routines in header files.351 \Indexc{-std=gnu11}\index{compilation option!-std=gnu11@{©-std=gnu11©}} 352 The 2011 C standard plus GNU extensions. 353 \item 354 \Indexc[deletekeywords=inline]{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{\lstinline[deletekeywords=inline]$-fgnu89-inline$}} 355 Use the traditional GNU semantics for inline routines in C11 mode, which allows inline routines in header files. 357 356 \end{description} 358 357 The following new \CFA options are available: … … 427 426 \begin{cfa} 428 427 #ifndef __CFORALL__ 429 #include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§428 #include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§ 430 429 #else 431 #include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§430 #include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§ 432 431 #endif 433 432 \end{cfa} 434 which conditionally includes the correct header file, if the program is compiled using \Indexc{gcc} or \Indexc{cfa}. 433 which conditionally includes the correct header file, if the program is compiled using \Indexc{gcc} or \Indexc{cfa}. 434 435 The \CFA translator has multiple steps. 436 The following flags control how the tranlator works, the stages run, and printing within a stage. 437 The majority of these flags are used by \CFA developers, but some are occasionally useful to programmers. 438 \begin{description}[topsep=5pt,itemsep=0pt,parsep=0pt] 439 \item 440 \Indexc{-h}\index{translator option!-h@{©-h©}}, \Indexc{--help}\index{translator option!--help@{©--help©}} \, print help message 441 \item 442 \Indexc{-l}\index{translator option!-l@{©-l©}}, \Indexc{--libcfa}\index{translator option!--libcfa@{©--libcfa©}} \, generate libcfa.c 443 \item 444 \Indexc{-L}\index{translator option!-L@{©-L©}}, \Indexc{--linemarks}\index{translator option!--linemarks@{©--linemarks©}} \, generate line marks 445 \item 446 \Indexc{-m}\index{translator option!-m@{©-m©}}, \Indexc{--no-main}\index{translator option!--no-main@{©--no-main©}} \, do not replace main 447 \item 448 \Indexc{-N}\index{translator option!-N@{©-N©}}, \Indexc{--no-linemarks}\index{translator option!--no-linemarks@{©--no-linemarks©}} \, do not generate line marks 449 \item 450 \Indexc{-n}\index{translator option!-n@{©-n©}}, \Indexc{--no-prelude}\index{translator option!--no-prelude@{©--no-prelude©}} \, do not read prelude 451 \item 452 \Indexc{-p}\index{translator option!-p@{©-p©}}, \Indexc{--prototypes}\index{translator option!--prototypes@{©--prototypes©}} \, generate prototypes for prelude functions 453 \item 454 \Indexc{-P}\index{translator option!-P@{©-P©}}, \Indexc{--print}\index{translator option!--print@{©--print©}} \, one of: 455 \begin{description}[topsep=0pt,itemsep=0pt,parsep=0pt] 456 \item 457 \Indexc{altexpr}\index{translator option!-P@{©-P©}!©altexpr©}\index{translator option!--print@{©-print©}!©altexpr©} \, alternatives for expressions 458 \item 459 \Indexc{ascodegen}\index{translator option!-P@{©-P©}!©ascodegen©}\index{translator option!--print@{©-print©}!©ascodegen©} \, as codegen rather than AST 460 \item 461 \Indexc{ast}\index{translator option!-P@{©-P©}!©ast©}\index{translator option!--print@{©-print©}!©ast©} \, AST after parsing 462 \item 463 \Indexc{astdecl}\index{translator option!-P@{©-P©}!©astdecl©}\index{translator option!--print@{©-print©}!©astdecl©} \, AST after declaration validation pass 464 \item 465 \Indexc{asterr}\index{translator option!-P@{©-P©}!©asterr©}\index{translator option!--print@{©-print©}!©asterr©} \, AST on error 466 \item 467 \Indexc{astexpr}\index{translator option!-P@{©-P©}!©astexpr©}\index{translator option!--print@{©-print©}!©altexpr©} \, AST after expression analysis 468 \item 469 \Indexc{astgen}\index{translator option!-P@{©-P©}!©astgen©}\index{translator option!--print@{©-print©}!©astgen©} \, AST after instantiate generics 470 \item 471 \Indexc{box}\index{translator option!-P@{©-P©}!©box©}\index{translator option!--print@{©-print©}!©box©} \, before box step 472 \item 473 \Indexc{ctordtor}\index{translator option!-P@{©-P©}!©ctordtor©}\index{translator option!--print@{©-print©}!©ctordtor©} \, after ctor/dtor are replaced 474 \item 475 \Indexc{codegen}\index{translator option!-P@{©-P©}!©codegen©}\index{translator option!--print@{©-print©}!©codegen©} \, before code generation 476 \item 477 \Indexc{declstats}\index{translator option!-P@{©-P©}!©declstats©}\index{translator option!--print@{©-print©}!©declstats©} \, code property statistics 478 \item 479 \Indexc{parse}\index{translator option!-P@{©-P©}!©parse©}\index{translator option!--print@{©-print©}!©parse©} \, yacc (parsing) debug information 480 \item 481 \Indexc{pretty}\index{translator option!-P@{©-P©}!©pretty©}\index{translator option!--print@{©-print©}!©pretty©} \, prettyprint for ascodegen flag 482 \item 483 \Indexc{resolver}\index{translator option!-P@{©-P©}!©resolver©}\index{translator option!--print@{©-print©}!©resolver©} \, before resolver step 484 \item 485 \Indexc{rproto}\index{translator option!-P@{©-P©}!©rproto©}\index{translator option!--print@{©-print©}!©rproto©} \, resolver-proto instance 486 \item 487 \Indexc{rsteps}\index{translator option!-P@{©-P©}!©rsteps©}\index{translator option!--print@{©-print©}!©rsteps©} \, resolver steps 488 \item 489 \Indexc{symevt}\index{translator option!-P@{©-P©}!©symevt©}\index{translator option!--print@{©-print©}!©symevt©} \, symbol table events 490 \item 491 \Indexc{tree}\index{translator option!-P@{©-P©}!©tree©}\index{translator option!--print@{©-print©}!©tree©} \, parse tree 492 \item 493 \Indexc{tuple}\index{translator option!-P@{©-P©}!©tuple©}\index{translator option!--print@{©-print©}!©tuple©} \, after tuple expansion 494 \end{description} 495 \item 496 \Indexc{--prelude-dir} <directory> \, prelude directory for debug/nodebug 497 \item 498 \Indexc{-S}\index{translator option!-S@{©-S©}!©counters,heap,time,all,none©}, \Indexc{--statistics}\index{translator option!--statistics@{©--statistics©}!©counters,heap,time,all,none©} <option-list> \, enable profiling information: 499 \begin{description}[topsep=0pt,itemsep=0pt,parsep=0pt] 500 \item 501 \Indexc{counters,heap,time,all,none} 502 \end{description} 503 \item 504 \Indexc{-t}\index{translator option!-t@{©-t©}}, \Indexc{--tree}\index{translator option!--tree@{©--tree©}} build in tree 505 \end{description} 506 507 508 \section{Backquote Identifiers} 509 \label{s:BackquoteIdentifiers} 510 511 \CFA introduces several new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code. 512 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism: 513 \begin{cfa} 514 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§ 515 double ®`®forall®`® = 3.5; 516 \end{cfa} 517 518 Existing C programs with keyword clashes can be converted by enclosing keyword identifiers in backquotes, and eventually the identifier name can be changed to a non-keyword name. 519 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files (see~\VRef{s:StandardHeaders}) can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©. 520 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience. 521 522 \begin{figure} 523 \begin{cfa} 524 // include file uses the CFA keyword "with". 525 #if ! defined( with ) §\C{// nesting ?}§ 526 #define with ®`®with®`® §\C{// make keyword an identifier}§ 527 #define __CFA_BFD_H__ 528 #endif 529 530 ®#include_next <bfdlink.h> §\C{// must have internal check for multiple expansion}§ 531 ® 532 #if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§ 533 #undef with 534 #undef __CFA_BFD_H__ 535 #endif 536 \end{cfa} 537 \caption{Header-File Interposition} 538 \label{f:HeaderFileInterposition} 539 \end{figure} 435 540 436 541 … … 439 544 Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg: 440 545 \begin{cfa} 441 2®_®147®_®483®_®648; §\C{// decimal constant}§442 56®_®ul; §\C{// decimal unsigned long constant}§443 0®_®377; §\C{// octal constant}§444 0x®_®ff®_®ff; §\C{// hexadecimal constant}§445 0x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§446 3.141®_®592®_®654; §\C{// floating constant}§447 10®_®e®_®+1®_®00; §\C{// floating constant}§448 0x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating}§449 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating long constant}§450 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§546 2®_®147®_®483®_®648; §\C{// decimal constant}§ 547 56®_®ul; §\C{// decimal unsigned long constant}§ 548 0®_®377; §\C{// octal constant}§ 549 0x®_®ff®_®ff; §\C{// hexadecimal constant}§ 550 0x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§ 551 3.141®_®592®_®654; §\C{// floating constant}§ 552 10®_®e®_®+1®_®00; §\C{// floating constant}§ 553 0x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating}§ 554 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating long constant}§ 555 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§ 451 556 \end{cfa} 452 557 The rules for placement of underscores are: … … 469 574 470 575 471 \section{Backquote Identifiers} 472 \label{s:BackquoteIdentifiers} 473 474 \CFA introduces several new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code. 475 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism: 476 \begin{cfa} 477 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§ 478 double ®`®forall®`® = 3.5; 479 \end{cfa} 480 481 Existing C programs with keyword clashes can be converted by enclosing keyword identifiers in backquotes, and eventually the identifier name can be changed to a non-keyword name. 482 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files (see~\VRef{s:StandardHeaders}) can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©. 483 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience. 576 \section{Exponentiation Operator} 577 578 C, \CC, and Java (and many other programming languages) have no exponentiation operator\index{exponentiation!operator}\index{operator!exponentiation}, \ie $x^y$, and instead use a routine, like \Indexc{pow}, to perform the exponentiation operation. 579 \CFA extends the basic operators with the exponentiation operator ©?\?©\index{?\\?@©?\?©} and ©?\=?©\index{?\\=?@©\=?©}, as in, ©x \ y© and ©x \= y©, which means $x^y$ and $x \leftarrow x^y$. 580 The priority of the exponentiation operator is between the cast and multiplicative operators, so that ©w * (int)x \ (int)y * z© is parenthesized as ©((w * (((int)x) \ ((int)y))) * z)©. 581 582 As for \Index{division}, there are exponentiation operators for integral and floating types, including the builtin \Index{complex} types. 583 Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the exponent is 2). 584 Overflow from large exponents or negative exponents return zero. 585 Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the exponent cannot be negative. 586 \begin{cfa} 587 sout | 1 ®\® 0 | 1 ®\® 1 | 2 ®\® 8 | -4 ®\® 3 | 5 ®\® 3 | 5 ®\® 32 | 5L ®\® 32 | 5L ®\® 64 | -4 ®\® -3 | -4.0 ®\® -3 | 4.0 ®\® 2.1 588 | (1.0f+2.0fi) ®\® (3.0f+2.0fi); 589 1 1 256 -64 125 ®0® 3273344365508751233 ®0® ®0® -0.015625 18.3791736799526 0.264715-1.1922i 590 \end{cfa} 591 Note, ©5 ®\® 32© and ©5L ®\® 64© overflow, and ©-4 ®\® -3© is a fraction but stored in an integer so all three computations generate an integral zero. 592 Parenthesis are necessary for complex constants or the expression is parsed as ©1.0f+®(®2.0fi \ 3.0f®)®+2.0fi©. 593 The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation version is available. 594 \begin{cfa} 595 forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } ) 596 OT ?®\®?( OT ep, unsigned int y ); 597 forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } ) 598 OT ?®\®?( OT ep, unsigned long int y ); 599 \end{cfa} 600 The user type ©T© must define multiplication, one, ©1©, and, ©*©. 601 602 603 \section{Control Structures} 604 605 \CFA identifies inconsistent, problematic, and missing control structures in C, and extends, modifies, and adds control structures to increase functionality and safety. 606 607 608 %\subsection{\texorpdfstring{\protect\lstinline@if@/\protect\lstinline@while@ Statement}{if Statement}} 609 \subsection{\texorpdfstring{\LstKeywordStyle{if}/\LstKeywordStyle{while} Statement}{if/while Statement}} 610 611 The ©if©/©while© expression allows declarations, similar to ©for© declaration expression. 612 (Does not make sense for ©do©-©while©.) 613 \begin{cfa} 614 if ( ®int x = f()® ) ... §\C{// x != 0}§ 615 if ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§ 616 if ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§ 617 if ( ®struct S { int i; } x = { f() }; x.i < 4® ) §\C{// relational expression}§ 618 619 while ( ®int x = f()® ) ... §\C{// x != 0}§ 620 while ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§ 621 while ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§ 622 while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... §\C{// relational expression}§ 623 \end{cfa} 624 Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the ©if©/©while© expression, and the results are combined using the logical ©&&© operator.\footnote{\CC only provides a single declaration always compared not equal to 0.} 625 The scope of the declaration(s) is local to the @if@ statement but exist within both the ``then'' and ``else'' clauses. 626 627 628 \subsection{Loop Control} 629 630 The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges (see Figure~\ref{f:LoopControlExamples}). 631 \begin{itemize} 632 \item 633 An empty conditional implies ©1©. 634 \item 635 The up-to range ©~©\index{~@©~©} means exclusive range [M,N). 636 \item 637 The up-to range ©~=©\index{~=@©~=©} means inclusive range [M,N]. 638 \item 639 The down-to range ©-~©\index{-~@©-~©} means exclusive range [N,M). 640 \item 641 The down-to range ©-~=©\index{-~=@©-~=©} means inclusive range [N,M]. 642 \item 643 ©@© means put nothing in this field. 644 \item 645 ©0© is the implicit start value; 646 \item 647 ©1© is the implicit increment value. 648 \item 649 The up-to range uses ©+=© for increment; 650 \item 651 The down-to range uses ©-=© for decrement. 652 \item 653 The loop index is polymorphic in the type of the start value or comparison value when start is implicitly ©0©. 654 \end{itemize} 484 655 485 656 \begin{figure} 486 \begin{cfa} 487 // include file uses the CFA keyword "with". 488 #if ! defined( with ) §\C{// nesting ?}§ 489 #define with ®`®with®`® §\C{// make keyword an identifier}§ 490 #define __CFA_BFD_H__ 491 #endif 492 493 ®#include_next <bfdlink.h> §\C{// must have internal check for multiple expansion}§ 494 ® 495 #if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§ 496 #undef with 497 #undef __CFA_BFD_H__ 498 #endif 499 \end{cfa} 500 \caption{Header-File Interposition} 501 \label{f:HeaderFileInterposition} 657 \begin{cquote} 658 \begin{tabular}{@{}l|l@{}} 659 \multicolumn{1}{c|}{loop control} & \multicolumn{1}{c}{output} \\ 660 \hline 661 \begin{cfa} 662 sout | nlOff; 663 while ®()® { sout | "empty"; break; } sout | nl; 664 do { sout | "empty"; break; } while ®()®; sout | nl; 665 for ®()® { sout | "empty"; break; } sout | nl; 666 for ( ®0® ) { sout | "A"; } sout | "zero" | nl; 667 for ( ®1® ) { sout | "A"; } sout | nl; 668 for ( ®10® ) { sout | "A"; } sout | nl; 669 for ( ®1 ~= 10 ~ 2® ) { sout | "B"; } sout | nl; 670 for ( ®10 -~= 1 ~ 2® ) { sout | "C"; } sout | nl; 671 for ( ®0.5 ~ 5.5® ) { sout | "D"; } sout | nl; 672 for ( ®5.5 -~ 0.5® ) { sout | "E"; } sout | nl; 673 for ( ®i; 10® ) { sout | i; } sout | nl; 674 for ( ®i; 1 ~= 10 ~ 2® ) { sout | i; } sout | nl; 675 for ( ®i; 10 -~= 1 ~ 2® ) { sout | i; } sout | nl; 676 for ( ®i; 0.5 ~ 5.5® ) { sout | i; } sout | nl; 677 for ( ®i; 5.5 -~ 0.5® ) { sout | i; } sout | nl; 678 for ( ®ui; 2u ~= 10u ~ 2u® ) { sout | ui; } sout | nl; 679 for ( ®ui; 10u -~= 2u ~ 2u® ) { sout | ui; } sout | nl; 680 enum { N = 10 }; 681 for ( ®N® ) { sout | "N"; } sout | nl; 682 for ( ®i; N® ) { sout | i; } sout | nl; 683 for ( ®i; N -~ 0® ) { sout | i; } sout | nl; 684 const int start = 3, comp = 10, inc = 2; 685 for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; } sout | nl; 686 for ( ®i; 1 ~ @® ) { if ( i > 10 ) break; 687 sout | i; } sout | nl; 688 for ( ®i; 10 -~ @® ) { if ( i < 0 ) break; 689 sout | i; } sout | nl; 690 for ( ®i; 2 ~ @ ~ 2® ) { if ( i > 10 ) break; 691 sout | i; } sout | nl; 692 for ( ®i; 2.1 ~ @ ~ @® ) { if ( i > 10.5 ) break; 693 sout | i; i += 1.7; } sout | nl; 694 for ( ®i; 10 -~ @ ~ 2® ) { if ( i < 0 ) break; 695 sout | i; } sout | nl; 696 for ( ®i; 12.1 ~ @ ~ @® ) { if ( i < 2.5 ) break; 697 sout | i; i -= 1.7; } sout | nl; 698 for ( ®i; 5 : j; -5 ~ @® ) { sout | i | j; } sout | nl; 699 for ( ®i; 5 : j; -5 -~ @® ) { sout | i | j; } sout | nl; 700 for ( ®i; 5 : j; -5 ~ @ ~ 2® ) { sout | i | j; } sout | nl; 701 for ( ®i; 5 : j; -5 -~ @ ~ 2® ) { sout | i | j; } sout | nl; 702 for ( ®j; -5 ~ @ : i; 5® ) { sout | i | j; } sout | nl; 703 for ( ®j; -5 -~ @ : i; 5® ) { sout | i | j; } sout | nl; 704 for ( ®j; -5 ~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl; 705 for ( ®j; -5 -~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl; 706 for ( ®j; -5 -~ @ ~ 2 : i; 5 : k; 1.5 ~ @® ) { 707 sout | i | j | k; } sout | nl; 708 for ( ®j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 5® ) { 709 sout | i | j | k; } sout | nl; 710 for ( ®k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 5® ) { 711 sout | i | j | k; } sout | nl; 712 \end{cfa} 713 & 714 \begin{cfa} 715 716 empty 717 empty 718 empty 719 zero 720 A 721 A A A A A A A A A A 722 B B B B B 723 C C C C C 724 D D D D D 725 E E E E E 726 0 1 2 3 4 5 6 7 8 9 727 1 3 5 7 9 728 10 8 6 4 2 729 0.5 1.5 2.5 3.5 4.5 730 5.5 4.5 3.5 2.5 1.5 731 2 4 6 8 10 732 10 8 6 4 2 733 734 N N N N N N N N N N 735 0 1 2 3 4 5 6 7 8 9 736 10 9 8 7 6 5 4 3 2 1 737 738 3 6 9 739 740 1 2 3 4 5 6 7 8 9 10 741 742 10 9 8 7 6 5 4 3 2 1 0 743 744 2 4 6 8 10 745 746 2.1 3.8 5.5 7.2 8.9 747 748 10 8 6 4 2 0 749 750 12.1 10.4 8.7 7 5.3 3.6 751 0 -5 1 -4 2 -3 3 -2 4 -1 752 0 -5 1 -6 2 -7 3 -8 4 -9 753 0 -5 1 -3 2 -1 3 1 4 3 754 0 -5 1 -7 2 -9 3 -11 4 -13 755 0 -5 1 -4 2 -3 3 -2 4 -1 756 0 -5 1 -6 2 -7 3 -8 4 -9 757 0 -5 1 -3 2 -1 3 1 4 3 758 0 -5 1 -7 2 -9 3 -11 4 -13 759 760 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 761 762 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 763 764 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 765 \end{cfa} 766 \end{tabular} 767 \end{cquote} 768 \caption{Loop Control Examples} 769 \label{f:LoopControlExamples} 502 770 \end{figure} 503 771 504 772 505 \section{Exponentiation Operator} 506 507 C, \CC, and Java (and many other programming languages) have no exponentiation operator\index{exponentiation!operator}\index{operator!exponentiation}, \ie $x^y$, and instead use a routine, like \Indexc{pow}, to perform the exponentiation operation. 508 \CFA extends the basic operators with the exponentiation operator ©?\?©\index{?\\?@\lstinline@?\?@} and ©?\=?©\index{?\\=?@\lstinline@?\=?@}, as in, ©x \ y© and ©x \= y©, which means $x^y$ and $x \leftarrow x^y$. 509 The priority of the exponentiation operator is between the cast and multiplicative operators, so that ©w * (int)x \ (int)y * z© is parenthesized as ©((w * (((int)x) \ ((int)y))) * z)©. 510 511 As for \Index{division}, there are exponentiation operators for integral and floating types, including the builtin \Index{complex} types. 512 Unsigned integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the base is 2). 513 Signed integral exponentiation\index{exponentiation!signed integral} is performed with repeated multiplication (or shifting if the base is 2), but yields a floating result because $x^{-y}=1/x^y$. 514 Hence, it is important to designate exponent integral-constants as unsigned or signed: ©3 \ 3u© return an integral result, while ©3 \ 3© returns a floating result. 515 Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the base cannot be negative. 516 \begin{cfa} 517 sout | 2 ®\® 8u | 4 ®\® 3u | -4 ®\® 3u | 4 ®\® -3 | -4 ®\® -3 | 4.0 ®\® 2.1 | (1.0f+2.0fi) ®\® (3.0f+2.0fi) | endl; 518 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i 519 \end{cfa} 520 Parenthesis are necessary for the complex constants or the expresion is parsed as ©1.0f+(2.0fi \ 3.0f)+2.0fi©. 521 The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation versions are available. 522 For returning an integral value, the user type ©T© must define multiplication, ©*©, and one, ©1©; 523 for returning a floating value, an additional divide of type ©T© into a ©double© returning a ©double© (©double ?/?( double, T )©) is necessary for negative exponents. 524 525 526 \section{\texorpdfstring{Labelled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labelled continue / break}} 773 %\section{\texorpdfstring{\protect\lstinline@switch@ Statement}{switch Statement}} 774 \subsection{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}} 775 776 C allows a number of questionable forms for the ©switch© statement: 777 \begin{enumerate} 778 \item 779 By default, the end of a ©case© clause\footnote{ 780 In this section, the term \emph{case clause} refers to either a ©case© or ©default© clause.} 781 \emph{falls through} to the next ©case© clause in the ©switch© statement; 782 to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly ©break©: 783 \begin{cfa} 784 switch ( i ) { 785 case 1: 786 ... 787 // fall-through 788 case 2: 789 ... 790 break; // exit switch statement 791 } 792 \end{cfa} 793 The ability to fall-through to the next clause \emph{is} a useful form of control flow, specifically when a sequence of case actions compound: 794 \begin{cquote} 795 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 796 \begin{cfa} 797 switch ( argc ) { 798 case 3: 799 // open output file 800 // fall-through 801 case 2: 802 // open input file 803 break; // exit switch statement 804 default: 805 // usage message 806 } 807 \end{cfa} 808 & 809 \begin{cfa} 810 811 if ( argc == 3 ) { 812 // open output file 813 ®// open input file 814 ®} else if ( argc == 2 ) { 815 ®// open input file (duplicate) 816 817 ®} else { 818 // usage message 819 } 820 \end{cfa} 821 \end{tabular} 822 \end{cquote} 823 In this example, case 2 is always done if case 3 is done. 824 This control flow is difficult to simulate with if statements or a ©switch© statement without fall-through as code must be duplicated or placed in a separate routine. 825 C also uses fall-through to handle multiple case-values resulting in the same action: 826 \begin{cfa} 827 switch ( i ) { 828 ®case 1: case 3: case 5:® // odd values 829 // odd action 830 break; 831 ®case 2: case 4: case 6:® // even values 832 // even action 833 break; 834 } 835 \end{cfa} 836 However, this situation is handled in other languages without fall-through by allowing a list of case values. 837 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from virtually all other programming languages with a ©switch© statement. 838 Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 839 840 \item 841 It is possible to place ©case© clauses on statements nested \emph{within} the body of the ©switch© statement: 842 \begin{cfa} 843 switch ( i ) { 844 case 0: 845 if ( j < k ) { 846 ... 847 ®case 1:® // transfer into "if" statement 848 ... 849 } // if 850 case 2: 851 while ( j < 5 ) { 852 ... 853 ®case 3:® // transfer into "while" statement 854 ... 855 } // while 856 } // switch 857 \end{cfa} 858 The problem with this usage is branching into control structures, which is known to cause both comprehension and technical difficulties. 859 The comprehension problem occurs from the inability to determine how control reaches a particular point due to the number of branches leading to it. 860 The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning. 861 There are no positive arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it. 862 Nevertheless, C does have an idiom where this capability is used, known as ``\Index*{Duff's device}''~\cite{Duff83}: 863 \begin{cfa} 864 register int n = (count + 7) / 8; 865 switch ( count % 8 ) { 866 case 0: do{ *to = *from++; 867 case 7: *to = *from++; 868 case 6: *to = *from++; 869 case 5: *to = *from++; 870 case 4: *to = *from++; 871 case 3: *to = *from++; 872 case 2: *to = *from++; 873 case 1: *to = *from++; 874 } while ( --n > 0 ); 875 } 876 \end{cfa} 877 which unrolls a loop N times (N = 8 above) and uses the ©switch© statement to deal with any iterations not a multiple of N. 878 While efficient, this sort of special purpose usage is questionable: 879 \begin{quote} 880 Disgusting, no? But it compiles and runs just fine. I feel a combination of pride and revulsion at this 881 discovery.~\cite{Duff83} 882 \end{quote} 883 \item 884 It is possible to place the ©default© clause anywhere in the list of labelled clauses for a ©switch© statement, rather than only at the end. 885 Virtually all programming languages with a ©switch© statement require the ©default© clause to appear last in the case-clause list. 886 The logic for this semantics is that after checking all the ©case© clauses without success, the ©default© clause is selected; 887 hence, physically placing the ©default© clause at the end of the ©case© clause list matches with this semantics. 888 This physical placement can be compared to the physical placement of an ©else© clause at the end of a series of connected ©if©/©else© statements. 889 890 \item 891 It is possible to place unreachable code at the start of a ©switch© statement, as in: 892 \begin{cfa} 893 switch ( x ) { 894 ®int y = 1;® §\C{// unreachable initialization}§ 895 ®x = 7;® §\C{// unreachable code without label/branch}§ 896 case 0: ... 897 ... 898 ®int z = 0;® §\C{// unreachable initialization, cannot appear after case}§ 899 z = 2; 900 case 1: 901 ®x = z;® §\C{// without fall through, z is uninitialized}§ 902 } 903 \end{cfa} 904 While the declaration of the local variable ©y© is useful with a scope across all ©case© clauses, the initialization for such a variable is defined to never be executed because control always transfers over it. 905 Furthermore, any statements before the first ©case© clause can only be executed if labelled and transferred to using a ©goto©, either from outside or inside of the ©switch©, both of which are problematic. 906 As well, the declaration of ©z© cannot occur after the ©case© because a label can only be attached to a statement, and without a fall through to case 3, ©z© is uninitialized. 907 The key observation is that the ©switch© statement branches into control structure, \ie there are multiple entry points into its statement body. 908 \end{enumerate} 909 910 Before discussing potential language changes to deal with these problems, it is worth observing that in a typical C program: 911 \begin{itemize} 912 \item 913 the number of ©switch© statements is small, 914 \item 915 most ©switch© statements are well formed (\ie no \Index*{Duff's device}), 916 \item 917 the ©default© clause is usually written as the last case-clause, 918 \item 919 and there is only a medium amount of fall-through from one ©case© clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound. 920 \end{itemize} 921 These observations put into perspective the \CFA changes to the ©switch©. 922 \begin{enumerate} 923 \item 924 Eliminating default fall-through has the greatest potential for affecting existing code. 925 However, even if fall-through is removed, most ©switch© statements would continue to work because of the explicit transfers already present at the end of each ©case© clause, the common placement of the ©default© clause at the end of the case list, and the most common use of fall-through, \ie a list of ©case© clauses executing common code, \eg: 926 \begin{cfa} 927 case 1: case 2: case 3: ... 928 \end{cfa} 929 still works. 930 Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments. 931 Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg: 932 \begin{cfa} 933 ®choose® ( i ) { 934 case 1: case 2: case 3: 935 ... 936 ®// implicit end of switch (break) 937 ®case 5: 938 ... 939 ®fallthru®; §\C{// explicit fall through}§ 940 case 7: 941 ... 942 ®break® §\C{// explicit end of switch (redundant)}§ 943 default: 944 j = 3; 945 } 946 \end{cfa} 947 Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses; 948 An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause. 949 An explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement. 950 As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers. 951 \item 952 \Index*{Duff's device} is eliminated from both ©switch© and ©choose© statements, and only invalidates a small amount of very questionable code. 953 Hence, the ©case© clause must appear at the same nesting level as the ©switch©/©choose© body, as is done in most other programming languages with ©switch© statements. 954 \item 955 The issue of ©default© at locations other than at the end of the cause clause can be solved by using good programming style, and there are a few reasonable situations involving fall-through where the ©default© clause needs to appear is locations other than at the end. 956 Therefore, no change is made for this issue. 957 \item 958 Dealing with unreachable code in a ©switch©/©choose© body is solved by restricting declarations and associated initialization to the start of statement body, which is executed \emph{before} the transfer to the appropriate ©case© clause\footnote{ 959 Essentially, these declarations are hoisted before the ©switch©/©choose© statement and both declarations and statement are surrounded by a compound statement.} and precluding statements before the first ©case© clause. 960 Further declarations at the same nesting level as the statement body are disallowed to ensure every transfer into the body is sound. 961 \begin{cfa} 962 switch ( x ) { 963 ®int i = 0;® §\C{// allowed only at start}§ 964 case 0: 965 ... 966 ®int j = 0;® §\C{// disallowed}§ 967 case 1: 968 { 969 ®int k = 0;® §\C{// allowed at different nesting levels}§ 970 ... 971 ®case 2:® §\C{// disallow case in nested statements}§ 972 } 973 ... 974 } 975 \end{cfa} 976 \end{enumerate} 977 978 979 %\section{\texorpdfstring{\protect\lstinline@case@ Clause}{case Clause}} 980 \subsection{\texorpdfstring{\LstKeywordStyle{case} Statement}{case Statement}} 981 982 C restricts the ©case© clause of a ©switch© statement to a single value. 983 For multiple ©case© clauses associated with the same statement, it is necessary to have multiple ©case© clauses rather than multiple values. 984 Requiring a ©case© clause for each value does not seem to be in the spirit of brevity normally associated with C. 985 Therefore, the ©case© clause is extended with a list of values, as in: 986 \begin{cquote} 987 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} 988 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\ 989 \begin{cfa} 990 switch ( i ) { 991 case ®1, 3, 5®: 992 ... 993 case ®2, 4, 6®: 994 ... 995 } 996 \end{cfa} 997 & 998 \begin{cfa} 999 switch ( i ) { 1000 case 1: case 3 : case 5: 1001 ... 1002 case 2: case 4 : case 6: 1003 ... 1004 } 1005 \end{cfa} 1006 & 1007 \begin{cfa} 1008 1009 // odd values 1010 1011 // even values 1012 1013 1014 \end{cfa} 1015 \end{tabular} 1016 \end{cquote} 1017 In addition, subranges are allowed to specify case values.\footnote{ 1018 gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, because a space is required after a number, otherwise the period is a decimal point.} 1019 \begin{cfa} 1020 switch ( i ) { 1021 case ®1~5:® §\C{// 1, 2, 3, 4, 5}§ 1022 ... 1023 case ®10~15:® §\C{// 10, 11, 12, 13, 14, 15}§ 1024 ... 1025 } 1026 \end{cfa} 1027 Lists of subranges are also allowed. 1028 \begin{cfa} 1029 case ®1~5, 12~21, 35~42®: 1030 \end{cfa} 1031 1032 1033 % for () => for ( ;; ) 1034 % for ( 10 - t ) => for ( typeof(10 - t) ? = 0 ; ? < 10 - t; ? += 1 ) // using 0 and 1 1035 % for ( i ; 10 - t ) => for ( typeof(10 - t) i = 0 ; i < 10 - t; i += 1 ) // using 0 and 1 1036 % for ( T i ; 10 - t ) => for ( T i = 0 ; i < 10 - t; i += 1 ) // using 0 and 1 1037 % for ( 3~9 ) => for ( int ? = 3 ; ? < 9; ? += 1 ) // using 1 1038 % for ( i ; 3~9 ) => for ( int i = 3 ; i < 9; i += 1 ) // using 1 1039 % for ( T i ; 3~9 ) => for ( T i = 3 ; i < 9; i += 1 ) // using 1 1040 1041 1042 %\subsection{\texorpdfstring{Labelled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labelled continue / break}} 1043 \subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}} 527 1044 528 1045 While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure. 529 1046 Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting. 530 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@ \lstinline@continue@!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline@break@!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}, as in Java.1047 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@©continue©!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@©break©!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}, as in Java. 531 1048 For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement; 532 1049 for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement. … … 613 1130 \end{figure} 614 1131 615 Both labelled ©continue© and ©break© are a ©goto©\index{goto@ \lstinline@goto@!restricted} restricted in the following ways:1132 Both labelled ©continue© and ©break© are a ©goto©\index{goto@©goto©!restricted} restricted in the following ways: 616 1133 \begin{itemize} 617 1134 \item … … 626 1143 With ©goto©, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader. 627 1144 Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting existing constructs. 628 The implicit targets of the current ©continue© and ©break©, \ie the closest enclosing loop or ©switch©, change as certain constructs are added or removed. 629 630 631 \section{\texorpdfstring{\protect\lstinline@switch@ Statement}{switch Statement}} 632 633 C allows a number of questionable forms for the ©switch© statement: 634 \begin{enumerate} 635 \item 636 By default, the end of a ©case© clause\footnote{ 637 In this section, the term \emph{case clause} refers to either a ©case© or ©default© clause.} 638 \emph{falls through} to the next ©case© clause in the ©switch© statement; 639 to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly ©break©: 640 \begin{cfa} 641 switch ( i ) { 642 case 1: 643 ... 644 // fall-through 645 case 2: 646 ... 647 break; // exit switch statement 648 } 649 \end{cfa} 650 The ability to fall-through to the next clause \emph{is} a useful form of control flow, specifically when a sequence of case actions compound: 651 \begin{cquote} 652 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 653 \begin{cfa} 654 switch ( argc ) { 655 case 3: 656 // open output file 657 // fall-through 658 case 2: 659 // open input file 660 break; // exit switch statement 661 default: 662 // usage message 663 } 664 \end{cfa} 665 & 666 \begin{cfa} 667 668 if ( argc == 3 ) { 669 // open output file 670 ®// open input file 671 ®} else if ( argc == 2 ) { 672 ®// open input file (duplicate) 673 674 ®} else { 675 // usage message 676 } 677 \end{cfa} 678 \end{tabular} 679 \end{cquote} 680 In this example, case 2 is always done if case 3 is done. 681 This control flow is difficult to simulate with if statements or a ©switch© statement without fall-through as code must be duplicated or placed in a separate routine. 682 C also uses fall-through to handle multiple case-values resulting in the same action: 683 \begin{cfa} 684 switch ( i ) { 685 ®case 1: case 3: case 5:® // odd values 686 // odd action 687 break; 688 ®case 2: case 4: case 6:® // even values 689 // even action 690 break; 691 } 692 \end{cfa} 693 However, this situation is handled in other languages without fall-through by allowing a list of case values. 694 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from virtually all other programming languages with a ©switch© statement. 695 Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 696 697 \item 698 It is possible to place ©case© clauses on statements nested \emph{within} the body of the ©switch© statement: 699 \begin{cfa} 700 switch ( i ) { 701 case 0: 702 if ( j < k ) { 703 ... 704 ®case 1:® // transfer into "if" statement 705 ... 706 } // if 707 case 2: 708 while ( j < 5 ) { 709 ... 710 ®case 3:® // transfer into "while" statement 711 ... 712 } // while 713 } // switch 714 \end{cfa} 715 The problem with this usage is branching into control structures, which is known to cause both comprehension and technical difficulties. 716 The comprehension problem occurs from the inability to determine how control reaches a particular point due to the number of branches leading to it. 717 The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning. 718 There are no positive arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it. 719 Nevertheless, C does have an idiom where this capability is used, known as ``\Index*{Duff's device}''~\cite{Duff83}: 720 \begin{cfa} 721 register int n = (count + 7) / 8; 722 switch ( count % 8 ) { 723 case 0: do{ *to = *from++; 724 case 7: *to = *from++; 725 case 6: *to = *from++; 726 case 5: *to = *from++; 727 case 4: *to = *from++; 728 case 3: *to = *from++; 729 case 2: *to = *from++; 730 case 1: *to = *from++; 731 } while ( --n > 0 ); 732 } 733 \end{cfa} 734 which unrolls a loop N times (N = 8 above) and uses the ©switch© statement to deal with any iterations not a multiple of N. 735 While efficient, this sort of special purpose usage is questionable: 736 \begin{quote} 737 Disgusting, no? But it compiles and runs just fine. I feel a combination of pride and revulsion at this 738 discovery.~\cite{Duff83} 739 \end{quote} 740 \item 741 It is possible to place the ©default© clause anywhere in the list of labelled clauses for a ©switch© statement, rather than only at the end. 742 Virtually all programming languages with a ©switch© statement require the ©default© clause to appear last in the case-clause list. 743 The logic for this semantics is that after checking all the ©case© clauses without success, the ©default© clause is selected; 744 hence, physically placing the ©default© clause at the end of the ©case© clause list matches with this semantics. 745 This physical placement can be compared to the physical placement of an ©else© clause at the end of a series of connected ©if©/©else© statements. 746 747 \item 748 It is possible to place unreachable code at the start of a ©switch© statement, as in: 749 \begin{cfa} 750 switch ( x ) { 751 ®int y = 1;® §\C{// unreachable initialization}§ 752 ®x = 7;® §\C{// unreachable code without label/branch}§ 753 case 0: ... 754 ... 755 ®int z = 0;® §\C{// unreachable initialization, cannot appear after case}§ 756 z = 2; 757 case 1: 758 ®x = z;® §\C{// without fall through, z is uninitialized}§ 759 } 760 \end{cfa} 761 While the declaration of the local variable ©y© is useful with a scope across all ©case© clauses, the initialization for such a variable is defined to never be executed because control always transfers over it. 762 Furthermore, any statements before the first ©case© clause can only be executed if labelled and transferred to using a ©goto©, either from outside or inside of the ©switch©, both of which are problematic. 763 As well, the declaration of ©z© cannot occur after the ©case© because a label can only be attached to a statement, and without a fall through to case 3, ©z© is uninitialized. 764 The key observation is that the ©switch© statement branches into control structure, \ie there are multiple entry points into its statement body. 765 \end{enumerate} 766 767 Before discussing potential language changes to deal with these problems, it is worth observing that in a typical C program: 768 \begin{itemize} 769 \item 770 the number of ©switch© statements is small, 771 \item 772 most ©switch© statements are well formed (\ie no \Index*{Duff's device}), 773 \item 774 the ©default© clause is usually written as the last case-clause, 775 \item 776 and there is only a medium amount of fall-through from one ©case© clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound. 777 \end{itemize} 778 These observations put into perspective the \CFA changes to the ©switch©. 779 \begin{enumerate} 780 \item 781 Eliminating default fall-through has the greatest potential for affecting existing code. 782 However, even if fall-through is removed, most ©switch© statements would continue to work because of the explicit transfers already present at the end of each ©case© clause, the common placement of the ©default© clause at the end of the case list, and the most common use of fall-through, \ie a list of ©case© clauses executing common code, \eg: 783 \begin{cfa} 784 case 1: case 2: case 3: ... 785 \end{cfa} 786 still works. 787 Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments. 788 Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg: 789 \begin{cfa} 790 ®choose® ( i ) { 791 case 1: case 2: case 3: 792 ... 793 ®// implicit end of switch (break) 794 ®case 5: 795 ... 796 ®fallthru®; §\C{// explicit fall through}§ 797 case 7: 798 ... 799 ®break® §\C{// explicit end of switch (redundant)}§ 800 default: 801 j = 3; 802 } 803 \end{cfa} 804 Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses; 805 An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause. 806 An explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement. 807 As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers. 808 \item 809 \Index*{Duff's device} is eliminated from both ©switch© and ©choose© statements, and only invalidates a small amount of very questionable code. 810 Hence, the ©case© clause must appear at the same nesting level as the ©switch©/©choose© body, as is done in most other programming languages with ©switch© statements. 811 \item 812 The issue of ©default© at locations other than at the end of the cause clause can be solved by using good programming style, and there are a few reasonable situations involving fall-through where the ©default© clause needs to appear is locations other than at the end. 813 Therefore, no change is made for this issue. 814 \item 815 Dealing with unreachable code in a ©switch©/©choose© body is solved by restricting declarations and associated initialization to the start of statement body, which is executed \emph{before} the transfer to the appropriate ©case© clause\footnote{ 816 Essentially, these declarations are hoisted before the ©switch©/©choose© statement and both declarations and statement are surrounded by a compound statement.} and precluding statements before the first ©case© clause. 817 Further declarations at the same nesting level as the statement body are disallowed to ensure every transfer into the body is sound. 818 \begin{cfa} 819 switch ( x ) { 820 ®int i = 0;® §\C{// allowed only at start}§ 821 case 0: 822 ... 823 ®int j = 0;® §\C{// disallowed}§ 824 case 1: 825 { 826 ®int k = 0;® §\C{// allowed at different nesting levels}§ 827 ... 828 ®case 2:® §\C{// disallow case in nested statements}§ 829 } 830 ... 831 } 832 \end{cfa} 833 \end{enumerate} 834 835 836 \section{\texorpdfstring{\protect\lstinline@case@ Clause}{case Clause}} 837 838 C restricts the ©case© clause of a ©switch© statement to a single value. 839 For multiple ©case© clauses associated with the same statement, it is necessary to have multiple ©case© clauses rather than multiple values. 840 Requiring a ©case© clause for each value does not seem to be in the spirit of brevity normally associated with C. 841 Therefore, the ©case© clause is extended with a list of values, as in: 842 \begin{cquote} 843 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} 844 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\ 845 \begin{cfa} 846 switch ( i ) { 847 case ®1, 3, 5®: 848 ... 849 case ®2, 4, 6®: 850 ... 851 } 852 \end{cfa} 853 & 854 \begin{cfa} 855 switch ( i ) { 856 case 1: case 3 : case 5: 857 ... 858 case 2: case 4 : case 6: 859 ... 860 } 861 \end{cfa} 862 & 863 \begin{cfa} 864 865 // odd values 866 867 // even values 868 869 870 \end{cfa} 871 \end{tabular} 872 \end{cquote} 873 In addition, subranges are allowed to specify case values.\footnote{ 874 gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, because a space is required after a number, otherwise the period is a decimal point.} 875 \begin{cfa} 876 switch ( i ) { 877 case ®1~5:® §\C{// 1, 2, 3, 4, 5}§ 878 ... 879 case ®10~15:® §\C{// 10, 11, 12, 13, 14, 15}§ 880 ... 881 } 882 \end{cfa} 883 Lists of subranges are also allowed. 884 \begin{cfa} 885 case ®1~5, 12~21, 35~42®: 886 \end{cfa} 887 888 889 \section{\texorpdfstring{\protect\lstinline@with@ Statement}{with Statement}} 1145 Otherwise, the implicit targets of the current ©continue© and ©break©, \ie the closest enclosing loop or ©switch©, change as certain constructs are added or removed. 1146 1147 1148 %\section{\texorpdfstring{\protect\lstinline@with@ Statement}{with Statement}} 1149 \section{\texorpdfstring{\LstKeywordStyle{with} Statement}{with Statement}} 890 1150 \label{s:WithStatement} 891 1151 892 1152 Grouping heterogeneous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers: 893 1153 \begin{cfa} 894 struct S { §\C{// aggregate}§895 char c; §\C{// fields}§1154 struct S { §\C{// aggregate}§ 1155 char c; §\C{// fields}§ 896 1156 int i; 897 1157 double d; … … 902 1162 \begin{cfa} 903 1163 void f( S s ) { 904 `s.`c; `s.`i; `s.`d;§\C{// access containing fields}§1164 ®s.®c; ®s.®i; ®s.®d; §\C{// access containing fields}§ 905 1165 } 906 1166 \end{cfa} … … 909 1169 \begin{C++} 910 1170 struct S { 911 char c; §\C{// fields}§1171 char c; §\C{// fields}§ 912 1172 int i; 913 1173 double d; 914 void f() { §\C{// implicit ``this'' aggregate}§915 `this->`c; `this->`i; `this->`d;§\C{// access containing fields}§1174 void f() { §\C{// implicit ``this'' aggregate}§ 1175 ®this->®c; ®this->®i; ®this->®d; §\C{// access containing fields}§ 916 1176 } 917 1177 } 918 1178 \end{C++} 919 Object-oriented nesting of member functions in a \lstinline[language=C++]@class/struct@ allows eliding \lstinline[language=C++] $this->$because of lexical scoping.1179 Object-oriented nesting of member functions in a \lstinline[language=C++]@class/struct@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping. 920 1180 However, for other aggregate parameters, qualification is necessary: 921 1181 \begin{cfa} 922 1182 struct T { double m, n; }; 923 int S::f( T & t ) { §\C{// multiple aggregate parameters}§924 c; i; d; §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§925 `t.`m; `t.`n;§\C{// must qualify}§926 } 927 \end{cfa} 928 929 To simplify the programmer experience, \CFA provides a @with@statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers.1183 int S::f( T & t ) { §\C{// multiple aggregate parameters}§ 1184 c; i; d; §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§ 1185 ®t.®m; ®t.®n; §\C{// must qualify}§ 1186 } 1187 \end{cfa} 1188 1189 To simplify the programmer experience, \CFA provides a ©with© statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers. 930 1190 Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block. 931 1191 \begin{cfa} 932 void f( S & this ) `with ( this )` {§\C{// with statement}§933 c; i; d; §\C{\color{red}// this.c, this.i, this.d}§1192 void f( S & this ) ®with ( this )® { §\C{// with statement}§ 1193 c; i; d; §\C{\color{red}// this.c, this.i, this.d}§ 934 1194 } 935 1195 \end{cfa} 936 1196 with the generality of opening multiple aggregate-parameters: 937 1197 \begin{cfa} 938 void f( S & s, T & t ) `with ( s, t )` {§\C{// multiple aggregate parameters}§939 c; i; d; §\C{\color{red}// s.c, s.i, s.d}§940 m; n; §\C{\color{red}// t.m, t.n}§941 } 942 \end{cfa} 943 944 In detail, the @with@statement has the form:1198 void f( S & s, T & t ) ®with ( s, t )® { §\C{// multiple aggregate parameters}§ 1199 c; i; d; §\C{\color{red}// s.c, s.i, s.d}§ 1200 m; n; §\C{\color{red}// t.m, t.n}§ 1201 } 1202 \end{cfa} 1203 1204 In detail, the ©with© statement has the form: 945 1205 \begin{cfa} 946 1206 §\emph{with-statement}§: … … 957 1217 The difference between parallel and nesting occurs for fields with the same name and type: 958 1218 \begin{cfa} 959 struct S { int `i`; int j; double m; } s, w;960 struct T { int `i`; int k; int m; } t, w;1219 struct S { int ®i®; int j; double m; } s, w; 1220 struct T { int ®i®; int k; int m; } t, w; 961 1221 with ( s, t ) { 962 j + k; §\C{// unambiguous, s.j + t.k}§963 m = 5.0; §\C{// unambiguous, t.m = 5.0}§964 m = 1; §\C{// unambiguous, s.m = 1}§965 int a = m; §\C{// unambiguous, a = s.i }§966 double b = m; §\C{// unambiguous, b = t.m}§967 int c = s.i + t.i; §\C{// unambiguous, qualification}§968 (double)m; §\C{// unambiguous, cast}§969 } 970 \end{cfa} 971 For parallel semantics, both @s.i@ and @t.i@ are visible, so @i@is ambiguous without qualification;972 for nested semantics, @t.i@ hides @s.i@, so @i@ implies @t.i@.1222 j + k; §\C{// unambiguous, s.j + t.k}§ 1223 m = 5.0; §\C{// unambiguous, t.m = 5.0}§ 1224 m = 1; §\C{// unambiguous, s.m = 1}§ 1225 int a = m; §\C{// unambiguous, a = s.i }§ 1226 double b = m; §\C{// unambiguous, b = t.m}§ 1227 int c = s.i + t.i; §\C{// unambiguous, qualification}§ 1228 (double)m; §\C{// unambiguous, cast}§ 1229 } 1230 \end{cfa} 1231 For parallel semantics, both ©s.i© and ©t.i© are visible, so ©i© is ambiguous without qualification; 1232 for nested semantics, ©t.i© hides ©s.i©, so ©i© implies ©t.i©. 973 1233 \CFA's ability to overload variables means fields with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates. 974 1234 Qualification or a cast is used to disambiguate. 975 1235 976 There is an interesting problem between parameters and the function-body @with@, \eg:977 \begin{cfa} 978 void ?{}( S & s, int i ) with ( s ) { §\C{// constructor}§979 `s.i = i;` j = 3; m = 5.5;§\C{// initialize fields}§980 } 981 \end{cfa} 982 Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the function-body @with@.1236 There is an interesting problem between parameters and the function-body ©with©, \eg: 1237 \begin{cfa} 1238 void ?{}( S & s, int i ) with ( s ) { §\C{// constructor}§ 1239 ®s.i = i;® j = 3; m = 5.5; §\C{// initialize fields}§ 1240 } 1241 \end{cfa} 1242 Here, the assignment ©s.i = i© means ©s.i = s.i©, which is meaningless, and there is no mechanism to qualify the parameter ©i©, making the assignment impossible using the function-body ©with©. 983 1243 To solve this problem, parameters are treated like an initialized aggregate: 984 1244 \begin{cfa} … … 990 1250 and implicitly opened \emph{after} a function-body open, to give them higher priority: 991 1251 \begin{cfa} 992 void ?{}( S & s, int `i` ) with ( s ) `with( §\emph{\color{red}params}§ )`{993 s.i = `i`; j = 3; m = 5.5;994 } 995 \end{cfa} 996 Finally, a cast may be used to disambiguate among overload variables in a @with@expression:997 \begin{cfa} 998 with ( w ) { ... } §\C{// ambiguous, same name and no context}§999 with ( (S)w ) { ... } §\C{// unambiguous, cast}§1000 \end{cfa} 1001 and @with@expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate:1252 void ?{}( S & s, int ®i® ) with ( s ) ®with( §\emph{\color{red}params}§ )® { 1253 s.i = ®i®; j = 3; m = 5.5; 1254 } 1255 \end{cfa} 1256 Finally, a cast may be used to disambiguate among overload variables in a ©with© expression: 1257 \begin{cfa} 1258 with ( w ) { ... } §\C{// ambiguous, same name and no context}§ 1259 with ( (S)w ) { ... } §\C{// unambiguous, cast}§ 1260 \end{cfa} 1261 and ©with© expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate: 1002 1262 % \begin{cfa} 1003 1263 % struct S { int i, j; } sv; 1004 % with ( sv ) { §\C{// implicit reference}§1264 % with ( sv ) { §\C{// implicit reference}§ 1005 1265 % S & sr = sv; 1006 % with ( sr ) { §\C{// explicit reference}§1266 % with ( sr ) { §\C{// explicit reference}§ 1007 1267 % S * sp = &sv; 1008 % with ( *sp ) { §\C{// computed reference}§1009 % i = 3; j = 4; §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§1268 % with ( *sp ) { §\C{// computed reference}§ 1269 % i = 3; j = 4; §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§ 1010 1270 % } 1011 % i = 2; j = 3; §\C{\color{red}// sr.i, sr.j}§1271 % i = 2; j = 3; §\C{\color{red}// sr.i, sr.j}§ 1012 1272 % } 1013 % i = 1; j = 2; §\C{\color{red}// sv.i, sv.j}§1273 % i = 1; j = 2; §\C{\color{red}// sv.i, sv.j}§ 1014 1274 % } 1015 1275 % \end{cfa} … … 1019 1279 class C { 1020 1280 int i, j; 1021 int mem() { §\C{\color{red}// implicit "this" parameter}§1022 i = 1; §\C{\color{red}// this->i}§1023 j = 2; §\C{\color{red}// this->j}§1281 int mem() { §\C{\color{red}// implicit "this" parameter}§ 1282 i = 1; §\C{\color{red}// this->i}§ 1283 j = 2; §\C{\color{red}// this->j}§ 1024 1284 } 1025 1285 } … … 1028 1288 \begin{cfa} 1029 1289 struct S { int i, j; }; 1030 int mem( S & ®this® ) { §\C{// explicit "this" parameter}§1031 ®this.®i = 1; §\C{// "this" is not elided}§1290 int mem( S & ®this® ) { §\C{// explicit "this" parameter}§ 1291 ®this.®i = 1; §\C{// "this" is not elided}§ 1032 1292 ®this.®j = 2; 1033 1293 } … … 1038 1298 \begin{cfa} 1039 1299 int mem( S & this ) ®with( this )® { §\C{// with clause}§ 1040 i = 1; §\C{\color{red}// this.i}§1041 j = 2; §\C{\color{red}// this.j}§1300 i = 1; §\C{\color{red}// this.i}§ 1301 j = 2; §\C{\color{red}// this.j}§ 1042 1302 } 1043 1303 \end{cfa} … … 1056 1316 struct S1 { ... } s1; 1057 1317 struct S2 { ... } s2; 1058 ®with( s1 )® { §\C{// with statement}§1318 ®with( s1 )® { §\C{// with statement}§ 1059 1319 // access fields of s1 without qualification 1060 ®with s2® { §\C{// nesting}§1320 ®with s2® { §\C{// nesting}§ 1061 1321 // access fields of s1 and s2 without qualification 1062 1322 } … … 1113 1373 Non-local transfer can cause stack unwinding, \ie non-local routine termination, depending on the kind of raise. 1114 1374 \begin{cfa} 1115 exception_t E {}; §\C{// exception type}§1375 exception_t E {}; §\C{// exception type}§ 1116 1376 void f(...) { 1117 ... throw E{}; ... §\C{// termination}§1118 ... throwResume E{}; ... §\C{// resumption}§1377 ... throw E{}; ... §\C{// termination}§ 1378 ... throwResume E{}; ... §\C{// resumption}§ 1119 1379 } 1120 1380 try { 1121 1381 f(...); 1122 } catch( E e ; §boolean-predicate§ ) { §\C[8cm]{// termination handler}§1382 } catch( E e ; §boolean-predicate§ ) { §\C[8cm]{// termination handler}§ 1123 1383 // recover and continue 1124 } catchResume( E e ; §boolean-predicate§ ) { §\C{// resumption handler}\CRT§1384 } catchResume( E e ; §boolean-predicate§ ) { §\C{// resumption handler}\CRT§ 1125 1385 // repair and return 1126 1386 } finally { … … 1182 1442 For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way: 1183 1443 \begin{cfa} 1184 int ®(*®f®())[®5®]® {...}; §\C{// definition}§1185 ... ®(*®f®())[®3®]® += 1; §\C{// usage}§1444 int ®(*®f®())[®5®]® {...}; §\C{// definition}§ 1445 ... ®(*®f®())[®3®]® += 1; §\C{// usage}§ 1186 1446 \end{cfa} 1187 1447 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}). 1188 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice. 1448 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice, even though Dennis Richie believed otherwise: 1449 \begin{quote} 1450 In spite of its difficulties, I believe that the C's approach to declarations remains plausible, and am comfortable with it; it is a useful unifying principle.~\cite[p.~12]{Ritchie93} 1451 \end{quote} 1189 1452 1190 1453 \CFA provides its own type, variable and routine declarations, using a different syntax. … … 1372 1635 *x = 3; // implicit dereference 1373 1636 int * ®const® y = (int *)104; 1374 *y = *x; // implicit dereference1637 *y = *x; // implicit dereference 1375 1638 \end{cfa} 1376 1639 \end{tabular} … … 1386 1649 \hline 1387 1650 \begin{cfa} 1388 lda r1,100 // load address of x1389 ld r2,(r1) // load value of x1390 lda r3,104 // load address of y1391 st r2,(r3) // store x into y1651 lda r1,100 // load address of x 1652 ld r2,(r1) // load value of x 1653 lda r3,104 // load address of y 1654 st r2,(r3) // store x into y 1392 1655 \end{cfa} 1393 1656 & 1394 1657 \begin{cfa} 1395 1658 1396 ld r2,(100) // load value of x1397 1398 st r2,(104) // store x into y1659 ld r2,(100) // load value of x 1660 1661 st r2,(104) // store x into y 1399 1662 \end{cfa} 1400 1663 \end{tabular} … … 1410 1673 \begin{cfa} 1411 1674 int x, y, ®*® p1, ®*® p2, ®**® p3; 1412 p1 = ®&®x; // p1 points to x1413 p2 = p1; // p2 points to x1414 p1 = ®&®y; // p1 points to y1415 p3 = &p2; // p3 points to p21675 p1 = ®&®x; // p1 points to x 1676 p2 = p1; // p2 points to x 1677 p1 = ®&®y; // p1 points to y 1678 p3 = &p2; // p3 points to p2 1416 1679 \end{cfa} 1417 1680 & … … 1424 1687 For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage 1425 1688 \begin{cfa} 1426 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§1689 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§ 1427 1690 \end{cfa} 1428 1691 Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation. 1429 Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices. 1692 Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices. 1430 1693 1431 1694 Rather than inferring dereference, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality. 1432 1695 In C, objects of pointer type always manipulate the pointer object's address: 1433 1696 \begin{cfa} 1434 p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§1435 p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§1697 p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§ 1698 p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§ 1436 1699 \end{cfa} 1437 1700 even though the assignment to ©p2© is likely incorrect, and the programmer probably meant: 1438 1701 \begin{cfa} 1439 p1 = p2; §\C{// pointer address assignment}§1440 ®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§1702 p1 = p2; §\C{// pointer address assignment}§ 1703 ®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§ 1441 1704 \end{cfa} 1442 1705 The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©). … … 1455 1718 \begin{cfa} 1456 1719 int x, y, ®&® r1, ®&® r2, ®&&® r3; 1457 ®&®r1 = &x; §\C{// r1 points to x}§1458 ®&®r2 = &r1; §\C{// r2 points to x}§1459 ®&®r1 = &y; §\C{// r1 points to y}§1460 ®&&®r3 = ®&®&r2; §\C{// r3 points to r2}§1720 ®&®r1 = &x; §\C{// r1 points to x}§ 1721 ®&®r2 = &r1; §\C{// r2 points to x}§ 1722 ®&®r1 = &y; §\C{// r1 points to y}§ 1723 ®&&®r3 = ®&®&r2; §\C{// r3 points to r2}§ 1461 1724 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§ 1462 1725 \end{cfa} … … 1474 1737 For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}): 1475 1738 \begin{cfa} 1476 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§1739 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§ 1477 1740 \end{cfa} 1478 1741 Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}): 1479 1742 \begin{cfa} 1480 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§1743 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§ 1481 1744 \end{cfa} 1482 1745 Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth. … … 1486 1749 int x, *p1 = &x, **p2 = &p1, ***p3 = &p2, 1487 1750 &r1 = x, &&r2 = r1, &&&r3 = r2; 1488 ***p3 = 3; §\C{// change x}§1489 r3 = 3; §\C{// change x, ***r3}§1490 **p3 = ...; §\C{// change p1}§1491 &r3 = ...; §\C{// change r1, (\&*)**r3, 1 cancellation}§1492 *p3 = ...; §\C{// change p2}§1493 &&r3 = ...; §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§1494 &&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§1751 ***p3 = 3; §\C{// change x}§ 1752 r3 = 3; §\C{// change x, ***r3}§ 1753 **p3 = ...; §\C{// change p1}§ 1754 &r3 = ...; §\C{// change r1, (\&*)**r3, 1 cancellation}§ 1755 *p3 = ...; §\C{// change p2}§ 1756 &&r3 = ...; §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§ 1757 &&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§ 1495 1758 \end{cfa} 1496 1759 Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types. … … 1499 1762 As for a pointer type, a reference type may have qualifiers: 1500 1763 \begin{cfa} 1501 const int cx = 5; §\C{// cannot change cx;}§1502 const int & cr = cx; §\C{// cannot change what cr points to}§1503 ®&®cr = &cx; §\C{// can change cr}§1504 cr = 7; §\C{// error, cannot change cx}§1505 int & const rc = x; §\C{// must be initialized}§1506 ®&®rc = &x; §\C{// error, cannot change rc}§1507 const int & const crc = cx; §\C{// must be initialized}§1508 crc = 7; §\C{// error, cannot change cx}§1509 ®&®crc = &cx; §\C{// error, cannot change crc}§1764 const int cx = 5; §\C{// cannot change cx;}§ 1765 const int & cr = cx; §\C{// cannot change what cr points to}§ 1766 ®&®cr = &cx; §\C{// can change cr}§ 1767 cr = 7; §\C{// error, cannot change cx}§ 1768 int & const rc = x; §\C{// must be initialized}§ 1769 ®&®rc = &x; §\C{// error, cannot change rc}§ 1770 const int & const crc = cx; §\C{// must be initialized}§ 1771 crc = 7; §\C{// error, cannot change cx}§ 1772 ®&®crc = &cx; §\C{// error, cannot change crc}§ 1510 1773 \end{cfa} 1511 1774 Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}: 1512 1775 \begin{cfa} 1513 int & const cr = *0; §\C{// where 0 is the int * zero}§1776 int & const cr = *0; §\C{// where 0 is the int * zero}§ 1514 1777 \end{cfa} 1515 1778 Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management: … … 1518 1781 cr = 5; 1519 1782 free( &cr ); 1520 cr = 7; §\C{// unsound pointer dereference}§1783 cr = 7; §\C{// unsound pointer dereference}§ 1521 1784 \end{cfa} 1522 1785 … … 1543 1806 \begin{cfa} 1544 1807 int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§ 1545 &ar[1] = &w; §\C{// change reference array element}§1546 typeof( ar[1] ) p; §\C{// (gcc) is int, \ie the type of referenced object}§1547 typeof( &ar[1] ) q; §\C{// (gcc) is int \&, \ie the type of reference}§1548 sizeof( ar[1] ) == sizeof( int ); §\C{// is true, \ie the size of referenced object}§1549 sizeof( &ar[1] ) == sizeof( int *) §\C{// is true, \ie the size of a reference}§1808 &ar[1] = &w; §\C{// change reference array element}§ 1809 typeof( ar[1] ) p; §\C{// (gcc) is int, \ie the type of referenced object}§ 1810 typeof( &ar[1] ) q; §\C{// (gcc) is int \&, \ie the type of reference}§ 1811 sizeof( ar[1] ) == sizeof( int ); §\C{// is true, \ie the size of referenced object}§ 1812 sizeof( &ar[1] ) == sizeof( int *) §\C{// is true, \ie the size of a reference}§ 1550 1813 \end{cfa} 1551 1814 … … 1564 1827 Therefore, for pointer/reference initialization, the initializing value must be an address not a value. 1565 1828 \begin{cfa} 1566 int * p = &x; §\C{// assign address of x}§1567 ®int * p = x;® §\C{// assign value of x}§1568 int & r = x; §\C{// must have address of x}§1829 int * p = &x; §\C{// assign address of x}§ 1830 ®int * p = x;® §\C{// assign value of x}§ 1831 int & r = x; §\C{// must have address of x}§ 1569 1832 \end{cfa} 1570 1833 Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given). … … 1575 1838 Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason. 1576 1839 \begin{cfa} 1577 int & f( int & r ); §\C{// reference parameter and return}§1578 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§1840 int & f( int & r ); §\C{// reference parameter and return}§ 1841 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§ 1579 1842 \end{cfa} 1580 1843 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©. … … 1603 1866 void f( int & r ); 1604 1867 void g( int * p ); 1605 f( 3 ); g( ®&®3 ); §\C{// compiler implicit generates temporaries}§1606 f( x + y ); g( ®&®(x + y) ); §\C{// compiler implicit generates temporaries}§1868 f( 3 ); g( ®&®3 ); §\C{// compiler implicit generates temporaries}§ 1869 f( x + y ); g( ®&®(x + y) ); §\C{// compiler implicit generates temporaries}§ 1607 1870 \end{cfa} 1608 1871 Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{ … … 1615 1878 \begin{cfa} 1616 1879 void f( int i ); 1617 void (* fp)( int ); §\C{// routine pointer}§1618 fp = f; §\C{// reference initialization}§1619 fp = &f; §\C{// pointer initialization}§1620 fp = *f; §\C{// reference initialization}§1621 fp(3); §\C{// reference invocation}§1622 (*fp)(3); §\C{// pointer invocation}§1880 void (* fp)( int ); §\C{// routine pointer}§ 1881 fp = f; §\C{// reference initialization}§ 1882 fp = &f; §\C{// pointer initialization}§ 1883 fp = *f; §\C{// reference initialization}§ 1884 fp(3); §\C{// reference invocation}§ 1885 (*fp)(3); §\C{// pointer invocation}§ 1623 1886 \end{cfa} 1624 1887 While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type. 1625 1888 Instead, a routine object should be referenced by a ©const© reference: 1626 1889 \begin{cfa} 1627 ®const® void (®&® fr)( int ) = f; §\C{// routine reference}§1628 fr = ... §\C{// error, cannot change code}§1629 &fr = ...; §\C{// changing routine reference}§1630 fr( 3 ); §\C{// reference call to f}§1631 (*fr)(3); §\C{// error, incorrect type}§1890 ®const® void (®&® fr)( int ) = f; §\C{// routine reference}§ 1891 fr = ... §\C{// error, cannot change code}§ 1892 &fr = ...; §\C{// changing routine reference}§ 1893 fr( 3 ); §\C{// reference call to f}§ 1894 (*fr)(3); §\C{// error, incorrect type}§ 1632 1895 \end{cfa} 1633 1896 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{ … … 1642 1905 \begin{itemize} 1643 1906 \item 1644 if ©R© is an \Index{rvalue} of type ©T & $_1$...&$_r$© where $r \ge 1$ references (©&© symbols) then ©&R© has type ©T ®*®&$_{\color{red}2}$...&$_{\color{red}r}$©, \ie ©T© pointer with $r-1$ references (©&© symbols).1645 1646 \item 1647 if ©L© is an \Index{lvalue} of type ©T & $_1$...&$_l$© where $l \ge 0$ references (©&© symbols) then ©&L© has type ©T ®*®&$_{\color{red}1}$...&$_{\color{red}l}$©, \ie ©T© pointer with $l$ references (©&© symbols).1907 if ©R© is an \Index{rvalue} of type ©T &©$_1\cdots$ ©&©$_r$, where $r \ge 1$ references (©&© symbols), than ©&R© has type ©T ®*®&©$_{\color{red}2}\cdots$ ©&©$_{\color{red}r}$, \ie ©T© pointer with $r-1$ references (©&© symbols). 1908 1909 \item 1910 if ©L© is an \Index{lvalue} of type ©T &©$_1\cdots$ ©&©$_l$, where $l \ge 0$ references (©&© symbols), than ©&L© has type ©T ®*®&©$_{\color{red}1}\cdots$ ©&©$_{\color{red}l}$, \ie ©T© pointer with $l$ references (©&© symbols). 1648 1911 \end{itemize} 1649 1912 The following example shows the first rule applied to different \Index{rvalue} contexts: … … 1651 1914 int x, * px, ** ppx, *** pppx, **** ppppx; 1652 1915 int & rx = x, && rrx = rx, &&& rrrx = rrx ; 1653 x = rrrx; // rrrx is an lvalue with type int &&& (equivalent to x)1654 px = &rrrx; // starting from rrrx, &rrrx is an rvalue with type int *&&& (&x)1655 ppx = &&rrrx; // starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx)1656 pppx = &&&rrrx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx)1657 ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx)1916 x = rrrx; §\C[2.0in]{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§ 1917 px = &rrrx; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (\&x)}§ 1918 ppx = &&rrrx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (\&rx)}§ 1919 pppx = &&&rrrx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (\&rrx)}§ 1920 ppppx = &&&&rrrx; §\C{// starting from \&\&\&rrrx, \&\&\&\&rrrx is an rvalue with type int **** (\&rrrx)}§ 1658 1921 \end{cfa} 1659 1922 The following example shows the second rule applied to different \Index{lvalue} contexts: … … 1661 1924 int x, * px, ** ppx, *** pppx; 1662 1925 int & rx = x, && rrx = rx, &&& rrrx = rrx ; 1663 rrrx = 2; // rrrx is an lvalue with type int &&& (equivalent to x)1664 &rrrx = px; // starting from rrrx, &rrrx is an rvalue with type int *&&& (rx)1665 &&rrrx = ppx; // starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx)1666 &&&rrrx = pppx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx)1926 rrrx = 2; §\C{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§ 1927 &rrrx = px; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (rx)}§ 1928 &&rrrx = ppx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (rrx)}§ 1929 &&&rrrx = pppx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (rrrx)}\CRT§ 1667 1930 \end{cfa} 1668 1931 … … 1677 1940 \begin{cfa} 1678 1941 int x; 1679 x + 1; // lvalue variable (int) converts to rvalue for expression1942 x + 1; §\C[2.0in]{// lvalue variable (int) converts to rvalue for expression}§ 1680 1943 \end{cfa} 1681 1944 An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped. … … 1687 1950 \begin{cfa} 1688 1951 int x, &r = x, f( int p ); 1689 x = ®r® + f( ®r® ); // lvalue reference converts to rvalue1952 x = ®r® + f( ®r® ); §\C{// lvalue reference converts to rvalue}§ 1690 1953 \end{cfa} 1691 1954 An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped. … … 1694 1957 lvalue to reference conversion: \lstinline[deletekeywords=lvalue]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references. 1695 1958 \begin{cfa} 1696 int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &)1697 f( ®x® ); // lvalue variable (int) convert to reference (int &)1959 int x, &r = ®x®, f( int & p ); §\C{// lvalue variable (int) convert to reference (int \&)}§ 1960 f( ®x® ); §\C{// lvalue variable (int) convert to reference (int \&)}§ 1698 1961 \end{cfa} 1699 1962 Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost. … … 1705 1968 \begin{cfa} 1706 1969 int x, & f( int & p ); 1707 f( ®x + 3® ); // rvalue parameter (int) implicitly converts to lvalue temporary reference (int &)1708 ®&f®(...) = &x; // rvalue result (int &) implicitly converts to lvalue temporary reference (int &)1970 f( ®x + 3® ); §\C[1.5in]{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}§ 1971 ®&f®(...) = &x; §\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}\CRT§ 1709 1972 \end{cfa} 1710 1973 In both case, modifications to the temporary are inaccessible (\Index{warning}). … … 1895 2158 in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in: 1896 2159 \begin{cfa} 1897 [§\,§] g(); §\C{// no input or output parameters}§1898 [ void ] g( void ); §\C{// no input or output parameters}§2160 [§\,§] g(); §\C{// no input or output parameters}§ 2161 [ void ] g( void ); §\C{// no input or output parameters}§ 1899 2162 \end{cfa} 1900 2163 … … 1914 2177 \begin{cfa} 1915 2178 typedef int foo; 1916 int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§2179 int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§ 1917 2180 \end{cfa} 1918 2181 The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo. … … 1922 2185 C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg: 1923 2186 \begin{cfa} 1924 [ int ] f( * int, int * ); §\C{// returns an integer, accepts 2 pointers to integers}§1925 [ * int, int * ] f( int ); §\C{// returns 2 pointers to integers, accepts an integer}§2187 [ int ] f( * int, int * ); §\C{// returns an integer, accepts 2 pointers to integers}§ 2188 [ * int, int * ] f( int ); §\C{// returns 2 pointers to integers, accepts an integer}§ 1926 2189 \end{cfa} 1927 2190 The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in: 1928 2191 \begin{cfa} 1929 2192 #define ptoa( n, d ) int (*n)[ d ] 1930 int f( ptoa( p, 5 ) ) ... §\C{// expands to int f( int (*p)[ 5 ] )}§1931 [ int ] f( ptoa( p, 5 ) ) ... §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§2193 int f( ptoa( p, 5 ) ) ... §\C{// expands to int f( int (*p)[ 5 ] )}§ 2194 [ int ] f( ptoa( p, 5 ) ) ... §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§ 1932 2195 \end{cfa} 1933 2196 Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms. … … 1951 2214 int z; 1952 2215 ... x = 0; ... y = z; ... 1953 ®return;® §\C{// implicitly return x, y}§2216 ®return;® §\C{// implicitly return x, y}§ 1954 2217 } 1955 2218 \end{cfa} … … 1961 2224 [ int x, int y ] f() { 1962 2225 ... 1963 } §\C{// implicitly return x, y}§2226 } §\C{// implicitly return x, y}§ 1964 2227 \end{cfa} 1965 2228 In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered. … … 1970 2233 [ int x, int y ] f( int, x, int y ) { 1971 2234 ... 1972 } §\C{// implicitly return x, y}§2235 } §\C{// implicitly return x, y}§ 1973 2236 \end{cfa} 1974 2237 This notation allows the compiler to eliminate temporary variables in nested routine calls. 1975 2238 \begin{cfa} 1976 [ int x, int y ] f( int, x, int y ); §\C{// prototype declaration}§2239 [ int x, int y ] f( int, x, int y ); §\C{// prototype declaration}§ 1977 2240 int a, b; 1978 2241 [a, b] = f( f( f( a, b ) ) ); … … 1988 2251 as well, parameter names are optional, \eg: 1989 2252 \begin{cfa} 1990 [ int x ] f (); §\C{// returning int with no parameters}§1991 [ * int ] g (int y); §\C{// returning pointer to int with int parameter}§1992 [ ] h ( int, char ); §\C{// returning no result with int and char parameters}§1993 [ * int, int ] j ( int ); §\C{// returning pointer to int and int, with int parameter}§2253 [ int x ] f (); §\C{// returning int with no parameters}§ 2254 [ * int ] g (int y); §\C{// returning pointer to int with int parameter}§ 2255 [ ] h ( int, char ); §\C{// returning no result with int and char parameters}§ 2256 [ * int, int ] j ( int ); §\C{// returning pointer to int and int, with int parameter}§ 1994 2257 \end{cfa} 1995 2258 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa). … … 2012 2275 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg: 2013 2276 \begin{cfa} 2014 * [ int x ] () fp; §\C{// pointer to routine returning int with no parameters}§2015 * [ * int ] (int y) gp; §\C{// pointer to routine returning pointer to int with int parameter}§2016 * [ ] (int,char) hp; §\C{// pointer to routine returning no result with int and char parameters}§2017 * [ * int,int ] ( int ) jp; §\C{// pointer to routine returning pointer to int and int, with int parameter}§2277 * [ int x ] () fp; §\C{// pointer to routine returning int with no parameters}§ 2278 * [ * int ] (int y) gp; §\C{// pointer to routine returning pointer to int with int parameter}§ 2279 * [ ] (int,char) hp; §\C{// pointer to routine returning no result with int and char parameters}§ 2280 * [ * int,int ] ( int ) jp; §\C{// pointer to routine returning pointer to int and int, with int parameter}§ 2018 2281 \end{cfa} 2019 2282 While parameter names are optional, \emph{a routine name cannot be specified}; 2020 2283 for example, the following is incorrect: 2021 2284 \begin{cfa} 2022 * [ int x ] f () fp; §\C{// routine name "f" is not allowed}§2285 * [ int x ] f () fp; §\C{// routine name "f" is not allowed}§ 2023 2286 \end{cfa} 2024 2287 … … 2043 2306 whereas a named (keyword) call may be: 2044 2307 \begin{cfa} 2045 p( z : 3, x : 4, y : 7 ); §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§2308 p( z : 3, x : 4, y : 7 ); §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§ 2046 2309 \end{cfa} 2047 2310 Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters. … … 2060 2323 For example, the following routine prototypes and definition are all valid. 2061 2324 \begin{cfa} 2062 void p( int, int, int ); §\C{// equivalent prototypes}§2325 void p( int, int, int ); §\C{// equivalent prototypes}§ 2063 2326 void p( int x, int y, int z ); 2064 2327 void p( int y, int x, int z ); 2065 2328 void p( int z, int y, int x ); 2066 void p( int q, int r, int s ) {} §\C{// match with this definition}§2329 void p( int q, int r, int s ) {} §\C{// match with this definition}§ 2067 2330 \end{cfa} 2068 2331 Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming. … … 2076 2339 int f( int x, double y ); 2077 2340 2078 f( j : 3, i : 4 ); §\C{// 1st f}§2079 f( x : 7, y : 8.1 ); §\C{// 2nd f}§2080 f( 4, 5 ); §\C{// ambiguous call}§2341 f( j : 3, i : 4 ); §\C{// 1st f}§ 2342 f( x : 7, y : 8.1 ); §\C{// 2nd f}§ 2343 f( 4, 5 ); §\C{// ambiguous call}§ 2081 2344 \end{cfa} 2082 2345 However, named arguments compound routine resolution in conjunction with conversions: 2083 2346 \begin{cfa} 2084 f( i : 3, 5.7 ); §\C{// ambiguous call ?}§2347 f( i : 3, 5.7 ); §\C{// ambiguous call ?}§ 2085 2348 \end{cfa} 2086 2349 Depending on the cost associated with named arguments, this call could be resolvable or ambiguous. … … 2096 2359 the allowable positional calls are: 2097 2360 \begin{cfa} 2098 p(); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§2099 p( 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§2100 p( 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§2101 p( 4, 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§2361 p(); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§ 2362 p( 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§ 2363 p( 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§ 2364 p( 4, 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§ 2102 2365 // empty arguments 2103 p( , 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§2104 p( 4, , 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§2105 p( 4, 4, ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§2106 p( 4, , ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§2107 p( , 4, ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§2108 p( , , 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§2109 p( , , ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§2366 p( , 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§ 2367 p( 4, , 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§ 2368 p( 4, 4, ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§ 2369 p( 4, , ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§ 2370 p( , 4, ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§ 2371 p( , , 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§ 2372 p( , , ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§ 2110 2373 \end{cfa} 2111 2374 Here the missing arguments are inserted from the default values in the parameter list. … … 2131 2394 Default values may only appear in a prototype versus definition context: 2132 2395 \begin{cfa} 2133 void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§2134 void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§2135 void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§2396 void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§ 2397 void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§ 2398 void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§ 2136 2399 \end{cfa} 2137 2400 The reason for this restriction is to allow separate compilation. … … 2158 2421 \begin{cfa} 2159 2422 void p( int x, int y = 2, int z = 3... ); 2160 p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§2161 p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§2423 p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§ 2424 p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§ 2162 2425 \end{cfa} 2163 2426 The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments; … … 2189 2452 Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as: 2190 2453 \begin{cfa} 2191 p( 1, /* default */, 5 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§2454 p( 1, /* default */, 5 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§ 2192 2455 \end{cfa} 2193 2456 … … 2202 2465 \begin{cfa} 2203 2466 struct { 2204 int f1; §\C{// named field}§2205 int f2 : 4; §\C{// named field with bit field size}§2206 int : 3; §\C{// unnamed field for basic type with bit field size}§2207 int ; §\C{// disallowed, unnamed field}§2208 int *; §\C{// disallowed, unnamed field}§2209 int (*)( int ); §\C{// disallowed, unnamed field}§2467 int f1; §\C{// named field}§ 2468 int f2 : 4; §\C{// named field with bit field size}§ 2469 int : 3; §\C{// unnamed field for basic type with bit field size}§ 2470 int ; §\C{// disallowed, unnamed field}§ 2471 int *; §\C{// disallowed, unnamed field}§ 2472 int (*)( int ); §\C{// disallowed, unnamed field}§ 2210 2473 }; 2211 2474 \end{cfa} … … 2215 2478 \begin{cfa} 2216 2479 struct { 2217 int , , ; §\C{// 3 unnamed fields}§2480 int , , ; §\C{// 3 unnamed fields}§ 2218 2481 } 2219 2482 \end{cfa} … … 2262 2525 struct T t; 2263 2526 } s; 2264 2527 2265 2528 2266 2529 … … 2309 2572 const unsigned int size = 5; 2310 2573 int ia[size]; 2311 ... §\C{// assign values to array ia}§2312 qsort( ia, size ); §\C{// sort ascending order using builtin ?<?}§2574 ... §\C{// assign values to array ia}§ 2575 qsort( ia, size ); §\C{// sort ascending order using builtin ?<?}§ 2313 2576 { 2314 2577 ®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§ 2315 qsort( ia, size ); §\C{// sort descending order by local redefinition}§2578 qsort( ia, size ); §\C{// sort descending order by local redefinition}§ 2316 2579 } 2317 2580 \end{cfa} … … 2321 2584 The following program in undefined in \CFA (and Indexc{gcc}) 2322 2585 \begin{cfa} 2323 [* [int]( int )] foo() { §\C{// int (* foo())( int )}§2586 [* [int]( int )] foo() { §\C{// int (* foo())( int )}§ 2324 2587 int ®i® = 7; 2325 2588 int bar( int p ) { 2326 ®i® += 1; §\C{// dependent on local variable}§2327 sout | ®i® | endl;2589 ®i® += 1; §\C{// dependent on local variable}§ 2590 sout | ®i®; 2328 2591 } 2329 return bar; §\C{// undefined because of local dependence}§2592 return bar; §\C{// undefined because of local dependence}§ 2330 2593 } 2331 2594 int main() { 2332 * [int]( int ) fp = foo(); §\C{// int (* fp)( int )}§2333 sout | fp( 3 ) | endl;2334 } 2335 \end{cfa} 2336 because 2595 * [int]( int ) fp = foo(); §\C{// int (* fp)( int )}§ 2596 sout | fp( 3 ); 2597 } 2598 \end{cfa} 2599 because 2337 2600 2338 2601 Currently, there are no \Index{lambda} expressions, \ie unnamed routines because routine names are very important to properly select the correct routine. … … 2343 2606 In C and \CFA, lists of elements appear in several contexts, such as the parameter list of a routine call. 2344 2607 \begin{cfa} 2345 f( ®2, x, 3 + i® ); §\C{// element list}§2608 f( ®2, x, 3 + i® ); §\C{// element list}§ 2346 2609 \end{cfa} 2347 2610 A list of elements is called a \newterm{tuple}, and is different from a \Index{comma expression}. … … 2360 2623 typedef struct { int quot, rem; } div_t; §\C[7cm]{// from include stdlib.h}§ 2361 2624 div_t div( int num, int den ); 2362 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§2363 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§2625 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§ 2626 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§ 2364 2627 \end{cfa} 2365 2628 This approach requires a name for the return type and fields, where \Index{naming} is a common programming-language issue. … … 2371 2634 For example, consider C's \Indexc{modf} function, which returns the integral and fractional part of a floating value. 2372 2635 \begin{cfa} 2373 double modf( double x, double * i ); §\C{// from include math.h}§2374 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§2375 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§2636 double modf( double x, double * i ); §\C{// from include math.h}§ 2637 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§ 2638 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§ 2376 2639 \end{cfa} 2377 2640 This approach requires allocating storage for the return values, which complicates the call site with a sequence of variable declarations leading to the call. … … 2400 2663 When a function call is passed as an argument to another call, the best match of actual arguments to formal parameters is evaluated given all possible expression interpretations in the current scope. 2401 2664 \begin{cfa} 2402 void g( int, int ); §\C{// 1}§2403 void g( double, double ); §\C{// 2}§2404 g( div( 13, 5 ) ); §\C{// select 1}§2405 g( modf( 13.5 ) ); §\C{// select 2}§2665 void g( int, int ); §\C{// 1}§ 2666 void g( double, double ); §\C{// 2}§ 2667 g( div( 13, 5 ) ); §\C{// select 1}§ 2668 g( modf( 13.5 ) ); §\C{// select 2}§ 2406 2669 \end{cfa} 2407 2670 In this case, there are two overloaded ©g© routines. … … 2412 2675 The previous examples can be rewritten passing the multiple returned-values directly to the ©printf© function call. 2413 2676 \begin{cfa} 2414 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§2415 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§2416 2417 [ double, double ] modf( double x ); §\C{// from include math}§2418 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§2677 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§ 2678 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§ 2679 2680 [ double, double ] modf( double x ); §\C{// from include math}§ 2681 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§ 2419 2682 \end{cfa} 2420 2683 This approach provides the benefits of compile-time checking for appropriate return statements as in aggregation, but without the required verbosity of declaring a new named type. … … 2426 2689 \begin{cfa} 2427 2690 int quot, rem; 2428 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§2429 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§2691 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§ 2692 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§ 2430 2693 \end{cfa} 2431 2694 Here, the multiple return-values are matched in much the same way as passing multiple return-values to multiple parameters in a call. … … 2433 2696 2434 2697 \subsection{Expressions} 2698 2699 % Change order of expression evaluation. 2700 % http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r2.pdf 2435 2701 2436 2702 Multiple-return-value functions provide \CFA with a new syntax for expressing a combination of expressions in the return statement and a combination of types in a function signature. … … 2453 2719 In \CFA, it is possible to overcome this restriction by declaring a \newterm{tuple variable}. 2454 2720 \begin{cfa} 2455 [int, int] ®qr® = div( 13, 5 ); §\C{// initialize tuple variable}§2456 printf( "%d %d\n", ®qr® ); §\C{// print quotient/remainder}§2721 [int, int] ®qr® = div( 13, 5 ); §\C{// initialize tuple variable}§ 2722 printf( "%d %d\n", ®qr® ); §\C{// print quotient/remainder}§ 2457 2723 \end{cfa} 2458 2724 It is now possible to match the multiple return-values to a single variable, in much the same way as \Index{aggregation}. … … 2460 2726 One way to access the individual components of a tuple variable is with assignment. 2461 2727 \begin{cfa} 2462 [ quot, rem ] = qr; §\C{// assign multiple variables}§2728 [ quot, rem ] = qr; §\C{// assign multiple variables}§ 2463 2729 \end{cfa} 2464 2730 … … 2483 2749 [int, double] * p; 2484 2750 2485 int y = x.0; §\C{// access int component of x}§2486 y = f().1; §\C{// access int component of f}§2487 p->0 = 5; §\C{// access int component of tuple pointed-to by p}§2488 g( x.1, x.0 ); §\C{// rearrange x to pass to g}§2489 double z = [ x, f() ].0.1; §\C{// access second component of first component of tuple expression}§2751 int y = x.0; §\C{// access int component of x}§ 2752 y = f().1; §\C{// access int component of f}§ 2753 p->0 = 5; §\C{// access int component of tuple pointed-to by p}§ 2754 g( x.1, x.0 ); §\C{// rearrange x to pass to g}§ 2755 double z = [ x, f() ].0.1; §\C{// access second component of first component of tuple expression}§ 2490 2756 \end{cfa} 2491 2757 Tuple-index expressions can occur on any tuple-typed expression, including tuple-returning functions, square-bracketed tuple expressions, and other tuple-index expressions, provided the retrieved component is also a tuple. … … 2554 2820 double y; 2555 2821 [int, double] z; 2556 [y, x] = 3.14; §\C{// mass assignment}§2822 [y, x] = 3.14; §\C{// mass assignment}§ 2557 2823 [x, y] = z; §\C{// multiple assignment}§ 2558 2824 z = 10; §\C{// mass assignment}§ 2559 z = [x, y]; §\C{// multiple assignment}§2825 z = [x, y]; §\C{// multiple assignment}§ 2560 2826 \end{cfa} 2561 2827 Let $L_i$ for $i$ in $[0, n)$ represent each component of the flattened left side, $R_i$ represent each component of the flattened right side of a multiple assignment, and $R$ represent the right side of a mass assignment. … … 2601 2867 double c, d; 2602 2868 [ void ] f( [ int, int ] ); 2603 f( [ c, a ] = [ b, d ] = 1.5 ); // assignments in parameter list2869 f( [ c, a ] = [ b, d ] = 1.5 ); §\C{// assignments in parameter list}§ 2604 2870 \end{cfa} 2605 2871 The tuple expression begins with a mass assignment of ©1.5© into ©[b, d]©, which assigns ©1.5© into ©b©, which is truncated to ©1©, and ©1.5© into ©d©, producing the tuple ©[1, 1.5]© as a result. … … 2614 2880 \begin{cfa} 2615 2881 struct S; 2616 void ?{}(S *); // (1)2617 void ?{}(S *, int); // (2)2618 void ?{}(S * double); // (3)2619 void ?{}(S *, S); // (4)2620 2621 [S, S] x = [3, 6.28]; // uses (2), (3), specialized constructors2622 [S, S] y; // uses (1), (1), default constructor2623 [S, S] z = x.0; // uses (4), (4), copy constructor2882 void ?{}(S *); §\C{// (1)}§ 2883 void ?{}(S *, int); §\C{// (2)}§ 2884 void ?{}(S * double); §\C{// (3)}§ 2885 void ?{}(S *, S); §\C{// (4)}§ 2886 2887 [S, S] x = [3, 6.28]; §\C{// uses (2), (3), specialized constructors}§ 2888 [S, S] y; §\C{// uses (1), (1), default constructor}§ 2889 [S, S] z = x.0; §\C{// uses (4), (4), copy constructor}§ 2624 2890 \end{cfa} 2625 2891 In this example, ©x© is initialized by the multiple constructor calls ©?{}(&x.0, 3)© and ©?{}(&x.1, 6.28)©, while ©y© is initialized by two default constructor calls ©?{}(&y.0)© and ©?{}(&y.1)©. … … 2662 2928 A member-access tuple may be used anywhere a tuple can be used, \eg: 2663 2929 \begin{cfa} 2664 s.[ y, z, x ] = [ 3, 3.2, 'x' ]; §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§2665 f( s.[ y, z ] ); §\C{// equivalent to f( s.y, s.z )}§2930 s.[ y, z, x ] = [ 3, 3.2, 'x' ]; §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§ 2931 f( s.[ y, z ] ); §\C{// equivalent to f( s.y, s.z )}§ 2666 2932 \end{cfa} 2667 2933 Note, the fields appearing in a record-field tuple may be specified in any order; … … 2673 2939 void f( double, long ); 2674 2940 2675 f( x.[ 0, 3 ] ); §\C{// f( x.0, x.3 )}§2676 x.[ 0, 1 ] = x.[ 1, 0 ]; §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§2941 f( x.[ 0, 3 ] ); §\C{// f( x.0, x.3 )}§ 2942 x.[ 0, 1 ] = x.[ 1, 0 ]; §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§ 2677 2943 [ long, int, long ] y = x.[ 2, 0, 2 ]; 2678 2944 \end{cfa} … … 2691 2957 \begin{cfa} 2692 2958 [ int, float, double ] f(); 2693 [ double, float ] x = f().[ 2, 1 ]; §\C{// f() called once}§2959 [ double, float ] x = f().[ 2, 1 ]; §\C{// f() called once}§ 2694 2960 \end{cfa} 2695 2961 … … 2704 2970 That is, a cast can be used to select the type of an expression when it is ambiguous, as in the call to an overloaded function. 2705 2971 \begin{cfa} 2706 int f(); // (1)2707 double f(); // (2)2708 2709 f(); // ambiguous - (1),(2) both equally viable2710 (int)f(); // choose (2)2972 int f(); §\C{// (1)}§ 2973 double f(); §\C{// (2)}§ 2974 2975 f(); §\C{// ambiguous - (1),(2) both equally viable}§ 2976 (int)f(); §\C{// choose (2)}§ 2711 2977 \end{cfa} 2712 2978 Since casting is a fundamental operation in \CFA, casts need to be given a meaningful interpretation in the context of tuples. … … 2716 2982 void g(); 2717 2983 2718 (void)f(); // valid, ignore results2719 (int)g(); // invalid, void cannot be converted to int2984 (void)f(); §\C{// valid, ignore results}§ 2985 (int)g(); §\C{// invalid, void cannot be converted to int}§ 2720 2986 2721 2987 struct A { int x; }; 2722 (struct A)f(); // invalid, int cannot be converted to A2988 (struct A)f(); §\C{// invalid, int cannot be converted to A}§ 2723 2989 \end{cfa} 2724 2990 In C, line 4 is a valid cast, which calls ©f© and discards its result. … … 2736 3002 [int, [int, int], int] g(); 2737 3003 2738 ([int, double])f(); // (1) valid2739 ([int, int, int])g(); // (2) valid2740 ([void, [int, int]])g(); // (3) valid2741 ([int, int, int, int])g(); // (4) invalid2742 ([int, [int, int, int]])g(); // (5) invalid3004 ([int, double])f(); §\C{// (1) valid}§ 3005 ([int, int, int])g(); §\C{// (2) valid}§ 3006 ([void, [int, int]])g(); §\C{// (3) valid}§ 3007 ([int, int, int, int])g(); §\C{// (4) invalid}§ 3008 ([int, [int, int, int]])g(); §\C{// (5) invalid}§ 2743 3009 \end{cfa} 2744 3010 … … 2800 3066 void f([int, int], int, int); 2801 3067 2802 f([0, 0], 0, 0); // no cost2803 f(0, 0, 0, 0); // cost for structuring2804 f([0, 0,], [0, 0]); // cost for flattening2805 f([0, 0, 0], 0); // cost for flattening and structuring3068 f([0, 0], 0, 0); §\C{// no cost}§ 3069 f(0, 0, 0, 0); §\C{// cost for structuring}§ 3070 f([0, 0,], [0, 0]); §\C{// cost for flattening}§ 3071 f([0, 0, 0], 0); §\C{// cost for flattening and structuring}§ 2806 3072 \end{cfa} 2807 3073 … … 2866 3132 [ unsigned int, char ] 2867 3133 [ double, double, double ] 2868 [ * int, int * ] §\C{// mix of CFA and ANSI}§3134 [ * int, int * ] §\C{// mix of CFA and ANSI}§ 2869 3135 [ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ] 2870 3136 \end{cfa} … … 2873 3139 Examples of declarations using tuple types are: 2874 3140 \begin{cfa} 2875 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§2876 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§3141 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§ 3142 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§ 2877 3143 [ [ int, int ] ] z ([ int, int ]); 2878 3144 \end{cfa} … … 2891 3157 [ int, int ] w1; 2892 3158 [ int, int, int ] w2; 2893 [ void ] f (int, int, int); /* three input parameters of type int */2894 [ void ] g ([ int, int, int ]); /* 3 element tuple as input */3159 [ void ] f (int, int, int); §\C{// three input parameters of type int}§ 3160 [ void ] g ([ int, int, int ]); §\C{3 element tuple as input}§ 2895 3161 f( [ 1, 2, 3 ] ); 2896 3162 f( w1, 3 ); … … 2972 3238 [ int, int, int, int ] w = [ 1, 2, 3, 4 ]; 2973 3239 int x = 5; 2974 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§3240 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§ 2975 3241 \end{cfa} 2976 3242 Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values; … … 3060 3326 both these examples produce indeterminate results: 3061 3327 \begin{cfa} 3062 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§3063 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in righthand side of multiple assignment}§3328 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§ 3329 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in righthand side of multiple assignment}§ 3064 3330 \end{cfa} 3065 3331 … … 3083 3349 3084 3350 3085 \section{I/O Library} 3086 \label{s:IOLibrary} 3087 \index{input/output library} 3088 3089 The goal of \CFA I/O is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way. 3090 The approach combines ideas from \CC and Python. 3091 The \CFA header file for the I/O library is \Indexc{fstream}. 3092 3093 The common case is printing out a sequence of variables separated by whitespace. 3351 \section{Stream I/O Library} 3352 \label{s:StreamIOLibrary} 3353 \index{input/output stream library} 3354 \index{stream library} 3355 3356 The goal of \CFA stream input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way. 3357 Stream I/O can be implicitly or explicitly formatted. 3358 Implicit formatting means \CFA selects the output or input format for values that match with the type of a variable. 3359 Explicit formatting means additional information is specified to augment how an output or input of value is interpreted. 3360 \CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators, and Python implicit spacing and newline. 3361 Specifically: 3362 \begin{itemize} 3363 \item 3364 ©printf©/Python format codes are dense, making them difficult to read and remember. 3365 \CFA/\CC format manipulators are named, making them easier to read and remember. 3366 \item 3367 ©printf©/Python separates format codes from associated variables, making it difficult to match codes with variables. 3368 \CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding. 3369 \item 3370 Format manipulators in \CFA have local effect, whereas \CC have global effect, except ©setw©. 3371 Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects. 3372 Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location. 3373 (To guarantee no side-effects, manipulator values must be saved and restored across function calls.) 3374 \item 3375 \CFA has more sophisticated implicit spacing between values than Python, plus implicit newline at the end of a print. 3376 \end{itemize} 3377 The \CFA header file for the I/O library is \Indexc{fstream.hfa}. 3378 3379 For implicit formatted output, the common case is printing a series of variables separated by whitespace. 3094 3380 \begin{cquote} 3095 \begin{tabular}{@{}l@{\hspace{ 3em}}l@{}}3096 \multicolumn{1}{c@{\hspace{ 3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\3381 \begin{tabular}{@{}l@{\hspace{2em}}l@{\hspace{2em}}l@{}} 3382 \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CC}} & \multicolumn{1}{c}{\textbf{Python}} \\ 3097 3383 \begin{cfa} 3098 3384 int x = 1, y = 2, z = 3; 3099 sout | x ®|® y ®|® z | endl;3385 sout | x ®|® y ®|® z; 3100 3386 \end{cfa} 3101 3387 & … … 3103 3389 3104 3390 cout << x ®<< " "® << y ®<< " "® << z << endl; 3391 \end{cfa} 3392 & 3393 \begin{cfa} 3394 x = 1; y = 2; z = 3 3395 print( x, y, z ) 3105 3396 \end{cfa} 3106 3397 \\ … … 3110 3401 & 3111 3402 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3112 1 2 3 3403 1® ®2® ®3 3404 \end{cfa} 3405 & 3406 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3407 1® ®2® ®3 3113 3408 \end{cfa} 3114 3409 \end{tabular} 3115 3410 \end{cquote} 3116 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators .3117 Similar simplification occurs for \Index{tuple} I/O, which prints all tuple valuesseparated by ``\lstinline[showspaces=true]@, @''.3411 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators and newline. 3412 Similar simplification occurs for \Index{tuple} I/O, which flattens the tuple and prints each value separated by ``\lstinline[showspaces=true]@, @''. 3118 3413 \begin{cfa} 3119 3414 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ]; 3120 sout | t1 | t2 | endl;§\C{// print tuples}§3415 sout | t1 | t2; §\C{// print tuples}§ 3121 3416 \end{cfa} 3122 3417 \begin{cfa}[showspaces=true,aboveskip=0pt] 3123 3418 1®, ®2®, ®3 4®, ®5®, ®6 3124 3419 \end{cfa} 3125 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadableoperator, other than assignment.3420 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority \emph{overloadable} operator, other than assignment. 3126 3421 Therefore, fewer output expressions require parenthesis. 3127 3422 \begin{cquote} … … 3130 3425 & 3131 3426 \begin{cfa} 3132 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;3427 sout | x * 3 | y + 1 | z << 2 | x == y | ®(®x | y®)® | ®(®x || y®)® | ®(®x > z ? 1 : 2®)®; 3133 3428 \end{cfa} 3134 3429 \\ … … 3136 3431 & 3137 3432 \begin{cfa} 3138 cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << (x | y) << (x || y) << (x > z ? 1 : 2)<< endl;3433 cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << ®(®x | y®)® << ®(®x || y®)® << ®(®x > z ? 1 : 2®)® << endl; 3139 3434 \end{cfa} 3140 3435 \\ … … 3145 3440 \end{tabular} 3146 3441 \end{cquote} 3147 There is a weak similarity between the \CFA logical-or operator and the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output. 3442 Input and output use a uniform operator, ©|©, rather than separate operators, as in ©>>© and ©<<© for \CC. 3443 There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output. 3444 3445 For implicit formatted input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable. 3446 \begin{cquote} 3447 \begin{lrbox}{\LstBox} 3448 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3449 int x; double y char z; 3450 \end{cfa} 3451 \end{lrbox} 3452 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{3em}}l@{}} 3453 \multicolumn{1}{@{}l@{}}{\usebox\LstBox} \\ 3454 \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CC}} & \multicolumn{1}{c}{\textbf{Python}} \\ 3455 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3456 sin | x | y | z; 3457 \end{cfa} 3458 & 3459 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3460 cin >> x >> y >> z; 3461 \end{cfa} 3462 & 3463 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3464 x = int(input()); y = float(input()); z = input(); 3465 \end{cfa} 3466 \\ 3467 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3468 ®1® ®2.5® ®A® 3469 3470 3471 \end{cfa} 3472 & 3473 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3474 ®1® ®2.5® ®A® 3475 3476 3477 \end{cfa} 3478 & 3479 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3480 ®1® 3481 ®2.5® 3482 ®A® 3483 \end{cfa} 3484 \end{tabular} 3485 \end{cquote} 3486 3148 3487 3149 3488 3150 3489 \subsection{Implicit Separator} 3151 3490 3152 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator .3491 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator for output. 3153 3492 The rules for implicitly adding the separator are: 3154 3493 \begin{enumerate} … … 3156 3495 A separator does not appear at the start or end of a line. 3157 3496 \begin{cfa}[belowskip=0pt] 3158 sout | 1 | 2 | 3 | endl;3497 sout | 1 | 2 | 3; 3159 3498 \end{cfa} 3160 3499 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3165 3504 A separator does not appear before or after a character literal or variable. 3166 3505 \begin{cfa} 3167 sout | '1' | '2' | '3' | endl;3506 sout | '1' | '2' | '3'; 3168 3507 123 3169 3508 \end{cfa} 3170 3509 3171 3510 \item 3172 A separator does not appear before or after a null (empty) C string .3173 \begin{cfa} 3174 sout | 1 | "" | 2 | "" | 3 | endl;3511 A separator does not appear before or after a null (empty) C string, which is a local mechanism to disable insertion of the separator character. 3512 \begin{cfa} 3513 sout | 1 | "" | 2 | "" | 3; 3175 3514 123 3176 3515 \end{cfa} 3177 which is a local mechanism to disable insertion of the separator character. 3178 3179 \item 3180 A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@ 3516 3517 \item 3518 {\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}} 3519 A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@, where \lstinline[basicstyle=\tt]@»@ is a closing citation mark. 3520 \begin{cfa}[belowskip=0pt] 3521 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" 3522 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x"; 3523 \end{cfa} 3524 \begin{cfa}[basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt] 3525 1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\color{red}\textcent§ x 8®»® x 9®)® x 10®]® x 11®}® x 3526 \end{cfa}}% 3527 3528 \item 3529 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@, where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark. 3181 3530 %$ 3182 3531 \begin{cfa}[mathescape=off] 3183 3532 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" 3184 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10 | endl;3533 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10; 3185 3534 \end{cfa} 3186 3535 %$ … … 3189 3538 \end{cfa} 3190 3539 %$ 3191 where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark. 3192 3193 \item 3194 {\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}} 3195 A seperator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@ 3540 3541 \item 3542 A seperator does not appear before/after a C string starting/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@ 3196 3543 \begin{cfa}[belowskip=0pt] 3197 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" 3198 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x" | endl; 3199 \end{cfa} 3200 \begin{cfa}[basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt] 3201 1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\color{red}\textcent§ x 8®»® x 9®)® x 10®]® x 11®}® x 3202 \end{cfa}}% 3203 where \lstinline[basicstyle=\tt]@»@ is a closing citation mark. 3204 3205 \item 3206 A seperator does not appear before or after a C string begining/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@ 3207 \begin{cfa}[belowskip=0pt] 3208 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx" | endl; 3544 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx"; 3209 3545 \end{cfa} 3210 3546 \begin{cfa}[basicstyle=\tt,showspaces=true,showtabs=true,aboveskip=0pt,belowskip=0pt] … … 3215 3551 If a space is desired before or after one of the special string start/end characters, simply insert a space. 3216 3552 \begin{cfa}[belowskip=0pt] 3217 sout | "x (§\color{red}\texttt{\textvisiblespace}§" | 1 | "§\color{red}\texttt{\textvisiblespace}§) x" | 2 | "§\color{red}\texttt{\textvisiblespace}§, x" | 3 | "§\color{red}\texttt{\textvisiblespace}§:x:§\color{red}\texttt{\textvisiblespace}§" | 4 | endl;3553 sout | "x (§\color{red}\texttt{\textvisiblespace}§" | 1 | "§\color{red}\texttt{\textvisiblespace}§) x" | 2 | "§\color{red}\texttt{\textvisiblespace}§, x" | 3 | "§\color{red}\texttt{\textvisiblespace}§:x:§\color{red}\texttt{\textvisiblespace}§" | 4; 3218 3554 \end{cfa} 3219 3555 \begin{cfa}[basicstyle=\tt,showspaces=true,showtabs=true,aboveskip=0pt,belowskip=0pt] … … 3223 3559 3224 3560 3225 \subsection{Manipulator} 3226 3227 The following \CC-style \Index{manipulator}s and routines control implicit seperation. 3561 \subsection{Separation Manipulators} 3562 3563 The following \Index{manipulator}s control \Index{implicit output separation}. 3564 The effect of these manipulators is global for an output stream (except ©sepOn© and ©sepOff©). 3228 3565 \begin{enumerate} 3229 3566 \item 3230 Routines\Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.3567 \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string. 3231 3568 The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 3232 3569 \begin{cfa}[mathescape=off,belowskip=0pt] 3233 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§3234 sout | 1 | 2 | 3 | " \"" | ®sep® | "\"" | endl;3570 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§ 3571 sout | 1 | 2 | 3 | " \"" | ®sep® | "\""; 3235 3572 \end{cfa} 3236 3573 %$ … … 3240 3577 %$ 3241 3578 \begin{cfa}[belowskip=0pt] 3242 sepSet( sout, " " ); §\C{// reset separator to " "}§3243 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"" | endl;3579 sepSet( sout, " " ); §\C{// reset separator to " "}§ 3580 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\""; 3244 3581 \end{cfa} 3245 3582 \begin{cfa}[showspaces=true,aboveskip=0pt] … … 3248 3585 ©sepGet© can be used to store a separator and then restore it: 3249 3586 \begin{cfa}[belowskip=0pt] 3250 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§3251 strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§3252 sepSet( sout, "_" ); §\C{// change separator to underscore}§3253 sout | 1 | 2 | 3 | endl;3587 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§ 3588 strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§ 3589 sepSet( sout, "_" ); §\C{// change separator to underscore}§ 3590 sout | 1 | 2 | 3; 3254 3591 \end{cfa} 3255 3592 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3257 3594 \end{cfa} 3258 3595 \begin{cfa}[belowskip=0pt] 3259 sepSet( sout, store ); §\C{// change separator back to original}§3260 sout | 1 | 2 | 3 | endl;3596 sepSet( sout, store ); §\C{// change separator back to original}§ 3597 sout | 1 | 2 | 3; 3261 3598 \end{cfa} 3262 3599 \begin{cfa}[showspaces=true,aboveskip=0pt] … … 3265 3602 3266 3603 \item 3267 Routine\Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.3604 \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string. 3268 3605 The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 3269 3606 \begin{cfa}[belowskip=0pt] 3270 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§3271 sout | t1 | t2 | " \"" | ®sepTuple® | "\"" | endl;3607 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§ 3608 sout | t1 | t2 | " \"" | ®sepTuple® | "\""; 3272 3609 \end{cfa} 3273 3610 \begin{cfa}[showspaces=true,aboveskip=0pt] … … 3275 3612 \end{cfa} 3276 3613 \begin{cfa}[belowskip=0pt] 3277 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§3278 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"" | endl;3614 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§ 3615 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\""; 3279 3616 \end{cfa} 3280 3617 \begin{cfa}[showspaces=true,aboveskip=0pt] … … 3284 3621 3285 3622 \item 3286 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items.3623 \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} toggle printing the separator. 3287 3624 \begin{cfa}[belowskip=0pt] 3288 sout | sepDisable | 1 | 2 | 3 | endl; §\C{// globallyturn off implicit separator}§3625 sout | sepDisable | 1 | 2 | 3; §\C{// turn off implicit separator}§ 3289 3626 \end{cfa} 3290 3627 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3292 3629 \end{cfa} 3293 3630 \begin{cfa}[belowskip=0pt] 3294 sout | sepEnable | 1 | 2 | 3 | endl; §\C{// globallyturn on implicit separator}§3631 sout | sepEnable | 1 | 2 | 3; §\C{// turn on implicit separator}§ 3295 3632 \end{cfa} 3296 3633 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3299 3636 3300 3637 \item 3301 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.3638 \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} toggle printing the separator with respect to the next printed item, and then return to the global seperator setting. 3302 3639 \begin{cfa}[belowskip=0pt] 3303 sout | 1 | sepOff | 2 | 3 | endl; §\C{// locally turn off implicit separator}§3640 sout | 1 | sepOff | 2 | 3; §\C{// turn off implicit separator for the next item}§ 3304 3641 \end{cfa} 3305 3642 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3307 3644 \end{cfa} 3308 3645 \begin{cfa}[belowskip=0pt] 3309 sout | sepDisable | 1 | sepOn | 2 | 3 | endl; §\C{// locally turn on implicit separator}§3646 sout | sepDisable | 1 | sepOn | 2 | 3; §\C{// turn on implicit separator for the next item}§ 3310 3647 \end{cfa} 3311 3648 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3314 3651 The tuple separator also responses to being turned on and off. 3315 3652 \begin{cfa}[belowskip=0pt] 3316 sout | t1 | sepOff | t2 | endl; §\C{// locally turn on/off implicit separator}§3653 sout | t1 | sepOff | t2; §\C{// turn off implicit separator for the next item}§ 3317 3654 \end{cfa} 3318 3655 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3322 3659 use ©sep© to accomplish this functionality. 3323 3660 \begin{cfa}[belowskip=0pt] 3324 sout | sepOn | 1 | 2 | 3 | sepOn | endl ;§\C{// sepOn does nothing at start/end of line}§3661 sout | sepOn | 1 | 2 | 3 | sepOn; §\C{// sepOn does nothing at start/end of line}§ 3325 3662 \end{cfa} 3326 3663 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3328 3665 \end{cfa} 3329 3666 \begin{cfa}[belowskip=0pt] 3330 sout | sep | 1 | 2 | 3 | sep | endl ;§\C{// use sep to print separator at start/end of line}§3667 sout | sep | 1 | 2 | 3 | sep ; §\C{// use sep to print separator at start/end of line}§ 3331 3668 \end{cfa} 3332 3669 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3333 3670 ® ®1 2 3® ® 3671 \end{cfa} 3672 \end{enumerate} 3673 3674 3675 \subsection{Newline Manipulators} 3676 3677 The following \Index{manipulators} control \Index{newline separation} for input and output. 3678 3679 For input: 3680 \begin{enumerate}[parsep=0pt] 3681 \item 3682 \Indexc{nl}\index{manipulator!nl@©nl©} scans characters until the next newline character, i.e., ignore the remaining characters in the line. 3683 \item 3684 \Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} reads the newline character, when reading single characters. 3685 \item 3686 \Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} read the newline character, when reading single characters. 3687 \end{enumerate} 3688 For example, in: 3689 \begin{cfa} 3690 sin | i | ®nl® | j; 3691 1 ®2® 3692 3 3693 \end{cfa} 3694 variable ©i© is assigned 1, the 2 is skipped, and variable ©j© is assigned 3. 3695 3696 For output: 3697 \begin{enumerate}[parsep=0pt] 3698 \item 3699 \Indexc{nl}\index{manipulator!nl@©nl©} inserts a newline. 3700 \begin{cfa} 3701 sout | nl; §\C{// only print newline}§ 3702 sout | 2; §\C{// implicit newline}§ 3703 sout | 3 | nl | 4 | nl; §\C{// terminating nl merged with implicit newline}§ 3704 sout | 5 | nl | nl; §\C{// again terminating nl merged with implicit newline}§ 3705 sout | 6; §\C{// implicit newline}§ 3706 3707 2 3708 3 3709 4 3710 5 3711 3712 6 3713 \end{cfa} 3714 Note, a terminating ©nl© is merged (overrides) with the implicit newline at the end of the ©sout© expression, otherwise it is impossible to to print a single newline 3715 \item 3716 \Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} implicitly prints a newline at the end of each output expression. 3717 \item 3718 \Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} implicitly print a newline at the end of each output expression. 3719 \end{enumerate} 3720 3721 3722 \subsection{Output Value Manipulators} 3723 3724 The following \Index{manipulator}s control formatting of output values (printing), and only affect the format of the argument. 3725 \begin{enumerate} 3726 \item 3727 \Indexc{bin}( integer )\index{manipulator!bin@©bin©} print value in base 2 preceded by ©0b©/©0B©. 3728 \begin{cfa}[belowskip=0pt] 3729 sout | bin( 0 ) | bin( 27HH ) | bin( 27H ) | bin( 27 ) | bin( 27L ); 3730 0b0 0b11011 0b11011 0b11011 0b11011 3731 sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L ); 3732 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b®(58 1s)®100101 3733 \end{cfa} 3734 3735 \item 3736 \Indexc{oct}( integer )\index{manipulator!oct@©oct©} print value in base 8 preceded by ©0©. 3737 \begin{cfa}[belowskip=0pt] 3738 sout | oct( 0 ) | oct( 27HH ) | oct( 27H ) | oct( 27 ) | oct( 27L ); 3739 0 033 033 033 033 3740 sout | oct( -27HH ) | oct( -27H ) | oct( -27 ) | oct( -27L ); 3741 0345 0177745 037777777745 01777777777777777777745 3742 \end{cfa} 3743 Note, octal 0 is \emph{not} preceded by ©0© to prevent confusion. 3744 3745 \item 3746 \Indexc{hex}( integer / floating-point )\index{manipulator!hex@©hex©} print value in base 16 preceded by ©0x©/©0X©. 3747 \begin{cfa}[belowskip=0pt] 3748 sout | hex( 0 ) | hex( 27HH ) | hex( 27H ) | hex( 27 ) | hex( 27L ); 3749 0 0x1b 0x1b 0x1b 0x1b 3750 sout | hex( -27HH ) | hex( -27H ) | hex( -27 ) | hex( -27L ); 3751 0xe5 0xffe5 0xffffffe5 0xffffffffffffffe5 3752 3753 sout | hex( 0.0 ) | hex( 27.5F ) | hex( 27.5 ) | hex( 27.5L ); 3754 0x0.p+0 0x1.b8p+4 0x1.b8p+4 0xd.cp+1 3755 sout | hex( -27.5F ) | hex( -27.5 ) | hex( -27.5L ); 3756 -0x1.b8p+4 -0x1.b8p+4 -0xd.cp+1 3757 \end{cfa} 3758 3759 \item 3760 \Indexc{sci}( floating-point )\index{manipulator!sci@©sci©} print value in scientific notation with exponent. 3761 Default is 6 digits of precision. 3762 \begin{cfa}[belowskip=0pt] 3763 sout | sci( 0.0 ) | sci( 27.5 ) | sci( -27.5 ); 3764 0.000000e+00 2.750000e+01 -2.750000e+01 3765 \end{cfa} 3766 3767 \item 3768 \Indexc{upcase}( bin / hex / floating-point )\index{manipulator!upcase@©upcase©} print letters in a value in upper case. Lower case is the default. 3769 \begin{cfa}[belowskip=0pt] 3770 sout | upcase( bin( 27 ) ) | upcase( hex( 27 ) ) | upcase( 27.5e-10 ) | upcase( hex( 27.5 ) ); 3771 0®B®11011 0®X®1®B® 2.75®E®-09 0®X®1.®B®8®P®+4 3772 \end{cfa} 3773 3774 \item 3775 \Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©. 3776 Printing the base is the default. 3777 \begin{cfa}[belowskip=0pt] 3778 sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) ); 3779 11011 33 1b 3780 \end{cfa} 3781 3782 \item 3783 \Indexc{nodp}( floating-point )\index{manipulator!nodp@©nodp©} do not print a decimal point if there are no fractional digits. 3784 Printing a decimal point is the default, if there are no fractional digits. 3785 \begin{cfa}[belowskip=0pt] 3786 sout | 0. | nodp( 0. ) | 27.0 | nodp( 27.0 ) | nodp( 27.5 ); 3787 0.0 ®0® 27.0 ®27® 27.5 3788 \end{cfa} 3789 3790 \item 3791 \Indexc{sign}( integer / floating-point )\index{manipulator!sign@©sign©} prefix with plus or minus sign (©+© or ©-©). Only printing the minus sign is the default. 3792 \begin{cfa}[belowskip=0pt] 3793 sout | sign( 27 ) | sign( -27 ) | sign( 27. ) | sign( -27. ) | sign( 27.5 ) | sign( -27.5 ); 3794 ®+®27 -27 ®+®27.0 -27.0 ®+®27.5 -27.5 3795 \end{cfa} 3796 3797 \item 3798 \Indexc{wd}©( unsigned char minimum, T val )©\index{manipulator!wd@©wd©}, ©wd( unsigned char minimum, unsigned char precision, T val )© 3799 For all types, ©minimum© is the minimum number of printed characters. 3800 If the value is shorter than the minimum, it is padded on the right with spaces. 3801 \begin{cfa}[belowskip=0pt] 3802 sout | wd( 4, 34) | wd( 3, 34 ) | wd( 2, 34 ); 3803 sout | wd( 10, 4.) | wd( 9, 4. ) | wd( 8, 4. ); 3804 sout | wd( 4, "ab" ) | wd( 3, "ab" ) | wd( 2, "ab" ); 3805 \end{cfa} 3806 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3807 ® ®34 ® ®34 34 3808 ® ®4.000000 ® ®4.000000 4.000000 3809 ® ®ab ® ®ab ab 3810 \end{cfa} 3811 If the value is larger, it is printed without truncation, ignoring the ©minimum©. 3812 \begin{cfa}[belowskip=0pt] 3813 sout | wd( 4, 34567 ) | wd( 3, 34567 ) | wd( 2, 34567 ); 3814 sout | wd( 4, 3456. ) | wd( 3, 3456. ) | wd( 2, 3456. ); 3815 sout | wd( 4, "abcde" ) | wd( 3, "abcde" ) | wd( 2,"abcde" ); 3816 \end{cfa} 3817 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3818 3456®7® 345®67® 34®567® 3819 3456®.® 345®6.® 34®56.® 3820 abcd®e® abc®de® ab®cde® 3821 \end{cfa} 3822 3823 For integer types, ©precision© is the minimum number of printed digits. 3824 If the value is shorter, it is padded on the left with leading zeros. 3825 \begin{cfa}[belowskip=0pt] 3826 sout | wd( 4,3, 34 ) | wd( 8,4, 34 ) | wd( 10,10, 34 ); 3827 \end{cfa} 3828 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3829 ®0®34 ®00®34 ®00000000®34 3830 \end{cfa} 3831 If the value is larger, it is printed without truncation, ignoring the ©precision©. 3832 \begin{cfa}[belowskip=0pt] 3833 sout | wd( 4,1, 3456 ) | wd( 8,2, 3456 ) | wd( 10,3, 3456 ); 3834 \end{cfa} 3835 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3836 3456 3456 3456 3837 \end{cfa} 3838 If ©precision© is 0, nothing is printed for zero. 3839 If ©precision© is greater than the minimum, it becomes the minimum. 3840 \begin{cfa}[belowskip=0pt] 3841 sout | wd( 4,0, 0 ) | wd( 3,10, 34 ); 3842 \end{cfa} 3843 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3844 ® ® ®00000000®34 3845 \end{cfa} 3846 For floating-point types, ©precision© is the minimum number of digits after the decimal point. 3847 \begin{cfa}[belowskip=0pt] 3848 sout | wd( 6,3, 27.5 ) | wd( 8,1, 27.5 ) | wd( 8,0, 27.5 ) | wd( 3,8, 27.5 ); 3849 \end{cfa} 3850 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3851 27.®500® 27.®5® 28. 27.®50000000® 3852 \end{cfa} 3853 For the C-string type, ©precision© is the maximum number of printed characters, so the string is truncared if it exceeds the maximum. 3854 \begin{cfa}[belowskip=0pt] 3855 sout | wd( 6,8, "abcd" ) | wd( 6,8, "abcdefghijk" ) | wd( 6,3, "abcd" ); 3856 \end{cfa} 3857 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3858 abcd abcdefgh abc 3859 \end{cfa} 3860 3861 \item 3862 \Indexc{ws( unsigned char minimum, unsigned char significant, floating-point )}\index{manipulator!ws@©ws©} 3863 For floating-point type, ©minimum© is the same as for manipulator ©wd©, but ©significant© is the maximum number of significant digits to be printed for both the integer and fractions (versus only the fraction for ©wd©). 3864 If a value's significant digits is greater than ©significant©, the last significant digit is rounded up. 3865 \begin{cfa}[belowskip=0pt] 3866 sout | ws(6,6, 234.567) | ws(6,5, 234.567) | ws(6,4, 234.567) | ws(6,3, 234.567); 3867 \end{cfa} 3868 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3869 234.567 234.5®7® 234.®6® 23®5® 3870 \end{cfa} 3871 If a value's magnitude is greater than ©significant©, the value is printed in scientific notation with the specified number of significant digits. 3872 \begin{cfa}[belowskip=0pt] 3873 sout | ws(6,6, 234567.) | ws(6,5, 234567.) | ws(6,4, 234567.) | ws(6,3, 234567.); 3874 \end{cfa} 3875 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3876 234567. 2.3457®e+05® 2.346®e+05® 2.35®e+05® 3877 \end{cfa} 3878 If ©significant© is greater than ©minimum©, it defines the number of printed characters. 3879 \begin{cfa}[belowskip=0pt] 3880 sout | ws(3,6, 234567.) | ws(4,6, 234567.) | ws(5,6, 234567.) | ws(6,6, 234567.); 3881 \end{cfa} 3882 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3883 234567. 234567. 234567. 234567. 3884 \end{cfa} 3885 3886 \item 3887 \Indexc{left}( field-width )\index{manipulator!left@©left©} left justify within the given field. 3888 \begin{cfa}[belowskip=0pt] 3889 sout | left(wd(4, 27)) | left(wd(10, 27.)) | left(wd(10, 27.5)) | left(wd(4,3, 27)) | left(wd(10,3, 27.5)); 3890 \end{cfa} 3891 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3892 27® ® 27.000000 27.500000 027 27.500® ® 3893 \end{cfa} 3894 3895 \item 3896 \Indexc{pad0}( field-width )\index{manipulator!pad0@©pad0©} left pad with zeroes (0). 3897 \begin{cfa}[belowskip=0pt] 3898 sout | pad0( wd( 4, 27 ) ) | pad0( wd( 4,3, 27 ) ) | pad0( wd( 8,3, 27.5 ) ); 3899 ®00®27 ®0®27 ®00®27.500 3334 3900 \end{cfa} 3335 3901 \end{enumerate} … … 3341 3907 int main( void ) { 3342 3908 int x = 1, y = 2, z = 3; 3343 sout | x | y | z | endl;3909 sout | x | y | z; 3344 3910 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ]; 3345 sout | t1 | t2 | endl; // print tuples3346 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;3347 sout | 1 | 2 | 3 | endl;3348 sout | '1' | '2' | '3' | endl;3349 sout | 1 | "" | 2 | "" | 3 | endl;3911 sout | t1 | t2; // print tuples 3912 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2); 3913 sout | 1 | 2 | 3; 3914 sout | '1' | '2' | '3'; 3915 sout | 1 | "" | 2 | "" | 3; 3350 3916 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" 3351 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10 | endl;3917 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10; 3352 3918 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" 3353 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x" | endl;3354 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx" | endl;3355 sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;3919 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x"; 3920 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx"; 3921 sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4; 3356 3922 3357 3923 sepSet( sout, ", $" ); // set separator from " " to ", $" 3358 sout | 1 | 2 | 3 | " \"" | sep | "\"" | endl;3924 sout | 1 | 2 | 3 | " \"" | sep | "\""; 3359 3925 sepSet( sout, " " ); // reset separator to " " 3360 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;3926 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\""; 3361 3927 3362 3928 char store[sepSize]; 3363 3929 strcpy( store, sepGet( sout ) ); 3364 3930 sepSet( sout, "_" ); 3365 sout | 1 | 2 | 3 | endl;3931 sout | 1 | 2 | 3; 3366 3932 sepSet( sout, store ); 3367 sout | 1 | 2 | 3 | endl;3933 sout | 1 | 2 | 3; 3368 3934 3369 3935 sepSetTuple( sout, " " ); // set tuple separator from ", " to " " 3370 sout | t1 | t2 | " \"" | sepTuple | "\"" | endl;3936 sout | t1 | t2 | " \"" | sepTuple | "\""; 3371 3937 sepSetTuple( sout, ", " ); // reset tuple separator to ", " 3372 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;3373 3374 sout | sepDisable | 1 | 2 | 3 | endl; // globally turn off implicit separator3375 sout | sepEnable | 1 | 2 | 3 | endl; // globally turn on implicit separator3376 3377 sout | 1 | sepOff | 2 | 3 | endl; // locally turn on implicit separator3378 sout | sepDisable | 1 | sepOn | 2 | 3 | endl; // globally turn off implicit separator3938 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\""; 3939 3940 sout | sepDisable | 1 | 2 | 3; // globally turn off implicit separator 3941 sout | sepEnable | 1 | 2 | 3; // globally turn on implicit separator 3942 3943 sout | 1 | sepOff | 2 | 3; // locally turn on implicit separator 3944 sout | sepDisable | 1 | sepOn | 2 | 3; // globally turn off implicit separator 3379 3945 sout | sepEnable; 3380 sout | t1 | sepOff | t2 | endl; // locally turn on/off implicit separator3381 3382 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // sepOn does nothing at start/end of line3383 sout | sep | 1 | 2 | 3 | sep | endl; // use sep to print separator at start/end of line3946 sout | t1 | sepOff | t2; // locally turn on/off implicit separator 3947 3948 sout | sepOn | 1 | 2 | 3 | sepOn ; // sepOn does nothing at start/end of line 3949 sout | sep | 1 | 2 | 3 | sep ; // use sep to print separator at start/end of line 3384 3950 } 3385 3951 … … 3390 3956 \end{comment} 3391 3957 %$ 3958 3959 3960 \subsection{Input Value Manipulators} 3961 3962 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable. 3963 For ©_Bool© type, the constants are ©true© and ©false©. 3964 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a 3965 \begin{itemize} 3966 \item 3967 ©1©-©9© prefix introduces a decimal value (©0©-©9©), 3968 \item 3969 ©0© prefix introduces an octal value (©0©-©7©), and 3970 \item 3971 ©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters. 3972 \end{itemize} 3973 For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits. 3974 Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©. 3975 3976 For the C-string type, the input values are \emph{not} the same as C-string constants, \ie double quotes bracketing arbitrary text with escape sequences. 3977 Instead, the next sequence of non-whitespace characters are read, and the input sequence is terminated with delimiter ©'\0'©. 3978 The string variable \emph{must} be large enough to contain the input sequence. 3979 3980 The following \Index{manipulator}s control formatting of input values (reading), and only affect the format of the argument. 3981 3982 \begin{enumerate} 3983 \item 3984 \Indexc{skip( const char * pattern )}\index{manipulator!skip@©skip©} / ©skip( unsigned int length )© / ©const char * pattern© 3985 The argument defines a ©pattern© or ©length©. 3986 The ©pattern© is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character. 3987 The ©length© is composed of the next $N$ characters, including the newline character. 3988 If the match successes, the input characters are discarded, and input continues with the next character. 3989 If the match fails, the input characters are left unread. 3990 \begin{cfa}[belowskip=0pt] 3991 char sk[$\,$] = "abc"; 3992 sin | "abc " | skip( sk ) | skip( 5 ); // match input sequence 3993 \end{cfa} 3994 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3995 ®abc ® 3996 ®abc ® 3997 ®xx® 3998 \end{cfa} 3999 4000 \item 4001 \Indexc{wdi}©( unsigned int maximum, T & val )©\index{manipulator!wdi@©wdi©} 4002 For all types except ©char©, ©maximum© is the maximum number of characters read for the current operation. 4003 \begin{cfa}[belowskip=0pt] 4004 char s[10]; int i; double d; 4005 sin | wdi( 4, s ) | wdi( 3, i ) | wdi( 8, d ); // c == "abcd", i == 123, d == 3.456E+2 4006 \end{cfa} 4007 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 4008 ®abcd1233.456E+2® 4009 \end{cfa} 4010 Note, input ©wdi© cannot be overloaded with output ©wd© because both have the same parameters but return different types. 4011 Currently, \CFA cannot distinguish between these two manipulators in the middle of an ©sout©/©sin© expression based on return type. 4012 4013 \item 4014 \Indexc{ignore( T & val )}\index{manipulator!ignore@©ignore©} 4015 For all types, the data is read from the stream depending on the argument type but ignored, \ie it is not stored in the argument. 4016 \begin{cfa}[belowskip=0pt] 4017 double d; 4018 sin | ignore( d ); // d is unchanged 4019 \end{cfa} 4020 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 4021 ® -75.35e-4® 25 4022 \end{cfa} 4023 4024 \item 4025 \Indexc{incl( const char * scanset, char * s )}\index{manipulator!incl@©incl©} 4026 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{in} the set. 4027 Matching characters are read into the C string and null terminated. 4028 \begin{cfa}[belowskip=0pt] 4029 char s[10]; 4030 sin | incl( "abc", s ); 4031 \end{cfa} 4032 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 4033 ®bca®xyz 4034 \end{cfa} 4035 4036 \item 4037 \Indexc{excl( const char * scanset, char * s )}\index{manipulator!excl@©excl©} 4038 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{not in} the set. 4039 Non-matching characters are read into the C string and null terminated. 4040 \begin{cfa}[belowskip=0pt] 4041 char s[10]; 4042 sin | excl( "abc", s ); 4043 \end{cfa} 4044 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 4045 ®xyz®bca 4046 \end{cfa} 4047 \end{enumerate} 3392 4048 3393 4049 … … 3759 4415 \begin{itemize} 3760 4416 \item 3761 preventing having to determine or writelong generic types,3762 \item 3763 ensur esecondary variables, related to a primary variable, always have the same type.4417 not determining or writing long generic types, 4418 \item 4419 ensuring secondary variables, related to a primary variable, always have the same type. 3764 4420 \end{itemize} 3765 4421 … … 3783 4439 There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type. 3784 4440 That is, when is the type of the variable more important than the type of its initialization expression. 3785 For example, if a change is made in an initialization expression, it can cause significantcascading type changes and/or errors.4441 For example, if a change is made in an initialization expression, it can cause cascading type changes and/or errors. 3786 4442 At some point, a variable type needs to remain constant and the expression to be in error when it changes. 3787 4443 … … 4016 4672 4017 4673 coroutine Fibonacci { 4018 int fn; §\C{// used for communication}§4674 int fn; §\C{// used for communication}§ 4019 4675 }; 4020 4676 void ?{}( Fibonacci * this ) { … … 4022 4678 } 4023 4679 void main( Fibonacci * this ) { 4024 int fn1, fn2; §\C{// retained between resumes}§4025 this->fn = 0; §\C{// case 0}§4680 int fn1, fn2; §\C{// retained between resumes}§ 4681 this->fn = 0; §\C{// case 0}§ 4026 4682 fn1 = this->fn; 4027 suspend(); §\C{// return to last resume}§4028 4029 this->fn = 1; §\C{// case 1}§4683 suspend(); §\C{// return to last resume}§ 4684 4685 this->fn = 1; §\C{// case 1}§ 4030 4686 fn2 = fn1; 4031 4687 fn1 = this->fn; 4032 suspend(); §\C{// return to last resume}§4033 4034 for ( ;; ) { §\C{// general case}§4688 suspend(); §\C{// return to last resume}§ 4689 4690 for ( ;; ) { §\C{// general case}§ 4035 4691 this->fn = fn1 + fn2; 4036 4692 fn2 = fn1; 4037 4693 fn1 = this->fn; 4038 suspend(); §\C{// return to last resume}§4694 suspend(); §\C{// return to last resume}§ 4039 4695 } // for 4040 4696 } 4041 4697 int next( Fibonacci * this ) { 4042 resume( this ); §\C{// transfer to last suspend}§4698 resume( this ); §\C{// transfer to last suspend}§ 4043 4699 return this->fn; 4044 4700 } … … 4046 4702 Fibonacci f1, f2; 4047 4703 for ( int i = 1; i <= 10; i += 1 ) { 4048 sout | next( &f1 ) | ' ' | next( &f2 ) | endl;4704 sout | next( &f1 ) | ' ' | next( &f2 ); 4049 4705 } // for 4050 4706 } … … 4112 4768 MyThread f[4]; 4113 4769 } 4114 sout | global.value | endl;4770 sout | global.value; 4115 4771 } 4116 4772 \end{cfa} … … 4190 4846 void main( First * this ) { 4191 4847 for ( int i = 0; i < 10; i += 1 ) { 4192 sout | "First : Suspend No." | i + 1 | endl;4848 sout | "First : Suspend No." | i + 1; 4193 4849 yield(); 4194 4850 } … … 4199 4855 wait( this->lock ); 4200 4856 for ( int i = 0; i < 10; i += 1 ) { 4201 sout | "Second : Suspend No." | i + 1 | endl;4857 sout | "Second : Suspend No." | i + 1; 4202 4858 yield(); 4203 4859 } … … 4206 4862 int main( void ) { 4207 4863 signal_once lock; 4208 sout | "User main begin" | endl;4864 sout | "User main begin"; 4209 4865 { 4210 4866 processor p; … … 4214 4870 } 4215 4871 } 4216 sout | "User main end" | endl;4872 sout | "User main end"; 4217 4873 } 4218 4874 \end{cfa} … … 4911 5567 void ?{}( Line * l ) { 4912 5568 l->lnth = 0.0; 4913 sout | "default" | endl;5569 sout | "default"; 4914 5570 } 4915 5571 … … 4918 5574 void ?{}( Line * l, float lnth ) { 4919 5575 l->lnth = lnth; 4920 sout | "lnth" | l->lnth | endl;5576 sout | "lnth" | l->lnth; 4921 5577 4922 5578 } … … 4924 5580 // destructor 4925 5581 void ^?() { 4926 sout | "destroyed" | endl;5582 sout | "destroyed"; 4927 5583 l.lnth = 0.0; 4928 5584 } … … 5585 6241 In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as: 5586 6242 \begin{cfa} 5587 *?§\color{red}\textvisiblespace§*? §\C{// dereference operator, dereference operator}§5588 *§\color{red}\textvisiblespace§?*? §\C{// dereference, multiplication operator}§6243 *?§\color{red}\textvisiblespace§*? §\C{// dereference operator, dereference operator}§ 6244 *§\color{red}\textvisiblespace§?*? §\C{// dereference, multiplication operator}§ 5589 6245 \end{cfa} 5590 6246 By default, the first interpretation is selected, which does not yield a meaningful parse. … … 5638 6294 \eg: 5639 6295 \begin{cfa} 5640 x; §\C{// int x}§5641 *y; §\C{// int *y}§5642 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§5643 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§6296 x; §\C{// int x}§ 6297 *y; §\C{// int *y}§ 6298 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§ 6299 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§ 5644 6300 \end{cfa} 5645 6301 \CFA continues to support K\&R routine definitions: 5646 6302 \begin{cfa} 5647 f( a, b, c ) §\C{// default int return}§5648 int a, b; char c §\C{// K\&R parameter declarations}§6303 f( a, b, c ) §\C{// default int return}§ 6304 int a, b; char c §\C{// K\&R parameter declarations}§ 5649 6305 { 5650 6306 ... … … 5665 6321 int rtn( int i ); 5666 6322 int rtn( char c ); 5667 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§6323 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§ 5668 6324 \end{cfa} 5669 6325 \item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first. 5670 6326 In particular, output of ©char© variable now print a character rather than the decimal ASCII value of the character. 5671 6327 \begin{cfa} 5672 sout | 'x' | " " | (int)'x' | endl;6328 sout | 'x' | " " | (int)'x'; 5673 6329 x 120 5674 6330 \end{cfa} … … 5687 6343 \item[Change:] make string literals ©const©: 5688 6344 \begin{cfa} 5689 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§5690 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§6345 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§ 6346 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§ 5691 6347 \end{cfa} 5692 6348 The type of a string literal is changed from ©[] char© to ©const [] char©. … … 5695 6351 \begin{cfa} 5696 6352 char * p = "abc"; 5697 p[0] = 'w'; §\C{// segment fault or change constant literal}§6353 p[0] = 'w'; §\C{// segment fault or change constant literal}§ 5698 6354 \end{cfa} 5699 6355 The same problem occurs when passing a string literal to a routine that changes its argument. … … 5707 6363 \item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope: 5708 6364 \begin{cfa} 5709 int i; §\C{// forward definition}§5710 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§5711 int i = 0; §\C{// definition}§6365 int i; §\C{// forward definition}§ 6366 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§ 6367 int i = 0; §\C{// definition}§ 5712 6368 \end{cfa} 5713 6369 is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed. … … 5715 6371 \begin{cfa} 5716 6372 struct X { int i; struct X *next; }; 5717 static struct X a; §\C{// forward definition}§6373 static struct X a; §\C{// forward definition}§ 5718 6374 static struct X b = { 0, ®&a® };§\C{// forward reference, valid in C, invalid in \CFA}§ 5719 static struct X a = { 1, &b }; §\C{// definition}§6375 static struct X a = { 1, &b }; §\C{// definition}§ 5720 6376 \end{cfa} 5721 6377 \item[Rationale:] avoids having different initialization rules for builtin types and user-defined types. … … 5732 6388 struct Person { 5733 6389 enum ®Colour® { R, G, B }; §\C[7cm]{// nested type}§ 5734 struct Face { §\C{// nested type}§5735 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§6390 struct Face { §\C{// nested type}§ 6391 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§ 5736 6392 }; 5737 ®.Colour® shirt; §\C{// type defined outside (top level)}§5738 ®Colour® pants; §\C{// type defined same level}§5739 Face looks[10]; §\C{// type defined same level}§6393 ®.Colour® shirt; §\C{// type defined outside (top level)}§ 6394 ®Colour® pants; §\C{// type defined same level}§ 6395 Face looks[10]; §\C{// type defined same level}§ 5740 6396 }; 5741 ®Colour® c = R; §\C{// type/enum defined same level}§6397 ®Colour® c = R; §\C{// type/enum defined same level}§ 5742 6398 Person®.Colour® pc = Person®.®R;§\C{// type/enum defined inside}§ 5743 Person®.®Face pretty; §\C{// type defined inside}\CRT§6399 Person®.®Face pretty; §\C{// type defined inside}\CRT§ 5744 6400 \end{cfa} 5745 6401 In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing. … … 5758 6414 \item[Difficulty of converting:] Semantic transformation. To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined. Example: 5759 6415 \begin{cfa} 5760 struct Y; §\C{// struct Y and struct X are at the same scope}§6416 struct Y; §\C{// struct Y and struct X are at the same scope}§ 5761 6417 struct X { 5762 6418 struct Y { /* ... */ } y; … … 5773 6429 \begin{cfa} 5774 6430 void foo() { 5775 int * b = malloc( sizeof(int) ); §\C{// implicitly convert void * to int *}§5776 char * c = b; §\C{// implicitly convert int * to void *, and then void * to char *}§6431 int * b = malloc( sizeof(int) ); §\C{// implicitly convert void * to int *}§ 6432 char * c = b; §\C{// implicitly convert int * to void *, and then void * to char *}§ 5777 6433 } 5778 6434 \end{cfa} … … 5947 6603 void * memalign( size_t align, size_t size );§\indexc{memalign}§ 5948 6604 int posix_memalign( void ** ptr, size_t align, size_t size );§\indexc{posix_memalign}§ 5949 }5950 5951 // §\CFA§ safe equivalents, i.e., implicit size specification5952 forall( dtype T | sized(T) ) T * malloc( void );5953 forall( dtype T | sized(T) ) T * calloc( size_t dim );5954 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );5955 forall( dtype T | sized(T) ) T * memalign( size_t align );5956 forall( dtype T | sized(T) ) T * aligned_alloc( size_t align );5957 forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t align );5958 5959 // §\CFA§ safe general allocation, fill, resize, array5960 forall( dtype T | sized(T) ) T * alloc( void );§\indexc{alloc}§5961 forall( dtype T | sized(T) ) T * alloc( char fill );5962 forall( dtype T | sized(T) ) T * alloc( size_t dim );5963 forall( dtype T | sized(T) ) T * alloc( size_t dim, char fill );5964 forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim );5965 forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim, char fill );5966 5967 // §\CFA§ safe general allocation, align, fill, array5968 forall( dtype T | sized(T) ) T * align_alloc( size_t align );5969 forall( dtype T | sized(T) ) T * align_alloc( size_t align, char fill );5970 forall( dtype T | sized(T) ) T * align_alloc( size_t align, size_t dim );5971 forall( dtype T | sized(T) ) T * align_alloc( size_t align, size_t dim, char fill );5972 6605 5973 6606 // C unsafe initialization/copy 5974 extern "C" {5975 6607 void * memset( void * dest, int c, size_t size ); 5976 6608 void * memcpy( void * dest, const void * src, size_t size ); 5977 6609 } 5978 6610 6611 forall( dtype T | sized(T) ) { 6612 // §\CFA§ safe equivalents, i.e., implicit size specification 6613 T * malloc( void ); 6614 T * calloc( size_t dim ); 6615 T * realloc( T * ptr, size_t size ); 6616 T * memalign( size_t align ); 6617 T * aligned_alloc( size_t align ); 6618 int posix_memalign( T ** ptr, size_t align ); 6619 6620 // §\CFA§ safe general allocation, fill, resize, array 6621 T * alloc( void );§\indexc{alloc}§ 6622 T * alloc( char fill ); 6623 T * alloc( size_t dim ); 6624 T * alloc( size_t dim, char fill ); 6625 T * alloc( T ptr[], size_t dim ); 6626 T * alloc( T ptr[], size_t dim, char fill ); 6627 6628 // §\CFA§ safe general allocation, align, fill, array 6629 T * align_alloc( size_t align ); 6630 T * align_alloc( size_t align, char fill ); 6631 T * align_alloc( size_t align, size_t dim ); 6632 T * align_alloc( size_t align, size_t dim, char fill ); 6633 5979 6634 // §\CFA§ safe initialization/copy, i.e., implicit size specification 5980 forall( dtype T | sized(T) )T * memset( T * dest, char c );§\indexc{memset}§5981 forall( dtype T | sized(T) )T * memcpy( T * dest, const T * src );§\indexc{memcpy}§6635 T * memset( T * dest, char c );§\indexc{memset}§ 6636 T * memcpy( T * dest, const T * src );§\indexc{memcpy}§ 5982 6637 5983 6638 // §\CFA§ safe initialization/copy array 5984 forall( dtype T | sized(T) ) T * memset( T dest[], size_t dim, char c ); 5985 forall( dtype T | sized(T) ) T * memcpy( T dest[], const T src[], size_t dim ); 6639 T * amemset( T dest[], char c, size_t dim ); 6640 T * amemcpy( T dest[], const T src[], size_t dim ); 6641 } 5986 6642 5987 6643 // §\CFA§ allocation/deallocation and constructor/destructor … … 5999 6655 6000 6656 6001 \subsection{ Conversion}6657 \subsection{String to Value Conversion} 6002 6658 6003 6659 \leavevmode … … 6035 6691 \leavevmode 6036 6692 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 6037 forall( otype T | { int ?<?( T, T ); } ) §\C{// location}§6693 forall( otype T | { int ?<?( T, T ); } ) §\C{// location}§ 6038 6694 T * bsearch( T key, const T * arr, size_t dim );§\indexc{bsearch}§ 6039 6695 6040 forall( otype T | { int ?<?( T, T ); } ) §\C{// position}§6696 forall( otype T | { int ?<?( T, T ); } ) §\C{// position}§ 6041 6697 unsigned int bsearch( T key, const T * arr, size_t dim ); 6042 6698 6043 6699 forall( otype T | { int ?<?( T, T ); } ) 6044 6700 void qsort( const T * arr, size_t dim );§\indexc{qsort}§ 6701 6702 forall( otype E | { int ?<?( E, E ); } ) { 6703 E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§ §\C{// location}§ 6704 size_t bsearch( E key, const E * vals, size_t dim );§\C{// position}§ 6705 E * bsearchl( E key, const E * vals, size_t dim );§\indexc{bsearchl}§ 6706 size_t bsearchl( E key, const E * vals, size_t dim ); 6707 E * bsearchu( E key, const E * vals, size_t dim );§\indexc{bsearchu}§ 6708 size_t bsearchu( E key, const E * vals, size_t dim ); 6709 } 6710 6711 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } ) { 6712 E * bsearch( K key, const E * vals, size_t dim ); 6713 size_t bsearch( K key, const E * vals, size_t dim ); 6714 E * bsearchl( K key, const E * vals, size_t dim ); 6715 size_t bsearchl( K key, const E * vals, size_t dim ); 6716 E * bsearchu( K key, const E * vals, size_t dim ); 6717 size_t bsearchu( K key, const E * vals, size_t dim ); 6718 } 6719 6720 forall( otype E | { int ?<?( E, E ); } ) { 6721 void qsort( E * vals, size_t dim );§\indexc{qsort}§ 6722 } 6045 6723 \end{cfa} 6046 6724 … … 6069 6747 \leavevmode 6070 6748 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 6071 void rand48seed( long int s );§\indexc{rand48seed}§ 6072 char rand48();§\indexc{rand48}§ 6073 int rand48(); 6074 unsigned int rand48(); 6075 long int rand48(); 6076 unsigned long int rand48(); 6077 float rand48(); 6078 double rand48(); 6079 float _Complex rand48(); 6080 double _Complex rand48(); 6081 long double _Complex rand48(); 6749 void srandom( unsigned int seed );§\indexc{srandom}§ 6750 char random( void );§\indexc{random}§ 6751 char random( char u ); §\C{// [0,u)}§ 6752 char random( char l, char u ); §\C{// [l,u)}§ 6753 int random( void ); 6754 int random( int u ); §\C{// [0,u)}§ 6755 int random( int l, int u ); §\C{// [l,u)}§ 6756 unsigned int random( void ); 6757 unsigned int random( unsigned int u ); §\C{// [0,u)}§ 6758 unsigned int random( unsigned int l, unsigned int u ); §\C{// [l,u)}§ 6759 long int random( void ); 6760 long int random( long int u ); §\C{// [0,u)}§ 6761 long int random( long int l, long int u ); §\C{// [l,u)}§ 6762 unsigned long int random( void ); 6763 unsigned long int random( unsigned long int u ); §\C{// [0,u)}§ 6764 unsigned long int random( unsigned long int l, unsigned long int u ); §\C{// [l,u)}§ 6765 float random( void ); §\C{// [0.0, 1.0)}§ 6766 double random( void ); §\C{// [0.0, 1.0)}§ 6767 float _Complex random( void ); §\C{// [0.0, 1.0)+[0.0, 1.0)i}§ 6768 double _Complex random( void ); §\C{// [0.0, 1.0)+[0.0, 1.0)i}§ 6769 long double _Complex random( void ); §\C{// [0.0, 1.0)+[0.0, 1.0)i}§ 6082 6770 \end{cfa} 6083 6771 … … 6122 6810 [ int, long double ] remquo( long double, long double ); 6123 6811 6124 float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§6812 float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§ 6125 6813 double div( double, double, int * ); 6126 6814 long double div( long double, long double, int * ); … … 6278 6966 long double atan2( long double, long double ); 6279 6967 6280 float atan( float, float ); §\C{// alternative name for atan2}§6968 float atan( float, float ); §\C{// alternative name for atan2}§ 6281 6969 double atan( double, double );§\indexc{atan}§ 6282 6970 long double atan( long double, long double ); … … 6458 7146 6459 7147 6460 \section{Time }6461 \label{s:Time Lib}7148 \section{Time Keeping} 7149 \label{s:TimeKeeping} 6462 7150 6463 7151 6464 7152 %\subsection{\texorpdfstring{\protect\lstinline@Duration@}{Duration}} 6465 \subsection{\texorpdfstring{\Lst KeywordStyle{\textmd{Duration}}}{Duration}}7153 \subsection{\texorpdfstring{\LstBasicStyle{Duration}}{Duration}} 6466 7154 \label{s:Duration} 6467 7155 … … 6469 7157 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 6470 7158 struct Duration { 6471 int64_t tv; §\C{// nanoseconds}§7159 int64_t tv; §\C{// nanoseconds}§ 6472 7160 }; 6473 7161 … … 6512 7200 6513 7201 Duration abs( Duration rhs ); 6514 6515 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur );6516 7202 6517 7203 Duration ?`ns( int64_t nsec ); … … 6537 7223 int64_t ?`d( Duration dur ); 6538 7224 int64_t ?`w( Duration dur ); 7225 7226 Duration max( Duration lhs, Duration rhs ); 7227 Duration min( Duration lhs, Duration rhs ); 6539 7228 \end{cfa} 6540 7229 6541 7230 6542 7231 %\subsection{\texorpdfstring{\protect\lstinline@\timeval@}{timeval}} 6543 \subsection{\texorpdfstring{\Lst KeywordStyle{\textmd{timeval}}}{timeval}}7232 \subsection{\texorpdfstring{\LstBasicStyle{timeval}}{timeval}} 6544 7233 \label{s:timeval} 6545 7234 … … 6560 7249 6561 7250 6562 \subsection{\texorpdfstring{\protect\lstinline@timespec@}{timespec}} 7251 %\subsection{\texorpdfstring{\protect\lstinline@timespec@}{timespec}} 7252 \subsection{\texorpdfstring{\LstBasicStyle{timespec}}{timespec}} 6563 7253 \label{s:timespec} 6564 7254 … … 6579 7269 6580 7270 6581 \subsection{\texorpdfstring{\protect\lstinline@itimerval@}{itimerval}} 7271 %\subsection{\texorpdfstring{\protect\lstinline@itimerval@}{itimerval}} 7272 \subsection{\texorpdfstring{\LstBasicStyle{itimerval}}{itimerval}} 6582 7273 \label{s:itimerval} 6583 7274 … … 6589 7280 6590 7281 6591 \subsection{\texorpdfstring{\protect\lstinline@Time@}{Time}} 7282 %\subsection{\texorpdfstring{\protect\lstinline@Time@}{Time}} 7283 \subsection{\texorpdfstring{\LstBasicStyle{Time}}{Time}} 6592 7284 \label{s:Time} 6593 7285 … … 6595 7287 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 6596 7288 struct Time { 6597 uint64_t tv; §\C{// nanoseconds since UNIX epoch}§7289 uint64_t tv; §\C{// nanoseconds since UNIX epoch}§ 6598 7290 }; 6599 7291 6600 7292 void ?{}( Time & time ); 6601 7293 void ?{}( Time & time, zero_t ); 6602 void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 ); 7294 6603 7295 Time ?=?( Time & time, zero_t ); 6604 7296 … … 6609 7301 Time ?=?( Time & time, timespec t ); 6610 7302 6611 Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; } 6612 Time ?+?( Duration lhs, Time rhs ) { return rhs + lhs; } 6613 Time ?+=?( Time & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; } 6614 6615 Duration ?-?( Time lhs, Time rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; } 6616 Time ?-?( Time lhs, Duration rhs ) { return (Time)@{ lhs.tv - rhs.tv }; } 6617 Time ?-=?( Time & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; } 6618 _Bool ?==?( Time lhs, Time rhs ) { return lhs.tv == rhs.tv; } 6619 _Bool ?!=?( Time lhs, Time rhs ) { return lhs.tv != rhs.tv; } 6620 _Bool ?<?( Time lhs, Time rhs ) { return lhs.tv < rhs.tv; } 6621 _Bool ?<=?( Time lhs, Time rhs ) { return lhs.tv <= rhs.tv; } 6622 _Bool ?>?( Time lhs, Time rhs ) { return lhs.tv > rhs.tv; } 6623 _Bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; } 6624 6625 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time ); 7303 Time ?+?( Time & lhs, Duration rhs ); 7304 Time ?+?( Duration lhs, Time rhs ); 7305 Time ?+=?( Time & lhs, Duration rhs ); 7306 7307 Duration ?-?( Time lhs, Time rhs ); 7308 Time ?-?( Time lhs, Duration rhs ); 7309 Time ?-=?( Time & lhs, Duration rhs ); 7310 _Bool ?==?( Time lhs, Time rhs ); 7311 _Bool ?!=?( Time lhs, Time rhs ); 7312 _Bool ?<?( Time lhs, Time rhs ); 7313 _Bool ?<=?( Time lhs, Time rhs ); 7314 _Bool ?>?( Time lhs, Time rhs ); 7315 _Bool ?>=?( Time lhs, Time rhs ); 6626 7316 6627 7317 char * yy_mm_dd( Time time, char * buf ); … … 6641 7331 6642 7332 size_t strftime( char * buf, size_t size, const char * fmt, Time time ); 7333 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time ); 6643 7334 \end{cfa} 6644 7335 … … 6661 7352 6662 7353 %\subsection{\texorpdfstring{\protect\lstinline@Clock@}{Clock}} 6663 \subsection{\texorpdfstring{\Lst KeywordStyle{\textmd{Clock}}}{Clock}}7354 \subsection{\texorpdfstring{\LstBasicStyle{Clock}}{Clock}} 6664 7355 \label{s:Clock} 6665 7356 … … 6667 7358 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 6668 7359 struct Clock { 6669 Duration offset; §\C{// for virtual clock: contains offset from real-time}§6670 int clocktype; §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§7360 Duration offset; §\C{// for virtual clock: contains offset from real-time}§ 7361 int clocktype; §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§ 6671 7362 }; 6672 7363 … … 6675 7366 void ?{}( Clock & clk ); 6676 7367 void ?{}( Clock & clk, Duration adj ); 6677 Duration getRes(); 6678 Time getTimeNsec(); §\C{// with nanoseconds}§ 6679 Time getTime(); §\C{// without nanoseconds}§ 7368 7369 Duration getResNsec(); §\C{// with nanoseconds}§ 7370 Duration getRes(); §\C{// without nanoseconds}§ 7371 7372 Time getTimeNsec(); §\C{// with nanoseconds}§ 7373 Time getTime(); §\C{// without nanoseconds}§ 6680 7374 Time getTime( Clock & clk ); 6681 7375 Time ?()( Clock & clk ); … … 6693 7387 6694 7388 \begin{cfa} 6695 void ?{}( Int * this ); §\C{// constructor/destructor}§7389 void ?{}( Int * this ); §\C{// constructor/destructor}§ 6696 7390 void ?{}( Int * this, Int init ); 6697 7391 void ?{}( Int * this, zero_t ); … … 6702 7396 void ^?{}( Int * this ); 6703 7397 6704 Int ?=?( Int * lhs, Int rhs ); §\C{// assignment}§7398 Int ?=?( Int * lhs, Int rhs ); §\C{// assignment}§ 6705 7399 Int ?=?( Int * lhs, long int rhs ); 6706 7400 Int ?=?( Int * lhs, unsigned long int rhs ); … … 6719 7413 unsigned long int narrow( Int val ); 6720 7414 6721 int ?==?( Int oper1, Int oper2 ); §\C{// comparison}§7415 int ?==?( Int oper1, Int oper2 ); §\C{// comparison}§ 6722 7416 int ?==?( Int oper1, long int oper2 ); 6723 7417 int ?==?( long int oper2, Int oper1 ); … … 6755 7449 int ?>=?( unsigned long int oper1, Int oper2 ); 6756 7450 6757 Int +?( Int oper ); §\C{// arithmetic}§7451 Int +?( Int oper ); §\C{// arithmetic}§ 6758 7452 Int -?( Int oper ); 6759 7453 Int ~?( Int oper ); … … 6837 7531 Int ?>>=?( Int * lhs, mp_bitcnt_t shift ); 6838 7532 6839 Int abs( Int oper ); §\C{// number functions}§7533 Int abs( Int oper ); §\C{// number functions}§ 6840 7534 Int fact( unsigned long int N ); 6841 7535 Int gcd( Int oper1, Int oper2 ); … … 6862 7556 #include <gmp>§\indexc{gmp}§ 6863 7557 int main( void ) { 6864 sout | "Factorial Numbers" | endl;7558 sout | "Factorial Numbers"; 6865 7559 Int fact = 1; 6866 7560 6867 sout | 0 | fact | endl;7561 sout | 0 | fact; 6868 7562 for ( unsigned int i = 1; i <= 40; i += 1 ) { 6869 7563 fact *= i; 6870 sout | i | fact | endl;7564 sout | i | fact; 6871 7565 } 6872 7566 } … … 6948 7642 // implementation 6949 7643 struct Rational {§\indexc{Rational}§ 6950 long int numerator, denominator; §\C{// invariant: denominator > 0}§7644 long int numerator, denominator; §\C{// invariant: denominator > 0}§ 6951 7645 }; // Rational 6952 7646 6953 Rational rational(); §\C{// constructors}§7647 Rational rational(); §\C{// constructors}§ 6954 7648 Rational rational( long int n ); 6955 7649 Rational rational( long int n, long int d ); … … 6957 7651 void ?{}( Rational * r, one_t ); 6958 7652 6959 long int numerator( Rational r ); §\C{// numerator/denominator getter/setter}§7653 long int numerator( Rational r ); §\C{// numerator/denominator getter/setter}§ 6960 7654 long int numerator( Rational r, long int n ); 6961 7655 long int denominator( Rational r ); 6962 7656 long int denominator( Rational r, long int d ); 6963 7657 6964 int ?==?( Rational l, Rational r ); §\C{// comparison}§7658 int ?==?( Rational l, Rational r ); §\C{// comparison}§ 6965 7659 int ?!=?( Rational l, Rational r ); 6966 7660 int ?<?( Rational l, Rational r ); … … 6969 7663 int ?>=?( Rational l, Rational r ); 6970 7664 6971 Rational -?( Rational r ); §\C{// arithmetic}§7665 Rational -?( Rational r ); §\C{// arithmetic}§ 6972 7666 Rational ?+?( Rational l, Rational r ); 6973 7667 Rational ?-?( Rational l, Rational r ); … … 6975 7669 Rational ?/?( Rational l, Rational r ); 6976 7670 6977 double widen( Rational r ); §\C{// conversion}§7671 double widen( Rational r ); §\C{// conversion}§ 6978 7672 Rational narrow( double f, long int md ); 6979 7673 -
doc/working/exception/impl/exception.c
r7951100 rb067d9b 243 243 244 244 // Get a function pointer from the relative offset and call it 245 // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher; 245 // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher; 246 246 247 247 _Unwind_Reason_Code (*matcher)() = … … 320 320 // on how the assembly works. 321 321 // Setup the personality routine 322 #if defined(__PIC__) 323 asm volatile (".cfi_personality 0x9b,CFA.ref.__gcfa_personality_v0"); 324 // Setup the exception table 325 asm volatile (".cfi_lsda 0x1b, .LLSDACFA2"); 326 #else 322 327 asm volatile (".cfi_personality 0x3,__gcfa_personality_v0"); 323 328 // Setup the exception table 324 329 asm volatile (".cfi_lsda 0x3, .LLSDACFA2"); 330 #endif 325 331 326 332 // Label which defines the start of the area for which the handler is setup … … 356 362 // Some more works need to be done if we want to have a single 357 363 // call to the try routine 364 #if defined(__PIC__) 365 asm ( 366 //HEADER 367 ".LFECFA1:\n" 368 " .globl __gcfa_personality_v0\n" 369 " .section .gcc_except_table,\"a\",@progbits\n" 370 ".LLSDACFA2:\n" //TABLE header 371 " .byte 0xff\n" 372 " .byte 0xff\n" 373 " .byte 0x1\n" 374 " .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n" // BODY length 375 // Body uses language specific data and therefore could be modified arbitrarily 376 ".LLSDACSBCFA2:\n" // BODY start 377 " .uleb128 .TRYSTART-__try_terminate\n" // Handled area start (relative to start of function) 378 " .uleb128 .TRYEND-.TRYSTART\n" // Handled area length 379 " .uleb128 .CATCH-__try_terminate\n" // Handler landing pad adress (relative to start of function) 380 " .uleb128 1\n" // Action code, gcc seems to use always 0 381 ".LLSDACSECFA2:\n" // BODY end 382 " .text\n" // TABLE footer 383 " .size __try_terminate, .-__try_terminate\n" 384 ); 385 386 // Somehow this piece of helps with the resolution of debug symbols. 387 __attribute__((unused)) static const int dummy = 0; 388 asm ( 389 " .hidden CFA.ref.__gcfa_personality_v0\n" // Declare an new hidden symbol 390 " .weak CFA.ref.__gcfa_personality_v0\n" 391 " .section .data.rel.local.CFA.ref.__gcfa_personality_v0,\"awG\",@progbits,CFA.ref.__gcfa_personality_v0,comdat\n" // No clue what this does specifically 392 " .align 8\n" 393 " .type CFA.ref.__gcfa_personality_v0, @object\n" // Type of our hidden symbol (it's not actually the function itself) 394 " .size CFA.ref.__gcfa_personality_v0, 8\n" // Size of our hidden symbol 395 "CFA.ref.__gcfa_personality_v0:\n" 396 " .quad __gcfa_personality_v0\n" 397 ); 398 #else 358 399 asm ( 359 400 //HEADER … … 375 416 " .text\n" // TABLE footer 376 417 " .size __try_terminate, .-__try_terminate\n" 377 " .ident \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"378 // " .section .note.GNU-stack,\"x\",@progbits\n"379 418 ); 419 #endif -
src/CodeGen/CodeGenerator.cc
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat May 5 09:08:32 201813 // Update Count : 49412 // Last Modified On : Sat Oct 19 19:30:38 2019 13 // Update Count : 506 14 14 // 15 15 #include "CodeGenerator.h" … … 83 83 void CodeGenerator::updateLocation( CodeLocation const & to ) { 84 84 // skip if linemarks shouldn't appear or if codelocation is unset 85 if ( ! lineMarks || to.isUnset() ) return;85 if ( !options.lineMarks || to.isUnset() ) return; 86 86 87 87 if ( currentLocation.followedBy( to, 0 ) ) { … … 116 116 } 117 117 118 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), printExprTypes( printExprTypes ), endl( *this ) {} 118 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( 0, CodeGenerator::tabsize ), output( os ), printLabels( *this ), options( pretty, genC, lineMarks, printExprTypes ), endl( *this ) {} 119 CodeGenerator::CodeGenerator( std::ostream & os, const Options &options ) : indent( 0, CodeGenerator::tabsize ), output( os ), printLabels( *this ), options(options), endl( *this ) {} 119 120 120 121 string CodeGenerator::mangleName( DeclarationWithType * decl ) { 121 122 // GCC builtins should always be printed unmangled 122 if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name;123 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name; 123 124 if ( decl->mangleName != "" ) { 124 125 // need to incorporate scope level in order to differentiate names for destructors … … 133 134 output << "__attribute__ (("; 134 135 for ( list< Attribute * >::iterator attr( attributes.begin() );; ) { 135 output << (*attr)-> get_name();136 if ( ! (*attr)-> get_parameters().empty() ) {136 output << (*attr)->name; 137 if ( ! (*attr)->parameters.empty() ) { 137 138 output << "("; 138 genCommaList( (*attr)-> get_parameters().begin(), (*attr)->get_parameters().end() );139 genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() ); 139 140 output << ")"; 140 141 } // if … … 164 165 previsit( (BaseSyntaxNode *)node ); 165 166 GuardAction( [this, node](){ 166 if ( printExprTypes) {167 output << " /* " << genType( node->result, "", pretty, genC) << " */ ";167 if ( options.printExprTypes && node->result ) { 168 output << " /* " << genType( node->result, "", options ) << " */ "; 168 169 } 169 170 } ); … … 173 174 void CodeGenerator::postvisit( FunctionDecl * functionDecl ) { 174 175 // deleted decls should never be used, so don't print them 175 if ( functionDecl->isDeleted && genC ) return;176 if ( functionDecl->isDeleted && options.genC ) return; 176 177 extension( functionDecl ); 177 178 genAttributes( functionDecl->get_attributes() ); … … 180 181 functionDecl->get_funcSpec().print( output ); 181 182 182 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC ); 183 Options subOptions = options; 184 subOptions.anonymousUnused = functionDecl->has_body(); 185 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), subOptions ); 183 186 184 187 asmName( functionDecl ); … … 194 197 void CodeGenerator::postvisit( ObjectDecl * objectDecl ) { 195 198 // deleted decls should never be used, so don't print them 196 if ( objectDecl->isDeleted && genC ) return; 197 if (objectDecl->get_name().empty() && genC ) { 199 if ( objectDecl->isDeleted && options.genC ) return; 200 201 // gcc allows an empty declarator (no name) for bit-fields and C states: 6.7.2.1 Structure and union specifiers, 202 // point 4, page 113: If the (bit field) value is zero, the declaration shall have no declarator. For anything 203 // else, the anonymous name refers to the anonymous object for plan9 inheritance. 204 if ( objectDecl->get_name().empty() && options.genC && ! objectDecl->get_bitfieldWidth() ) { 198 205 // only generate an anonymous name when generating C code, otherwise it clutters the output too much 199 206 static UniqueName name = { "__anonymous_object" }; 200 207 objectDecl->set_name( name.newName() ); 208 // Stops unused parameter warnings. 209 if ( options.anonymousUnused ) { 210 objectDecl->attributes.push_back( new Attribute( "unused" ) ); 211 } 201 212 } 202 213 … … 205 216 206 217 handleStorageClass( objectDecl ); 207 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty,genC );218 output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC ); 208 219 209 220 asmName( objectDecl ); … … 224 235 225 236 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) { 226 if( ! aggDecl-> get_parameters().empty() && !genC ) {237 if( ! aggDecl->parameters.empty() && ! options.genC ) { 227 238 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 228 239 output << "forall("; 229 genCommaList( aggDecl-> get_parameters().begin(), aggDecl->get_parameters().end() );240 genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() ); 230 241 output << ")" << endl; 231 242 output << indent; … … 233 244 234 245 output << kind; 235 genAttributes( aggDecl-> get_attributes());236 output << aggDecl-> get_name();246 genAttributes( aggDecl->attributes ); 247 output << aggDecl->name; 237 248 238 249 if ( aggDecl->has_body() ) { 239 std::list< Declaration * > & memb = aggDecl-> get_members();250 std::list< Declaration * > & memb = aggDecl->members; 240 251 output << " {" << endl; 241 252 … … 294 305 295 306 void CodeGenerator::postvisit( TraitDecl * traitDecl ) { 296 assertf( ! genC, "TraitDecls should not reach code generation." );307 assertf( ! options.genC, "TraitDecls should not reach code generation." ); 297 308 extension( traitDecl ); 298 309 handleAggregate( traitDecl, "trait " ); … … 300 311 301 312 void CodeGenerator::postvisit( TypedefDecl * typeDecl ) { 302 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );313 assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." ); 303 314 output << "typedef "; 304 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC) << endl;315 output << genType( typeDecl->get_base(), typeDecl->get_name(), options ) << endl; 305 316 } 306 317 307 318 void CodeGenerator::postvisit( TypeDecl * typeDecl ) { 308 assertf( ! genC, "TypeDecls should not reach code generation." );319 assertf( ! options.genC, "TypeDecls should not reach code generation." ); 309 320 output << typeDecl->genTypeString() << " " << typeDecl->name; 310 321 if ( typeDecl->sized ) { … … 371 382 372 383 void CodeGenerator::postvisit( ConstructorInit * init ){ 373 assertf( ! genC, "ConstructorInit nodes should not reach code generation." );384 assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." ); 374 385 // pseudo-output for constructor/destructor pairs 375 386 output << "<ctorinit>{" << endl << ++indent << "ctor: "; … … 507 518 } else { 508 519 // no constructors with 0 or more than 2 parameters 509 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );520 assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." ); 510 521 output << "("; 511 522 (*arg++)->accept( *visitor ); … … 604 615 // an lvalue cast, this has been taken out. 605 616 output << "("; 606 output << genType( castExpr->get_result(), "", pretty, genC);617 output << genType( castExpr->get_result(), "", options ); 607 618 output << ")"; 608 619 } // if … … 612 623 613 624 void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) { 614 assertf( ! genC, "KeywordCast should not reach code generation." );625 assertf( ! options.genC, "KeywordCast should not reach code generation." ); 615 626 extension( castExpr ); 616 627 output << "((" << castExpr->targetString() << " &)"; … … 620 631 621 632 void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) { 622 assertf( ! genC, "VirtualCastExpr should not reach code generation." );633 assertf( ! options.genC, "VirtualCastExpr should not reach code generation." ); 623 634 extension( castExpr ); 624 635 output << "(virtual "; … … 628 639 629 640 void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) { 630 assertf( ! genC, "UntypedMemberExpr should not reach code generation." );641 assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." ); 631 642 extension( memberExpr ); 632 643 memberExpr->get_aggregate()->accept( *visitor ); … … 661 672 output << "sizeof("; 662 673 if ( sizeofExpr->get_isType() ) { 663 output << genType( sizeofExpr->get_type(), "", pretty, genC);674 output << genType( sizeofExpr->get_type(), "", options ); 664 675 } else { 665 676 sizeofExpr->get_expr()->accept( *visitor ); … … 673 684 output << "__alignof__("; 674 685 if ( alignofExpr->get_isType() ) { 675 output << genType( alignofExpr->get_type(), "", pretty, genC);686 output << genType( alignofExpr->get_type(), "", options ); 676 687 } else { 677 688 alignofExpr->get_expr()->accept( *visitor ); … … 681 692 682 693 void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) { 683 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );694 assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." ); 684 695 output << "offsetof("; 685 output << genType( offsetofExpr->get_type(), "", pretty, genC);696 output << genType( offsetofExpr->get_type(), "", options ); 686 697 output << ", " << offsetofExpr->get_member(); 687 698 output << ")"; … … 691 702 // use GCC builtin 692 703 output << "__builtin_offsetof("; 693 output << genType( offsetofExpr->get_type(), "", pretty, genC);704 output << genType( offsetofExpr->get_type(), "", options ); 694 705 output << ", " << mangleName( offsetofExpr->get_member() ); 695 706 output << ")"; … … 697 708 698 709 void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) { 699 assertf( ! genC, "OffsetPackExpr should not reach code generation." );700 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC) << ")";710 assertf( ! options.genC, "OffsetPackExpr should not reach code generation." ); 711 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options ) << ")"; 701 712 } 702 713 … … 728 739 extension( commaExpr ); 729 740 output << "("; 730 if ( genC ) {741 if ( options.genC ) { 731 742 // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings. 732 743 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) ); … … 739 750 740 751 void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) { 741 assertf( ! genC, "TupleAssignExpr should not reach code generation." );752 assertf( ! options.genC, "TupleAssignExpr should not reach code generation." ); 742 753 tupleExpr->stmtExpr->accept( *visitor ); 743 754 } 744 755 745 756 void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) { 746 assertf( ! genC, "UntypedTupleExpr should not reach code generation." );757 assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." ); 747 758 extension( tupleExpr ); 748 759 output << "["; … … 752 763 753 764 void CodeGenerator::postvisit( TupleExpr * tupleExpr ) { 754 assertf( ! genC, "TupleExpr should not reach code generation." );765 assertf( ! options.genC, "TupleExpr should not reach code generation." ); 755 766 extension( tupleExpr ); 756 767 output << "["; … … 760 771 761 772 void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) { 762 assertf( ! genC, "TupleIndexExpr should not reach code generation." );773 assertf( ! options.genC, "TupleIndexExpr should not reach code generation." ); 763 774 extension( tupleExpr ); 764 775 tupleExpr->get_tuple()->accept( *visitor ); … … 767 778 768 779 void CodeGenerator::postvisit( TypeExpr * typeExpr ) { 769 // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;770 // assertf( ! genC, "TypeExpr should not reach code generation." );771 if ( ! genC ) {772 output << genType( typeExpr->get_type(), "", pretty, genC);780 // if ( options.genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl; 781 // assertf( ! options.genC, "TypeExpr should not reach code generation." ); 782 if ( ! options.genC ) { 783 output << genType( typeExpr->get_type(), "", options ); 773 784 } 774 785 } … … 788 799 void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) { 789 800 assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 790 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC) << ")";801 output << "(" << genType( compLitExpr->get_result(), "", options ) << ")"; 791 802 compLitExpr->get_initializer()->accept( *visitor ); 792 803 } 793 804 794 805 void CodeGenerator::postvisit( UniqueExpr * unqExpr ) { 795 assertf( ! genC, "Unique expressions should not reach code generation." );806 assertf( ! options.genC, "Unique expressions should not reach code generation." ); 796 807 output << "unq<" << unqExpr->get_id() << ">{ "; 797 808 unqExpr->get_expr()->accept( *visitor ); … … 829 840 830 841 void CodeGenerator::postvisit( ConstructorExpr * expr ) { 831 assertf( ! genC, "Unique expressions should not reach code generation." );842 assertf( ! options.genC, "Unique expressions should not reach code generation." ); 832 843 expr->callExpr->accept( *visitor ); 833 844 } 834 845 835 846 void CodeGenerator::postvisit( DeletedExpr * expr ) { 836 assertf( ! genC, "Deleted expressions should not reach code generation." );847 assertf( ! options.genC, "Deleted expressions should not reach code generation." ); 837 848 expr->expr->accept( *visitor ); 838 849 } 839 850 851 void CodeGenerator::postvisit( DefaultArgExpr * arg ) { 852 assertf( ! options.genC, "Default argument expressions should not reach code generation." ); 853 arg->expr->accept( *visitor ); 854 } 855 840 856 void CodeGenerator::postvisit( GenericExpr * expr ) { 841 assertf( ! genC, "C11 _Generic expressions should not reach code generation." );857 assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." ); 842 858 output << "_Generic("; 843 859 expr->control->accept( *visitor ); … … 849 865 output << "default: "; 850 866 } else { 851 output << genType( assoc.type, "", pretty, genC) << ": ";867 output << genType( assoc.type, "", options ) << ": "; 852 868 } 853 869 assoc.expr->accept( *visitor ); … … 884 900 void CodeGenerator::postvisit( ExprStmt * exprStmt ) { 885 901 assert( exprStmt ); 886 if ( genC ) {902 if ( options.genC ) { 887 903 // cast the top-level expression to void to reduce gcc warnings. 888 904 exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) ); … … 994 1010 case BranchStmt::FallThrough: 995 1011 case BranchStmt::FallThroughDefault: 996 assertf( ! genC, "fallthru should not reach code generation." );1012 assertf( ! options.genC, "fallthru should not reach code generation." ); 997 1013 output << "fallthru"; 998 1014 break; 999 1015 } // switch 1000 1016 // print branch target for labelled break/continue/fallthru in debug mode 1001 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {1017 if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) { 1002 1018 if ( ! branchStmt->get_target().empty() ) { 1003 1019 output << " " << branchStmt->get_target(); … … 1016 1032 1017 1033 void CodeGenerator::postvisit( ThrowStmt * throwStmt ) { 1018 assertf( ! genC, "Throw statements should not reach code generation." );1034 assertf( ! options.genC, "Throw statements should not reach code generation." ); 1019 1035 1020 1036 output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ? … … 1031 1047 } 1032 1048 void CodeGenerator::postvisit( CatchStmt * stmt ) { 1033 assertf( ! genC, "Catch statements should not reach code generation." );1049 assertf( ! options.genC, "Catch statements should not reach code generation." ); 1034 1050 1035 1051 output << ((stmt->get_kind() == CatchStmt::Terminate) ? … … 1048 1064 1049 1065 void CodeGenerator::postvisit( WaitForStmt * stmt ) { 1050 assertf( ! genC, "Waitfor statements should not reach code generation." );1066 assertf( ! options.genC, "Waitfor statements should not reach code generation." ); 1051 1067 1052 1068 bool first = true; … … 1094 1110 1095 1111 void CodeGenerator::postvisit( WithStmt * with ) { 1096 if ( ! genC ) {1112 if ( ! options.genC ) { 1097 1113 output << "with ( "; 1098 1114 genCommaList( with->exprs.begin(), with->exprs.end() ); … … 1160 1176 1161 1177 void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) { 1162 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );1178 assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." ); 1163 1179 stmt->callStmt->accept( *visitor ); 1164 1180 } -
src/CodeGen/CodeGenerator.h
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 18 15:40:00 201713 // Update Count : 5 612 // Last Modified On : Tue Apr 30 12:01:00 2019 13 // Update Count : 57 14 14 // 15 15 … … 20 20 #include <string> // for string 21 21 22 #include "CodeGen/Options.h" // for Options 22 23 #include "Common/Indenter.h" // for Indenter 23 24 #include "Common/PassVisitor.h" // for PassVisitor … … 31 32 32 33 CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false, bool printExprTypes = false ); 34 CodeGenerator( std::ostream &os, const Options &options ); 33 35 34 36 //*** Turn off visit_children for all nodes … … 94 96 void postvisit( ConstructorExpr * ); 95 97 void postvisit( DeletedExpr * ); 98 void postvisit( DefaultArgExpr * ); 96 99 void postvisit( GenericExpr * ); 97 100 … … 143 146 std::ostream & output; 144 147 LabelPrinter printLabels; 145 bool pretty = false; // pretty print 146 bool genC = false; // true if output has to be C code 147 bool lineMarks = false; 148 bool printExprTypes = false; 148 Options options; 149 149 public: 150 150 LineEnder endl; -
src/CodeGen/GenType.cc
r7951100 rb067d9b 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 : Fri Mar 17 09:02:28 201713 // Update Count : 2 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed May 1 15:24:00 2019 13 // Update Count : 23 14 14 // 15 15 #include "GenType.h" … … 27 27 namespace CodeGen { 28 28 struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting { 29 GenType( const std::string &typeString, bool pretty = false, bool genC = false, bool lineMarks = false ); 30 std::string get_typeString() const { return typeString; } 31 void set_typeString( const std::string &newValue ) { typeString = newValue; } 29 std::string typeString; 30 GenType( const std::string &typeString, const Options &options ); 32 31 33 32 void previsit( BaseSyntaxNode * ); … … 48 47 void postvisit( ZeroType * zeroType ); 49 48 void postvisit( OneType * oneType ); 49 void postvisit( GlobalScopeType * globalType ); 50 50 void postvisit( TraitInstType * inst ); 51 51 void postvisit( TypeofType * typeof ); 52 void postvisit( QualifiedType * qualType ); 52 53 53 54 private: … … 56 57 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 57 58 58 std::string typeString; 59 bool pretty = false; // pretty print 60 bool genC = false; // generating C code? 61 bool lineMarks = false; 59 Options options; 62 60 }; 63 61 62 std::string genType( Type *type, const std::string &baseString, const Options &options ) { 63 PassVisitor<GenType> gt( baseString, options ); 64 std::ostringstream os; 65 66 if ( ! type->get_attributes().empty() ) { 67 PassVisitor<CodeGenerator> cg( os, options ); 68 cg.pass.genAttributes( type->get_attributes() ); 69 } // if 70 71 type->accept( gt ); 72 return os.str() + gt.pass.typeString; 73 } 74 64 75 std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) { 65 PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks ); 66 std::ostringstream os; 67 68 if ( ! type->get_attributes().empty() ) { 69 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 70 cg.pass.genAttributes( type->get_attributes() ); 71 } // if 72 73 type->accept( gt ); 74 return os.str() + gt.pass.get_typeString(); 75 } 76 77 std::string genPrettyType( Type * type, const std::string & baseString ) { 78 return genType( type, baseString, true, false ); 79 } 80 81 GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {} 76 return genType( type, baseString, Options(pretty, genC, lineMarks, false ) ); 77 } 78 79 std::string genPrettyType( Type * type, const std::string & baseString ) { 80 return genType( type, baseString, true, false ); 81 } 82 83 GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {} 82 84 83 85 // *** BaseSyntaxNode … … 133 135 } // if 134 136 if ( dimension != 0 ) { 135 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );137 PassVisitor<CodeGenerator> cg( os, options ); 136 138 dimension->accept( cg ); 137 139 } else if ( isVarLen ) { … … 167 169 void GenType::postvisit( ReferenceType * refType ) { 168 170 assert( refType->base != 0); 169 assertf( ! genC, "Reference types should not reach code generation." );171 assertf( ! options.genC, "Reference types should not reach code generation." ); 170 172 handleQualifiers( refType ); 171 173 typeString = "&" + typeString; … … 195 197 } // if 196 198 } else { 197 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );199 PassVisitor<CodeGenerator> cg( os, options ); 198 200 os << "(" ; 199 201 … … 215 217 216 218 // add forall 217 if( ! funcType->forall.empty() && ! genC ) {219 if( ! funcType->forall.empty() && ! options.genC ) { 218 220 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 219 221 std::ostringstream os; 220 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );222 PassVisitor<CodeGenerator> cg( os, options ); 221 223 os << "forall("; 222 224 cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() ); … … 229 231 if ( ! refType->parameters.empty() ) { 230 232 std::ostringstream os; 231 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );233 PassVisitor<CodeGenerator> cg( os, options ); 232 234 os << "("; 233 235 cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() ); … … 240 242 void GenType::postvisit( StructInstType * structInst ) { 241 243 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString; 242 if ( genC ) typeString = "struct " + typeString;244 if ( options.genC ) typeString = "struct " + typeString; 243 245 handleQualifiers( structInst ); 244 246 } … … 246 248 void GenType::postvisit( UnionInstType * unionInst ) { 247 249 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString; 248 if ( genC ) typeString = "union " + typeString;250 if ( options.genC ) typeString = "union " + typeString; 249 251 handleQualifiers( unionInst ); 250 252 } … … 252 254 void GenType::postvisit( EnumInstType * enumInst ) { 253 255 typeString = enumInst->name + " " + typeString; 254 if ( genC ) typeString = "enum " + typeString;256 if ( options.genC ) typeString = "enum " + typeString; 255 257 handleQualifiers( enumInst ); 256 258 } … … 262 264 263 265 void GenType::postvisit( TupleType * tupleType ) { 264 assertf( ! genC, "Tuple types should not reach code generation." );266 assertf( ! options.genC, "Tuple types should not reach code generation." ); 265 267 unsigned int i = 0; 266 268 std::ostringstream os; … … 268 270 for ( Type * t : *tupleType ) { 269 271 i++; 270 os << genType( t, "", pretty, genC, lineMarks ) << (i == tupleType->size() ? "" : ", ");272 os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", "); 271 273 } 272 274 os << "] "; … … 281 283 void GenType::postvisit( ZeroType * zeroType ) { 282 284 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 283 typeString = ( pretty ? "zero_t " : "long int ") + typeString;285 typeString = (options.pretty ? "zero_t " : "long int ") + typeString; 284 286 handleQualifiers( zeroType ); 285 287 } … … 287 289 void GenType::postvisit( OneType * oneType ) { 288 290 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 289 typeString = ( pretty ? "one_t " : "long int ") + typeString;291 typeString = (options.pretty ? "one_t " : "long int ") + typeString; 290 292 handleQualifiers( oneType ); 291 293 } 292 294 295 void GenType::postvisit( GlobalScopeType * globalType ) { 296 assertf( ! options.genC, "Global scope type should not reach code generation." ); 297 handleQualifiers( globalType ); 298 } 299 293 300 void GenType::postvisit( TraitInstType * inst ) { 294 assertf( ! genC, "Trait types should not reach code generation." );301 assertf( ! options.genC, "Trait types should not reach code generation." ); 295 302 typeString = inst->name + " " + typeString; 296 303 handleQualifiers( inst ); … … 299 306 void GenType::postvisit( TypeofType * typeof ) { 300 307 std::ostringstream os; 301 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );308 PassVisitor<CodeGenerator> cg( os, options ); 302 309 os << "typeof("; 303 310 typeof->expr->accept( cg ); … … 307 314 } 308 315 316 void GenType::postvisit( QualifiedType * qualType ) { 317 assertf( ! options.genC, "Qualified types should not reach code generation." ); 318 std::ostringstream os; 319 os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString; 320 typeString = os.str(); 321 handleQualifiers( qualType ); 322 } 323 309 324 void GenType::handleQualifiers( Type * type ) { 310 325 if ( type->get_const() ) { … … 320 335 typeString = "_Atomic " + typeString; 321 336 } // if 322 if ( type->get_lvalue() && ! genC ) {323 // when not generating C code, print lvalue for debugging.324 typeString = "lvalue " + typeString;325 }326 337 } 327 338 } // namespace CodeGen -
src/CodeGen/GenType.h
r7951100 rb067d9b 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 : Fri Jul 21 22:17:23 201713 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 30 11:47:00 2019 13 // Update Count : 3 14 14 // 15 15 … … 18 18 #include <string> // for string 19 19 20 #include "CodeGen/Options.h" // for Options 21 20 22 class Type; 21 23 22 24 namespace CodeGen { 25 std::string genType( Type *type, const std::string &baseString, const Options &options ); 23 26 std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false, bool lineMarks = false ); 24 27 std::string genPrettyType( Type * type, const std::string & baseString ); -
src/CodeGen/module.mk
r7951100 rb067d9b 18 18 # ArgTweak/Mutate.cc 19 19 20 SRC += CodeGen/Generate.cc\20 SRC_CODEGEN = \ 21 21 CodeGen/CodeGenerator.cc \ 22 CodeGen/FixMain.cc \ 22 23 CodeGen/GenType.cc \ 23 CodeGen/FixNames.cc \24 CodeGen/FixMain.cc \25 24 CodeGen/OperatorTable.cc 25 26 27 SRC += $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/FixNames.cc 28 SRCDEMANGLE += $(SRC_CODEGEN) -
src/CodeTools/module.mk
r7951100 rb067d9b 16 16 17 17 SRC += CodeTools/DeclStats.cc \ 18 CodeTools/ResolvProtoDump.cc \ 18 19 CodeTools/TrackLoc.cc -
src/Common/Assert.cc
r7951100 rb067d9b 39 39 } 40 40 41 void abort(const char *fmt, ... ) noexcept __attribute__((noreturn, format(printf, 1, 2))); 42 void abort(const char *fmt, ... ) noexcept { 43 va_list args; 44 va_start( args, fmt ); 45 vfprintf( stderr, fmt, args ); 46 va_end( args ); 47 fprintf( stderr, "\n" ); 48 abort(); 49 } 50 41 51 // Local Variables: // 42 52 // tab-width: 4 // -
src/Common/Debug.h
r7951100 rb067d9b 28 28 namespace Debug { 29 29 /// debug codegen a translation unit 30 static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec:: Compiler) {30 static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Builtin ) { 31 31 #ifdef DEBUG 32 32 std::list< Declaration * > decls; -
src/Common/Indenter.h
r7951100 rb067d9b 18 18 19 19 struct Indenter { 20 static unsigned tabsize; 20 static unsigned tabsize; ///< default number of spaces in one level of indentation 21 21 22 Indenter( unsigned int amt = tabsize, unsigned int indent = 0 ) : amt( amt ), indent( indent ) {} 23 unsigned int amt; // amount 1 level increases indent by (i.e. how much to increase by in operator++) 24 unsigned int indent; 22 unsigned int indent; ///< number of spaces to indent 23 unsigned int amt; ///< spaces in one level of indentation 25 24 26 Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; } 27 Indenter & operator-=(int nlevels) { indent -= amt*nlevels; return *this; } 25 Indenter( unsigned int indent = 0, unsigned int amt = tabsize ) 26 : indent( indent ), amt( amt ) {} 27 28 Indenter & operator+=(int nlevels) { indent += nlevels; return *this; } 29 Indenter & operator-=(int nlevels) { indent -= nlevels; return *this; } 28 30 Indenter operator+(int nlevels) { Indenter indenter = *this; return indenter += nlevels; } 29 31 Indenter operator-(int nlevels) { Indenter indenter = *this; return indenter -= nlevels; } … … 33 35 34 36 inline std::ostream & operator<<( std::ostream & out, const Indenter & indent ) { 35 return out << std::string(indent.indent , ' ');37 return out << std::string(indent.indent * indent.amt, ' '); 36 38 } 37 39 -
src/Common/PassVisitor.h
r7951100 rb067d9b 4 4 5 5 #include <stack> 6 6 #include <type_traits> 7 8 #include "Common/Stats.h" 7 9 #include "Common/utility.h" 8 10 … … 58 60 59 61 virtual void visit( ObjectDecl * objectDecl ) override final; 62 virtual void visit( const ObjectDecl * objectDecl ) override final; 60 63 virtual void visit( FunctionDecl * functionDecl ) override final; 64 virtual void visit( const FunctionDecl * functionDecl ) override final; 61 65 virtual void visit( StructDecl * aggregateDecl ) override final; 66 virtual void visit( const StructDecl * aggregateDecl ) override final; 62 67 virtual void visit( UnionDecl * aggregateDecl ) override final; 68 virtual void visit( const UnionDecl * aggregateDecl ) override final; 63 69 virtual void visit( EnumDecl * aggregateDecl ) override final; 70 virtual void visit( const EnumDecl * aggregateDecl ) override final; 64 71 virtual void visit( TraitDecl * aggregateDecl ) override final; 72 virtual void visit( const TraitDecl * aggregateDecl ) override final; 65 73 virtual void visit( TypeDecl * typeDecl ) override final; 74 virtual void visit( const TypeDecl * typeDecl ) override final; 66 75 virtual void visit( TypedefDecl * typeDecl ) override final; 76 virtual void visit( const TypedefDecl * typeDecl ) override final; 67 77 virtual void visit( AsmDecl * asmDecl ) override final; 78 virtual void visit( const AsmDecl * asmDecl ) override final; 68 79 virtual void visit( StaticAssertDecl * assertDecl ) override final; 80 virtual void visit( const StaticAssertDecl * assertDecl ) override final; 69 81 70 82 virtual void visit( CompoundStmt * compoundStmt ) override final; 83 virtual void visit( const CompoundStmt * compoundStmt ) override final; 71 84 virtual void visit( ExprStmt * exprStmt ) override final; 85 virtual void visit( const ExprStmt * exprStmt ) override final; 72 86 virtual void visit( AsmStmt * asmStmt ) override final; 87 virtual void visit( const AsmStmt * asmStmt ) override final; 73 88 virtual void visit( DirectiveStmt * dirStmt ) override final; 89 virtual void visit( const DirectiveStmt * dirStmt ) override final; 74 90 virtual void visit( IfStmt * ifStmt ) override final; 91 virtual void visit( const IfStmt * ifStmt ) override final; 75 92 virtual void visit( WhileStmt * whileStmt ) override final; 93 virtual void visit( const WhileStmt * whileStmt ) override final; 76 94 virtual void visit( ForStmt * forStmt ) override final; 95 virtual void visit( const ForStmt * forStmt ) override final; 77 96 virtual void visit( SwitchStmt * switchStmt ) override final; 97 virtual void visit( const SwitchStmt * switchStmt ) override final; 78 98 virtual void visit( CaseStmt * caseStmt ) override final; 99 virtual void visit( const CaseStmt * caseStmt ) override final; 79 100 virtual void visit( BranchStmt * branchStmt ) override final; 101 virtual void visit( const BranchStmt * branchStmt ) override final; 80 102 virtual void visit( ReturnStmt * returnStmt ) override final; 103 virtual void visit( const ReturnStmt * returnStmt ) override final; 81 104 virtual void visit( ThrowStmt * throwStmt ) override final; 105 virtual void visit( const ThrowStmt * throwStmt ) override final; 82 106 virtual void visit( TryStmt * tryStmt ) override final; 107 virtual void visit( const TryStmt * tryStmt ) override final; 83 108 virtual void visit( CatchStmt * catchStmt ) override final; 109 virtual void visit( const CatchStmt * catchStmt ) override final; 84 110 virtual void visit( FinallyStmt * finallyStmt ) override final; 111 virtual void visit( const FinallyStmt * finallyStmt ) override final; 85 112 virtual void visit( WaitForStmt * waitforStmt ) override final; 113 virtual void visit( const WaitForStmt * waitforStmt ) override final; 86 114 virtual void visit( WithStmt * withStmt ) override final; 115 virtual void visit( const WithStmt * withStmt ) override final; 87 116 virtual void visit( NullStmt * nullStmt ) override final; 117 virtual void visit( const NullStmt * nullStmt ) override final; 88 118 virtual void visit( DeclStmt * declStmt ) override final; 119 virtual void visit( const DeclStmt * declStmt ) override final; 89 120 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final; 121 virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) override final; 90 122 91 123 virtual void visit( ApplicationExpr * applicationExpr ) override final; 124 virtual void visit( const ApplicationExpr * applicationExpr ) override final; 92 125 virtual void visit( UntypedExpr * untypedExpr ) override final; 126 virtual void visit( const UntypedExpr * untypedExpr ) override final; 93 127 virtual void visit( NameExpr * nameExpr ) override final; 128 virtual void visit( const NameExpr * nameExpr ) override final; 94 129 virtual void visit( CastExpr * castExpr ) override final; 130 virtual void visit( const CastExpr * castExpr ) override final; 95 131 virtual void visit( KeywordCastExpr * castExpr ) override final; 132 virtual void visit( const KeywordCastExpr * castExpr ) override final; 96 133 virtual void visit( VirtualCastExpr * castExpr ) override final; 134 virtual void visit( const VirtualCastExpr * castExpr ) override final; 97 135 virtual void visit( AddressExpr * addressExpr ) override final; 136 virtual void visit( const AddressExpr * addressExpr ) override final; 98 137 virtual void visit( LabelAddressExpr * labAddressExpr ) override final; 138 virtual void visit( const LabelAddressExpr * labAddressExpr ) override final; 99 139 virtual void visit( UntypedMemberExpr * memberExpr ) override final; 140 virtual void visit( const UntypedMemberExpr * memberExpr ) override final; 100 141 virtual void visit( MemberExpr * memberExpr ) override final; 142 virtual void visit( const MemberExpr * memberExpr ) override final; 101 143 virtual void visit( VariableExpr * variableExpr ) override final; 144 virtual void visit( const VariableExpr * variableExpr ) override final; 102 145 virtual void visit( ConstantExpr * constantExpr ) override final; 146 virtual void visit( const ConstantExpr * constantExpr ) override final; 103 147 virtual void visit( SizeofExpr * sizeofExpr ) override final; 148 virtual void visit( const SizeofExpr * sizeofExpr ) override final; 104 149 virtual void visit( AlignofExpr * alignofExpr ) override final; 150 virtual void visit( const AlignofExpr * alignofExpr ) override final; 105 151 virtual void visit( UntypedOffsetofExpr * offsetofExpr ) override final; 152 virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) override final; 106 153 virtual void visit( OffsetofExpr * offsetofExpr ) override final; 154 virtual void visit( const OffsetofExpr * offsetofExpr ) override final; 107 155 virtual void visit( OffsetPackExpr * offsetPackExpr ) override final; 108 virtual void visit( AttrExpr * attrExpr ) override final;156 virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final; 109 157 virtual void visit( LogicalExpr * logicalExpr ) override final; 158 virtual void visit( const LogicalExpr * logicalExpr ) override final; 110 159 virtual void visit( ConditionalExpr * conditionalExpr ) override final; 160 virtual void visit( const ConditionalExpr * conditionalExpr ) override final; 111 161 virtual void visit( CommaExpr * commaExpr ) override final; 162 virtual void visit( const CommaExpr * commaExpr ) override final; 112 163 virtual void visit( TypeExpr * typeExpr ) override final; 164 virtual void visit( const TypeExpr * typeExpr ) override final; 113 165 virtual void visit( AsmExpr * asmExpr ) override final; 166 virtual void visit( const AsmExpr * asmExpr ) override final; 114 167 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override final; 168 virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) override final; 115 169 virtual void visit( ConstructorExpr * ctorExpr ) override final; 170 virtual void visit( const ConstructorExpr * ctorExpr ) override final; 116 171 virtual void visit( CompoundLiteralExpr * compLitExpr ) override final; 172 virtual void visit( const CompoundLiteralExpr * compLitExpr ) override final; 117 173 virtual void visit( RangeExpr * rangeExpr ) override final; 174 virtual void visit( const RangeExpr * rangeExpr ) override final; 118 175 virtual void visit( UntypedTupleExpr * tupleExpr ) override final; 176 virtual void visit( const UntypedTupleExpr * tupleExpr ) override final; 119 177 virtual void visit( TupleExpr * tupleExpr ) override final; 178 virtual void visit( const TupleExpr * tupleExpr ) override final; 120 179 virtual void visit( TupleIndexExpr * tupleExpr ) override final; 180 virtual void visit( const TupleIndexExpr * tupleExpr ) override final; 121 181 virtual void visit( TupleAssignExpr * assignExpr ) override final; 182 virtual void visit( const TupleAssignExpr * assignExpr ) override final; 122 183 virtual void visit( StmtExpr * stmtExpr ) override final; 184 virtual void visit( const StmtExpr * stmtExpr ) override final; 123 185 virtual void visit( UniqueExpr * uniqueExpr ) override final; 186 virtual void visit( const UniqueExpr * uniqueExpr ) override final; 124 187 virtual void visit( UntypedInitExpr * initExpr ) override final; 188 virtual void visit( const UntypedInitExpr * initExpr ) override final; 125 189 virtual void visit( InitExpr * initExpr ) override final; 190 virtual void visit( const InitExpr * initExpr ) override final; 126 191 virtual void visit( DeletedExpr * delExpr ) override final; 192 virtual void visit( const DeletedExpr * delExpr ) override final; 193 virtual void visit( DefaultArgExpr * argExpr ) override final; 194 virtual void visit( const DefaultArgExpr * argExpr ) override final; 127 195 virtual void visit( GenericExpr * genExpr ) override final; 196 virtual void visit( const GenericExpr * genExpr ) override final; 128 197 129 198 virtual void visit( VoidType * basicType ) override final; 199 virtual void visit( const VoidType * basicType ) override final; 130 200 virtual void visit( BasicType * basicType ) override final; 201 virtual void visit( const BasicType * basicType ) override final; 131 202 virtual void visit( PointerType * pointerType ) override final; 203 virtual void visit( const PointerType * pointerType ) override final; 132 204 virtual void visit( ArrayType * arrayType ) override final; 205 virtual void visit( const ArrayType * arrayType ) override final; 133 206 virtual void visit( ReferenceType * referenceType ) override final; 207 virtual void visit( const ReferenceType * referenceType ) override final; 208 virtual void visit( QualifiedType * qualType ) override final; 209 virtual void visit( const QualifiedType * qualType ) override final; 134 210 virtual void visit( FunctionType * functionType ) override final; 211 virtual void visit( const FunctionType * functionType ) override final; 135 212 virtual void visit( StructInstType * aggregateUseType ) override final; 213 virtual void visit( const StructInstType * aggregateUseType ) override final; 136 214 virtual void visit( UnionInstType * aggregateUseType ) override final; 215 virtual void visit( const UnionInstType * aggregateUseType ) override final; 137 216 virtual void visit( EnumInstType * aggregateUseType ) override final; 217 virtual void visit( const EnumInstType * aggregateUseType ) override final; 138 218 virtual void visit( TraitInstType * aggregateUseType ) override final; 219 virtual void visit( const TraitInstType * aggregateUseType ) override final; 139 220 virtual void visit( TypeInstType * aggregateUseType ) override final; 221 virtual void visit( const TypeInstType * aggregateUseType ) override final; 140 222 virtual void visit( TupleType * tupleType ) override final; 223 virtual void visit( const TupleType * tupleType ) override final; 141 224 virtual void visit( TypeofType * typeofType ) override final; 225 virtual void visit( const TypeofType * typeofType ) override final; 142 226 virtual void visit( AttrType * attrType ) override final; 227 virtual void visit( const AttrType * attrType ) override final; 143 228 virtual void visit( VarArgsType * varArgsType ) override final; 229 virtual void visit( const VarArgsType * varArgsType ) override final; 144 230 virtual void visit( ZeroType * zeroType ) override final; 231 virtual void visit( const ZeroType * zeroType ) override final; 145 232 virtual void visit( OneType * oneType ) override final; 233 virtual void visit( const OneType * oneType ) override final; 234 virtual void visit( GlobalScopeType * globalType ) override final; 235 virtual void visit( const GlobalScopeType * globalType ) override final; 146 236 147 237 virtual void visit( Designation * designation ) override final; 238 virtual void visit( const Designation * designation ) override final; 148 239 virtual void visit( SingleInit * singleInit ) override final; 240 virtual void visit( const SingleInit * singleInit ) override final; 149 241 virtual void visit( ListInit * listInit ) override final; 242 virtual void visit( const ListInit * listInit ) override final; 150 243 virtual void visit( ConstructorInit * ctorInit ) override final; 151 152 virtual void visit( Subrange * subrange ) override final; 244 virtual void visit( const ConstructorInit * ctorInit ) override final; 153 245 154 246 virtual void visit( Constant * constant ) override final; 247 virtual void visit( const Constant * constant ) override final; 155 248 156 249 virtual void visit( Attribute * attribute ) override final; 250 virtual void visit( const Attribute * attribute ) override final; 157 251 158 252 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final; … … 183 277 virtual Statement * mutate( FinallyStmt * finallyStmt ) override final; 184 278 virtual Statement * mutate( WaitForStmt * waitforStmt ) override final; 185 virtual Statement* mutate( WithStmt * withStmt ) override final;279 virtual Declaration * mutate( WithStmt * withStmt ) override final; 186 280 virtual NullStmt * mutate( NullStmt * nullStmt ) override final; 187 281 virtual Statement * mutate( DeclStmt * declStmt ) override final; … … 205 299 virtual Expression * mutate( OffsetofExpr * offsetofExpr ) override final; 206 300 virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) override final; 207 virtual Expression * mutate( AttrExpr * attrExpr ) override final;208 301 virtual Expression * mutate( LogicalExpr * logicalExpr ) override final; 209 302 virtual Expression * mutate( ConditionalExpr * conditionalExpr ) override final; … … 224 317 virtual Expression * mutate( InitExpr * initExpr ) override final; 225 318 virtual Expression * mutate( DeletedExpr * delExpr ) override final; 319 virtual Expression * mutate( DefaultArgExpr * argExpr ) override final; 226 320 virtual Expression * mutate( GenericExpr * genExpr ) override final; 227 321 … … 231 325 virtual Type * mutate( ArrayType * arrayType ) override final; 232 326 virtual Type * mutate( ReferenceType * referenceType ) override final; 327 virtual Type * mutate( QualifiedType * qualType ) override final; 233 328 virtual Type * mutate( FunctionType * functionType ) override final; 234 329 virtual Type * mutate( StructInstType * aggregateUseType ) override final; … … 243 338 virtual Type * mutate( ZeroType * zeroType ) override final; 244 339 virtual Type * mutate( OneType * oneType ) override final; 340 virtual Type * mutate( GlobalScopeType * globalType ) override final; 245 341 246 342 virtual Designation * mutate( Designation * designation ) override final; … … 249 345 virtual Initializer * mutate( ConstructorInit * ctorInit ) override final; 250 346 251 virtual Subrange * mutate( Subrange * subrange ) override final;252 253 347 virtual Constant * mutate( Constant * constant ) override final; 254 348 … … 258 352 259 353 private: 354 bool inFunction = false; 355 260 356 template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 357 template<typename pass_t> friend void acceptAll( const std::list< const Declaration * > &decls, PassVisitor< pass_t >& visitor ); 261 358 template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 262 359 template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor ); 360 template< typename TreeType, typename pass_t > friend void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_t > & visitor ); 263 361 template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator ); 264 362 template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor ); 363 template< typename Container, typename pass_t > friend void maybeAccept_impl( const Container & container, PassVisitor< pass_t > & visitor ); 265 364 template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator ); 266 365 267 366 template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); } 367 template<typename node_type> void call_previsit ( const node_type * node ) { previsit_impl ( pass, node, 0 ); } 268 368 template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); } 369 template<typename node_type> void call_postvisit( const node_type * node ) { postvisit_impl( pass, node, 0 ); } 269 370 270 371 template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); } … … 280 381 void visitStatementList ( std::list< Statement* > &statements ); 281 382 void mutateStatementList( std::list< Statement* > &statements ); 383 void visitStatementList ( const std::list< Statement * > & statements ); 282 384 283 385 template< typename func_t > … … 285 387 Statement * visitStatement ( Statement * stmt ); 286 388 Statement * mutateStatement( Statement * stmt ); 389 void visitStatement ( const Statement * stmt ); 287 390 288 391 template< typename func_t > … … 290 393 Expression * visitExpression ( Expression * expr ); 291 394 Expression * mutateExpression( Expression * expr ); 292 293 294 TypeSubstitution ** get_env_ptr () { return env_impl ( pass, 0); } 395 void visitExpression ( const Expression * expr ); 396 397 398 auto get_env_ptr () -> decltype(env_impl( pass, 0)) { return env_impl( pass, 0); } 295 399 std::list< Statement* > * get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); } 296 400 std::list< Statement* > * get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); } … … 303 407 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); } 304 408 void indexerScopeLeave () { indexer_impl_leaveScope ( pass, 0 ); } 305 void indexerAddId ( DeclarationWithType* node ) { indexer_impl_addId ( pass, 0, node ); }306 void indexerAddType ( NamedTypeDecl* node ) { indexer_impl_addType ( pass, 0, node ); }409 void indexerAddId ( const DeclarationWithType * node ) { indexer_impl_addId ( pass, 0, node ); } 410 void indexerAddType ( const NamedTypeDecl * node ) { indexer_impl_addType ( pass, 0, node ); } 307 411 void indexerAddStruct ( const std::string & id ) { indexer_impl_addStruct ( pass, 0, id ); } 308 void indexerAddStruct ( StructDecl* node ) { indexer_impl_addStruct ( pass, 0, node ); }309 void indexerAddStructFwd( StructDecl* node ) { indexer_impl_addStructFwd( pass, 0, node ); }310 void indexerAddEnum ( EnumDecl* node ) { indexer_impl_addEnum ( pass, 0, node ); }412 void indexerAddStruct ( const StructDecl * node ) { indexer_impl_addStruct ( pass, 0, node ); } 413 void indexerAddStructFwd( const StructDecl * node ) { indexer_impl_addStructFwd( pass, 0, node ); } 414 void indexerAddEnum ( const EnumDecl * node ) { indexer_impl_addEnum ( pass, 0, node ); } 311 415 void indexerAddUnion ( const std::string & id ) { indexer_impl_addUnion ( pass, 0, id ); } 312 void indexerAddUnion ( UnionDecl* node ) { indexer_impl_addUnion ( pass, 0, node ); }313 void indexerAddUnionFwd ( UnionDecl* node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }314 void indexerAddTrait ( TraitDecl* node ) { indexer_impl_addTrait ( pass, 0, node ); }315 void indexerAddWith ( std::list< Expression * > & exprs, BaseSyntaxNode* withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }416 void indexerAddUnion ( const UnionDecl * node ) { indexer_impl_addUnion ( pass, 0, node ); } 417 void indexerAddUnionFwd ( const UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 418 void indexerAddTrait ( const TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 419 void indexerAddWith ( const std::list< Expression * > & exprs, const Declaration * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); } 316 420 317 421 318 422 template< typename TreeType, typename VisitorType > 319 friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );423 friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ); 320 424 321 425 template< typename TreeType, typename VisitorType > 322 friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor ); 426 friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ); 427 428 template< typename TreeType, typename VisitorType > 429 friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor ); 323 430 }; 324 431 … … 337 444 public: 338 445 TypeSubstitution * env = nullptr; 446 }; 447 448 class WithConstTypeSubstitution { 449 protected: 450 WithConstTypeSubstitution() = default; 451 ~WithConstTypeSubstitution() = default; 452 453 public: 454 const TypeSubstitution * env = nullptr; 339 455 }; 340 456 … … 418 534 }; 419 535 536 #include "Common/Stats.h" 537 538 extern struct PassVisitorStats { 539 size_t depth = 0; 540 Stats::Counters::MaxCounter<double> * max = nullptr; 541 Stats::Counters::AverageCounter<double> * avg = nullptr; 542 } pass_visitor_stats; 543 420 544 #include "SynTree/TypeSubstitution.h" 421 545 #include "PassVisitor.impl.h" -
src/Common/PassVisitor.impl.h
r7951100 rb067d9b 20 20 21 21 #define MUTATE_END( type, node ) \ 22 return call_postmutate< type * >( node ); \ 23 24 25 #define VISIT_BODY( node ) \ 26 VISIT_START( node ); \ 27 if( children_guard ) { \ 28 Visitor::visit( node ); \ 29 } \ 30 VISIT_END( node ); \ 31 32 33 #define MUTATE_BODY( type, node ) \ 34 MUTATE_START( node ); \ 35 if( children_guard ) { \ 36 Mutator::mutate( node ); \ 37 } \ 38 MUTATE_END( type, node ); \ 39 22 auto __return = call_postmutate< type * >( node ); \ 23 assert( __return ); \ 24 return __return; 40 25 41 26 … … 67 52 SemanticErrorException errors; 68 53 54 pass_visitor_stats.depth++; 55 pass_visitor_stats.max->push(pass_visitor_stats.depth); 56 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 69 57 for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) { 58 59 70 60 // splice in new declarations after previous decl 71 61 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } … … 83 73 if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); } 84 74 } 75 pass_visitor_stats.depth--; 76 if ( ! errors.isEmpty() ) { 77 throw errors; 78 } 79 } 80 81 template< typename pass_type > 82 inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) { 83 SemanticErrorException errors; 84 85 pass_visitor_stats.depth++; 86 pass_visitor_stats.max->push(pass_visitor_stats.depth); 87 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 88 for ( const Declaration * decl : decls ) { 89 try { 90 // run visitor on declaration 91 maybeAccept_impl( decl, visitor ); 92 } 93 catch( SemanticErrorException &e ) { 94 errors.append( e ); 95 } 96 } 97 pass_visitor_stats.depth--; 85 98 if ( ! errors.isEmpty() ) { 86 99 throw errors; … … 94 107 SemanticErrorException errors; 95 108 109 pass_visitor_stats.depth++; 110 pass_visitor_stats.max->push(pass_visitor_stats.depth); 111 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 96 112 for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) { 97 113 // splice in new declarations after previous decl … … 109 125 if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); } 110 126 } 127 pass_visitor_stats.depth--; 111 128 if ( ! errors.isEmpty() ) { 112 129 throw errors; … … 122 139 } 123 140 141 template< typename TreeType, typename pass_type > 142 inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) { 143 if ( ! visitor.get_visit_children() ) return; 144 if ( tree ) { 145 tree->accept( visitor ); 146 } 147 } 148 124 149 template< typename Container, typename pass_type > 125 150 inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) { 126 151 if ( ! visitor.get_visit_children() ) return; 127 152 SemanticErrorException errors; 153 154 pass_visitor_stats.depth++; 155 pass_visitor_stats.max->push(pass_visitor_stats.depth); 156 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 128 157 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { 129 158 try { … … 135 164 } 136 165 } 166 pass_visitor_stats.depth--; 167 if ( ! errors.isEmpty() ) { 168 throw errors; 169 } 170 } 171 172 template< typename Container, typename pass_type > 173 inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) { 174 if ( ! visitor.get_visit_children() ) return; 175 SemanticErrorException errors; 176 177 pass_visitor_stats.depth++; 178 pass_visitor_stats.max->push(pass_visitor_stats.depth); 179 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 180 for ( const auto & i : container ) { 181 try { 182 if ( i ) { 183 i->accept( visitor ); 184 } 185 } catch( SemanticErrorException &e ) { 186 errors.append( e ); 187 } 188 } 189 pass_visitor_stats.depth--; 137 190 if ( ! errors.isEmpty() ) { 138 191 throw errors; … … 151 204 template< typename Container, typename pass_type > 152 205 inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) { 206 153 207 if ( ! mutator.get_visit_children() ) return; 154 208 SemanticErrorException errors; 209 210 pass_visitor_stats.depth++; 211 pass_visitor_stats.max->push(pass_visitor_stats.depth); 212 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 155 213 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { 156 214 try { … … 163 221 } // try 164 222 } // for 223 pass_visitor_stats.depth--; 165 224 if ( ! errors.isEmpty() ) { 166 225 throw errors; … … 185 244 DeclList_t* afterDecls = get_afterDecls(); 186 245 246 pass_visitor_stats.depth++; 247 pass_visitor_stats.max->push(pass_visitor_stats.depth); 248 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 187 249 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { 188 250 … … 192 254 try { 193 255 func( *i ); 256 assert( *i ); 194 257 assert(( empty( beforeStmts ) && empty( afterStmts )) 195 258 || ( empty( beforeDecls ) && empty( afterDecls )) ); … … 202 265 if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); } 203 266 } 267 pass_visitor_stats.depth--; 204 268 205 269 if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); } … … 216 280 217 281 template< typename pass_type > 282 void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) { 283 if ( ! get_visit_children() ) return; 284 SemanticErrorException errors; 285 286 pass_visitor_stats.depth++; 287 pass_visitor_stats.max->push(pass_visitor_stats.depth); 288 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 289 for ( const Statement * i : statements ) { 290 try { 291 maybeAccept_impl( i, *this ); 292 } catch ( SemanticErrorException &e ) { 293 errors.append( e ); 294 } 295 } 296 pass_visitor_stats.depth--; 297 if ( !errors.isEmpty() ) { throw errors; } 298 } 299 300 template< typename pass_type > 218 301 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) { 219 302 handleStatementList( statements, [this]( Statement *& stmt) { … … 229 312 230 313 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 231 ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr() );314 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 232 315 ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() ); 233 316 ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () ); … … 264 347 265 348 template< typename pass_type > 349 void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) { 350 if ( ! get_visit_children() ) return; 351 352 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 353 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 354 355 maybeAccept_impl( stmt, *this ); 356 } 357 358 template< typename pass_type > 266 359 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) { 267 360 return handleStatement( stmt, [this]( Statement * stmt ) { … … 295 388 296 389 template< typename pass_type > 390 void PassVisitor< pass_type >::visitExpression( const Expression * expr ) { 391 if ( ! get_visit_children() ) return; 392 if( !expr ) return; 393 394 auto env_ptr = get_env_ptr(); 395 if ( env_ptr && expr->get_env() ) { 396 *env_ptr = expr->get_env(); 397 } 398 399 maybeAccept_impl( expr, *this ); 400 } 401 402 template< typename pass_type > 297 403 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) { 298 404 return handleExpression(expr, [this]( Expression * expr ) { … … 304 410 template< typename TreeType, typename VisitorType > 305 411 inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) { 412 if ( ! visitor.get_visit_children() ) return; 413 auto guard = makeFuncGuard( 414 [&visitor]() { visitor.indexerScopeEnter(); }, 415 [&visitor]() { visitor.indexerScopeLeave(); } 416 ); 417 maybeAccept_impl( tree, visitor ); 418 } 419 420 template< typename TreeType, typename VisitorType > 421 inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) { 306 422 if ( ! visitor.get_visit_children() ) return; 307 423 auto guard = makeFuncGuard( … … 366 482 367 483 template< typename pass_type > 484 void PassVisitor< pass_type >::visit( const ObjectDecl * node ) { 485 VISIT_START( node ); 486 487 maybeAccept_impl( node->type , *this ); 488 maybeAccept_impl( node->init , *this ); 489 maybeAccept_impl( node->bitfieldWidth, *this ); 490 maybeAccept_impl( node->attributes , *this ); 491 492 VISIT_END( node ); 493 } 494 495 template< typename pass_type > 368 496 DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) { 369 497 MUTATE_START( node ); … … 404 532 indexerAddId( &func ); 405 533 maybeAccept_impl( node->type, *this ); 534 // function body needs to have the same scope as parameters - CompoundStmt will not enter 535 // a new scope if inFunction is true 536 ValueGuard< bool > oldInFunction( inFunction ); 537 inFunction = true; 538 maybeAccept_impl( node->statements, *this ); 539 maybeAccept_impl( node->attributes, *this ); 540 } 541 } 542 543 VISIT_END( node ); 544 } 545 546 template< typename pass_type > 547 void PassVisitor< pass_type >::visit( const FunctionDecl * node ) { 548 VISIT_START( node ); 549 550 indexerAddId( node ); 551 552 maybeAccept_impl( node->withExprs, *this ); 553 { 554 // with clause introduces a level of scope (for the with expression members). 555 // with clause exprs are added to the indexer before parameters so that parameters 556 // shadow with exprs and not the other way around. 557 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 558 indexerAddWith( node->withExprs, node ); 559 { 560 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 561 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 562 static ObjectDecl func( 563 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 564 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 565 nullptr 566 ); 567 indexerAddId( &func ); 568 maybeAccept_impl( node->type, *this ); 569 // function body needs to have the same scope as parameters - CompoundStmt will not enter 570 // a new scope if inFunction is true 571 ValueGuard< bool > oldInFunction( inFunction ); 572 inFunction = true; 406 573 maybeAccept_impl( node->statements, *this ); 407 574 maybeAccept_impl( node->attributes, *this ); … … 434 601 indexerAddId( &func ); 435 602 maybeMutate_impl( node->type, *this ); 603 // function body needs to have the same scope as parameters - CompoundStmt will not enter 604 // a new scope if inFunction is true 605 ValueGuard< bool > oldInFunction( inFunction ); 606 inFunction = true; 436 607 maybeMutate_impl( node->statements, *this ); 437 608 maybeMutate_impl( node->attributes, *this ); … … 465 636 466 637 template< typename pass_type > 467 Declaration * PassVisitor< pass_type >::mutate(StructDecl * node ) {468 MUTATE_START( node );638 void PassVisitor< pass_type >::visit( const StructDecl * node ) { 639 VISIT_START( node ); 469 640 470 641 // make up a forward declaration and add it before processing the members … … 474 645 { 475 646 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 647 maybeAccept_impl( node->parameters, *this ); 648 maybeAccept_impl( node->members , *this ); 649 } 650 651 // this addition replaces the forward declaration 652 indexerAddStruct( node ); 653 654 VISIT_END( node ); 655 } 656 657 template< typename pass_type > 658 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) { 659 MUTATE_START( node ); 660 661 // make up a forward declaration and add it before processing the members 662 // needs to be on the heap because addStruct saves the pointer 663 indexerAddStructFwd( node ); 664 665 { 666 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 476 667 maybeMutate_impl( node->parameters, *this ); 477 668 maybeMutate_impl( node->members , *this ); … … 503 694 VISIT_END( node ); 504 695 } 696 template< typename pass_type > 697 void PassVisitor< pass_type >::visit( const UnionDecl * node ) { 698 VISIT_START( node ); 699 700 // make up a forward declaration and add it before processing the members 701 indexerAddUnionFwd( node ); 702 703 { 704 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 705 maybeAccept_impl( node->parameters, *this ); 706 maybeAccept_impl( node->members , *this ); 707 } 708 709 indexerAddUnion( node ); 710 711 VISIT_END( node ); 712 } 505 713 506 714 template< typename pass_type > … … 538 746 539 747 template< typename pass_type > 748 void PassVisitor< pass_type >::visit( const EnumDecl * node ) { 749 VISIT_START( node ); 750 751 indexerAddEnum( node ); 752 753 // unlike structs, traits, and unions, enums inject their members into the global scope 754 maybeAccept_impl( node->parameters, *this ); 755 maybeAccept_impl( node->members , *this ); 756 757 VISIT_END( node ); 758 } 759 760 template< typename pass_type > 540 761 Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) { 541 762 MUTATE_START( node ); … … 554 775 template< typename pass_type > 555 776 void PassVisitor< pass_type >::visit( TraitDecl * node ) { 777 VISIT_START( node ); 778 779 { 780 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 781 maybeAccept_impl( node->parameters, *this ); 782 maybeAccept_impl( node->members , *this ); 783 } 784 785 indexerAddTrait( node ); 786 787 VISIT_END( node ); 788 } 789 790 template< typename pass_type > 791 void PassVisitor< pass_type >::visit( const TraitDecl * node ) { 556 792 VISIT_START( node ); 557 793 … … 606 842 } 607 843 608 template< typename pass_type > 609 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) { 610 MUTATE_START( node ); 844 845 template< typename pass_type > 846 void PassVisitor< pass_type >::visit( const TypeDecl * node ) { 847 VISIT_START( node ); 611 848 612 849 { 613 850 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 614 maybe Mutate_impl( node->parameters, *this );615 maybe Mutate_impl( node->base , *this );851 maybeAccept_impl( node->parameters, *this ); 852 maybeAccept_impl( node->base , *this ); 616 853 } 617 854 … … 621 858 indexerAddType( node ); 622 859 860 maybeAccept_impl( node->assertions, *this ); 861 862 indexerScopedAccept( node->init, *this ); 863 864 VISIT_END( node ); 865 } 866 867 template< typename pass_type > 868 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) { 869 MUTATE_START( node ); 870 871 { 872 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 873 maybeMutate_impl( node->parameters, *this ); 874 maybeMutate_impl( node->base , *this ); 875 } 876 877 // see A NOTE ON THE ORDER OF TRAVERSAL, above 878 // note that assertions come after the type is added to the symtab, since they are not part of the type proper 879 // and may depend on the type itself 880 indexerAddType( node ); 881 623 882 maybeMutate_impl( node->assertions, *this ); 624 883 … … 648 907 649 908 template< typename pass_type > 909 void PassVisitor< pass_type >::visit( const TypedefDecl * node ) { 910 VISIT_START( node ); 911 912 { 913 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 914 maybeAccept_impl( node->parameters, *this ); 915 maybeAccept_impl( node->base , *this ); 916 } 917 918 indexerAddType( node ); 919 920 maybeAccept_impl( node->assertions, *this ); 921 922 VISIT_END( node ); 923 } 924 925 template< typename pass_type > 650 926 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) { 651 927 MUTATE_START( node ); … … 676 952 677 953 template< typename pass_type > 954 void PassVisitor< pass_type >::visit( const AsmDecl * node ) { 955 VISIT_START( node ); 956 957 maybeAccept_impl( node->stmt, *this ); 958 959 VISIT_END( node ); 960 } 961 962 template< typename pass_type > 678 963 AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) { 679 964 MUTATE_START( node ); … … 697 982 698 983 template< typename pass_type > 984 void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) { 985 VISIT_START( node ); 986 987 visitExpression( node->condition ); 988 maybeAccept_impl( node->message, *this ); 989 990 VISIT_END( node ); 991 } 992 993 template< typename pass_type > 699 994 StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) { 700 995 MUTATE_START( node ); … … 712 1007 VISIT_START( node ); 713 1008 { 714 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1009 // do not enter a new scope if inFunction is true - needs to check old state before the assignment 1010 ValueGuard< bool > oldInFunction( inFunction ); 1011 auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } ); 715 1012 auto guard2 = makeFuncGuard( [this]() { call_beginScope(); }, [this]() { call_endScope(); } ); 1013 inFunction = false; 716 1014 visitStatementList( node->kids ); 717 1015 } … … 720 1018 721 1019 template< typename pass_type > 1020 void PassVisitor< pass_type >::visit( const CompoundStmt * node ) { 1021 VISIT_START( node ); 1022 { 1023 // do not enter a new scope if inFunction is true - needs to check old state before the assignment 1024 ValueGuard< bool > oldInFunction( inFunction ); 1025 auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } ); 1026 auto guard2 = makeFuncGuard( [this]() { call_beginScope(); }, [this]() { call_endScope(); } ); 1027 inFunction = false; 1028 visitStatementList( node->kids ); 1029 } 1030 VISIT_END( node ); 1031 } 1032 1033 template< typename pass_type > 722 1034 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) { 723 1035 MUTATE_START( node ); 724 1036 { 725 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1037 // do not enter a new scope if inFunction is true - needs to check old state before the assignment 1038 ValueGuard< bool > oldInFunction( inFunction ); 1039 auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } ); 726 1040 auto guard2 = makeFuncGuard( [this]() { call_beginScope(); }, [this]() { call_endScope(); } ); 1041 inFunction = false; 727 1042 mutateStatementList( node->kids ); 728 1043 } … … 734 1049 template< typename pass_type > 735 1050 void PassVisitor< pass_type >::visit( ExprStmt * node ) { 1051 VISIT_START( node ); 1052 1053 visitExpression( node->expr ); 1054 1055 VISIT_END( node ); 1056 } 1057 1058 template< typename pass_type > 1059 void PassVisitor< pass_type >::visit( const ExprStmt * node ) { 736 1060 VISIT_START( node ); 737 1061 … … 765 1089 766 1090 template< typename pass_type > 1091 void PassVisitor< pass_type >::visit( const AsmStmt * node ) { 1092 VISIT_START( node ) 1093 1094 maybeAccept_impl( node->instruction, *this ); 1095 maybeAccept_impl( node->output, *this ); 1096 maybeAccept_impl( node->input, *this ); 1097 maybeAccept_impl( node->clobber, *this ); 1098 1099 VISIT_END( node ); 1100 } 1101 1102 template< typename pass_type > 767 1103 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) { 768 1104 MUTATE_START( node ); … … 786 1122 787 1123 template< typename pass_type > 1124 void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) { 1125 VISIT_START( node ) 1126 1127 VISIT_END( node ); 1128 } 1129 1130 template< typename pass_type > 788 1131 Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) { 789 1132 MUTATE_START( node ); … … 800 1143 // if statements introduce a level of scope (for the initialization) 801 1144 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 802 maybeAccept_impl( node-> get_initialization(), *this );1145 maybeAccept_impl( node->initialization, *this ); 803 1146 visitExpression ( node->condition ); 804 1147 node->thenPart = visitStatement( node->thenPart ); … … 809 1152 810 1153 template< typename pass_type > 811 Statement * PassVisitor< pass_type >::mutate(IfStmt * node ) {812 MUTATE_START( node );1154 void PassVisitor< pass_type >::visit( const IfStmt * node ) { 1155 VISIT_START( node ); 813 1156 { 814 1157 // if statements introduce a level of scope (for the initialization) 815 1158 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 816 maybeMutate_impl( node->get_initialization(), *this ); 1159 maybeAccept_impl( node->initialization, *this ); 1160 visitExpression ( node->condition ); 1161 visitStatement ( node->thenPart ); 1162 visitStatement ( node->elsePart ); 1163 } 1164 VISIT_END( node ); 1165 } 1166 1167 template< typename pass_type > 1168 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) { 1169 MUTATE_START( node ); 1170 { 1171 // if statements introduce a level of scope (for the initialization) 1172 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1173 maybeMutate_impl( node->initialization, *this ); 817 1174 node->condition = mutateExpression( node->condition ); 818 1175 node->thenPart = mutateStatement ( node->thenPart ); … … 834 1191 visitExpression ( node->condition ); 835 1192 node->body = visitStatement( node->body ); 1193 } 1194 1195 VISIT_END( node ); 1196 } 1197 1198 template< typename pass_type > 1199 void PassVisitor< pass_type >::visit( const WhileStmt * node ) { 1200 VISIT_START( node ); 1201 1202 { 1203 // while statements introduce a level of scope (for the initialization) 1204 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1205 maybeAccept_impl( node->initialization, *this ); 1206 visitExpression ( node->condition ); 1207 visitStatement ( node->body ); 836 1208 } 837 1209 … … 872 1244 873 1245 template< typename pass_type > 1246 void PassVisitor< pass_type >::visit( const ForStmt * node ) { 1247 VISIT_START( node ); 1248 { 1249 // for statements introduce a level of scope (for the initialization) 1250 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1251 maybeAccept_impl( node->initialization, *this ); 1252 visitExpression( node->condition ); 1253 visitExpression( node->increment ); 1254 visitStatement ( node->body ); 1255 } 1256 VISIT_END( node ); 1257 } 1258 1259 template< typename pass_type > 874 1260 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) { 875 1261 MUTATE_START( node ); … … 898 1284 899 1285 template< typename pass_type > 1286 void PassVisitor< pass_type >::visit( const SwitchStmt * node ) { 1287 VISIT_START( node ); 1288 1289 visitExpression ( node->condition ); 1290 visitStatementList( node->statements ); 1291 1292 VISIT_END( node ); 1293 } 1294 1295 template< typename pass_type > 900 1296 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) { 901 1297 MUTATE_START( node ); … … 920 1316 921 1317 template< typename pass_type > 1318 void PassVisitor< pass_type >::visit( const CaseStmt * node ) { 1319 VISIT_START( node ); 1320 1321 visitExpression ( node->condition ); 1322 visitStatementList( node->stmts ); 1323 1324 VISIT_END( node ); 1325 } 1326 1327 template< typename pass_type > 922 1328 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) { 923 1329 MUTATE_START( node ); … … 938 1344 939 1345 template< typename pass_type > 1346 void PassVisitor< pass_type >::visit( const BranchStmt * node ) { 1347 VISIT_START( node ); 1348 VISIT_END( node ); 1349 } 1350 1351 template< typename pass_type > 940 1352 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) { 941 1353 MUTATE_START( node ); … … 955 1367 956 1368 template< typename pass_type > 1369 void PassVisitor< pass_type >::visit( const ReturnStmt * node ) { 1370 VISIT_START( node ); 1371 1372 visitExpression( node->expr ); 1373 1374 VISIT_END( node ); 1375 } 1376 1377 template< typename pass_type > 957 1378 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) { 958 1379 MUTATE_START( node ); … … 965 1386 //-------------------------------------------------------------------------- 966 1387 // ThrowStmt 967 968 1388 template< typename pass_type > 969 1389 void PassVisitor< pass_type >::visit( ThrowStmt * node ) { … … 977 1397 978 1398 template< typename pass_type > 1399 void PassVisitor< pass_type >::visit( const ThrowStmt * node ) { 1400 VISIT_START( node ); 1401 1402 maybeAccept_impl( node->expr, *this ); 1403 maybeAccept_impl( node->target, *this ); 1404 1405 VISIT_END( node ); 1406 } 1407 1408 template< typename pass_type > 979 1409 Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) { 980 1410 MUTATE_START( node ); … … 990 1420 template< typename pass_type > 991 1421 void PassVisitor< pass_type >::visit( TryStmt * node ) { 1422 VISIT_START( node ); 1423 1424 maybeAccept_impl( node->block , *this ); 1425 maybeAccept_impl( node->handlers , *this ); 1426 maybeAccept_impl( node->finallyBlock, *this ); 1427 1428 VISIT_END( node ); 1429 } 1430 1431 template< typename pass_type > 1432 void PassVisitor< pass_type >::visit( const TryStmt * node ) { 992 1433 VISIT_START( node ); 993 1434 … … 1026 1467 1027 1468 template< typename pass_type > 1469 void PassVisitor< pass_type >::visit( const CatchStmt * node ) { 1470 VISIT_START( node ); 1471 { 1472 // catch statements introduce a level of scope (for the caught exception) 1473 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1474 maybeAccept_impl( node->decl, *this ); 1475 visitExpression ( node->cond ); 1476 visitStatement ( node->body ); 1477 } 1478 VISIT_END( node ); 1479 } 1480 1481 template< typename pass_type > 1028 1482 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) { 1029 1483 MUTATE_START( node ); … … 1050 1504 1051 1505 template< typename pass_type > 1506 void PassVisitor< pass_type >::visit( const FinallyStmt * node ) { 1507 VISIT_START( node ); 1508 1509 maybeAccept_impl( node->block, *this ); 1510 1511 VISIT_END( node ); 1512 } 1513 1514 template< typename pass_type > 1052 1515 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) { 1053 1516 MUTATE_START( node ); … … 1082 1545 1083 1546 template< typename pass_type > 1547 void PassVisitor< pass_type >::visit( const WaitForStmt * node ) { 1548 VISIT_START( node ); 1549 1550 for( auto & clause : node->clauses ) { 1551 maybeAccept_impl( clause.target.function, *this ); 1552 maybeAccept_impl( clause.target.arguments, *this ); 1553 1554 maybeAccept_impl( clause.statement, *this ); 1555 maybeAccept_impl( clause.condition, *this ); 1556 } 1557 1558 maybeAccept_impl( node->timeout.time, *this ); 1559 maybeAccept_impl( node->timeout.statement, *this ); 1560 maybeAccept_impl( node->timeout.condition, *this ); 1561 maybeAccept_impl( node->orelse.statement, *this ); 1562 maybeAccept_impl( node->orelse.condition, *this ); 1563 1564 VISIT_END( node ); 1565 } 1566 1567 template< typename pass_type > 1084 1568 Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) { 1085 1569 MUTATE_START( node ); … … 1105 1589 1106 1590 //-------------------------------------------------------------------------- 1107 // NullStmt1591 // WithStmt 1108 1592 template< typename pass_type > 1109 1593 void PassVisitor< pass_type >::visit( WithStmt * node ) { … … 1120 1604 1121 1605 template< typename pass_type > 1122 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1606 void PassVisitor< pass_type >::visit( const WithStmt * node ) { 1607 VISIT_START( node ); 1608 maybeAccept_impl( node->exprs, *this ); 1609 { 1610 // catch statements introduce a level of scope (for the caught exception) 1611 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1612 indexerAddWith( node->exprs, node ); 1613 maybeAccept_impl( node->stmt, *this ); 1614 } 1615 VISIT_END( node ); 1616 } 1617 1618 template< typename pass_type > 1619 Declaration * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1123 1620 MUTATE_START( node ); 1124 1621 maybeMutate_impl( node->exprs, *this ); … … 1129 1626 maybeMutate_impl( node->stmt, *this ); 1130 1627 } 1628 MUTATE_END( Declaration, node ); 1629 } 1630 1631 //-------------------------------------------------------------------------- 1632 // NullStmt 1633 template< typename pass_type > 1634 void PassVisitor< pass_type >::visit( NullStmt * node ) { 1635 VISIT_START( node ); 1636 VISIT_END( node ); 1637 } 1638 1639 template< typename pass_type > 1640 void PassVisitor< pass_type >::visit( const NullStmt * node ) { 1641 VISIT_START( node ); 1642 VISIT_END( node ); 1643 } 1644 1645 template< typename pass_type > 1646 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) { 1647 MUTATE_START( node ); 1648 MUTATE_END( NullStmt, node ); 1649 } 1650 1651 //-------------------------------------------------------------------------- 1652 // DeclStmt 1653 template< typename pass_type > 1654 void PassVisitor< pass_type >::visit( DeclStmt * node ) { 1655 VISIT_START( node ); 1656 1657 maybeAccept_impl( node->decl, *this ); 1658 1659 VISIT_END( node ); 1660 } 1661 1662 template< typename pass_type > 1663 void PassVisitor< pass_type >::visit( const DeclStmt * node ) { 1664 VISIT_START( node ); 1665 1666 maybeAccept_impl( node->decl, *this ); 1667 1668 VISIT_END( node ); 1669 } 1670 1671 template< typename pass_type > 1672 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) { 1673 MUTATE_START( node ); 1674 1675 maybeMutate_impl( node->decl, *this ); 1676 1131 1677 MUTATE_END( Statement, node ); 1132 1678 } 1133 1679 1134 1680 //-------------------------------------------------------------------------- 1135 // NullStmt 1136 template< typename pass_type > 1137 void PassVisitor< pass_type >::visit( NullStmt * node ) { 1138 VISIT_START( node ); 1139 VISIT_END( node ); 1140 } 1141 1142 template< typename pass_type > 1143 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) { 1144 MUTATE_START( node ); 1145 MUTATE_END( NullStmt, node ); 1146 } 1147 1148 //-------------------------------------------------------------------------- 1149 // DeclStmt 1150 template< typename pass_type > 1151 void PassVisitor< pass_type >::visit( DeclStmt * node ) { 1152 VISIT_START( node ); 1153 1154 maybeAccept_impl( node->decl, *this ); 1155 1156 VISIT_END( node ); 1157 } 1158 1159 template< typename pass_type > 1160 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) { 1161 MUTATE_START( node ); 1162 1163 maybeMutate_impl( node->decl, *this ); 1681 // ImplicitCtorDtorStmt 1682 template< typename pass_type > 1683 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) { 1684 VISIT_START( node ); 1685 1686 maybeAccept_impl( node->callStmt, *this ); 1687 1688 VISIT_END( node ); 1689 } 1690 1691 template< typename pass_type > 1692 void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) { 1693 VISIT_START( node ); 1694 1695 maybeAccept_impl( node->callStmt, *this ); 1696 1697 VISIT_END( node ); 1698 } 1699 1700 template< typename pass_type > 1701 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) { 1702 MUTATE_START( node ); 1703 1704 maybeMutate_impl( node->callStmt, *this ); 1164 1705 1165 1706 MUTATE_END( Statement, node ); … … 1167 1708 1168 1709 //-------------------------------------------------------------------------- 1169 // ImplicitCtorDtorStmt1170 template< typename pass_type >1171 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {1172 VISIT_START( node );1173 1174 maybeAccept_impl( node->callStmt, *this );1175 1176 VISIT_END( node );1177 }1178 1179 template< typename pass_type >1180 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {1181 MUTATE_START( node );1182 1183 maybeMutate_impl( node->callStmt, *this );1184 1185 MUTATE_END( Statement, node );1186 }1187 1188 //--------------------------------------------------------------------------1189 1710 // ApplicationExpr 1190 1711 template< typename pass_type > … … 1193 1714 1194 1715 indexerScopedAccept( node->result , *this ); 1195 maybeAccept_impl ( node->function, *this ); 1196 maybeAccept_impl ( node->args , *this ); 1716 maybeAccept_impl ( node->function, *this ); 1717 maybeAccept_impl ( node->args , *this ); 1718 1719 VISIT_END( node ); 1720 } 1721 1722 template< typename pass_type > 1723 void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) { 1724 VISIT_START( node ); 1725 1726 indexerScopedAccept( node->result , *this ); 1727 maybeAccept_impl ( node->function, *this ); 1728 maybeAccept_impl ( node->args , *this ); 1197 1729 1198 1730 VISIT_END( node ); … … 1228 1760 1229 1761 template< typename pass_type > 1762 void PassVisitor< pass_type >::visit( const UntypedExpr * node ) { 1763 VISIT_START( node ); 1764 1765 indexerScopedAccept( node->result, *this ); 1766 1767 for ( auto expr : node->args ) { 1768 visitExpression( expr ); 1769 } 1770 1771 VISIT_END( node ); 1772 } 1773 1774 template< typename pass_type > 1230 1775 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) { 1231 1776 MUTATE_START( node ); … … 1253 1798 1254 1799 template< typename pass_type > 1800 void PassVisitor< pass_type >::visit( const NameExpr * node ) { 1801 VISIT_START( node ); 1802 1803 indexerScopedAccept( node->result, *this ); 1804 1805 VISIT_END( node ); 1806 } 1807 1808 template< typename pass_type > 1255 1809 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) { 1256 1810 MUTATE_START( node ); … … 1269 1823 1270 1824 indexerScopedAccept( node->result, *this ); 1271 maybeAccept_impl ( node->arg , *this ); 1825 maybeAccept_impl ( node->arg , *this ); 1826 1827 VISIT_END( node ); 1828 } 1829 1830 template< typename pass_type > 1831 void PassVisitor< pass_type >::visit( const CastExpr * node ) { 1832 VISIT_START( node ); 1833 1834 indexerScopedAccept( node->result, *this ); 1835 maybeAccept_impl ( node->arg , *this ); 1272 1836 1273 1837 VISIT_END( node ); … … 1298 1862 1299 1863 template< typename pass_type > 1864 void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) { 1865 VISIT_START( node ); 1866 1867 indexerScopedAccept( node->result, *this ); 1868 maybeAccept_impl ( node->arg , *this ); 1869 1870 VISIT_END( node ); 1871 } 1872 1873 template< typename pass_type > 1300 1874 Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) { 1301 1875 MUTATE_START( node ); … … 1315 1889 1316 1890 indexerScopedAccept( node->result, *this ); 1317 maybeAccept_impl( node->arg, *this ); 1891 maybeAccept_impl ( node->arg, *this ); 1892 1893 VISIT_END( node ); 1894 } 1895 1896 template< typename pass_type > 1897 void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) { 1898 VISIT_START( node ); 1899 1900 indexerScopedAccept( node->result, *this ); 1901 maybeAccept_impl ( node->arg, *this ); 1318 1902 1319 1903 VISIT_END( node ); … … 1344 1928 1345 1929 template< typename pass_type > 1930 void PassVisitor< pass_type >::visit( const AddressExpr * node ) { 1931 VISIT_START( node ); 1932 1933 indexerScopedAccept( node->result, *this ); 1934 maybeAccept_impl ( node->arg , *this ); 1935 1936 VISIT_END( node ); 1937 } 1938 1939 template< typename pass_type > 1346 1940 Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) { 1347 1941 MUTATE_START( node ); … … 1366 1960 1367 1961 template< typename pass_type > 1962 void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) { 1963 VISIT_START( node ); 1964 1965 indexerScopedAccept( node->result, *this ); 1966 1967 VISIT_END( node ); 1968 } 1969 1970 template< typename pass_type > 1368 1971 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) { 1369 1972 MUTATE_START( node ); … … 1379 1982 template< typename pass_type > 1380 1983 void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) { 1984 VISIT_START( node ); 1985 1986 indexerScopedAccept( node->result , *this ); 1987 maybeAccept_impl ( node->aggregate, *this ); 1988 maybeAccept_impl ( node->member , *this ); 1989 1990 VISIT_END( node ); 1991 } 1992 1993 template< typename pass_type > 1994 void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) { 1381 1995 VISIT_START( node ); 1382 1996 … … 1413 2027 1414 2028 template< typename pass_type > 2029 void PassVisitor< pass_type >::visit( const MemberExpr * node ) { 2030 VISIT_START( node ); 2031 2032 indexerScopedAccept( node->result , *this ); 2033 maybeAccept_impl ( node->aggregate, *this ); 2034 2035 VISIT_END( node ); 2036 } 2037 2038 template< typename pass_type > 1415 2039 Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) { 1416 2040 MUTATE_START( node ); … … 1435 2059 1436 2060 template< typename pass_type > 2061 void PassVisitor< pass_type >::visit( const VariableExpr * node ) { 2062 VISIT_START( node ); 2063 2064 indexerScopedAccept( node->result, *this ); 2065 2066 VISIT_END( node ); 2067 } 2068 2069 template< typename pass_type > 1437 2070 Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) { 1438 2071 MUTATE_START( node ); … … 1448 2081 template< typename pass_type > 1449 2082 void PassVisitor< pass_type >::visit( ConstantExpr * node ) { 2083 VISIT_START( node ); 2084 2085 indexerScopedAccept( node->result , *this ); 2086 maybeAccept_impl ( &node->constant, *this ); 2087 2088 VISIT_END( node ); 2089 } 2090 2091 template< typename pass_type > 2092 void PassVisitor< pass_type >::visit( const ConstantExpr * node ) { 1450 2093 VISIT_START( node ); 1451 2094 … … 1473 2116 template< typename pass_type > 1474 2117 void PassVisitor< pass_type >::visit( SizeofExpr * node ) { 2118 VISIT_START( node ); 2119 2120 indexerScopedAccept( node->result, *this ); 2121 if ( node->get_isType() ) { 2122 maybeAccept_impl( node->type, *this ); 2123 } else { 2124 maybeAccept_impl( node->expr, *this ); 2125 } 2126 2127 VISIT_END( node ); 2128 } 2129 2130 template< typename pass_type > 2131 void PassVisitor< pass_type >::visit( const SizeofExpr * node ) { 1475 2132 VISIT_START( node ); 1476 2133 … … 1517 2174 1518 2175 template< typename pass_type > 2176 void PassVisitor< pass_type >::visit( const AlignofExpr * node ) { 2177 VISIT_START( node ); 2178 2179 indexerScopedAccept( node->result, *this ); 2180 if ( node->get_isType() ) { 2181 maybeAccept_impl( node->type, *this ); 2182 } else { 2183 maybeAccept_impl( node->expr, *this ); 2184 } 2185 2186 VISIT_END( node ); 2187 } 2188 2189 template< typename pass_type > 1519 2190 Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) { 1520 2191 MUTATE_START( node ); … … 1544 2215 1545 2216 template< typename pass_type > 2217 void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) { 2218 VISIT_START( node ); 2219 2220 indexerScopedAccept( node->result, *this ); 2221 maybeAccept_impl ( node->type , *this ); 2222 2223 VISIT_END( node ); 2224 } 2225 2226 template< typename pass_type > 1546 2227 Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) { 1547 2228 MUTATE_START( node ); … … 1567 2248 1568 2249 template< typename pass_type > 2250 void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) { 2251 VISIT_START( node ); 2252 2253 indexerScopedAccept( node->result, *this ); 2254 maybeAccept_impl ( node->type , *this ); 2255 2256 VISIT_END( node ); 2257 } 2258 2259 template< typename pass_type > 1569 2260 Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) { 1570 2261 MUTATE_START( node ); … … 1590 2281 1591 2282 template< typename pass_type > 2283 void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) { 2284 VISIT_START( node ); 2285 2286 indexerScopedAccept( node->result, *this ); 2287 maybeAccept_impl ( node->type , *this ); 2288 2289 VISIT_END( node ); 2290 } 2291 2292 template< typename pass_type > 1592 2293 Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) { 1593 2294 MUTATE_START( node ); … … 1601 2302 1602 2303 //-------------------------------------------------------------------------- 1603 // AttrExpr1604 template< typename pass_type >1605 void PassVisitor< pass_type >::visit( AttrExpr * node ) {1606 VISIT_START( node );1607 1608 indexerScopedAccept( node->result, *this );1609 if ( node->get_isType() ) {1610 maybeAccept_impl( node->type, *this );1611 } else {1612 maybeAccept_impl( node->expr, *this );1613 }1614 1615 VISIT_END( node );1616 }1617 1618 template< typename pass_type >1619 Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {1620 MUTATE_START( node );1621 1622 indexerScopedMutate( node->env , *this );1623 indexerScopedMutate( node->result, *this );1624 if ( node->get_isType() ) {1625 maybeMutate_impl( node->type, *this );1626 } else {1627 maybeMutate_impl( node->expr, *this );1628 }1629 1630 MUTATE_END( Expression, node );1631 }1632 1633 //--------------------------------------------------------------------------1634 2304 // LogicalExpr 1635 2305 template< typename pass_type > 1636 2306 void PassVisitor< pass_type >::visit( LogicalExpr * node ) { 2307 VISIT_START( node ); 2308 2309 indexerScopedAccept( node->result, *this ); 2310 maybeAccept_impl ( node->arg1 , *this ); 2311 maybeAccept_impl ( node->arg2 , *this ); 2312 2313 VISIT_END( node ); 2314 } 2315 2316 template< typename pass_type > 2317 void PassVisitor< pass_type >::visit( const LogicalExpr * node ) { 1637 2318 VISIT_START( node ); 1638 2319 … … 1666 2347 maybeAccept_impl ( node->arg2 , *this ); 1667 2348 maybeAccept_impl ( node->arg3 , *this ); 2349 2350 VISIT_END( node ); 2351 } 2352 2353 template< typename pass_type > 2354 void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) { 2355 VISIT_START( node ); 2356 2357 indexerScopedAccept( node->result, *this ); 2358 maybeAccept_impl ( node->arg1 , *this ); 2359 maybeAccept_impl ( node->arg2 , *this ); 2360 maybeAccept_impl ( node->arg3 , *this ); 1668 2361 1669 2362 VISIT_END( node ); … … 1697 2390 1698 2391 template< typename pass_type > 2392 void PassVisitor< pass_type >::visit( const CommaExpr * node ) { 2393 VISIT_START( node ); 2394 2395 indexerScopedAccept( node->result, *this ); 2396 maybeAccept_impl ( node->arg1 , *this ); 2397 maybeAccept_impl ( node->arg2 , *this ); 2398 2399 VISIT_END( node ); 2400 } 2401 2402 template< typename pass_type > 1699 2403 Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) { 1700 2404 MUTATE_START( node ); … … 1721 2425 1722 2426 template< typename pass_type > 2427 void PassVisitor< pass_type >::visit( const TypeExpr * node ) { 2428 VISIT_START( node ); 2429 2430 indexerScopedAccept( node->result, *this ); 2431 maybeAccept_impl ( node->type, *this ); 2432 2433 VISIT_END( node ); 2434 } 2435 2436 template< typename pass_type > 1723 2437 Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) { 1724 2438 MUTATE_START( node ); … … 1735 2449 template< typename pass_type > 1736 2450 void PassVisitor< pass_type >::visit( AsmExpr * node ) { 2451 VISIT_START( node ); 2452 2453 indexerScopedAccept( node->result , *this ); 2454 maybeAccept_impl ( node->inout , *this ); 2455 maybeAccept_impl ( node->constraint, *this ); 2456 maybeAccept_impl ( node->operand , *this ); 2457 2458 VISIT_END( node ); 2459 } 2460 2461 template< typename pass_type > 2462 void PassVisitor< pass_type >::visit( const AsmExpr * node ) { 1737 2463 VISIT_START( node ); 1738 2464 … … 1764 2490 VISIT_START( node ); 1765 2491 1766 indexerScopedAccept( node->result , *this ); 1767 maybeAccept_impl ( node->callExpr , *this ); 1768 maybeAccept_impl ( node->tempDecls , *this ); 1769 maybeAccept_impl ( node->returnDecls, *this ); 1770 maybeAccept_impl ( node->dtors , *this ); 2492 indexerScopedAccept( node->result , *this ); 2493 maybeAccept_impl ( node->callExpr , *this ); 2494 2495 VISIT_END( node ); 2496 } 2497 2498 template< typename pass_type > 2499 void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) { 2500 VISIT_START( node ); 2501 2502 indexerScopedAccept( node->result , *this ); 2503 maybeAccept_impl ( node->callExpr , *this ); 1771 2504 1772 2505 VISIT_END( node ); … … 1777 2510 MUTATE_START( node ); 1778 2511 1779 indexerScopedMutate( node->env , *this ); 1780 indexerScopedMutate( node->result , *this ); 1781 maybeMutate_impl ( node->callExpr , *this ); 1782 maybeMutate_impl ( node->tempDecls , *this ); 1783 maybeMutate_impl ( node->returnDecls, *this ); 1784 maybeMutate_impl ( node->dtors , *this ); 2512 indexerScopedMutate( node->env , *this ); 2513 indexerScopedMutate( node->result , *this ); 2514 maybeMutate_impl ( node->callExpr , *this ); 1785 2515 1786 2516 MUTATE_END( Expression, node ); … … 1791 2521 template< typename pass_type > 1792 2522 void PassVisitor< pass_type >::visit( ConstructorExpr * node ) { 2523 VISIT_START( node ); 2524 2525 indexerScopedAccept( node->result , *this ); 2526 maybeAccept_impl ( node->callExpr, *this ); 2527 2528 VISIT_END( node ); 2529 } 2530 2531 template< typename pass_type > 2532 void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) { 1793 2533 VISIT_START( node ); 1794 2534 … … 1823 2563 1824 2564 template< typename pass_type > 2565 void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) { 2566 VISIT_START( node ); 2567 2568 indexerScopedAccept( node->result , *this ); 2569 maybeAccept_impl ( node->initializer, *this ); 2570 2571 VISIT_END( node ); 2572 } 2573 2574 template< typename pass_type > 1825 2575 Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) { 1826 2576 MUTATE_START( node ); … … 1837 2587 template< typename pass_type > 1838 2588 void PassVisitor< pass_type >::visit( RangeExpr * node ) { 2589 VISIT_START( node ); 2590 2591 indexerScopedAccept( node->result, *this ); 2592 maybeAccept_impl ( node->low , *this ); 2593 maybeAccept_impl ( node->high , *this ); 2594 2595 VISIT_END( node ); 2596 } 2597 2598 template< typename pass_type > 2599 void PassVisitor< pass_type >::visit( const RangeExpr * node ) { 1839 2600 VISIT_START( node ); 1840 2601 … … 1871 2632 1872 2633 template< typename pass_type > 2634 void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) { 2635 VISIT_START( node ); 2636 2637 indexerScopedAccept( node->result, *this ); 2638 maybeAccept_impl ( node->exprs , *this ); 2639 2640 VISIT_END( node ); 2641 } 2642 2643 template< typename pass_type > 1873 2644 Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) { 1874 2645 MUTATE_START( node ); … … 1894 2665 1895 2666 template< typename pass_type > 2667 void PassVisitor< pass_type >::visit( const TupleExpr * node ) { 2668 VISIT_START( node ); 2669 2670 indexerScopedAccept( node->result, *this ); 2671 maybeAccept_impl ( node->exprs , *this ); 2672 2673 VISIT_END( node ); 2674 } 2675 2676 template< typename pass_type > 1896 2677 Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) { 1897 2678 MUTATE_START( node ); … … 1917 2698 1918 2699 template< typename pass_type > 2700 void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) { 2701 VISIT_START( node ); 2702 2703 indexerScopedAccept( node->result, *this ); 2704 maybeAccept_impl ( node->tuple , *this ); 2705 2706 VISIT_END( node ); 2707 } 2708 2709 template< typename pass_type > 1919 2710 Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) { 1920 2711 MUTATE_START( node ); … … 1940 2731 1941 2732 template< typename pass_type > 2733 void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) { 2734 VISIT_START( node ); 2735 2736 indexerScopedAccept( node->result , *this ); 2737 maybeAccept_impl( node->stmtExpr, *this ); 2738 2739 VISIT_END( node ); 2740 } 2741 2742 template< typename pass_type > 1942 2743 Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) { 1943 2744 MUTATE_START( node ); … … 1957 2758 1958 2759 // don't want statements from outer CompoundStmts to be added to this StmtExpr 1959 ValueGuardPtr< TypeSubstitution * > oldEnv( get_env_ptr() );2760 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 1960 2761 ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); 1961 2762 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); … … 1970 2771 1971 2772 template< typename pass_type > 2773 void PassVisitor< pass_type >::visit( const StmtExpr * node ) { 2774 VISIT_START( node ); 2775 2776 // don't want statements from outer CompoundStmts to be added to this StmtExpr 2777 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 2778 ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); 2779 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); 2780 2781 indexerScopedAccept( node->result , *this ); 2782 maybeAccept_impl ( node->statements , *this ); 2783 maybeAccept_impl ( node->returnDecls, *this ); 2784 maybeAccept_impl ( node->dtors , *this ); 2785 2786 VISIT_END( node ); 2787 } 2788 2789 template< typename pass_type > 1972 2790 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) { 1973 2791 MUTATE_START( node ); 1974 2792 1975 2793 // don't want statements from outer CompoundStmts to be added to this StmtExpr 1976 ValueGuardPtr< TypeSubstitution * > oldEnv( get_env_ptr() );2794 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 1977 2795 ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); 1978 2796 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); … … 1999 2817 2000 2818 template< typename pass_type > 2819 void PassVisitor< pass_type >::visit( const UniqueExpr * node ) { 2820 VISIT_START( node ); 2821 2822 indexerScopedAccept( node->result, *this ); 2823 maybeAccept_impl ( node->expr , *this ); 2824 2825 VISIT_END( node ); 2826 } 2827 2828 template< typename pass_type > 2001 2829 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) { 2002 2830 MUTATE_START( node ); … … 2013 2841 template< typename pass_type > 2014 2842 void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) { 2843 VISIT_START( node ); 2844 2845 indexerScopedAccept( node->result, *this ); 2846 maybeAccept_impl ( node->expr , *this ); 2847 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 2848 2849 VISIT_END( node ); 2850 } 2851 2852 template< typename pass_type > 2853 void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) { 2015 2854 VISIT_START( node ); 2016 2855 … … 2048 2887 2049 2888 template< typename pass_type > 2889 void PassVisitor< pass_type >::visit( const InitExpr * node ) { 2890 VISIT_START( node ); 2891 2892 indexerScopedAccept( node->result, *this ); 2893 maybeAccept_impl ( node->expr , *this ); 2894 maybeAccept_impl ( node->designation, *this ); 2895 2896 VISIT_END( node ); 2897 } 2898 2899 template< typename pass_type > 2050 2900 Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) { 2051 2901 MUTATE_START( node ); … … 2066 2916 2067 2917 indexerScopedAccept( node->result, *this ); 2068 maybeAccept_impl( node->expr, *this ); 2918 maybeAccept_impl ( node->expr, *this ); 2919 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2920 2921 VISIT_END( node ); 2922 } 2923 2924 template< typename pass_type > 2925 void PassVisitor< pass_type >::visit( const DeletedExpr * node ) { 2926 VISIT_START( node ); 2927 2928 indexerScopedAccept( node->result, *this ); 2929 maybeAccept_impl ( node->expr, *this ); 2069 2930 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2070 2931 … … 2084 2945 2085 2946 //-------------------------------------------------------------------------- 2947 // DefaultArgExpr 2948 template< typename pass_type > 2949 void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) { 2950 VISIT_START( node ); 2951 2952 indexerScopedAccept( node->result, *this ); 2953 maybeAccept_impl ( node->expr, *this ); 2954 2955 VISIT_END( node ); 2956 } 2957 2958 template< typename pass_type > 2959 void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) { 2960 VISIT_START( node ); 2961 2962 indexerScopedAccept( node->result, *this ); 2963 maybeAccept_impl ( node->expr, *this ); 2964 2965 VISIT_END( node ); 2966 } 2967 2968 template< typename pass_type > 2969 Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) { 2970 MUTATE_START( node ); 2971 2972 indexerScopedMutate( node->env, *this ); 2973 indexerScopedMutate( node->result, *this ); 2974 maybeMutate_impl( node->expr, *this ); 2975 2976 MUTATE_END( Expression, node ); 2977 } 2978 2979 //-------------------------------------------------------------------------- 2086 2980 // GenericExpr 2087 2981 template< typename pass_type > … … 2092 2986 maybeAccept_impl( node->control, *this ); 2093 2987 for ( GenericExpr::Association & assoc : node->associations ) { 2988 indexerScopedAccept( assoc.type, *this ); 2989 maybeAccept_impl( assoc.expr, *this ); 2990 } 2991 2992 VISIT_END( node ); 2993 } 2994 2995 template< typename pass_type > 2996 void PassVisitor< pass_type >::visit( const GenericExpr * node ) { 2997 VISIT_START( node ); 2998 2999 indexerScopedAccept( node->result, *this ); 3000 maybeAccept_impl( node->control, *this ); 3001 for ( const GenericExpr::Association & assoc : node->associations ) { 2094 3002 indexerScopedAccept( assoc.type, *this ); 2095 3003 maybeAccept_impl( assoc.expr, *this ); … … 2126 3034 2127 3035 template< typename pass_type > 3036 void PassVisitor< pass_type >::visit( const VoidType * node ) { 3037 VISIT_START( node ); 3038 3039 maybeAccept_impl( node->forall, *this ); 3040 3041 VISIT_END( node ); 3042 } 3043 3044 template< typename pass_type > 2128 3045 Type * PassVisitor< pass_type >::mutate( VoidType * node ) { 2129 3046 MUTATE_START( node ); … … 2138 3055 template< typename pass_type > 2139 3056 void PassVisitor< pass_type >::visit( BasicType * node ) { 3057 VISIT_START( node ); 3058 3059 maybeAccept_impl( node->forall, *this ); 3060 3061 VISIT_END( node ); 3062 } 3063 3064 template< typename pass_type > 3065 void PassVisitor< pass_type >::visit( const BasicType * node ) { 2140 3066 VISIT_START( node ); 2141 3067 … … 2168 3094 2169 3095 template< typename pass_type > 3096 void PassVisitor< pass_type >::visit( const PointerType * node ) { 3097 VISIT_START( node ); 3098 3099 maybeAccept_impl( node->forall, *this ); 3100 // xxx - should PointerType visit/mutate dimension? 3101 maybeAccept_impl( node->base, *this ); 3102 3103 VISIT_END( node ); 3104 } 3105 3106 template< typename pass_type > 2170 3107 Type * PassVisitor< pass_type >::mutate( PointerType * node ) { 2171 3108 MUTATE_START( node ); … … 2192 3129 2193 3130 template< typename pass_type > 3131 void PassVisitor< pass_type >::visit( const ArrayType * node ) { 3132 VISIT_START( node ); 3133 3134 maybeAccept_impl( node->forall, *this ); 3135 maybeAccept_impl( node->dimension, *this ); 3136 maybeAccept_impl( node->base, *this ); 3137 3138 VISIT_END( node ); 3139 } 3140 3141 template< typename pass_type > 2194 3142 Type * PassVisitor< pass_type >::mutate( ArrayType * node ) { 2195 3143 MUTATE_START( node ); … … 2215 3163 2216 3164 template< typename pass_type > 3165 void PassVisitor< pass_type >::visit( const ReferenceType * node ) { 3166 VISIT_START( node ); 3167 3168 maybeAccept_impl( node->forall, *this ); 3169 maybeAccept_impl( node->base, *this ); 3170 3171 VISIT_END( node ); 3172 } 3173 3174 template< typename pass_type > 2217 3175 Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) { 2218 3176 MUTATE_START( node ); … … 2220 3178 maybeMutate_impl( node->forall, *this ); 2221 3179 maybeMutate_impl( node->base, *this ); 3180 3181 MUTATE_END( Type, node ); 3182 } 3183 3184 //-------------------------------------------------------------------------- 3185 // QualifiedType 3186 template< typename pass_type > 3187 void PassVisitor< pass_type >::visit( QualifiedType * node ) { 3188 VISIT_START( node ); 3189 3190 maybeAccept_impl( node->forall, *this ); 3191 maybeAccept_impl( node->parent, *this ); 3192 maybeAccept_impl( node->child, *this ); 3193 3194 VISIT_END( node ); 3195 } 3196 3197 template< typename pass_type > 3198 void PassVisitor< pass_type >::visit( const QualifiedType * node ) { 3199 VISIT_START( node ); 3200 3201 maybeAccept_impl( node->forall, *this ); 3202 maybeAccept_impl( node->parent, *this ); 3203 maybeAccept_impl( node->child, *this ); 3204 3205 VISIT_END( node ); 3206 } 3207 3208 template< typename pass_type > 3209 Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) { 3210 MUTATE_START( node ); 3211 3212 maybeMutate_impl( node->forall, *this ); 3213 maybeMutate_impl( node->parent, *this ); 3214 maybeMutate_impl( node->child, *this ); 2222 3215 2223 3216 MUTATE_END( Type, node ); … … 2238 3231 2239 3232 template< typename pass_type > 3233 void PassVisitor< pass_type >::visit( const FunctionType * node ) { 3234 VISIT_START( node ); 3235 3236 maybeAccept_impl( node->forall, *this ); 3237 maybeAccept_impl( node->returnVals, *this ); 3238 maybeAccept_impl( node->parameters, *this ); 3239 3240 VISIT_END( node ); 3241 } 3242 3243 template< typename pass_type > 2240 3244 Type * PassVisitor< pass_type >::mutate( FunctionType * node ) { 2241 3245 MUTATE_START( node ); … … 2266 3270 2267 3271 template< typename pass_type > 3272 void PassVisitor< pass_type >::visit( const StructInstType * node ) { 3273 VISIT_START( node ); 3274 3275 indexerAddStruct( node->name ); 3276 3277 { 3278 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 3279 maybeAccept_impl( node->forall , *this ); 3280 maybeAccept_impl( node->parameters, *this ); 3281 } 3282 3283 VISIT_END( node ); 3284 } 3285 3286 template< typename pass_type > 2268 3287 Type * PassVisitor< pass_type >::mutate( StructInstType * node ) { 2269 3288 MUTATE_START( node ); … … 2298 3317 2299 3318 template< typename pass_type > 3319 void PassVisitor< pass_type >::visit( const UnionInstType * node ) { 3320 VISIT_START( node ); 3321 3322 indexerAddStruct( node->name ); 3323 3324 { 3325 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 3326 maybeAccept_impl( node->forall , *this ); 3327 maybeAccept_impl( node->parameters, *this ); 3328 } 3329 3330 VISIT_END( node ); 3331 } 3332 3333 template< typename pass_type > 2300 3334 Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) { 2301 3335 MUTATE_START( node ); … … 2325 3359 2326 3360 template< typename pass_type > 3361 void PassVisitor< pass_type >::visit( const EnumInstType * node ) { 3362 VISIT_START( node ); 3363 3364 maybeAccept_impl( node->forall, *this ); 3365 maybeAccept_impl( node->parameters, *this ); 3366 3367 VISIT_END( node ); 3368 } 3369 3370 template< typename pass_type > 2327 3371 Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) { 2328 3372 MUTATE_START( node ); … … 2347 3391 2348 3392 template< typename pass_type > 3393 void PassVisitor< pass_type >::visit( const TraitInstType * node ) { 3394 VISIT_START( node ); 3395 3396 maybeAccept_impl( node->forall , *this ); 3397 maybeAccept_impl( node->parameters, *this ); 3398 3399 VISIT_END( node ); 3400 } 3401 3402 template< typename pass_type > 2349 3403 Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) { 2350 3404 MUTATE_START( node ); … … 2360 3414 template< typename pass_type > 2361 3415 void PassVisitor< pass_type >::visit( TypeInstType * node ) { 3416 VISIT_START( node ); 3417 3418 maybeAccept_impl( node->forall , *this ); 3419 maybeAccept_impl( node->parameters, *this ); 3420 3421 VISIT_END( node ); 3422 } 3423 3424 template< typename pass_type > 3425 void PassVisitor< pass_type >::visit( const TypeInstType * node ) { 2362 3426 VISIT_START( node ); 2363 3427 … … 2392 3456 2393 3457 template< typename pass_type > 3458 void PassVisitor< pass_type >::visit( const TupleType * node ) { 3459 VISIT_START( node ); 3460 3461 maybeAccept_impl( node->forall, *this ); 3462 maybeAccept_impl( node->types, *this ); 3463 maybeAccept_impl( node->members, *this ); 3464 3465 VISIT_END( node ); 3466 } 3467 3468 template< typename pass_type > 2394 3469 Type * PassVisitor< pass_type >::mutate( TupleType * node ) { 2395 3470 MUTATE_START( node ); … … 2406 3481 template< typename pass_type > 2407 3482 void PassVisitor< pass_type >::visit( TypeofType * node ) { 3483 VISIT_START( node ); 3484 3485 assert( node->expr ); 3486 maybeAccept_impl( node->expr, *this ); 3487 3488 VISIT_END( node ); 3489 } 3490 3491 template< typename pass_type > 3492 void PassVisitor< pass_type >::visit( const TypeofType * node ) { 2408 3493 VISIT_START( node ); 2409 3494 … … 2442 3527 2443 3528 template< typename pass_type > 3529 void PassVisitor< pass_type >::visit( const AttrType * node ) { 3530 VISIT_START( node ); 3531 3532 if ( node->isType ) { 3533 assert( node->type ); 3534 maybeAccept_impl( node->type, *this ); 3535 } else { 3536 assert( node->expr ); 3537 maybeAccept_impl( node->expr, *this ); 3538 } // if 3539 3540 VISIT_END( node ); 3541 } 3542 3543 template< typename pass_type > 2444 3544 Type * PassVisitor< pass_type >::mutate( AttrType * node ) { 2445 3545 MUTATE_START( node ); … … 2468 3568 2469 3569 template< typename pass_type > 3570 void PassVisitor< pass_type >::visit( const VarArgsType * node ) { 3571 VISIT_START( node ); 3572 3573 maybeAccept_impl( node->forall, *this ); 3574 3575 VISIT_END( node ); 3576 } 3577 3578 template< typename pass_type > 2470 3579 Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) { 2471 3580 MUTATE_START( node ); … … 2488 3597 2489 3598 template< typename pass_type > 3599 void PassVisitor< pass_type >::visit( const ZeroType * node ) { 3600 VISIT_START( node ); 3601 3602 maybeAccept_impl( node->forall, *this ); 3603 3604 VISIT_END( node ); 3605 } 3606 3607 template< typename pass_type > 2490 3608 Type * PassVisitor< pass_type >::mutate( ZeroType * node ) { 2491 3609 MUTATE_START( node ); … … 2508 3626 2509 3627 template< typename pass_type > 3628 void PassVisitor< pass_type >::visit( const OneType * node ) { 3629 VISIT_START( node ); 3630 3631 maybeAccept_impl( node->forall, *this ); 3632 3633 VISIT_END( node ); 3634 } 3635 3636 template< typename pass_type > 2510 3637 Type * PassVisitor< pass_type >::mutate( OneType * node ) { 2511 3638 MUTATE_START( node ); … … 2517 3644 2518 3645 //-------------------------------------------------------------------------- 3646 // GlobalScopeType 3647 template< typename pass_type > 3648 void PassVisitor< pass_type >::visit( GlobalScopeType * node ) { 3649 VISIT_START( node ); 3650 3651 maybeAccept_impl( node->forall, *this ); 3652 3653 VISIT_END( node ); 3654 } 3655 3656 template< typename pass_type > 3657 void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) { 3658 VISIT_START( node ); 3659 3660 maybeAccept_impl( node->forall, *this ); 3661 3662 VISIT_END( node ); 3663 } 3664 3665 template< typename pass_type > 3666 Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) { 3667 MUTATE_START( node ); 3668 3669 maybeMutate_impl( node->forall, *this ); 3670 3671 MUTATE_END( Type, node ); 3672 } 3673 3674 //-------------------------------------------------------------------------- 2519 3675 // Designation 2520 3676 template< typename pass_type > … … 2528 3684 2529 3685 template< typename pass_type > 3686 void PassVisitor< pass_type >::visit( const Designation * node ) { 3687 VISIT_START( node ); 3688 3689 maybeAccept_impl( node->designators, *this ); 3690 3691 VISIT_END( node ); 3692 } 3693 3694 template< typename pass_type > 2530 3695 Designation * PassVisitor< pass_type >::mutate( Designation * node ) { 2531 3696 MUTATE_START( node ); … … 2548 3713 2549 3714 template< typename pass_type > 3715 void PassVisitor< pass_type >::visit( const SingleInit * node ) { 3716 VISIT_START( node ); 3717 3718 visitExpression( node->value ); 3719 3720 VISIT_END( node ); 3721 } 3722 3723 template< typename pass_type > 2550 3724 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) { 2551 3725 MUTATE_START( node ); … … 2560 3734 template< typename pass_type > 2561 3735 void PassVisitor< pass_type >::visit( ListInit * node ) { 3736 VISIT_START( node ); 3737 3738 maybeAccept_impl( node->designations, *this ); 3739 maybeAccept_impl( node->initializers, *this ); 3740 3741 VISIT_END( node ); 3742 } 3743 3744 template< typename pass_type > 3745 void PassVisitor< pass_type >::visit( const ListInit * node ) { 2562 3746 VISIT_START( node ); 2563 3747 … … 2592 3776 2593 3777 template< typename pass_type > 3778 void PassVisitor< pass_type >::visit( const ConstructorInit * node ) { 3779 VISIT_START( node ); 3780 3781 maybeAccept_impl( node->ctor, *this ); 3782 maybeAccept_impl( node->dtor, *this ); 3783 maybeAccept_impl( node->init, *this ); 3784 3785 VISIT_END( node ); 3786 } 3787 3788 template< typename pass_type > 2594 3789 Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) { 2595 3790 MUTATE_START( node ); … … 2603 3798 2604 3799 //-------------------------------------------------------------------------- 2605 // Subrange2606 template< typename pass_type >2607 void PassVisitor< pass_type >::visit( Subrange * node ) {2608 VISIT_START( node );2609 2610 VISIT_END( node );2611 }2612 2613 template< typename pass_type >2614 Subrange * PassVisitor< pass_type >::mutate( Subrange * node ) {2615 MUTATE_START( node );2616 2617 MUTATE_END( Subrange, node );2618 }2619 2620 //--------------------------------------------------------------------------2621 3800 // Attribute 2622 3801 template< typename pass_type > … … 2628 3807 2629 3808 template< typename pass_type > 3809 void PassVisitor< pass_type >::visit( const Constant * node ) { 3810 VISIT_START( node ); 3811 3812 VISIT_END( node ); 3813 } 3814 3815 template< typename pass_type > 2630 3816 Constant * PassVisitor< pass_type >::mutate( Constant * node ) { 2631 3817 MUTATE_START( node ); … … 2638 3824 template< typename pass_type > 2639 3825 void PassVisitor< pass_type >::visit( Attribute * node ) { 3826 VISIT_START( node ); 3827 3828 maybeAccept_impl( node->parameters, *this ); 3829 3830 VISIT_END( node ); 3831 } 3832 3833 template< typename pass_type > 3834 void PassVisitor< pass_type >::visit( const Attribute * node ) { 2640 3835 VISIT_START( node ); 2641 3836 … … 2669 3864 MUTATE_END( TypeSubstitution, node ); 2670 3865 } 3866 3867 #undef VISIT_START 3868 #undef VISIT_END 3869 3870 #undef MUTATE_START 3871 #undef MUTATE_END -
src/Common/PassVisitor.proto.h
r7951100 rb067d9b 118 118 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {} 119 119 120 template<typename pass_type, typename node_type> 121 static inline auto previsit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) { 122 pass.previsit( node ); 123 } 124 125 template<typename pass_type, typename node_type> 126 static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {} 127 128 129 template<typename pass_type, typename node_type> 130 static inline auto postvisit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) { 131 pass.postvisit( node ); 132 } 133 134 template<typename pass_type, typename node_type> 135 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {} 136 120 137 //--------------------------------------------------------- 121 138 // Mutate … … 165 182 static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;} \ 166 183 167 FIELD_PTR( TypeSubstitution *, env )184 FIELD_PTR( const TypeSubstitution *, env ) 168 185 FIELD_PTR( std::list< Statement* >, stmtsToAddBefore ) 169 186 FIELD_PTR( std::list< Statement* >, stmtsToAddAfter ) … … 174 191 FIELD_PTR( PassVisitor<pass_type> * const, visitor ) 175 192 193 #undef FIELD_PTR 194 176 195 //--------------------------------------------------------- 177 196 // Indexer … … 198 217 pass.indexer.func( arg ); \ 199 218 } \ 200 \ 201 template<typename pass_type> \ 202 static inline void indexer_impl_##func ( pass_type &, long, type ) { } \ 219 template<typename pass_type> \ 220 static inline void indexer_impl_##func ( pass_type &, long, type ) { } 203 221 204 222 #define INDEXER_FUNC2( func, type1, type2 ) \ … … 207 225 pass.indexer.func( arg1, arg2 ); \ 208 226 } \ 209 \210 227 template<typename pass_type> \ 211 228 static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { } 212 229 213 230 214 INDEXER_FUNC1( addId , DeclarationWithType * ); 215 INDEXER_FUNC1( addType , NamedTypeDecl * ); 216 INDEXER_FUNC1( addStruct , StructDecl * ); 217 INDEXER_FUNC1( addEnum , EnumDecl * ); 218 INDEXER_FUNC1( addUnion , UnionDecl * ); 219 INDEXER_FUNC1( addTrait , TraitDecl * ); 220 INDEXER_FUNC2( addWith , std::list< Expression * > &, BaseSyntaxNode * ); 221 222 223 template<typename pass_type> 224 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 231 INDEXER_FUNC1( addId , const DeclarationWithType * ); 232 INDEXER_FUNC1( addType , const NamedTypeDecl * ); 233 INDEXER_FUNC1( addStruct , const StructDecl * ); 234 INDEXER_FUNC1( addEnum , const EnumDecl * ); 235 INDEXER_FUNC1( addUnion , const UnionDecl * ); 236 INDEXER_FUNC1( addTrait , const TraitDecl * ); 237 INDEXER_FUNC2( addWith , const std::list< Expression * > &, const Declaration * ); 238 239 #undef INDEXER_FUNC1 240 #undef INDEXER_FUNC2 241 242 template<typename pass_type> 243 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 225 244 StructDecl * fwd = new StructDecl( decl->name ); 226 245 cloneAll( decl->parameters, fwd->parameters ); … … 229 248 230 249 template<typename pass_type> 231 static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {}232 233 template<typename pass_type> 234 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {250 static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {} 251 252 template<typename pass_type> 253 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) { 235 254 UnionDecl * fwd = new UnionDecl( decl->name ); 236 255 cloneAll( decl->parameters, fwd->parameters ); … … 239 258 240 259 template<typename pass_type> 241 static inline auto indexer_impl_addUnionFwd( pass_type &, long, UnionDecl * ) {}260 static inline auto indexer_impl_addUnionFwd( pass_type &, long, const UnionDecl * ) {} 242 261 243 262 template<typename pass_type> -
src/Common/ScopedMap.h
r7951100 rb067d9b 22 22 #include <vector> 23 23 24 /// Default (empty) ScopedMap note type 25 struct EmptyNote {}; 26 24 27 /// A map 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 Key, typename Value> 28 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward. 29 /// Scopes may be annotated with a value; the annotation defaults to empty 30 template<typename Key, typename Value, typename Note = EmptyNote> 27 31 class ScopedMap { 28 typedef std::map< Key, Value > Scope; 32 typedef std::map< Key, Value > MapType; 33 struct Scope { 34 MapType map; 35 Note note; 36 37 template<typename N> 38 Scope(N&& n) : map(), note(std::forward<N>(n)) {} 39 40 Scope() = default; 41 Scope(const Scope&) = default; 42 Scope(Scope&&) = default; 43 Scope& operator= (const Scope&) = default; 44 Scope& operator= (Scope&&) = default; 45 }; 29 46 typedef std::vector< Scope > ScopeList; 30 47 31 48 ScopeList scopes; ///< scoped list of maps 32 49 public: 33 typedef typename Scope::key_type key_type;34 typedef typename Scope::mapped_type mapped_type;35 typedef typename Scope::value_type value_type;50 typedef typename MapType::key_type key_type; 51 typedef typename MapType::mapped_type mapped_type; 52 typedef typename MapType::value_type value_type; 36 53 typedef typename ScopeList::size_type size_type; 37 54 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;55 typedef typename MapType::reference reference; 56 typedef typename MapType::const_reference const_reference; 57 typedef typename MapType::pointer pointer; 58 typedef typename MapType::const_pointer const_pointer; 42 59 43 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, … … 45 62 friend class ScopedMap; 46 63 friend class const_iterator; 47 typedef typename std::map< Key, Value >::iterator wrapped_iterator;48 typedef typename std::vector< std::map< Key, Value > >scope_list;64 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 65 typedef typename ScopedMap::ScopeList scope_list; 49 66 typedef typename scope_list::size_type size_type; 50 67 51 68 /// Checks if this iterator points to a valid item 52 69 bool is_valid() const { 53 return it != (*scopes)[level]. end();70 return it != (*scopes)[level].map.end(); 54 71 } 55 72 … … 79 96 80 97 iterator& operator++ () { 81 if ( it == (*scopes)[level]. end() ) {98 if ( it == (*scopes)[level].map.end() ) { 82 99 if ( level == 0 ) return *this; 83 100 --level; 84 it = (*scopes)[level]. begin();101 it = (*scopes)[level].map.begin(); 85 102 } else { 86 103 ++it; … … 92 109 iterator& operator-- () { 93 110 // may fail if this is the begin iterator; allowed by STL spec 94 if ( it == (*scopes)[level]. begin() ) {111 if ( it == (*scopes)[level].map.begin() ) { 95 112 ++level; 96 it = (*scopes)[level]. end();113 it = (*scopes)[level].map.end(); 97 114 } 98 115 --it; … … 107 124 108 125 size_type get_level() const { return level; } 126 127 Note& get_note() { return (*scopes)[level].note; } 128 const Note& get_note() const { return (*scopes)[level].note; } 109 129 110 130 private: … … 117 137 value_type > { 118 138 friend class ScopedMap; 119 typedef typename std::map< Key, Value >::iterator wrapped_iterator;120 typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator;121 typedef typename std::vector< std::map< Key, Value > >scope_list;139 typedef typename ScopedMap::MapType::iterator wrapped_iterator; 140 typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator; 141 typedef typename ScopedMap::ScopeList scope_list; 122 142 typedef typename scope_list::size_type size_type; 123 143 124 144 /// Checks if this iterator points to a valid item 125 145 bool is_valid() const { 126 return it != (*scopes)[level]. end();146 return it != (*scopes)[level].map.end(); 127 147 } 128 148 … … 157 177 158 178 const_iterator& operator++ () { 159 if ( it == (*scopes)[level]. end() ) {179 if ( it == (*scopes)[level].map.end() ) { 160 180 if ( level == 0 ) return *this; 161 181 --level; 162 it = (*scopes)[level]. begin();182 it = (*scopes)[level].map.begin(); 163 183 } else { 164 184 ++it; … … 170 190 const_iterator& operator-- () { 171 191 // may fail if this is the begin iterator; allowed by STL spec 172 if ( it == (*scopes)[level]. begin() ) {192 if ( it == (*scopes)[level].map.begin() ) { 173 193 ++level; 174 it = (*scopes)[level]. end();194 it = (*scopes)[level].map.end(); 175 195 } 176 196 --it; … … 185 205 186 206 size_type get_level() const { return level; } 207 208 const Note& get_note() const { return (*scopes)[level].note; } 187 209 188 210 private: … … 197 219 } 198 220 221 // Starts a new scope with the given note 222 template<typename N> 223 void beginScope( N&& n ) { 224 scopes.emplace_back( std::forward<N>(n) ); 225 } 226 199 227 /// Ends a scope; invalidates any iterators pointing to elements of that scope 200 228 void endScope() { … … 204 232 205 233 /// Default constructor initializes with one scope 206 ScopedMap() { beginScope(); } 207 208 iterator begin() { return iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); } 209 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); } 210 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); } 211 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 212 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 213 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 234 ScopedMap() : scopes() { beginScope(); } 235 236 /// Constructs with a given note on the outermost scope 237 template<typename N> 238 ScopedMap( N&& n ) : scopes() { beginScope(std::forward<N>(n)); } 239 240 iterator begin() { return iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); } 241 const_iterator begin() const { return const_iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); } 242 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); } 243 iterator end() { return iterator(scopes, scopes[0].map.end(), 0); } 244 const_iterator end() const { return const_iterator(scopes, scopes[0].map.end(), 0); } 245 const_iterator cend() const { return const_iterator(scopes, scopes[0].map.end(), 0); } 214 246 215 247 /// Gets the index of the current scope (counted from 1) 216 248 size_type currentScope() const { return scopes.size() - 1; } 249 250 /// Gets the note at the given scope 251 Note& getNote( size_type i ) { return scopes[i].note; } 252 const Note& getNote( size_type i ) const { return scopes[i].note; } 217 253 218 254 /// Finds the given key in the outermost scope it occurs; returns end() for none such 219 255 iterator find( const Key &key ) { 220 256 for ( size_type i = scopes.size() - 1; ; --i ) { 221 typename Scope::iterator val = scopes[i].find( key );222 if ( val != scopes[i]. end() ) return iterator( scopes, val, i );257 typename MapType::iterator val = scopes[i].map.find( key ); 258 if ( val != scopes[i].map.end() ) return iterator( scopes, val, i ); 223 259 if ( i == 0 ) break; 224 260 } … … 226 262 } 227 263 const_iterator find( const Key &key ) const { 228 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) );264 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->find( key ) ); 229 265 } 230 266 231 267 /// Finds the given key in the provided scope; returns end() for none such 232 268 iterator findAt( size_type scope, const Key& key ) { 233 typename Scope::iterator val = scopes[scope].find( key );234 if ( val != scopes[scope]. end() ) return iterator( scopes, val, scope );269 typename MapType::iterator val = scopes[scope].map.find( key ); 270 if ( val != scopes[scope].map.end() ) return iterator( scopes, val, scope ); 235 271 return end(); 236 272 } 237 273 const_iterator findAt( size_type scope, const Key& key ) const { 238 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findAt( scope, key ) );274 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findAt( scope, key ) ); 239 275 } 240 276 … … 243 279 if ( it.level == 0 ) return end(); 244 280 for ( size_type i = it.level - 1; ; --i ) { 245 typename Scope::iterator val = scopes[i].find( key );246 if ( val != scopes[i]. end() ) return iterator( scopes, val, i );281 typename MapType::iterator val = scopes[i].map.find( key ); 282 if ( val != scopes[i].map.end() ) return iterator( scopes, val, i ); 247 283 if ( i == 0 ) break; 248 284 } … … 250 286 } 251 287 const_iterator findNext( const_iterator &it, const Key &key ) const { 252 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) );288 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findNext( it, key ) ); 253 289 } 254 290 … … 256 292 template< typename value_type_t > 257 293 std::pair< iterator, bool > insert( value_type_t&& value ) { 258 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( std::forward<value_type_t>( value ) );294 std::pair< typename MapType::iterator, bool > res = scopes.back().map.insert( std::forward<value_type_t>( value ) ); 259 295 return std::make_pair( iterator(scopes, std::move( res.first ), scopes.size()-1), std::move( res.second ) ); 260 296 } … … 262 298 template< typename value_type_t > 263 299 std::pair< iterator, bool > insert( iterator at, value_type_t&& value ) { 264 Scope& scope = (*at.scopes) [ at.level ];265 std::pair< typename Scope::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );300 MapType& scope = (*at.scopes)[ at.level ].map; 301 std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) ); 266 302 return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) ); 267 303 } … … 272 308 template< typename value_type_t > 273 309 std::pair< iterator, bool > insertAt( size_type scope, value_type_t&& value ) { 274 std::pair< typename Scope::iterator, bool > res = scopes.at(scope).insert( std::forward<value_type_t>( value ) );310 std::pair< typename MapType::iterator, bool > res = scopes.at(scope).map.insert( std::forward<value_type_t>( value ) ); 275 311 return std::make_pair( iterator(scopes, std::move( res.first ), scope), std::move( res.second ) ); 276 312 } … … 288 324 289 325 iterator erase( iterator pos ) { 290 Scope& scope = (*pos.scopes) [ pos.level ];326 MapType& scope = (*pos.scopes)[ pos.level ].map; 291 327 const typename iterator::wrapped_iterator& new_it = scope.erase( pos.it ); 292 328 iterator it( *pos.scopes, new_it, pos.level ); -
src/Common/SemanticError.h
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 16 15:01:23201813 // Update Count : 3 012 // Last Modified On : Thu Jul 19 10:09:17 2018 13 // Update Count : 31 14 14 // 15 15 … … 17 17 18 18 #include "ErrorObjects.h" 19 #include "AST/Node.hpp" 19 20 #include <cstring> 20 21 … … 56 57 {"reference-conversion" , "rvalue to reference conversion of rvalue: %s" , Severity::Warn}, 57 58 {"qualifiers-zero_t-one_t", "questionable use of type qualifier %s with %s", Severity::Warn}, 59 {"aggregate-forward-decl" , "forward declaration of nested aggregate: %s" , Severity::Warn}, 60 {"superfluous-decl" , "declaration does not allocate storage: %s" , Severity::Warn}, 61 {"gcc-attributes" , "invalid attribute: %s" , Severity::Warn}, 58 62 }; 59 63 … … 62 66 RvalueToReferenceConversion, 63 67 BadQualifiersZeroOne, 64 NUMBER_OF_WARNINGS, //This MUST be the last warning 68 AggrForwardDecl, 69 SuperfluousDecl, 70 GccAttributes, 71 NUMBER_OF_WARNINGS, // This MUST be the last warning 65 72 }; 66 73 -
src/Common/module.mk
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 SRC += Common/SemanticError.cc \ 18 Common/UniqueName.cc \ 19 Common/DebugMalloc.cc \ 20 Common/Assert.cc \ 21 Common/Heap.cc 17 SRC_COMMON = \ 18 Common/Assert.cc \ 19 Common/Eval.cc \ 20 Common/PassVisitor.cc \ 21 Common/SemanticError.cc \ 22 Common/Stats/Counter.cc \ 23 Common/Stats/Heap.cc \ 24 Common/Stats/Stats.cc \ 25 Common/Stats/Time.cc \ 26 Common/UniqueName.cc 27 28 SRC += $(SRC_COMMON) Common/DebugMalloc.cc 29 SRCDEMANGLE += $(SRC_COMMON) -
src/Common/utility.h
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 6 22:24:16 201813 // Update Count : 4 012 // Last Modified On : Wed Jul 24 14:28:19 2019 13 // Update Count : 41 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <cassert> 18 19 #include <cctype> 19 20 #include <algorithm> … … 26 27 #include <string> 27 28 #include <type_traits> 28 29 #include < cassert>29 #include <utility> 30 #include <vector> 30 31 31 32 #include "Common/Indenter.h" 33 34 class Expression; 35 36 /// bring std::move into global scope 37 using std::move; 38 39 /// partner to move that copies any copyable type 40 template<typename T> 41 T copy( const T & x ) { return x; } 32 42 33 43 template< typename T > … … 71 81 72 82 template< typename Container > 73 void deleteAll( Container &container ) {74 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i) {75 delete *i;83 void deleteAll( const Container &container ) { 84 for ( const auto &i : container ) { 85 delete i; 76 86 } // for 77 87 } … … 142 152 return ret; 143 153 } // switch 154 } 155 156 /// Splice src onto the end of dst, clearing src 157 template< typename T > 158 void splice( std::vector< T > & dst, std::vector< T > & src ) { 159 dst.reserve( dst.size() + src.size() ); 160 for ( T & x : src ) { dst.emplace_back( std::move( x ) ); } 161 src.clear(); 162 } 163 164 /// Splice src onto the begining of dst, clearing src 165 template< typename T > 166 void spliceBegin( std::vector< T > & dst, std::vector< T > & src ) { 167 splice( src, dst ); 168 dst.swap( src ); 144 169 } 145 170 … … 456 481 } // ilog2 457 482 483 // ----------------------------------------------------------------------------- 484 /// evaluates expr as a long long int. If second is false, expr could not be evaluated 485 std::pair<long long int, bool> eval(const Expression * expr); 486 487 namespace ast { 488 class Expr; 489 } 490 491 std::pair<long long int, bool> eval(const ast::Expr * expr); 492 493 // ----------------------------------------------------------------------------- 494 /// Reorders the input range in-place so that the minimal-value elements according to the 495 /// comparator are in front; 496 /// returns the iterator after the last minimal-value element. 497 template<typename Iter, typename Compare> 498 Iter sort_mins( Iter begin, Iter end, Compare& lt ) { 499 if ( begin == end ) return end; 500 501 Iter min_pos = begin; 502 for ( Iter i = begin + 1; i != end; ++i ) { 503 if ( lt( *i, *min_pos ) ) { 504 // new minimum cost; swap into first position 505 min_pos = begin; 506 std::iter_swap( min_pos, i ); 507 } else if ( ! lt( *min_pos, *i ) ) { 508 // duplicate minimum cost; swap into next minimum position 509 ++min_pos; 510 std::iter_swap( min_pos, i ); 511 } 512 } 513 return ++min_pos; 514 } 515 516 template<typename Iter, typename Compare> 517 inline Iter sort_mins( Iter begin, Iter end, Compare&& lt ) { 518 return sort_mins( begin, end, lt ); 519 } 520 521 /// sort_mins defaulted to use std::less 522 template<typename Iter> 523 inline Iter sort_mins( Iter begin, Iter end ) { 524 return sort_mins( begin, end, std::less<typename std::iterator_traits<Iter>::value_type>{} ); 525 } 458 526 459 527 // Local Variables: // -
src/Concurrency/Keywords.cc
r7951100 rb067d9b 97 97 "__thrd", 98 98 "get_thread", 99 "thread keyword requires threads to be in scope, add #include <thread >",99 "thread keyword requires threads to be in scope, add #include <thread.hfa>", 100 100 true, 101 101 KeywordCastExpr::Thread … … 129 129 "__cor", 130 130 "get_coroutine", 131 "coroutine keyword requires coroutines to be in scope, add #include <coroutine >",131 "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>", 132 132 true, 133 133 KeywordCastExpr::Coroutine … … 161 161 "__mon", 162 162 "get_monitor", 163 "monitor keyword requires monitors to be in scope, add #include <monitor >",163 "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>", 164 164 false, 165 165 KeywordCastExpr::Monitor … … 488 488 // Do we have the required headers 489 489 if( !monitor_decl || !guard_decl || !dtor_guard_decl ) 490 SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor >\n" );490 SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor.hfa>\n" ); 491 491 492 492 // Instrument the body … … 501 501 void MutexKeyword::postvisit(StructDecl* decl) { 502 502 503 if( decl->name == "monitor_desc" ) {503 if( decl->name == "monitor_desc" && decl->body ) { 504 504 assert( !monitor_decl ); 505 505 monitor_decl = decl; 506 506 } 507 else if( decl->name == "monitor_guard_t" ) {507 else if( decl->name == "monitor_guard_t" && decl->body ) { 508 508 assert( !guard_decl ); 509 509 guard_decl = decl; 510 510 } 511 else if( decl->name == "monitor_dtor_guard_t" ) {511 else if( decl->name == "monitor_dtor_guard_t" && decl->body ) { 512 512 assert( !dtor_guard_decl ); 513 513 dtor_guard_decl = decl; … … 575 575 576 576 //in reverse order : 577 // monitor_ guard_t __guard = { __monitors, #, func };577 // monitor_dtor_guard_t __guard = { __monitors, func }; 578 578 body->push_front( 579 579 new DeclStmt( new ObjectDecl( … … 634 634 assert(generic_func); 635 635 636 // in reverse order :636 // in reverse order : 637 637 // monitor_guard_t __guard = { __monitors, #, func }; 638 638 body->push_front( … … 685 685 if( type && type->get_baseStruct()->is_thread() ) { 686 686 if( !thread_decl || !thread_ctor_seen ) { 687 SemanticError( type->get_baseStruct()->location, "thread keyword requires threads to be in scope, add #include <thread >");687 SemanticError( type->get_baseStruct()->location, "thread keyword requires threads to be in scope, add #include <thread.hfa>"); 688 688 } 689 689 -
src/Concurrency/Waitfor.cc
r7951100 rb067d9b 11 11 // Last Modified By : 12 12 // Last Modified On : 13 // Update Count : 513 // Update Count : 7 14 14 // 15 15 … … 66 66 void foo() { 67 67 while( true ) { 68 69 acceptable_t acceptables[3]; 70 if( a < 1 ) { 71 acceptables[0].func = f; 72 acceptables[0].mon = a; 73 } 74 acceptables[1].func = g; 75 acceptables[1].mon = a; 76 77 acceptables[2].func = f; 78 acceptables[2].mon = a; 79 acceptables[2].is_dtor = true; 80 81 int ret = waitfor_internal( acceptables, swagl() ); 82 83 switch( ret ) { 84 case 0: 85 { 86 bar(); 68 { 69 acceptable_t acceptables[3]; 70 if( a < 1 ) { 71 acceptables[0].func = f; 72 acceptables[0].mon = a; 87 73 } 88 case 1: 89 { 90 baz(); 74 acceptables[1].func = g; 75 acceptables[1].mon = a; 76 77 acceptables[2].func = f; 78 acceptables[2].mon = a; 79 acceptables[2].is_dtor = true; 80 81 int ret = waitfor_internal( acceptables, swagl() ); 82 83 switch( ret ) { 84 case 0: 85 { 86 bar(); 87 } 88 case 1: 89 { 90 baz(); 91 } 92 case 2: 93 signal(a); 94 { 95 break; 96 } 91 97 } 92 case 2:93 signal(a);94 {95 break;96 }97 98 } 98 99 } … … 250 251 Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) { 251 252 if( !decl_monitor || !decl_acceptable || !decl_mask ) 252 SemanticError( waitfor, "waitfor keyword requires monitors to be in scope, add #include <monitor >" );253 SemanticError( waitfor, "waitfor keyword requires monitors to be in scope, add #include <monitor.hfa>" ); 253 254 254 255 CompoundStmt * stmt = new CompoundStmt(); … … 555 556 new ConstantExpr( Constant::from_ulong( i++ ) ), 556 557 { 557 clause.statement, 558 new BranchStmt( 559 "", 560 BranchStmt::Break 561 ) 558 new CompoundStmt({ 559 clause.statement, 560 new BranchStmt( 561 "", 562 BranchStmt::Break 563 ) 564 }) 562 565 } 563 566 ) … … 570 573 new ConstantExpr( Constant::from_int( -2 ) ), 571 574 { 572 waitfor->timeout.statement, 573 new BranchStmt( 574 "", 575 BranchStmt::Break 576 ) 575 new CompoundStmt({ 576 waitfor->timeout.statement, 577 new BranchStmt( 578 "", 579 BranchStmt::Break 580 ) 581 }) 577 582 } 578 583 ) … … 585 590 new ConstantExpr( Constant::from_int( -1 ) ), 586 591 { 587 waitfor->orelse.statement, 588 new BranchStmt( 589 "", 590 BranchStmt::Break 591 ) 592 new CompoundStmt({ 593 waitfor->orelse.statement, 594 new BranchStmt( 595 "", 596 BranchStmt::Break 597 ) 598 }) 592 599 } 593 600 ) -
src/Concurrency/module.mk
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 SRC += Concurrency/Keywords.cc \18 Concurrency/Waitfor.cc17 SRC += Concurrency/Keywords.cc Concurrency/Waitfor.cc 18 SRCDEMANGLE += Concurrency/Keywords.cc 19 19 -
src/ControlStruct/ExceptTranslate.cc
r7951100 rb067d9b 9 9 // Author : Andrew Beach 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Aug 17 17:19:00 201713 // Update Count : 911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 13 18:15:29 2019 13 // Update Count : 11 14 14 // 15 15 … … 319 319 } 320 320 321 block->push_back( handler-> get_body());322 handler-> set_body( nullptr );321 block->push_back( handler->body ); 322 handler->body = nullptr; 323 323 324 324 std::list<Statement *> caseBody … … 617 617 return create_terminate_rethrow( throwStmt ); 618 618 } else { 619 a ssertf(false,"Invalid throw in %s at %i\n",619 abort("Invalid throw in %s at %i\n", 620 620 throwStmt->location.filename.c_str(), 621 621 throwStmt->location.first_line); 622 return nullptr;623 622 } 624 623 } else { … … 628 627 return create_resume_rethrow( throwStmt ); 629 628 } else { 630 a ssertf(false,"Invalid throwResume in %s at %i\n",629 abort("Invalid throwResume in %s at %i\n", 631 630 throwStmt->location.filename.c_str(), 632 631 throwStmt->location.first_line); 633 return nullptr;634 632 } 635 633 } -
src/ControlStruct/ForExprMutator.cc
r7951100 rb067d9b 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Aug 18 10:22:00 201713 // Update Count : 1 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 11 22:26:52 2019 13 // Update Count : 14 14 14 // 15 15 … … 21 21 22 22 namespace ControlStruct { 23 Statement * hoist( Statement *originalStmt, std::list<Statement *> &init ) {23 Statement * hoist( Statement * originalStmt, std::list<Statement *> & init ) { 24 24 // If no hoisting is needed, skip: 25 25 if ( 0 == init.size() ) { … … 29 29 // Create compound statement, move initializers outside, 30 30 // the resut of the original stays as is. 31 CompoundStmt * block = new CompoundStmt();32 std::list<Statement *> & stmts = block->get_kids();31 CompoundStmt * block = new CompoundStmt(); 32 std::list<Statement *> & stmts = block->get_kids(); 33 33 stmts.splice( stmts.end(), init ); 34 34 … … 38 38 } 39 39 40 Statement * ForExprMutator::postmutate( IfStmt *ifStmt ) {40 Statement * ForExprMutator::postmutate( IfStmt * ifStmt ) { 41 41 return hoist( ifStmt, ifStmt->initialization ); 42 42 } 43 Statement * ForExprMutator::postmutate( ForStmt *forStmt ) {43 Statement * ForExprMutator::postmutate( ForStmt * forStmt ) { 44 44 // hoist any initializer declarations to make them C89 (rather than C99) 45 45 return hoist( forStmt, forStmt->initialization ); 46 46 } 47 Statement * ForExprMutator::postmutate( WhileStmt *whileStmt ) {47 Statement * ForExprMutator::postmutate( WhileStmt * whileStmt ) { 48 48 return hoist( whileStmt, whileStmt->initialization ); 49 49 } -
src/ControlStruct/LabelFixer.cc
r7951100 rb067d9b 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Tue Jul 28 13:32:43 201513 // Update Count : 15 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 11 22:26:02 2019 13 // Update Count : 159 14 14 // 15 15 … … 32 32 } 33 33 34 LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) {34 LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) { 35 35 if ( generator == 0 ) 36 36 generator = LabelGenerator::getGenerator(); … … 49 49 50 50 // prune to at most one label definition for each statement 51 void LabelFixer::previsit( Statement * stmt ) {51 void LabelFixer::previsit( Statement * stmt ) { 52 52 std::list< Label > &labels = stmt->get_labels(); 53 53 … … 58 58 } 59 59 60 void LabelFixer::previsit( BranchStmt * branchStmt ) {60 void LabelFixer::previsit( BranchStmt * branchStmt ) { 61 61 previsit( ( Statement *)branchStmt ); 62 62 … … 75 75 76 76 77 // sets the definition of the labelTable entry to be the provided 78 // statement for every label in the listparameter. Happens for every kind of statement79 Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement *definition ) {77 // sets the definition of the labelTable entry to be the provided statement for every label in the list 78 // parameter. Happens for every kind of statement 79 Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) { 80 80 assert( definition != 0 ); 81 81 assert( llabel.size() > 0 ); … … 100 100 } // for 101 101 102 // produce one of the labels attached to this statement to be 103 // temporarily used as the canonical label 102 // produce one of the labels attached to this statement to be temporarily used as the canonical label 104 103 return labelTable[ llabel.front() ]->get_label(); 105 104 } … … 117 116 118 117 // Builds a table that maps a label to its defining statement. 119 std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) {118 std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) { 120 119 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 121 120 for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { -
src/ControlStruct/LabelGenerator.cc
r7951100 rb067d9b 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Aug 14 14:14:00 201513 // Update Count : 1 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 11 22:23:20 2019 13 // Update Count : 15 14 14 // 15 15 … … 24 24 25 25 namespace ControlStruct { 26 LabelGenerator * LabelGenerator::labelGenerator = 0;26 LabelGenerator * LabelGenerator::labelGenerator = 0; 27 27 28 LabelGenerator * LabelGenerator::getGenerator() {28 LabelGenerator * LabelGenerator::getGenerator() { 29 29 if ( LabelGenerator::labelGenerator == 0 ) 30 30 LabelGenerator::labelGenerator = new LabelGenerator(); 31 32 31 return labelGenerator; 33 32 } … … 38 37 if ( stmt && ! stmt->get_labels().empty() ) { 39 38 os << "_" << stmt->get_labels().front() << "__"; 40 } 39 } // if 41 40 std::string ret = os.str(); 42 41 Label l( ret ); -
src/ControlStruct/MLEMutator.cc
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Mar 8 17:08:25 201813 // Update Count : 2 1912 // Last Modified On : Tue Oct 22 17:22:44 2019 13 // Update Count : 220 14 14 // 15 15 … … 313 313 } 314 314 315 void MLEMutator::premutate( TryStmt * tryStmt ) { 316 // generate a label for breaking out of a labeled if 317 bool labeledBlock = !(tryStmt->get_labels().empty()); 318 if ( labeledBlock ) { 319 Label brkLabel = generator->newLabel("blockBreak", tryStmt); 320 enclosingControlStructures.push_back( Entry( tryStmt, brkLabel ) ); 321 GuardAction( [this]() { enclosingControlStructures.pop_back(); } ); 322 } // if 323 } 324 325 Statement * MLEMutator::postmutate( TryStmt * tryStmt ) { 326 bool labeledBlock = !(tryStmt->get_labels().empty()); 327 if ( labeledBlock ) { 328 if ( ! enclosingControlStructures.back().useBreakExit().empty() ) { 329 set_breakLabel( enclosingControlStructures.back().useBreakExit() ); 330 } // if 331 } // if 332 return tryStmt; 333 } 334 315 335 void MLEMutator::premutate( CaseStmt *caseStmt ) { 316 336 visit_children = false; -
src/ControlStruct/MLEMutator.h
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Mar 8 16:42:32 201813 // Update Count : 4 112 // Last Modified On : Tue Oct 22 17:22:47 2019 13 // Update Count : 45 14 14 // 15 15 … … 47 47 void premutate( SwitchStmt *switchStmt ); 48 48 Statement * postmutate( SwitchStmt *switchStmt ); 49 void premutate( TryStmt *tryStmt ); 50 Statement * postmutate( TryStmt *tryStmt ); 49 51 50 52 Statement *mutateLoop( Statement *bodyLoop, Entry &e ); … … 73 75 explicit Entry( SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) : 74 76 stmt( stmt ), breakExit( breakExit ), fallDefaultExit( fallDefaultExit ) {} 77 78 explicit Entry( TryStmt *stmt, Label breakExit ) : 79 stmt( stmt ), breakExit( breakExit ) {} 75 80 76 81 bool operator==( const Statement *other ) { return stmt == other; } -
src/ControlStruct/module.mk
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 SRC += ControlStruct/LabelGenerator.cc \ 17 SRC_CONTROLSTRUCT = \ 18 ControlStruct/ForExprMutator.cc \ 18 19 ControlStruct/LabelFixer.cc \ 20 ControlStruct/LabelGenerator.cc \ 19 21 ControlStruct/MLEMutator.cc \ 20 ControlStruct/Mutate.cc \ 21 ControlStruct/ForExprMutator.cc \ 22 ControlStruct/ExceptTranslate.cc 22 ControlStruct/Mutate.cc 23 24 SRC += $(SRC_CONTROLSTRUCT) ControlStruct/ExceptTranslate.cc 25 SRCDEMANGLE += $(SRC_CONTROLSTRUCT) 26 -
src/GenPoly/Box.cc
r7951100 rb067d9b 76 76 77 77 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 78 class Pass1 final : public BoxPass, public With TypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {78 class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting { 79 79 public: 80 80 Pass1(); … … 150 150 /// * Calculates polymorphic offsetof expressions from offset array 151 151 /// * Inserts dynamic calculation of polymorphic type layouts where needed 152 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public With TypeSubstitution {152 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithConstTypeSubstitution { 153 153 public: 154 154 PolyGenericCalculator(); … … 657 657 paramExpr = new AddressExpr( paramExpr ); 658 658 } // if 659 arg = appExpr-> get_args().insert( arg, paramExpr ); // add argument to function call659 arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call 660 660 arg++; 661 661 // Build a comma expression to call the function and emulate a normal return. 662 662 CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr ); 663 commaExpr-> set_env( appExpr->get_env() );664 appExpr-> set_env( 0 );663 commaExpr->env = appExpr->env; 664 appExpr->env = nullptr; 665 665 return commaExpr; 666 666 } … … 708 708 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 709 709 if ( isDynRet( function, tyVars ) ) { 710 ret = addRetParam( appExpr, function-> get_returnVals().front()->get_type(), arg );710 ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg ); 711 711 } // if 712 712 std::string mangleName = mangleAdapterName( function, tyVars ); … … 715 715 // cast adaptee to void (*)(), since it may have any type inside a polymorphic function 716 716 Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 717 appExpr->get_args().push_front( new CastExpr( appExpr-> get_function(), adapteeType ) );717 appExpr->get_args().push_front( new CastExpr( appExpr->function, adapteeType ) ); 718 718 appExpr->set_function( new NameExpr( adapterName ) ); // xxx - result is never set on NameExpr 719 719 … … 725 725 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 726 726 727 if ( arg-> result->get_lvalue() ) {727 if ( arg->get_lvalue() ) { 728 728 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 729 729 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { … … 798 798 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 799 799 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) { 800 InferredParams::const_iterator inferParam = appExpr-> get_inferParams().find( (*assert)->get_uniqueId() );801 assertf( inferParam != appExpr-> get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );800 InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() ); 801 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() ); 802 802 Expression *newExpr = inferParam->second.expr->clone(); 803 803 addCast( newExpr, (*assert)->get_type(), tyVars ); … … 837 837 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 838 838 deref->result = arg->get_type()->clone(); 839 deref->result->set_lvalue( true );840 839 return deref; 841 840 } // if … … 1764 1763 1765 1764 Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) { 1766 Type *ty = sizeofExpr->get_isType() ? 1765 Type *ty = sizeofExpr->get_isType() ? 1767 1766 sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result(); 1768 1767 1769 1768 Expression * gen = genSizeof( ty ); 1770 1769 if ( gen ) { -
src/GenPoly/GenPoly.cc
r7951100 rb067d9b 24 24 #include <vector> // for vector 25 25 26 #include "AST/Type.hpp" 26 27 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 27 28 #include "ResolvExpr/typeops.h" // for flatten … … 262 263 } else { 263 264 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise 265 } 266 } 267 268 const ast::FunctionType * getFunctionType( const ast::Type * ty ) { 269 if ( auto pty = dynamic_cast< const ast::PointerType * >( ty ) ) { 270 return pty->base.as< ast::FunctionType >(); 271 } else { 272 return dynamic_cast< const ast::FunctionType * >( ty ); 264 273 } 265 274 } … … 440 449 } 441 450 442 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {451 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) { 443 452 // is parameter is not polymorphic, don't need to box 444 453 if ( ! isPolyType( param, exprTyVars ) ) return false; … … 450 459 } 451 460 452 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {461 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) { 453 462 FunctionType * function = getFunctionType( appExpr->function->result ); 454 463 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); … … 459 468 460 469 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 461 // xxx - should this actually be insert? 462 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar }; 470 tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } ); 463 471 } 464 472 -
src/GenPoly/GenPoly.h
r7951100 rb067d9b 20 20 21 21 #include "ErasableScopedMap.h" // for ErasableScopedMap 22 #include "AST/Fwd.hpp" 22 23 #include "SymTab/Mangler.h" // for Mangler 23 24 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... … … 72 73 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise 73 74 FunctionType *getFunctionType( Type *ty ); 75 const ast::FunctionType * getFunctionType( const ast::Type * ty ); 74 76 75 77 /// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise; … … 81 83 82 84 /// true if arg requires boxing given exprTyVars 83 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );85 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ); 84 86 85 87 /// true if arg requires boxing in the call to appExpr 86 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );88 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ); 87 89 88 90 /// Adds the type variable `tyVar` to `tyVarMap` -
src/GenPoly/InstantiateGeneric.cc
r7951100 rb067d9b 168 168 169 169 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 170 struct GenericInstantiator final : public With TypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {170 struct GenericInstantiator final : public WithConstTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards { 171 171 /// Map of (generic type, parameter list) pairs to concrete type instantiations 172 172 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; -
src/GenPoly/Lvalue.cc
r7951100 rb067d9b 21 21 #include "Lvalue.h" 22 22 23 #include "InitTweak/InitTweak.h" 23 24 #include "Parser/LinkageSpec.h" // for Spec, isBuiltin, Intrinsic 24 25 #include "ResolvExpr/TypeEnvironment.h" // for AssertionSet, OpenVarSet 25 26 #include "ResolvExpr/Unify.h" // for unify 26 27 #include "ResolvExpr/typeops.h" 27 #include "SymTab/Autogen.h"28 28 #include "SymTab/Indexer.h" // for Indexer 29 29 #include "SynTree/Declaration.h" // for Declaration, FunctionDecl … … 33 33 #include "SynTree/Type.h" // for PointerType, Type, FunctionType 34 34 #include "SynTree/Visitor.h" // for Visitor, acceptAll 35 #include "Validate/FindSpecialDecls.h" // for dereferenceOperator 35 36 36 37 #if 0 … … 44 45 // TODO: fold this into the general createDeref function?? 45 46 Expression * mkDeref( Expression * arg ) { 46 if ( SymTab::dereferenceOperator ) {47 if ( Validate::dereferenceOperator ) { 47 48 // note: reference depth can be arbitrarily deep here, so peel off the outermost pointer/reference, not just pointer because they are effecitvely equivalent in this pass 48 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator );49 VariableExpr * deref = new VariableExpr( Validate::dereferenceOperator ); 49 50 deref->result = new PointerType( Type::Qualifiers(), deref->result ); 50 51 Type * base = InitTweak::getPointerBase( arg->result ); … … 53 54 delete ret->result; 54 55 ret->result = base->clone(); 55 ret->result->set_lvalue( true );56 56 return ret; 57 57 } else { … … 146 146 147 147 namespace { 148 // true for intrinsic function calls that return a reference148 // true for intrinsic function calls that return an lvalue in C 149 149 bool isIntrinsicReference( Expression * expr ) { 150 // known intrinsic-reference prelude functions 151 static std::set<std::string> lvalueFunctions = { "*?", "?[?]" }; 150 152 if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) { 151 153 std::string fname = InitTweak::getFunctionName( untyped ); 152 // known intrinsic-reference prelude functions 153 return fname == "*?" || fname == "?[?]"; 154 return lvalueFunctions.count(fname); 154 155 } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) { 155 156 if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) { 156 // use type of return variable rather than expr result type, since it may have been changed to a pointer type 157 FunctionType * ftype = GenPoly::getFunctionType( func->get_type() ); 158 Type * ret = ftype->returnVals.empty() ? nullptr : ftype->returnVals.front()->get_type(); 159 return func->linkage == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret ); 157 return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name); 160 158 } 161 159 } … … 168 166 ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result ); 169 167 appExpr->result = result->base->clone(); 170 appExpr->result->set_lvalue( true );171 168 if ( ! inIntrinsic ) { 172 169 // when not in an intrinsic function, add a cast to … … 197 194 unsigned int i = 0; 198 195 const unsigned int end = ftype->parameters.size(); 196 197 /// The for loop may eagerly dereference the iterators and fail on empty lists 198 if(i == end) { return appExpr; } 199 199 for ( auto p : unsafe_group_iterate( appExpr->args, ftype->parameters ) ) { 200 if (i == end) break;201 200 Expression *& arg = std::get<0>( p ); 202 201 Type * formal = std::get<1>( p )->get_type(); … … 212 211 // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation. 213 212 214 if ( function-> get_linkage()!= LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {213 if ( function->linkage != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 215 214 // needed for definition of prelude functions, etc. 216 215 // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address … … 228 227 arg = new AddressExpr( arg ); 229 228 // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) { 230 } else if ( function-> get_linkage()== LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {229 } else if ( function->linkage == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) { 231 230 // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument 232 231 PRINT( … … 243 242 } 244 243 ++i; 244 if (i == end) break; 245 245 } 246 246 } … … 355 355 Type * destType = castExpr->result; 356 356 Type * srcType = castExpr->arg->result; 357 assertf( destType, "Cast to no type in: %s", toCString( castExpr ) ); 358 assertf( srcType, "Cast from no type in: %s", toCString( castExpr ) ); 357 359 int depth1 = destType->referenceDepth(); 358 360 int depth2 = srcType->referenceDepth(); 359 361 int diff = depth1 - depth2; 360 362 361 if ( diff > 0 && ! srcType->get_lvalue() ) {363 if ( diff > 0 && ! castExpr->arg->get_lvalue() ) { 362 364 // rvalue to reference conversion -- introduce temporary 363 365 // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g. … … 403 405 ret = new AddressExpr( ret ); 404 406 } 405 if ( srcType->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {407 if ( castExpr->arg->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) { 406 408 // must keep cast if cast-to type is different from the actual type 407 409 castExpr->arg = ret; … … 432 434 delete ret->result; 433 435 ret->result = castExpr->result; 434 ret->result->set_lvalue( true); // ensure result is lvalue436 assert( ret->get_lvalue() ); // ensure result is lvalue 435 437 castExpr->env = nullptr; 436 438 castExpr->arg = nullptr; -
src/GenPoly/ScopedSet.h
r7951100 rb067d9b 38 38 typedef typename Scope::pointer pointer; 39 39 typedef typename Scope::const_pointer const_pointer; 40 40 41 41 class iterator : public std::iterator< std::bidirectional_iterator_tag, 42 42 value_type > { … … 72 72 return *this; 73 73 } 74 74 75 75 reference operator* () { return *it; } 76 76 pointer operator-> () { return it.operator->(); } … … 104 104 bool operator!= (const iterator &that) { return !( *this == that ); } 105 105 106 size_type get_level() const { return i; } 107 106 108 private: 107 109 scope_list const *scopes; … … 180 182 bool operator!= (const const_iterator &that) { return !( *this == that ); } 181 183 184 size_type get_level() const { return i; } 185 182 186 private: 183 187 scope_list const *scopes; … … 185 189 size_type i; 186 190 }; 187 191 188 192 /// Starts a new scope 189 193 void beginScope() { … … 222 226 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 223 227 } 224 228 225 229 /// Finds the given key in the outermost scope inside the given scope where it occurs 226 230 iterator findNext( const_iterator &it, const Value &key ) { … … 242 246 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 243 247 } 244 248 245 249 }; 246 250 } // namespace GenPoly -
src/GenPoly/ScrubTyVars.cc
r7951100 rb067d9b 50 50 delete typeInst; 51 51 return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 52 default: 53 assertf(false, "Unhandled tyvar kind: %d", tyVar->second.kind); 52 54 } // switch 53 55 } // if -
src/GenPoly/Specialize.cc
r7951100 rb067d9b 42 42 43 43 namespace GenPoly { 44 struct Specialize final : public With TypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {44 struct Specialize final : public WithConstTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> { 45 45 Expression * postmutate( ApplicationExpr *applicationExpr ); 46 46 Expression * postmutate( CastExpr *castExpr ); … … 54 54 55 55 /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type. 56 bool needsPolySpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {56 bool needsPolySpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) { 57 57 if ( env ) { 58 58 using namespace ResolvExpr; … … 145 145 } 146 146 147 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {147 bool needsSpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) { 148 148 return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType ); 149 149 } … … 245 245 appExpr->env = TypeSubstitution::newFromExpr( appExpr, env ); 246 246 if ( inferParams ) { 247 appExpr-> get_inferParams()= *inferParams;247 appExpr->inferParams = *inferParams; 248 248 } // if 249 249 … … 284 284 std::list< Expression* >::iterator actual; 285 285 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 286 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr-> get_inferParams());286 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->inferParams ); 287 287 } 288 288 } … … 295 295 // alternatively, if order starts to matter then copy appExpr's inferParams and pass them to handleExplicitParams. 296 296 handleExplicitParams( appExpr ); 297 for ( InferredParams::iterator inferParam = appExpr-> get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {298 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get());297 for ( InferredParams::iterator inferParam = appExpr->inferParams.begin(); inferParam != appExpr->inferParams.end(); ++inferParam ) { 298 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &inferParam->second.expr->inferParams ); 299 299 } 300 300 } -
src/GenPoly/module.mk
r7951100 rb067d9b 22 22 GenPoly/FindFunction.cc \ 23 23 GenPoly/InstantiateGeneric.cc 24 25 SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/Lvalue.cc 26 -
src/InitTweak/FixGlobalInit.cc
r7951100 rb067d9b 37 37 class GlobalFixer : public WithShortCircuiting { 38 38 public: 39 GlobalFixer( const std::string & name,bool inLibrary );39 GlobalFixer( bool inLibrary ); 40 40 41 41 void previsit( ObjectDecl *objDecl ); … … 52 52 }; 53 53 54 void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name,bool inLibrary ) {55 PassVisitor<GlobalFixer> visitor( name,inLibrary );54 void fixGlobalInit( std::list< Declaration * > & translationUnit, bool inLibrary ) { 55 PassVisitor<GlobalFixer> visitor( inLibrary ); 56 56 acceptAll( translationUnit, visitor ); 57 57 GlobalFixer & fixer = visitor.pass; … … 70 70 } 71 71 72 std::string globalFunctionName( const std::string & name ) { 73 // get basename 74 std::string ret = name.substr( 0, name.find( '.' ) ); 75 // replace invalid characters with _ 76 static std::string invalid = "/-"; 77 replace_if( ret.begin(), ret.end(), []( char c ) { return invalid.find(c) != std::string::npos; }, '_' ); 78 return ret; 79 } 80 81 GlobalFixer::GlobalFixer( const std::string & name, bool inLibrary ) : tempNamer( "_global_init" ) { 82 std::string fixedName = globalFunctionName( name ); 72 GlobalFixer::GlobalFixer( bool inLibrary ) : tempNamer( "_global_init" ) { 83 73 std::list< Expression * > ctorParameters; 84 74 std::list< Expression * > dtorParameters; … … 90 80 // for library code are run before constructors and destructors for user code, 91 81 // specify a priority when building the library. Priorities 0-100 are reserved by gcc. 92 ctorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) ); 93 dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) ); 82 // Priorities 101-200 are reserved by cfa, so use priority 200 for CFA library globals, 83 // allowing room for overriding with a higher priority. 84 ctorParameters.push_back( new ConstantExpr( Constant::from_int( 200 ) ) ); 85 dtorParameters.push_back( new ConstantExpr( Constant::from_int( 200 ) ) ); 94 86 } 95 initFunction = new FunctionDecl( "_ init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );87 initFunction = new FunctionDecl( "__global_init__", Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() ); 96 88 initFunction->get_attributes().push_back( new Attribute( "constructor", ctorParameters ) ); 97 destroyFunction = new FunctionDecl( "_ destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );89 destroyFunction = new FunctionDecl( "__global_destroy__", Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() ); 98 90 destroyFunction->get_attributes().push_back( new Attribute( "destructor", dtorParameters ) ); 99 91 } … … 110 102 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) { 111 103 // a decision should have been made by the resolver, so ctor and init are not both non-NULL 112 assert( ! ctorInit-> get_ctor() || ! ctorInit->get_init());104 assert( ! ctorInit->ctor || ! ctorInit->init ); 113 105 114 Statement * dtor = ctorInit-> get_dtor();106 Statement * dtor = ctorInit->dtor; 115 107 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 116 108 // don't need to call intrinsic dtor, because it does nothing, but 117 109 // non-intrinsic dtors must be called 118 110 destroyStatements.push_front( dtor ); 119 ctorInit-> set_dtor( NULL );111 ctorInit->dtor = nullptr; 120 112 } // if 121 if ( Statement * ctor = ctorInit-> get_ctor()) {113 if ( Statement * ctor = ctorInit->ctor ) { 122 114 initStatements.push_back( ctor ); 123 objDecl-> set_init( NULL );124 ctorInit-> set_ctor( NULL );125 } else if ( Initializer * init = ctorInit-> get_init()) {126 objDecl-> set_init( init );127 ctorInit-> set_init( NULL );115 objDecl->init = nullptr; 116 ctorInit->ctor = nullptr; 117 } else if ( Initializer * init = ctorInit->init ) { 118 objDecl->init = init; 119 ctorInit->init = nullptr; 128 120 } else { 129 121 // no constructor and no initializer, which is okay 130 objDecl-> set_init( NULL );122 objDecl->init = nullptr; 131 123 } // if 132 124 delete ctorInit; -
src/InitTweak/FixGlobalInit.h
r7951100 rb067d9b 22 22 23 23 namespace InitTweak { 24 /// Moves global initialization into an _init function that is unique to the translation unit. 25 /// Sets the priority of the initialization function depending on whether the initialization 26 /// function is for library code. 27 void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ); 28 29 /// Apply transformations to a file name to get a valid C identifier which will be used as 30 /// the name of the generated initializer function. 31 std::string globalFunctionName( const std::string & name ); 24 /// Moves global initialization into an _init function that is unique to the translation unit. 25 /// Sets the priority of the initialization function depending on whether the initialization 26 /// function is for library code. 27 void fixGlobalInit( std::list< Declaration * > & translationUnit, bool inLibrary ); 32 28 } // namespace 33 29 -
src/InitTweak/FixInit.cc
r7951100 rb067d9b 10 10 // Created On : Wed Jan 13 16:29:30 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 21 17:35:05 201713 // Update Count : 7 412 // Last Modified On : Wed Feb 13 18:15:56 2019 13 // Update Count : 76 14 14 // 15 15 #include "FixInit.h" … … 54 54 #include "SynTree/Type.h" // for Type, Type::StorageClasses 55 55 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution, operator<< 56 #include "SynTree/DeclReplacer.h" // for DeclReplacer 56 57 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 58 #include "Validate/FindSpecialDecls.h" // for dtorStmt, dtorStructDestroy 57 59 58 60 bool ctordtorp = false; // print all debug … … 66 68 namespace InitTweak { 67 69 namespace { 68 typedef std::unordered_map< int, int > UnqCount;69 70 70 struct SelfAssignChecker { 71 71 void previsit( ApplicationExpr * appExpr ); 72 72 }; 73 73 74 struct InsertImplicitCalls : public WithTypeSubstitution { 74 struct StmtExprResult { 75 static void link( std::list< Declaration * > & translationUnit ); 76 77 void previsit( StmtExpr * stmtExpr ); 78 }; 79 80 struct InsertImplicitCalls : public WithConstTypeSubstitution { 75 81 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which 76 82 /// function calls need their parameters to be copy constructed … … 80 86 }; 81 87 82 struct ResolveCopyCtors final : public With Indexer, public WithShortCircuiting, public WithTypeSubstitution{88 struct ResolveCopyCtors final : public WithStmtsToAdd, public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution, public WithVisitorRef<ResolveCopyCtors> { 83 89 /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr, 84 90 /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both 85 91 /// arguments and return value temporaries 86 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ); 87 88 ResolveCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ) {} 89 90 void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ); 91 void postvisit( StmtExpr * stmtExpr ); 92 void previsit( UniqueExpr * unqExpr ); 93 void postvisit( UniqueExpr * unqExpr ); 92 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit ); 93 94 Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ); 95 void premutate( StmtExpr * stmtExpr ); 96 void premutate( UniqueExpr * unqExpr ); 94 97 95 98 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) … … 98 101 bool skipCopyConstruct( Type * type ); 99 102 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ); 100 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 101 102 UnqCount & unqCount; // count the number of times each unique expr ID appears 103 std::unordered_set< int > vars; 103 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr, Expression *& arg ); 104 104 }; 105 105 … … 162 162 using Parent::previsit; 163 163 164 void previsit( ObjectDecl * objDecl );165 164 void previsit( FunctionDecl * funcDecl ); 166 165 167 void previsit( CompoundStmt * compoundStmt );168 void postvisit( CompoundStmt * compoundStmt );169 void previsit( ReturnStmt * returnStmt );170 166 void previsit( BranchStmt * stmt ); 171 167 private: … … 185 181 186 182 std::list< Declaration * > staticDtorDecls; 187 };188 189 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public WithTypeSubstitution {190 public:191 FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}192 /// expand ImplicitCopyCtorExpr nodes into the temporary declarations, copy constructors, call expression,193 /// and destructors194 static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );195 196 Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr );197 void premutate( StmtExpr * stmtExpr );198 void premutate( UniqueExpr * unqExpr );199 200 UnqCount & unqCount;201 183 }; 202 184 … … 236 218 Expression * postmutate( ConstructorExpr * ctorExpr ); 237 219 }; 220 221 struct SplitExpressions : public WithShortCircuiting, public WithTypeSubstitution, public WithStmtsToAdd { 222 /// add CompoundStmts around top-level expressions so that temporaries are destroyed in the correct places. 223 static void split( std::list< Declaration * > &translationUnit ); 224 225 Statement * postmutate( ExprStmt * stmt ); 226 void premutate( TupleAssignExpr * expr ); 227 }; 238 228 } // namespace 239 229 240 void fix( std::list< Declaration * > & translationUnit, const std::string & filename,bool inLibrary ) {230 void fix( std::list< Declaration * > & translationUnit, bool inLibrary ) { 241 231 PassVisitor<SelfAssignChecker> checker; 242 232 acceptAll( translationUnit, checker ); 243 233 234 // fixes StmtExpr to properly link to their resulting expression 235 StmtExprResult::link( translationUnit ); 236 244 237 // fixes ConstructorInit for global variables. should happen before fixInitializers. 245 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); 246 247 UnqCount unqCount; 238 InitTweak::fixGlobalInit( translationUnit, inLibrary ); 239 240 // must happen before ResolveCopyCtors because temporaries have to be inserted into the correct scope 241 SplitExpressions::split( translationUnit ); 248 242 249 243 InsertImplicitCalls::insert( translationUnit ); 250 ResolveCopyCtors::resolveImplicitCalls( translationUnit, unqCount ); 244 245 // Needs to happen before ResolveCopyCtors, because argument/return temporaries should not be considered in 246 // error checking branch statements 251 247 InsertDtors::insert( translationUnit ); 248 249 ResolveCopyCtors::resolveImplicitCalls( translationUnit ); 252 250 FixInit::fixInitializers( translationUnit ); 253 254 // FixCopyCtors must happen after FixInit, so that destructors are placed correctly255 FixCopyCtors::fixCopyCtors( translationUnit, unqCount );256 257 251 GenStructMemberCalls::generate( translationUnit ); 258 252 259 // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a 260 // hack in the way untyped assignments are generated, where the first argument cannot have 261 // its address taken because of the way codegeneration handles UntypedExpr vs. ApplicationExpr. 262 // Thus such assignment exprs must never pushed through expression resolution (and thus should 263 // not go through the FixCopyCtors pass), otherwise they will fail -- guaranteed. 264 // Also needs to happen after GenStructMemberCalls, since otherwise member constructors exprs 265 // don't look right, and a member can be constructed more than once. 253 // Needs to happen after GenStructMemberCalls, since otherwise member constructors exprs 254 // don't have the correct form, and a member can be constructed more than once. 266 255 FixCtorExprs::fix( translationUnit ); 267 256 } 268 257 269 258 namespace { 259 /// find and return the destructor used in `input`. If `input` is not a simple destructor call, generate a thunk 260 /// that wraps the destructor, insert it into `stmtsToAdd` and return the new function declaration 261 DeclarationWithType * getDtorFunc( ObjectDecl * objDecl, Statement * input, std::list< Statement * > & stmtsToAdd ) { 262 // unwrap implicit statement wrapper 263 Statement * dtor = input; 264 assert( dtor ); 265 std::list< Expression * > matches; 266 collectCtorDtorCalls( dtor, matches ); 267 268 if ( dynamic_cast< ExprStmt * >( dtor ) ) { 269 // only one destructor call in the expression 270 if ( matches.size() == 1 ) { 271 DeclarationWithType * func = getFunction( matches.front() ); 272 assertf( func, "getFunction failed to find function in %s", toString( matches.front() ).c_str() ); 273 274 // cleanup argument must be a function, not an object (including function pointer) 275 if ( FunctionDecl * dtorFunc = dynamic_cast< FunctionDecl * > ( func ) ) { 276 if ( dtorFunc->type->forall.empty() ) { 277 // simple case where the destructor is a monomorphic function call - can simply 278 // use that function as the cleanup function. 279 delete dtor; 280 return func; 281 } 282 } 283 } 284 } 285 286 // otherwise the cleanup is more complicated - need to build a single argument cleanup function that 287 // wraps the more complicated code. 288 static UniqueName dtorNamer( "__cleanup_dtor" ); 289 std::string name = dtorNamer.newName(); 290 FunctionDecl * dtorFunc = FunctionDecl::newFunction( name, SymTab::genDefaultType( objDecl->type->stripReferences(), false ), new CompoundStmt() ); 291 stmtsToAdd.push_back( new DeclStmt( dtorFunc ) ); 292 293 // the original code contains uses of objDecl - replace them with the newly generated 'this' parameter. 294 ObjectDecl * thisParam = getParamThis( dtorFunc->type ); 295 Expression * replacement = new VariableExpr( thisParam ); 296 297 Type * base = replacement->result->stripReferences(); 298 if ( dynamic_cast< ArrayType * >( base ) || dynamic_cast< TupleType * > ( base ) ) { 299 // need to cast away reference for array types, since the destructor is generated without the reference type, 300 // and for tuple types since tuple indexing does not work directly on a reference 301 replacement = new CastExpr( replacement, base->clone() ); 302 } 303 DeclReplacer::replace( dtor, { std::make_pair( objDecl, replacement ) } ); 304 dtorFunc->statements->push_back( strict_dynamic_cast<Statement *>( dtor ) ); 305 306 return dtorFunc; 307 } 308 309 void StmtExprResult::link( std::list< Declaration * > & translationUnit ) { 310 PassVisitor<StmtExprResult> linker; 311 acceptAll( translationUnit, linker ); 312 } 313 314 void SplitExpressions::split( std::list< Declaration * > & translationUnit ) { 315 PassVisitor<SplitExpressions> splitter; 316 mutateAll( translationUnit, splitter ); 317 } 318 270 319 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) { 271 320 PassVisitor<InsertImplicitCalls> inserter; … … 273 322 } 274 323 275 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit , UnqCount & unqCount) {276 PassVisitor<ResolveCopyCtors> resolver ( unqCount );277 acceptAll( translationUnit, resolver );324 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit ) { 325 PassVisitor<ResolveCopyCtors> resolver; 326 mutateAll( translationUnit, resolver ); 278 327 } 279 328 … … 303 352 } 304 353 305 void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {306 PassVisitor<FixCopyCtors> fixer( unqCount );307 mutateAll( translationUnit, fixer );308 }309 310 354 void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) { 311 355 PassVisitor<GenStructMemberCalls> warner; … … 318 362 } 319 363 320 namespace { 321 // Relatively simple structural comparison for expressions, needed to determine 322 // if two expressions are "the same" (used to determine if self assignment occurs) 323 struct StructuralChecker { 324 Expression * stripCasts( Expression * expr ) { 325 // this might be too permissive. It's possible that only particular casts are relevant. 326 while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) { 327 expr = cast->arg; 328 } 329 return expr; 330 } 331 332 void previsit( Expression * ) { 333 // anything else does not qualify 334 isSimilar = false; 335 } 336 337 template<typename T> 338 T * cast( Expression * node ) { 339 // all expressions need to ignore casts, so this bit has been factored out 340 return dynamic_cast< T * >( stripCasts( node ) ); 341 } 342 343 // ignore casts 344 void previsit( CastExpr * ) {} 345 346 void previsit( MemberExpr * memExpr ) { 347 if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) { 348 if ( otherMember->member == memExpr->member ) { 349 other = otherMember->aggregate; 350 return; 351 } 352 } 353 isSimilar = false; 354 } 355 356 void previsit( VariableExpr * varExpr ) { 357 if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) { 358 if ( otherVar->var == varExpr->var ) { 359 return; 360 } 361 } 362 isSimilar = false; 363 } 364 365 void previsit( AddressExpr * ) { 366 if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) { 367 other = addrExpr->arg; 364 void StmtExprResult::previsit( StmtExpr * stmtExpr ) { 365 // we might loose the result expression here so add a pointer to trace back 366 assert( stmtExpr->result ); 367 Type * result = stmtExpr->result; 368 if ( ! result->isVoid() ) { 369 CompoundStmt * body = stmtExpr->statements; 370 assert( ! body->kids.empty() ); 371 stmtExpr->resultExpr = strict_dynamic_cast< ExprStmt * >( body->kids.back() ); 372 } 373 } 374 375 Statement * SplitExpressions::postmutate( ExprStmt * stmt ) { 376 // wrap each top-level ExprStmt in a block so that destructors for argument and return temporaries are destroyed 377 // in the correct places 378 CompoundStmt * ret = new CompoundStmt( { stmt } ); 379 return ret; 380 } 381 382 void SplitExpressions::premutate( TupleAssignExpr * ) { 383 // don't do this within TupleAssignExpr, since it is already broken up into multiple expressions 384 visit_children = false; 385 } 386 387 // Relatively simple structural comparison for expressions, needed to determine 388 // if two expressions are "the same" (used to determine if self assignment occurs) 389 struct StructuralChecker { 390 Expression * stripCasts( Expression * expr ) { 391 // this might be too permissive. It's possible that only particular casts are relevant. 392 while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) { 393 expr = cast->arg; 394 } 395 return expr; 396 } 397 398 void previsit( Expression * ) { 399 // anything else does not qualify 400 isSimilar = false; 401 } 402 403 template<typename T> 404 T * cast( Expression * node ) { 405 // all expressions need to ignore casts, so this bit has been factored out 406 return dynamic_cast< T * >( stripCasts( node ) ); 407 } 408 409 // ignore casts 410 void previsit( CastExpr * ) {} 411 412 void previsit( MemberExpr * memExpr ) { 413 if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) { 414 if ( otherMember->member == memExpr->member ) { 415 other = otherMember->aggregate; 368 416 return; 369 417 } 370 isSimilar = false; 371 } 372 373 Expression * other = nullptr; 374 bool isSimilar = true; 375 }; 376 377 bool structurallySimilar( Expression * e1, Expression * e2 ) { 378 PassVisitor<StructuralChecker> checker; 379 checker.pass.other = e2; 380 e1->accept( checker ); 381 return checker.pass.isSimilar; 382 } 418 } 419 isSimilar = false; 420 } 421 422 void previsit( VariableExpr * varExpr ) { 423 if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) { 424 if ( otherVar->var == varExpr->var ) { 425 return; 426 } 427 } 428 isSimilar = false; 429 } 430 431 void previsit( AddressExpr * ) { 432 if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) { 433 other = addrExpr->arg; 434 return; 435 } 436 isSimilar = false; 437 } 438 439 Expression * other = nullptr; 440 bool isSimilar = true; 441 }; 442 443 bool structurallySimilar( Expression * e1, Expression * e2 ) { 444 PassVisitor<StructuralChecker> checker; 445 checker.pass.other = e2; 446 e1->accept( checker ); 447 return checker.pass.isSimilar; 383 448 } 384 449 … … 457 522 if ( TupleAssignExpr * assign = dynamic_cast< TupleAssignExpr * >( resolved ) ) { 458 523 // fix newly generated StmtExpr 459 p ostvisit( assign->stmtExpr );524 premutate( assign->stmtExpr ); 460 525 } 461 526 return resolved; … … 489 554 // so that the object isn't changed inside of the polymorphic function 490 555 if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return; 556 // xxx - leaking tmp 491 557 } 492 558 } … … 496 562 497 563 // replace argument to function call with temporary 498 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 499 impCpCtorExpr->tempDecls.push_back( tmp ); 500 impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) ); 501 } 502 503 void ResolveCopyCtors::destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) { 504 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) ); 505 } 506 507 void ResolveCopyCtors::postvisit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 564 stmtsToAddBefore.push_back( new DeclStmt( tmp ) ); 565 arg = cpCtor; 566 destructRet( tmp, impCpCtorExpr, arg ); 567 568 // impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) ); 569 } 570 571 void ResolveCopyCtors::destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * /*impCpCtorExpr*/, Expression *& arg ) { 572 // TODO: refactor code for generating cleanup attribute, since it's common and reused in ~3-4 places 573 // check for existing cleanup attribute before adding another(?) 574 // need to add __Destructor for _tmp_cp variables as well 575 576 assertf( Validate::dtorStruct && Validate::dtorStruct->members.size() == 2, "Destructor generation requires __Destructor definition." ); 577 assertf( Validate::dtorStructDestroy, "Destructor generation requires __destroy_Destructor." ); 578 579 // generate a __Destructor for ret that calls the destructor 580 Expression * dtor = makeCtorDtor( "^?{}", ret ); 581 582 // if the chosen destructor is intrinsic, elide the generated dtor handler 583 if ( arg && isIntrinsicCallExpr( dtor ) ) { 584 arg = new CommaExpr( arg, new VariableExpr( ret ) ); 585 return; 586 } 587 588 if ( ! dtor->env ) dtor->env = maybeClone( env ); 589 DeclarationWithType * dtorFunc = getDtorFunc( ret, new ExprStmt( dtor ), stmtsToAddBefore ); 590 591 StructInstType * dtorStructType = new StructInstType( Type::Qualifiers(), Validate::dtorStruct ); 592 dtorStructType->parameters.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 593 594 // cast destructor pointer to void (*)(void *), to silence GCC incompatible pointer warnings 595 FunctionType * dtorFtype = new FunctionType( Type::Qualifiers(), false ); 596 dtorFtype->parameters.push_back( ObjectDecl::newObject( "", new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), nullptr ) ); 597 Type * dtorType = new PointerType( Type::Qualifiers(), dtorFtype ); 598 599 static UniqueName namer( "_ret_dtor" ); 600 ObjectDecl * retDtor = ObjectDecl::newObject( namer.newName(), dtorStructType, new ListInit( { new SingleInit( new ConstantExpr( Constant::null() ) ), new SingleInit( new CastExpr( new VariableExpr( dtorFunc ), dtorType ) ) } ) ); 601 retDtor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( Validate::dtorStructDestroy ) } ) ); 602 stmtsToAddBefore.push_back( new DeclStmt( retDtor ) ); 603 604 if ( arg ) { 605 Expression * member = new MemberExpr( strict_dynamic_cast<DeclarationWithType *>( Validate::dtorStruct->members.front() ), new VariableExpr( retDtor ) ); 606 Expression * object = new CastExpr( new AddressExpr( new VariableExpr( ret ) ), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ); 607 Expression * assign = createBitwiseAssignment( member, object ); 608 arg = new CommaExpr( new CommaExpr( arg, assign ), new VariableExpr( ret ) ); 609 } 610 611 // impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) ); 612 } 613 614 Expression * ResolveCopyCtors::postmutate( ImplicitCopyCtorExpr *impCpCtorExpr ) { 508 615 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 509 616 510 617 ApplicationExpr * appExpr = impCpCtorExpr->callExpr; 618 ObjectDecl * returnDecl = nullptr; 511 619 512 620 // take each argument and attempt to copy construct it. … … 517 625 for ( Expression * & arg : appExpr->args ) { 518 626 Type * formal = nullptr; 519 if ( iter != params.end() ) { 627 if ( iter != params.end() ) { // does not copy construct C-style variadic arguments 520 628 DeclarationWithType * param = *iter++; 521 629 formal = param->get_type(); … … 535 643 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr ); 536 644 ret->type->set_const( false ); 537 impCpCtorExpr->returnDecls.push_back( ret ); 645 returnDecl = ret; 646 stmtsToAddBefore.push_back( new DeclStmt( ret ) ); 538 647 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 648 } // for 649 CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; ) 650 // ------------------------------------------------------ 651 652 CP_CTOR_PRINT( std::cerr << "Coming out the back..." << impCpCtorExpr << std::endl; ) 653 654 // detach fields from wrapper node so that it can be deleted without deleting too much 655 impCpCtorExpr->callExpr = nullptr; 656 std::swap( impCpCtorExpr->env, appExpr->env ); 657 assert( impCpCtorExpr->env == nullptr ); 658 delete impCpCtorExpr; 659 660 if ( returnDecl ) { 661 Expression * assign = createBitwiseAssignment( new VariableExpr( returnDecl ), appExpr ); 539 662 if ( ! dynamic_cast< ReferenceType * >( result ) ) { 540 663 // destructing reference returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary 541 destructRet( ret, impCpCtorExpr ); 542 } 664 destructRet( returnDecl, impCpCtorExpr, assign ); 665 } else { 666 assign = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 667 } 668 // move env from appExpr to retExpr 669 std::swap( assign->env, appExpr->env ); 670 return assign; 671 } else { 672 return appExpr; 673 } // if 674 } 675 676 void ResolveCopyCtors::premutate( StmtExpr * stmtExpr ) { 677 // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression, 678 // since temporaries can be shared across sub-expressions, e.g. 679 // [A, A] f(); // decl 680 // g([A] x, [A] y); // decl 681 // g(f()); // call 682 // f is executed once, so the return temporary is shared across the tuple constructors for x and y. 683 // Explicitly mutating children instead of mutating the inner compound statement forces the temporaries to be added 684 // to the outer context, rather than inside of the statement expression. 685 visit_children = false; 686 687 assert( env ); 688 689 indexer.enterScope(); 690 // visit all statements 691 std::list< Statement * > & stmts = stmtExpr->statements->get_kids(); 692 for ( Statement *& stmt : stmts ) { 693 stmt = stmt->acceptMutator( *visitor ); 543 694 } // for 544 CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; ) 545 } 546 547 void ResolveCopyCtors::postvisit( StmtExpr * stmtExpr ) { 548 assert( env ); 549 assert( stmtExpr->get_result() ); 550 Type * result = stmtExpr->get_result(); 695 indexer.leaveScope(); 696 697 assert( stmtExpr->result ); 698 Type * result = stmtExpr->result; 551 699 if ( ! result->isVoid() ) { 552 700 static UniqueName retNamer("_tmp_stmtexpr_ret"); … … 562 710 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr ); 563 711 ret->type->set_const( false ); 564 stmtExpr->returnDecls.push_front( ret ); 712 stmtsToAddBefore.push_back( new DeclStmt( ret ) ); 713 714 assertf( 715 stmtExpr->resultExpr, 716 "Statement-Expression should have a resulting expression at %s:%d", 717 stmtExpr->location.filename.c_str(), 718 stmtExpr->location.first_line 719 ); 720 721 ExprStmt * last = stmtExpr->resultExpr; 722 try { 723 last->expr = makeCtorDtor( "?{}", ret, last->expr ); 724 } catch(...) { 725 std::cerr << "*CFA internal error: "; 726 std::cerr << "can't resolve implicit constructor"; 727 std::cerr << " at " << stmtExpr->location.filename; 728 std::cerr << ":" << stmtExpr->location.first_line << std::endl; 729 730 abort(); 731 } 732 733 // add destructors after current statement 734 stmtsToAddAfter.push_back( new ExprStmt( makeCtorDtor( "^?{}", ret ) ) ); 565 735 566 736 // must have a non-empty body, otherwise it wouldn't have a result 567 CompoundStmt * body = stmtExpr->statements; 568 assert( ! body->get_kids().empty() ); 569 // must be an ExprStmt, otherwise it wouldn't have a result 570 ExprStmt * last = strict_dynamic_cast< ExprStmt * >( body->get_kids().back() ); 571 last->expr = makeCtorDtor( "?{}", ret, last->get_expr() ); 572 573 stmtExpr->dtors.push_front( makeCtorDtor( "^?{}", ret ) ); 737 assert( ! stmts.empty() ); 738 739 // if there is a return decl, add a use as the last statement; will not have return decl on non-constructable returns 740 stmts.push_back( new ExprStmt( new VariableExpr( ret ) ) ); 574 741 } // if 575 } 576 577 void ResolveCopyCtors::previsit( UniqueExpr * unqExpr ) { 578 unqCount[ unqExpr->get_id() ]++; // count the number of unique expressions for each ID 579 if ( vars.count( unqExpr->get_id() ) ) { 580 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated 581 visit_children = false; 582 } 742 743 assert( stmtExpr->returnDecls.empty() ); 744 assert( stmtExpr->dtors.empty() ); 583 745 } 584 746 … … 597 759 } 598 760 599 void ResolveCopyCtors::postvisit( UniqueExpr * unqExpr ) { 600 if ( vars.count( unqExpr->get_id() ) ) { 601 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated 602 return; 603 } 604 605 // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought 606 assert( unqExpr->get_result() ); 607 if ( ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast<ImplicitCopyCtorExpr*>( unqExpr->get_expr() ) ) { 608 // note the variable used as the result from the call 609 assert( impCpCtorExpr->get_result() && impCpCtorExpr->get_returnDecls().size() == 1 ); 610 unqExpr->set_var( new VariableExpr( impCpCtorExpr->get_returnDecls().front() ) ); 761 void ResolveCopyCtors::premutate( UniqueExpr * unqExpr ) { 762 visit_children = false; 763 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated 764 static std::unordered_map< int, UniqueExpr * > unqMap; 765 if ( ! unqMap.count( unqExpr->get_id() ) ) { 766 // resolve expr and find its 767 768 ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( unqExpr->expr ); 769 // PassVisitor<ResolveCopyCtors> fixer; 770 unqExpr->expr = unqExpr->expr->acceptMutator( *visitor ); 771 772 // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought 773 assert( unqExpr->result ); 774 if ( impCpCtorExpr ) { 775 CommaExpr * comma = strict_dynamic_cast< CommaExpr * >( unqExpr->expr ); 776 VariableExpr * var = strict_dynamic_cast<VariableExpr *>( comma->arg2 ); 777 // note the variable used as the result from the call 778 unqExpr->var = var->clone(); 779 } else { 780 // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression 781 unqExpr->object = ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->result->clone(), makeInit( unqExpr->result ) ); 782 unqExpr->var = new VariableExpr( unqExpr->object ); 783 } 784 785 // stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore ); 786 // stmtsToAddAfter.splice( stmtsToAddAfter.end(), fixer.pass.stmtsToAddAfter ); 787 unqMap[unqExpr->get_id()] = unqExpr; 611 788 } else { 612 // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression613 unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), makeInit( unqExpr->get_result() ) ) );614 unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );615 }616 vars.insert( unqExpr->get_id() );617 }618 619 Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {620 CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )621 622 std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();623 std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();624 std::list< Expression * > & dtors = impCpCtorExpr->get_dtors();625 626 // add all temporary declarations and their constructors627 for ( ObjectDecl * obj : tempDecls ) {628 stmtsToAddBefore.push_back( new DeclStmt( obj ) );629 } // for630 for ( ObjectDecl * obj : returnDecls ) {631 stmtsToAddBefore.push_back( new DeclStmt( obj ) );632 } // for633 634 // add destructors after current statement635 for ( Expression * dtor : dtors ) {636 // take relevant bindings from environment637 assert( ! dtor->env );638 dtor->env = maybeClone( env );639 stmtsToAddAfter.push_back( new ExprStmt( dtor ) );640 } // for641 642 ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();643 Expression * callExpr = impCpCtorExpr->get_callExpr();644 645 CP_CTOR_PRINT( std::cerr << "Coming out the back..." << impCpCtorExpr << std::endl; )646 647 // detach fields from wrapper node so that it can be deleted without deleting too much648 dtors.clear();649 tempDecls.clear();650 returnDecls.clear();651 impCpCtorExpr->set_callExpr( nullptr );652 std::swap( impCpCtorExpr->env, callExpr->env );653 assert( impCpCtorExpr->env == nullptr );654 delete impCpCtorExpr;655 656 if ( returnDecl ) {657 ApplicationExpr * assign = createBitwiseAssignment( new VariableExpr( returnDecl ), callExpr );658 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );659 // move env from callExpr to retExpr660 std::swap( retExpr->env, callExpr->env );661 return retExpr;662 } else {663 return callExpr;664 } // if665 }666 667 void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {668 // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,669 // since temporaries can be shared across sub-expressions, e.g.670 // [A, A] f();671 // g([A] x, [A] y);672 // g(f());673 // f is executed once, so the return temporary is shared across the tuple constructors for x and y.674 // Explicitly mutating children instead of mutating the inner compound statment forces the temporaries to be added675 // to the outer context, rather than inside of the statement expression.676 visit_children = false;677 std::list< Statement * > & stmts = stmtExpr->statements->get_kids();678 for ( Statement *& stmt : stmts ) {679 stmt = stmt->acceptMutator( *visitor );680 } // for681 assert( stmtExpr->result );682 Type * result = stmtExpr->result;683 if ( ! result->isVoid() ) {684 for ( ObjectDecl * obj : stmtExpr->returnDecls ) {685 stmtsToAddBefore.push_back( new DeclStmt( obj ) );686 } // for687 // add destructors after current statement688 for ( Expression * dtor : stmtExpr->dtors ) {689 stmtsToAddAfter.push_back( new ExprStmt( dtor ) );690 } // for691 // must have a non-empty body, otherwise it wouldn't have a result692 assert( ! stmts.empty() );693 assertf( ! stmtExpr->returnDecls.empty() || stmtExpr->dtors.empty(), "StmtExpr returns non-void, but no return decls: %s", toString( stmtExpr ).c_str() );694 // if there is a return decl, add a use as the last statement; will not have return decl on non-constructable returns695 if ( ! stmtExpr->returnDecls.empty() ) {696 stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->returnDecls.front() ) ) );697 }698 stmtExpr->returnDecls.clear();699 stmtExpr->dtors.clear();700 }701 assert( stmtExpr->returnDecls.empty() );702 assert( stmtExpr->dtors.empty() );703 }704 705 void FixCopyCtors::premutate( UniqueExpr * unqExpr ) {706 visit_children = false;707 unqCount[ unqExpr->get_id() ]--;708 static std::unordered_map< int, std::list< Statement * > > dtors;709 static std::unordered_map< int, UniqueExpr * > unqMap;710 // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes711 if ( unqMap.count( unqExpr->get_id() ) ) {712 789 // take data from other UniqueExpr to ensure consistency 713 790 delete unqExpr->get_expr(); 714 unqExpr->set_expr( unqMap[unqExpr->get_id()]->get_expr()->clone() ); 715 delete unqExpr->get_result(); 716 unqExpr->set_result( maybeClone( unqExpr->get_expr()->get_result() ) ); 717 if ( unqCount[ unqExpr->get_id() ] == 0 ) { // insert destructor after the last use of the unique expression 718 stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] ); 719 } 720 return; 721 } 722 PassVisitor<FixCopyCtors> fixer( unqCount ); 723 unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup 724 stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore ); 725 unqMap[unqExpr->get_id()] = unqExpr; 726 if ( unqCount[ unqExpr->get_id() ] == 0 ) { // insert destructor after the last use of the unique expression 727 stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] ); 728 } else { // remember dtors for last instance of unique expr 729 dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter; 730 } 731 return; 791 unqExpr->expr = unqMap[unqExpr->get_id()]->expr->clone(); 792 delete unqExpr->result; 793 unqExpr->result = maybeClone( unqExpr->expr->result ); 794 } 732 795 } 733 796 … … 844 907 ctorInit->ctor = nullptr; 845 908 } 909 910 Statement * dtor = ctorInit->dtor; 911 if ( dtor ) { 912 ImplicitCtorDtorStmt * implicit = strict_dynamic_cast< ImplicitCtorDtorStmt * >( dtor ); 913 Statement * dtorStmt = implicit->callStmt; 914 915 // don't need to call intrinsic dtor, because it does nothing, but 916 // non-intrinsic dtors must be called 917 if ( ! isIntrinsicSingleArgCallStmt( dtorStmt ) ) { 918 // set dtor location to the object's location for error messages 919 DeclarationWithType * dtorFunc = getDtorFunc( objDecl, dtorStmt, stmtsToAddBefore ); 920 objDecl->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( dtorFunc ) } ) ); 921 ctorInit->dtor = nullptr; 922 } // if 923 } 846 924 } // if 847 925 } else if ( Initializer * init = ctorInit->init ) { … … 886 964 887 965 888 template<typename Iterator, typename OutputIterator>889 void insertDtors( Iterator begin, Iterator end, OutputIterator out ) {890 for ( Iterator it = begin ; it != end ; ++it ) {891 // extract destructor statement from the object decl and insert it into the output. Note that this is892 // only called on lists of non-static objects with implicit non-intrinsic dtors, so if the user manually893 // calls an intrinsic dtor then the call must (and will) still be generated since the argument may894 // contain side effects.895 ObjectDecl * objDecl = *it;896 ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() );897 assert( ctorInit && ctorInit->get_dtor() );898 *out++ = ctorInit->get_dtor()->clone();899 } // for900 }901 902 void InsertDtors::previsit( ObjectDecl * objDecl ) {903 // remember non-static destructed objects so that their destructors can be inserted later904 if ( ! objDecl->get_storageClasses().is_static ) {905 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {906 // a decision should have been made by the resolver, so ctor and init are not both non-NULL907 assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );908 Statement * dtor = ctorInit->get_dtor();909 // don't need to call intrinsic dtor, because it does nothing, but910 // non-intrinsic dtors must be called911 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {912 // set dtor location to the object's location for error messages913 ctorInit->dtor->location = objDecl->location;914 reverseDeclOrder.front().push_front( objDecl );915 } // if916 } // if917 } // if918 }919 920 966 void InsertDtors::previsit( FunctionDecl * funcDecl ) { 921 967 // each function needs to have its own set of labels … … 930 976 } 931 977 932 void InsertDtors::previsit( CompoundStmt * compoundStmt ) {933 // visit statements - this will also populate reverseDeclOrder list. don't want to dump all destructors934 // when block is left, just the destructors associated with variables defined in this block, so push a new935 // list to the top of the stack so that we can differentiate scopes936 reverseDeclOrder.push_front( OrderedDecls() );937 Parent::previsit( compoundStmt );938 }939 940 void InsertDtors::postvisit( CompoundStmt * compoundStmt ) {941 // add destructors for the current scope that we're exiting, unless the last statement is a return, which942 // causes unreachable code warnings943 std::list< Statement * > & statements = compoundStmt->get_kids();944 if ( ! statements.empty() && ! dynamic_cast< ReturnStmt * >( statements.back() ) ) {945 insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) );946 }947 reverseDeclOrder.pop_front();948 }949 950 void InsertDtors::previsit( ReturnStmt * ) {951 // return exits all scopes, so dump destructors for all scopes952 for ( OrderedDecls & od : reverseDeclOrder ) {953 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) );954 } // for955 }956 957 978 // Handle break/continue/goto in the same manner as C++. Basic idea: any objects that are in scope at the 958 979 // BranchStmt but not at the labelled (target) statement must be destructed. If there are any objects in scope … … 973 994 std::cerr << "S_L = " << printSet( lvars ) << std::endl; 974 995 ) 996 997 998 // std::set_difference requires that the inputs be sorted. 999 lvars.sort(); 1000 curVars.sort(); 975 1001 976 1002 ObjectSet diff; … … 982 1008 if ( ! diff.empty() ) { 983 1009 SemanticError( stmt, std::string("jump to label '") + stmt->get_target().get_name() + "' crosses initialization of " + (*diff.begin())->get_name() + " " ); 984 } // if985 // S_G-S_L results in set of objects that must be destructed986 diff.clear();987 std::set_difference( curVars.begin(), curVars.end(), lvars.begin(), lvars.end(), std::inserter( diff, diff.end() ) );988 DTOR_PRINT(989 std::cerr << "S_G-S_L = " << printSet( diff ) << std::endl;990 )991 if ( ! diff.empty() ) {992 // create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages.993 std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() );994 995 // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor996 OrderedDecls ordered;997 for ( OrderedDecls & rdo : reverseDeclOrder ) {998 // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.999 copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );1000 } // for1001 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) );1002 1010 } // if 1003 1011 } … … 1103 1111 arg2 = new MemberExpr( field, new VariableExpr( params.back() ) ); 1104 1112 } 1105 InitExpander srcParam( arg2 );1113 InitExpander_old srcParam( arg2 ); 1106 1114 // cast away reference type and construct field. 1107 1115 Expression * thisExpr = new CastExpr( new VariableExpr( thisParam ), thisParam->get_type()->stripReferences()->clone() ); … … 1116 1124 callStmt->acceptMutator( *visitor ); 1117 1125 if ( isCtor ) { 1118 function-> get_statements()->push_front( callStmt );1119 } else { 1126 function->statements->push_front( callStmt ); 1127 } else { // TODO: don't generate destructor function/object for intrinsic calls 1120 1128 // destructor statements should be added at the end 1121 function->get_statements()->push_back( callStmt ); 1129 // function->get_statements()->push_back( callStmt ); 1130 1131 // Optimization: do not need to call intrinsic destructors on members 1132 if ( isIntrinsicSingleArgCallStmt( callStmt ) ) continue;; 1133 1134 // __Destructor _dtor0 = { (void *)&b.a1, (void (*)(void *)_destroy_A }; 1135 std::list< Statement * > stmtsToAdd; 1136 1137 static UniqueName memberDtorNamer = { "__memberDtor" }; 1138 assertf( Validate::dtorStruct, "builtin __Destructor not found." ); 1139 assertf( Validate::dtorStructDestroy, "builtin __destroy_Destructor not found." ); 1140 1141 Expression * thisExpr = new CastExpr( new AddressExpr( new VariableExpr( thisParam ) ), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ); 1142 Expression * dtorExpr = new VariableExpr( getDtorFunc( thisParam, callStmt, stmtsToAdd ) ); 1143 1144 // cast destructor pointer to void (*)(void *), to silence GCC incompatible pointer warnings 1145 FunctionType * dtorFtype = new FunctionType( Type::Qualifiers(), false ); 1146 dtorFtype->parameters.push_back( ObjectDecl::newObject( "", new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), nullptr ) ); 1147 Type * dtorType = new PointerType( Type::Qualifiers(), dtorFtype ); 1148 1149 ObjectDecl * destructor = ObjectDecl::newObject( memberDtorNamer.newName(), new StructInstType( Type::Qualifiers(), Validate::dtorStruct ), new ListInit( { new SingleInit( thisExpr ), new SingleInit( new CastExpr( dtorExpr, dtorType ) ) } ) ); 1150 function->statements->push_front( new DeclStmt( destructor ) ); 1151 destructor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( Validate::dtorStructDestroy ) } ) ); 1152 1153 function->statements->kids.splice( function->statements->kids.begin(), stmtsToAdd ); 1122 1154 } 1123 1155 } catch ( SemanticErrorException & error ) { … … 1163 1195 1164 1196 std::string fname = getFunctionName( appExpr ); 1165 if ( fname == function-> get_name()) {1197 if ( fname == function->name ) { 1166 1198 // call to same kind of function 1167 Expression * firstParam = appExpr-> get_args().front();1199 Expression * firstParam = appExpr->args.front(); 1168 1200 1169 1201 if ( isThisExpression( firstParam, thisParam ) ) { … … 1174 1206 // if first parameter is a member expression on the this parameter, 1175 1207 // then remove the member from unhandled set. 1176 if ( isThisExpression( memberExpr-> get_aggregate(), thisParam ) ) {1177 unhandled.erase( memberExpr-> get_member());1208 if ( isThisExpression( memberExpr->aggregate, thisParam ) ) { 1209 unhandled.erase( memberExpr->member ); 1178 1210 } 1179 1211 } -
src/InitTweak/FixInit.h
r7951100 rb067d9b 24 24 /// replace constructor initializers with expression statements 25 25 /// and unwrap basic C-style initializers 26 void fix( std::list< Declaration * > & translationUnit, const std::string & name,bool inLibrary );26 void fix( std::list< Declaration * > & translationUnit, bool inLibrary ); 27 27 } // namespace 28 28 -
src/InitTweak/GenInit.cc
r7951100 rb067d9b 15 15 #include "GenInit.h" 16 16 17 #include <stddef.h> // for NULL 18 #include <algorithm> // for any_of 19 #include <cassert> // for assert, strict_dynamic_cast, assertf 20 #include <iterator> // for back_inserter, inserter, back_inse... 21 #include <list> // for _List_iterator, list 22 17 #include <stddef.h> // for NULL 18 #include <algorithm> // for any_of 19 #include <cassert> // for assert, strict_dynamic_cast, assertf 20 #include <deque> 21 #include <iterator> // for back_inserter, inserter, back_inse... 22 #include <list> // for _List_iterator, list 23 24 #include "AST/Decl.hpp" 25 #include "AST/Init.hpp" 26 #include "AST/Node.hpp" 27 #include "AST/Stmt.hpp" 23 28 #include "CodeGen/OperatorTable.h" 24 #include "Common/PassVisitor.h" // for PassVisitor, WithGuards, WithShort...25 #include "Common/SemanticError.h" // for SemanticError26 #include "Common/UniqueName.h" // for UniqueName27 #include "Common/utility.h" // for ValueGuard, maybeClone28 #include "GenPoly/GenPoly.h" // for getFunctionType, isPolyType29 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::const_iter...30 #include "InitTweak.h" // for isConstExpr, InitExpander, checkIn...31 #include "Parser/LinkageSpec.h" // for isOverridable, C29 #include "Common/PassVisitor.h" // for PassVisitor, WithGuards, WithShort... 30 #include "Common/SemanticError.h" // for SemanticError 31 #include "Common/UniqueName.h" // for UniqueName 32 #include "Common/utility.h" // for ValueGuard, maybeClone 33 #include "GenPoly/GenPoly.h" // for getFunctionType, isPolyType 34 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::const_iter... 35 #include "InitTweak.h" // for isConstExpr, InitExpander, checkIn... 36 #include "Parser/LinkageSpec.h" // for isOverridable, C 32 37 #include "ResolvExpr/Resolver.h" 33 #include "SymTab/Autogen.h" // for genImplicitCall, SizeType 34 #include "SymTab/Mangler.h" // for Mangler 35 #include "SynTree/Declaration.h" // for ObjectDecl, DeclarationWithType 36 #include "SynTree/Expression.h" // for VariableExpr, UntypedExpr, Address... 37 #include "SynTree/Initializer.h" // for ConstructorInit, SingleInit, Initi... 38 #include "SynTree/Label.h" // for Label 39 #include "SynTree/Mutator.h" // for mutateAll 40 #include "SynTree/Statement.h" // for CompoundStmt, ImplicitCtorDtorStmt 41 #include "SynTree/Type.h" // for Type, ArrayType, Type::Qualifiers 42 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 43 #include "Tuples/Tuples.h" // for maybeImpure 38 #include "SymTab/Autogen.h" // for genImplicitCall 39 #include "SymTab/Mangler.h" // for Mangler 40 #include "SynTree/Declaration.h" // for ObjectDecl, DeclarationWithType 41 #include "SynTree/Expression.h" // for VariableExpr, UntypedExpr, Address... 42 #include "SynTree/Initializer.h" // for ConstructorInit, SingleInit, Initi... 43 #include "SynTree/Label.h" // for Label 44 #include "SynTree/Mutator.h" // for mutateAll 45 #include "SynTree/Statement.h" // for CompoundStmt, ImplicitCtorDtorStmt 46 #include "SynTree/Type.h" // for Type, ArrayType, Type::Qualifiers 47 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 48 #include "Tuples/Tuples.h" // for maybeImpure 49 #include "Validate/FindSpecialDecls.h" // for SizeType 44 50 45 51 namespace InitTweak { … … 186 192 187 193 // need to resolve array dimensions in order to accurately determine if constexpr 188 ResolvExpr::findSingleExpression( arrayType->dimension, SymTab::SizeType->clone(), indexer );194 ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer ); 189 195 // array is variable-length when the dimension is not constexpr 190 196 arrayType->isVarLen = ! isConstExpr( arrayType->dimension ); … … 192 198 if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return; 193 199 194 ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );200 ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) ); 195 201 arrayDimension->get_type()->set_const( true ); 196 202 … … 273 279 assertf( objDecl, "genCtorDtor passed null objDecl" ); 274 280 std::list< Statement * > stmts; 275 InitExpander srcParam( maybeClone( arg ) );281 InitExpander_old srcParam( maybeClone( arg ) ); 276 282 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl ); 277 283 assert( stmts.size() <= 1 ); … … 285 291 std::list< Statement * > dtor; 286 292 287 InitExpander srcParam( objDecl->get_init() );288 InitExpander nullParam( (Initializer *)NULL );293 InitExpander_old srcParam( objDecl->get_init() ); 294 InitExpander_old nullParam( (Initializer *)NULL ); 289 295 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 290 296 SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); … … 352 358 GuardScope( managedTypes ); 353 359 } 360 361 ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ) { 362 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor for each 363 // constructable object 364 InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr }; 365 366 ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall( 367 srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl ); 368 ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall( 369 nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl, 370 SymTab::LoopBackward ); 371 372 // check that either both ctor and dtor are present, or neither 373 assert( (bool)ctor == (bool)dtor ); 374 375 if ( ctor ) { 376 // need to remember init expression, in case no ctors exist. If ctor does exist, want to 377 // use ctor expression instead of init. 378 ctor.strict_as< ast::ImplicitCtorDtorStmt >(); 379 dtor.strict_as< ast::ImplicitCtorDtorStmt >(); 380 381 return new ast::ConstructorInit{ loc, ctor, dtor, objDecl->init }; 382 } 383 384 return nullptr; 385 } 386 354 387 } // namespace InitTweak 355 388 -
src/InitTweak/GenInit.h
r7951100 rb067d9b 19 19 #include <string> // for string 20 20 21 #include "AST/Fwd.hpp" 22 #include "Common/CodeLocation.h" 23 #include "GenPoly/ScopedSet.h" // for ScopedSet 21 24 #include "SynTree/SynTree.h" // for Visitor Nodes 22 23 #include "GenPoly/ScopedSet.h" // for ScopedSet24 25 25 26 namespace InitTweak { … … 35 36 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer 36 37 ConstructorInit * genCtorInit( ObjectDecl * objDecl ); 38 ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ); 37 39 38 40 class ManagedTypes { -
src/InitTweak/InitTweak.cc
r7951100 rb067d9b 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo 3 // 4 // The contents of this file are covered under the licence agreement in the 5 // file "LICENCE" distributed with Cforall. 6 // 7 // InitTweak.cc -- 8 // 9 // Author : Rob Schluntz 10 // Created On : Fri May 13 11:26:36 2016 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:21:48 2019 13 // Update Count : 7 14 // 15 1 16 #include <algorithm> // for find, all_of 2 17 #include <cassert> // for assertf, assert, strict_dynamic_cast … … 4 19 #include <iterator> // for back_insert_iterator, back_inserter 5 20 #include <memory> // for __shared_ptr 6 21 #include <vector> 22 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp" 25 #include "AST/Node.hpp" 26 #include "AST/Pass.hpp" 27 #include "AST/Stmt.hpp" 28 #include "AST/Type.hpp" 7 29 #include "Common/PassVisitor.h" 8 30 #include "Common/SemanticError.h" // for SemanticError … … 26 48 #include "Tuples/Tuples.h" // for Tuples::isTtype 27 49 28 class UntypedValofExpr;29 30 50 namespace InitTweak { 31 51 namespace { … … 67 87 }; 68 88 69 struct InitFlattener : public WithShortCircuiting {89 struct InitFlattener_old : public WithShortCircuiting { 70 90 void previsit( SingleInit * singleInit ) { 71 91 visit_children = false; … … 75 95 }; 76 96 77 } 97 struct InitFlattener_new : public ast::WithShortCircuiting { 98 std::vector< ast::ptr< ast::Expr > > argList; 99 100 void previsit( const ast::SingleInit * singleInit ) { 101 visit_children = false; 102 argList.emplace_back( singleInit->value ); 103 } 104 }; 105 106 } // anonymous namespace 78 107 79 108 std::list< Expression * > makeInitList( Initializer * init ) { 80 PassVisitor<InitFlattener > flattener;109 PassVisitor<InitFlattener_old> flattener; 81 110 maybeAccept( init, flattener ); 82 111 return flattener.pass.argList; … … 95 124 } 96 125 97 class InitExpander::ExpanderImpl { 126 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) { 127 ast::Pass< InitFlattener_new > flattener; 128 maybe_accept( init, flattener ); 129 return std::move( flattener.pass.argList ); 130 } 131 132 class InitExpander_old::ExpanderImpl { 98 133 public: 99 134 virtual ~ExpanderImpl() = default; … … 102 137 }; 103 138 104 class InitImpl : public InitExpander::ExpanderImpl {139 class InitImpl_old : public InitExpander_old::ExpanderImpl { 105 140 public: 106 InitImpl ( Initializer * init ) : init( init ) {}107 virtual ~InitImpl () = default;141 InitImpl_old( Initializer * init ) : init( init ) {} 142 virtual ~InitImpl_old() = default; 108 143 109 144 virtual std::list< Expression * > next( __attribute((unused)) std::list< Expression * > & indices ) { … … 119 154 }; 120 155 121 class ExprImpl : public InitExpander::ExpanderImpl {156 class ExprImpl_old : public InitExpander_old::ExpanderImpl { 122 157 public: 123 ExprImpl ( Expression * expr ) : arg( expr ) {}124 virtual ~ExprImpl () { delete arg; }158 ExprImpl_old( Expression * expr ) : arg( expr ) {} 159 virtual ~ExprImpl_old() { delete arg; } 125 160 126 161 virtual std::list< Expression * > next( std::list< Expression * > & indices ) { … … 146 181 }; 147 182 148 InitExpander ::InitExpander( Initializer * init ) : expander( new InitImpl( init ) ) {}149 150 InitExpander ::InitExpander( Expression * expr ) : expander( new ExprImpl( expr ) ) {}151 152 std::list< Expression * > InitExpander ::operator*() {183 InitExpander_old::InitExpander_old( Initializer * init ) : expander( new InitImpl_old( init ) ) {} 184 185 InitExpander_old::InitExpander_old( Expression * expr ) : expander( new ExprImpl_old( expr ) ) {} 186 187 std::list< Expression * > InitExpander_old::operator*() { 153 188 return cur; 154 189 } 155 190 156 InitExpander & InitExpander::operator++() {191 InitExpander_old & InitExpander_old::operator++() { 157 192 cur = expander->next( indices ); 158 193 return *this; … … 160 195 161 196 // use array indices list to build switch statement 162 void InitExpander ::addArrayIndex( Expression * index, Expression * dimension ) {197 void InitExpander_old::addArrayIndex( Expression * index, Expression * dimension ) { 163 198 indices.push_back( index ); 164 199 indices.push_back( dimension ); 165 200 } 166 201 167 void InitExpander ::clearArrayIndices() {202 void InitExpander_old::clearArrayIndices() { 168 203 deleteAll( indices ); 169 204 indices.clear(); 170 205 } 171 206 172 bool InitExpander ::addReference() {207 bool InitExpander_old::addReference() { 173 208 bool added = false; 174 209 for ( Expression *& expr : cur ) { … … 201 236 202 237 template< typename OutIterator > 203 void build( UntypedExpr * callExpr, InitExpander ::IndexList::iterator idx, InitExpander::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {238 void build( UntypedExpr * callExpr, InitExpander_old::IndexList::iterator idx, InitExpander_old::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) { 204 239 if ( idx == idxEnd ) return; 205 240 Expression * index = *idx++; … … 258 293 // remaining elements. 259 294 // To accomplish this, generate switch statement, consuming all of expander's elements 260 Statement * InitImpl ::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {295 Statement * InitImpl_old::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 261 296 if ( ! init ) return nullptr; 262 297 CompoundStmt * block = new CompoundStmt(); … … 271 306 } 272 307 273 Statement * ExprImpl ::buildListInit( UntypedExpr *, std::list< Expression * > & ) {308 Statement * ExprImpl_old::buildListInit( UntypedExpr *, std::list< Expression * > & ) { 274 309 return nullptr; 275 310 } 276 311 277 Statement * InitExpander ::buildListInit( UntypedExpr * dst ) {312 Statement * InitExpander_old::buildListInit( UntypedExpr * dst ) { 278 313 return expander->buildListInit( dst, indices ); 279 314 } 315 316 class InitExpander_new::ExpanderImpl { 317 public: 318 virtual ~ExpanderImpl() = default; 319 virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0; 320 virtual ast::ptr< ast::Stmt > buildListInit( 321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 322 }; 323 324 namespace { 325 template< typename Out > 326 void buildCallExpr( 327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 328 const ast::Init * init, Out & out 329 ) { 330 const CodeLocation & loc = init->location; 331 332 auto cond = new ast::UntypedExpr{ 333 loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } }; 334 335 std::vector< ast::ptr< ast::Expr > > args = makeInitList( init ); 336 splice( callExpr->args, args ); 337 338 out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } ); 339 340 out.emplace_back( new ast::ExprStmt{ 341 loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } ); 342 } 343 344 template< typename Out > 345 void build( 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 347 const ast::Init * init, Out & out 348 ) { 349 if ( indices.empty() ) return; 350 351 unsigned idx = 0; 352 353 const ast::Expr * index = indices[idx++]; 354 assert( idx != indices.size() ); 355 const ast::Expr * dimension = indices[idx++]; 356 357 if ( idx == indices.size() ) { 358 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) { 359 for ( const ast::Init * init : *listInit ) { 360 buildCallExpr( callExpr, index, dimension, init, out ); 361 } 362 } else { 363 buildCallExpr( callExpr, index, dimension, init, out ); 364 } 365 } else { 366 const CodeLocation & loc = init->location; 367 368 unsigned long cond = 0; 369 auto listInit = dynamic_cast< const ast::ListInit * >( init ); 370 if ( ! listInit ) { SemanticError( loc, "unbalanced list initializers" ); } 371 372 static UniqueName targetLabel( "L__autogen__" ); 373 ast::Label switchLabel{ 374 loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } }; 375 376 std::vector< ast::ptr< ast::Stmt > > branches; 377 for ( const ast::Init * init : *listInit ) { 378 auto condition = ast::ConstantExpr::from_ulong( loc, cond ); 379 ++cond; 380 381 std::vector< ast::ptr< ast::Stmt > > stmts; 382 build( callExpr, indices, init, stmts ); 383 stmts.emplace_back( 384 new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } ); 385 branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } ); 386 } 387 out.emplace_back( new ast::SwitchStmt{ loc, index, std::move( branches ) } ); 388 out.emplace_back( new ast::NullStmt{ loc, { switchLabel } } ); 389 } 390 } 391 392 class InitImpl_new final : public InitExpander_new::ExpanderImpl { 393 ast::ptr< ast::Init > init; 394 public: 395 InitImpl_new( const ast::Init * i ) : init( i ) {} 396 397 std::vector< ast::ptr< ast::Expr > > next( InitExpander_new::IndexList & ) override { 398 return makeInitList( init ); 399 } 400 401 ast::ptr< ast::Stmt > buildListInit( 402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 403 ) override { 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 408 // statement consuming all of expander's elements 409 410 if ( ! init ) return {}; 411 412 std::list< ast::ptr< ast::Stmt > > stmts; 413 build( callExpr, indices, init, stmts ); 414 if ( stmts.empty() ) { 415 return {}; 416 } else { 417 auto block = new ast::CompoundStmt{ init->location, std::move( stmts ) }; 418 init = nullptr; // consumed in creating the list init 419 return block; 420 } 421 } 422 }; 423 424 class ExprImpl_new final : public InitExpander_new::ExpanderImpl { 425 ast::ptr< ast::Expr > arg; 426 public: 427 ExprImpl_new( const ast::Expr * a ) : arg( a ) {} 428 429 std::vector< ast::ptr< ast::Expr > > next( 430 InitExpander_new::IndexList & indices 431 ) override { 432 if ( ! arg ) return {}; 433 434 const CodeLocation & loc = arg->location; 435 const ast::Expr * expr = arg; 436 for ( auto it = indices.rbegin(); it != indices.rend(); ++it ) { 437 // go through indices and layer on subscript exprs ?[?] 438 ++it; 439 expr = new ast::UntypedExpr{ 440 loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } }; 441 } 442 return { expr }; 443 } 444 445 ast::ptr< ast::Stmt > buildListInit( 446 ast::UntypedExpr *, InitExpander_new::IndexList & 447 ) override { 448 return {}; 449 } 450 }; 451 } // anonymous namespace 452 453 InitExpander_new::InitExpander_new( const ast::Init * init ) 454 : expander( new InitImpl_new{ init } ), crnt(), indices() {} 455 456 InitExpander_new::InitExpander_new( const ast::Expr * expr ) 457 : expander( new ExprImpl_new{ expr } ), crnt(), indices() {} 458 459 std::vector< ast::ptr< ast::Expr > > InitExpander_new::operator* () { return crnt; } 460 461 InitExpander_new & InitExpander_new::operator++ () { 462 crnt = expander->next( indices ); 463 return *this; 464 } 465 466 /// builds statement which has the same semantics as a C-style list initializer (for array 467 /// initializers) using callExpr as the base expression to perform initialization 468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) { 469 return expander->buildListInit( callExpr, indices ); 470 } 471 472 void InitExpander_new::addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ) { 473 indices.emplace_back( index ); 474 indices.emplace_back( dimension ); 475 } 476 477 void InitExpander_new::clearArrayIndices() { indices.clear(); } 478 479 bool InitExpander_new::addReference() { 480 for ( ast::ptr< ast::Expr > & expr : crnt ) { 481 expr = new ast::AddressExpr{ expr }; 482 } 483 return ! crnt.empty(); 484 } 280 485 281 486 Type * getTypeofThis( FunctionType * ftype ) { … … 306 511 } 307 512 308 struct CallFinder {309 CallFinder ( const std::list< std::string > & names ) : names( names ) {}513 struct CallFinder_old { 514 CallFinder_old( const std::list< std::string > & names ) : names( names ) {} 310 515 311 516 void postvisit( ApplicationExpr * appExpr ) { … … 330 535 }; 331 536 537 struct CallFinder_new final { 538 std::vector< ast::ptr< ast::Expr > > matches; 539 const std::vector< std::string > names; 540 541 CallFinder_new( std::vector< std::string > && ns ) : matches(), names( std::move(ns) ) {} 542 543 void handleCallExpr( const ast::Expr * expr ) { 544 std::string fname = getFunctionName( expr ); 545 if ( std::find( names.begin(), names.end(), fname ) != names.end() ) { 546 matches.emplace_back( expr ); 547 } 548 } 549 550 void postvisit( const ast::ApplicationExpr * expr ) { handleCallExpr( expr ); } 551 void postvisit( const ast::UntypedExpr * expr ) { handleCallExpr( expr ); } 552 }; 553 332 554 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) { 333 static PassVisitor<CallFinder > finder( std::list< std::string >{ "?{}", "^?{}" } );555 static PassVisitor<CallFinder_old> finder( std::list< std::string >{ "?{}", "^?{}" } ); 334 556 finder.pass.matches = &matches; 335 557 maybeAccept( stmt, finder ); 558 } 559 560 std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) { 561 ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } }; 562 maybe_accept( stmt, finder ); 563 return std::move( finder.pass.matches ); 336 564 } 337 565 … … 339 567 std::list< Expression * > matches; 340 568 collectCtorDtorCalls( stmt, matches ); 341 assert ( matches.size() <= 1);569 assertf( matches.size() <= 1, "%zd constructor/destructors found in %s", matches.size(), toString( stmt ).c_str() ); 342 570 return matches.size() == 1 ? matches.front() : nullptr; 343 571 } … … 345 573 namespace { 346 574 DeclarationWithType * getCalledFunction( Expression * expr ); 575 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ); 347 576 348 577 template<typename CallExpr> … … 354 583 return getCalledFunction( expr->get_args().front() ); 355 584 } 585 586 template<typename CallExpr> 587 const ast::DeclWithType * handleDerefCalledFunction( const CallExpr * expr ) { 588 // (*f)(x) => should get "f" 589 std::string name = getFunctionName( expr ); 590 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() ); 591 assertf( ! expr->args.empty(), "Cannot get called function from dereference with no arguments" ); 592 return getCalledFunction( expr->args.front() ); 593 } 594 356 595 357 596 DeclarationWithType * getCalledFunction( Expression * expr ) { … … 374 613 return nullptr; 375 614 } 615 616 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ) { 617 assert( expr ); 618 if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( expr ) ) { 619 return varExpr->var; 620 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( expr ) ) { 621 return memberExpr->member; 622 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) { 623 return getCalledFunction( castExpr->arg ); 624 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( expr ) ) { 625 return handleDerefCalledFunction( untypedExpr ); 626 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * > ( expr ) ) { 627 return handleDerefCalledFunction( appExpr ); 628 } else if ( const ast::AddressExpr * addrExpr = dynamic_cast< const ast::AddressExpr * >( expr ) ) { 629 return getCalledFunction( addrExpr->arg ); 630 } else if ( const ast::CommaExpr * commaExpr = dynamic_cast< const ast::CommaExpr * >( expr ) ) { 631 return getCalledFunction( commaExpr->arg2 ); 632 } 633 return nullptr; 634 } 635 636 DeclarationWithType * getFunctionCore( const Expression * expr ) { 637 if ( const auto * appExpr = dynamic_cast< const ApplicationExpr * >( expr ) ) { 638 return getCalledFunction( appExpr->function ); 639 } else if ( const auto * untyped = dynamic_cast< const UntypedExpr * >( expr ) ) { 640 return getCalledFunction( untyped->function ); 641 } 642 assertf( false, "getFunction with unknown expression: %s", toString( expr ).c_str() ); 643 } 376 644 } 377 645 378 646 DeclarationWithType * getFunction( Expression * expr ) { 379 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) { 380 return getCalledFunction( appExpr->get_function() ); 381 } else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) { 382 return getCalledFunction( untyped->get_function() ); 647 return getFunctionCore( expr ); 648 } 649 650 const DeclarationWithType * getFunction( const Expression * expr ) { 651 return getFunctionCore( expr ); 652 } 653 654 const ast::DeclWithType * getFunction( const ast::Expr * expr ) { 655 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) { 656 return getCalledFunction( appExpr->func ); 657 } else if ( const ast::UntypedExpr * untyped = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) { 658 return getCalledFunction( untyped->func ); 383 659 } 384 660 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() ); … … 395 671 } 396 672 673 const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr ) { 674 auto appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ); 675 if ( ! appExpr ) return nullptr; 676 677 const ast::DeclWithType * func = getCalledFunction( appExpr->func ); 678 assertf( func, 679 "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() ); 680 681 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 682 // autogenerated ctor/dtor will call all member dtors, and some members may have a 683 // user-defined dtor 684 return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr; 685 } 686 397 687 namespace { 398 688 template <typename Predicate> … … 403 693 return std::all_of( callExprs.begin(), callExprs.end(), pred); 404 694 } 695 696 template <typename Predicate> 697 bool allofCtorDtor( const ast::Stmt * stmt, const Predicate & pred ) { 698 std::vector< ast::ptr< ast::Expr > > callExprs = collectCtorDtorCalls( stmt ); 699 return std::all_of( callExprs.begin(), callExprs.end(), pred ); 700 } 405 701 } 406 702 … … 408 704 return allofCtorDtor( stmt, []( Expression * callExpr ){ 409 705 if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 410 FunctionType *funcType = GenPoly::getFunctionType( appExpr-> get_function()->get_result());706 FunctionType *funcType = GenPoly::getFunctionType( appExpr->function->result ); 411 707 assert( funcType ); 412 708 return funcType->get_parameters().size() == 1; 709 } 710 return false; 711 }); 712 } 713 714 bool isIntrinsicSingleArgCallStmt( const ast::Stmt * stmt ) { 715 return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){ 716 if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 717 const ast::FunctionType * funcType = 718 GenPoly::getFunctionType( appExpr->func->result ); 719 assert( funcType ); 720 return funcType->params.size() == 1; 413 721 } 414 722 return false; … … 429 737 if ( pos == 0 ) return arg; 430 738 pos--; 739 } 740 assert( false ); 741 } 742 743 template<typename CallExpr> 744 const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) { 745 if( pos >= call->args.size() ) { 746 assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.", 747 pos, toString( call ).c_str() ); 748 } 749 for ( const ast::Expr * arg : call->args ) { 750 if ( pos == 0 ) return arg; 751 --pos; 431 752 } 432 753 assert( false ); … … 453 774 } 454 775 776 const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) { 777 if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) { 778 return callArg( app, pos ); 779 } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) { 780 return callArg( untyped, pos ); 781 } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) { 782 const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids; 783 assertf( ! stmts.empty(), "TupleAssignExpr missing statements." ); 784 auto stmt = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back().get() ); 785 auto tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr.get() ); 786 assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr."); 787 return getCallArg( tuple->exprs.front(), pos ); 788 } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) { 789 return getCallArg( ctor->callExpr, pos ); 790 } else { 791 assertf( false, "Unexpected expression type passed to getCallArg: %s", 792 toString( call ).c_str() ); 793 } 794 } 795 455 796 namespace { 456 797 std::string funcName( Expression * func ); 798 std::string funcName( const ast::Expr * func ); 457 799 458 800 template<typename CallExpr> … … 463 805 assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" ); 464 806 return funcName( expr->get_args().front() ); 807 } 808 809 template<typename CallExpr> 810 std::string handleDerefName( const CallExpr * expr ) { 811 // (*f)(x) => should get name "f" 812 std::string name = getFunctionName( expr ); 813 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() ); 814 assertf( ! expr->args.empty(), "Cannot get function name from dereference with no arguments" ); 815 return funcName( expr->args.front() ); 465 816 } 466 817 … … 486 837 } 487 838 } 839 840 std::string funcName( const ast::Expr * func ) { 841 if ( const ast::NameExpr * nameExpr = dynamic_cast< const ast::NameExpr * >( func ) ) { 842 return nameExpr->name; 843 } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) { 844 return varExpr->var->name; 845 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) { 846 return funcName( castExpr->arg ); 847 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) { 848 return memberExpr->member->name; 849 } else if ( const ast::UntypedMemberExpr * memberExpr = dynamic_cast< const ast::UntypedMemberExpr * > ( func ) ) { 850 return funcName( memberExpr->member ); 851 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( func ) ) { 852 return handleDerefName( untypedExpr ); 853 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( func ) ) { 854 return handleDerefName( appExpr ); 855 } else if ( const ast::ConstructorExpr * ctorExpr = dynamic_cast< const ast::ConstructorExpr * >( func ) ) { 856 return funcName( getCallArg( ctorExpr->callExpr, 0 ) ); 857 } else { 858 assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() ); 859 } 860 } 488 861 } 489 862 … … 502 875 } 503 876 877 std::string getFunctionName( const ast::Expr * expr ) { 878 // there's some unforunate overlap here with getCalledFunction. Ideally this would be able to use getCalledFunction and 879 // return the name of the DeclarationWithType, but this needs to work for NameExpr and UntypedMemberExpr, where getCalledFunction 880 // can't possibly do anything reasonable. 881 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) { 882 return funcName( appExpr->func ); 883 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) { 884 return funcName( untypedExpr->func ); 885 } else { 886 std::cerr << expr << std::endl; 887 assertf( false, "Unexpected expression type passed to getFunctionName" ); 888 } 889 } 890 504 891 Type * getPointerBase( Type * type ) { 505 892 if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) { … … 513 900 } 514 901 } 902 const ast::Type* getPointerBase( const ast::Type* t ) { 903 if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) { 904 return p->base; 905 } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) { 906 return a->base; 907 } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) { 908 return r->base; 909 } else return nullptr; 910 } 515 911 516 912 Type * isPointerType( Type * type ) { … … 561 957 void previsit( OffsetofExpr * ) {} 562 958 void previsit( OffsetPackExpr * ) {} 563 void previsit( AttrExpr * ) {}564 959 void previsit( CommaExpr * ) {} 565 960 void previsit( LogicalExpr * ) {} … … 609 1004 bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); } 610 1005 611 FunctionDecl * isCopyFunction(Declaration * decl, const std::string & fname ) {612 FunctionDecl * function = dynamic_cast<FunctionDecl * >( decl );1006 const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ) { 1007 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( decl ); 613 1008 if ( ! function ) return nullptr; 614 1009 if ( function->name != fname ) return nullptr; … … 627 1022 } 628 1023 629 FunctionDecl * isAssignment( Declaration * decl ) { 1024 bool isCopyFunction( const ast::FunctionDecl * decl ) { 1025 const ast::FunctionType * ftype = decl->type; 1026 if ( ftype->params.size() != 2 ) return false; 1027 1028 const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() ); 1029 if ( ! t1 ) return false; 1030 const ast::Type * t2 = ftype->params.back()->get_type(); 1031 1032 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); 1033 } 1034 1035 const FunctionDecl * isAssignment( const Declaration * decl ) { 630 1036 return isCopyFunction( decl, "?=?" ); 631 1037 } 632 FunctionDecl * isDestructor(Declaration * decl ) {633 if ( isDestructor( decl-> get_name()) ) {634 return dynamic_cast< FunctionDecl * >( decl );1038 const FunctionDecl * isDestructor( const Declaration * decl ) { 1039 if ( isDestructor( decl->name ) ) { 1040 return dynamic_cast< const FunctionDecl * >( decl ); 635 1041 } 636 1042 return nullptr; 637 1043 } 638 FunctionDecl * isDefaultConstructor(Declaration * decl ) {1044 const FunctionDecl * isDefaultConstructor( const Declaration * decl ) { 639 1045 if ( isConstructor( decl->name ) ) { 640 if ( FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl ) ) {1046 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) { 641 1047 if ( func->type->parameters.size() == 1 ) { 642 1048 return func; … … 646 1052 return nullptr; 647 1053 } 648 FunctionDecl * isCopyConstructor(Declaration * decl ) {1054 const FunctionDecl * isCopyConstructor( const Declaration * decl ) { 649 1055 return isCopyFunction( decl, "?{}" ); 650 1056 } -
src/InitTweak/InitTweak.h
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // RemoveInit.h --7 // InitTweak.h -- 8 8 // 9 9 // Author : Rob Schluntz 10 10 // Created On : Fri May 13 11:26:36 2016 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:30:33 201713 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 19 14:18:00 2019 13 // Update Count : 6 14 14 // 15 15 … … 19 19 #include <memory> // for shared_ptr 20 20 #include <string> // for string, allocator 21 #include <vector> 21 22 23 #include "AST/Fwd.hpp" // for AST nodes 22 24 #include "SynTree/SynTree.h" // for Visitor Nodes 23 25 24 26 // helper functions for initialization 25 27 namespace InitTweak { 26 FunctionDecl * isAssignment( Declaration * decl ); 27 FunctionDecl * isDestructor( Declaration * decl ); 28 FunctionDecl * isDefaultConstructor( Declaration * decl ); 29 FunctionDecl * isCopyConstructor( Declaration * decl ); 30 FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ); 28 const FunctionDecl * isAssignment( const Declaration * decl ); 29 const FunctionDecl * isDestructor( const Declaration * decl ); 30 const FunctionDecl * isDefaultConstructor( const Declaration * decl ); 31 const FunctionDecl * isCopyConstructor( const Declaration * decl ); 32 const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ); 33 bool isCopyFunction( const ast::FunctionDecl * decl ); 31 34 32 35 /// returns the base type of the first parameter to a constructor/destructor/assignment function … … 41 44 /// transform Initializer into an argument list that can be passed to a call expression 42 45 std::list< Expression * > makeInitList( Initializer * init ); 46 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ); 43 47 44 48 /// True if the resolver should try to construct dwt … … 57 61 /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr) 58 62 DeclarationWithType * getFunction( Expression * expr ); 63 const DeclarationWithType * getFunction( const Expression * expr ); 64 const ast::DeclWithType * getFunction( const ast::Expr * expr ); 59 65 60 66 /// Non-Null if expr is a call expression whose target function is intrinsic 61 67 ApplicationExpr * isIntrinsicCallExpr( Expression * expr ); 68 const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr); 62 69 63 70 /// True if stmt is a call statement where the function called is intrinsic and takes one parameter. … … 65 72 /// Currently has assertions that make it less than fully general. 66 73 bool isIntrinsicSingleArgCallStmt( Statement * stmt ); 74 bool isIntrinsicSingleArgCallStmt( const ast::Stmt * stmt ); 67 75 68 76 /// True if stmt is a call statement where the function called is intrinsic. … … 71 79 /// get all Ctor/Dtor call expressions from a Statement 72 80 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ); 81 std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ); 73 82 74 83 /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call … … 77 86 /// returns the name of the function being called 78 87 std::string getFunctionName( Expression * expr ); 88 std::string getFunctionName( const ast::Expr * expr ); 79 89 80 90 /// returns the argument to a call expression in position N indexed from 0 81 91 Expression *& getCallArg( Expression * callExpr, unsigned int pos ); 92 const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ); 82 93 83 94 /// returns the base type of a PointerType or ArrayType, else returns NULL 84 95 Type * getPointerBase( Type * ); 96 const ast::Type* getPointerBase( const ast::Type* ); 85 97 86 98 /// returns the argument if it is a PointerType or ArrayType, else returns NULL … … 91 103 bool isConstExpr( Initializer * init ); 92 104 93 class InitExpander {105 class InitExpander_old { 94 106 public: 95 107 // expand by stepping through init to get each list of arguments 96 InitExpander ( Initializer * init );108 InitExpander_old( Initializer * init ); 97 109 98 110 // always expand to expr 99 InitExpander ( Expression * expr );111 InitExpander_old( Expression * expr ); 100 112 101 113 // iterator-like interface 102 114 std::list< Expression * > operator*(); 103 InitExpander & operator++();115 InitExpander_old & operator++(); 104 116 105 117 // builds statement which has the same semantics as a C-style list initializer … … 120 132 IndexList indices; 121 133 }; 134 135 class InitExpander_new { 136 public: 137 using IndexList = std::vector< ast::ptr< ast::Expr > >; 138 class ExpanderImpl; 139 140 private: 141 std::shared_ptr< ExpanderImpl > expander; 142 std::vector< ast::ptr< ast::Expr > > crnt; 143 // invariant: list of size 2N (elements come in pairs [index, dimension]) 144 IndexList indices; 145 146 public: 147 /// Expand by stepping through init to get each list of arguments 148 InitExpander_new( const ast::Init * init ); 149 150 /// Always expand to expression 151 InitExpander_new( const ast::Expr * expr ); 152 153 std::vector< ast::ptr< ast::Expr > > operator* (); 154 InitExpander_new & operator++ (); 155 156 /// builds statement which has the same semantics as a C-style list initializer (for array 157 /// initializers) using callExpr as the base expression to perform initialization. 158 /// Mutates callExpr 159 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); 160 161 void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ); 162 163 void clearArrayIndices(); 164 165 bool addReference(); 166 }; 122 167 } // namespace 123 168 -
src/InitTweak/module.mk
r7951100 rb067d9b 20 20 InitTweak/InitTweak.cc 21 21 22 SRCDEMANGLE += InitTweak/GenInit.cc \ 23 InitTweak/InitTweak.cc 24 -
src/MakeLibCfa.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 10:33:33 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Fri Apr 22 13:54:15 201613 // Update Count : 4 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Feb 17 21:08:09 2019 13 // Update Count : 41 14 14 // 15 15 … … 146 146 } // namespace 147 147 } // namespace LibCfa 148 149 // Local Variables: // 150 // tab-width: 4 // 151 // End: // -
src/Makefile.am
r7951100 rb067d9b 10 10 ## Author : Peter A. Buhr 11 11 ## Created On : Sun May 31 08:51:46 2015 12 ## Last Modified By : Andrew Beach13 ## Last Modified On : Tus Jul 25 10:34:00 201714 ## Update Count : 7612 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Aug 5 12:57:46 2019 14 ## Update Count : 98 15 15 ############################################################################### 16 16 17 17 # create object files in directory with source files 18 AUTOMAKE_OPTIONS = subdir-objects 18 AUTOMAKE_OPTIONS = foreign subdir-objects 19 ACLOCAL_AMFLAGS = -I automake 19 20 20 21 SRC = main.cc \ 21 MakeLibCfa.cc 22 MakeLibCfa.cc \ 23 CompilationState.cc 24 25 SRCDEMANGLE = CompilationState.cc 22 26 23 27 MAINTAINERCLEANFILES = 28 MOSTLYCLEANFILES = 24 29 25 # Is there a way to use a variable for the directory names? 30 if WITH_LIBPROFILER 31 LIBPROFILER = -lprofiler 32 endif 26 33 34 if WITH_LIBTCMALLOC 35 LIBTCMALLOC = -ltcmalloc 36 TCMALLOCFLAG = -DTCMALLOC 37 endif 38 39 include AST/module.mk 27 40 include CodeGen/module.mk 28 41 include CodeTools/module.mk … … 37 50 include SynTree/module.mk 38 51 include Tuples/module.mk 52 include Validate/module.mk 39 53 include Virtual/module.mk 40 54 55 $(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h 56 57 $(srcdir)/AST/Type.hpp : BasicTypes-gen.cc 58 ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra 59 @./BasicTypes-gen 60 @rm BasicTypes-gen 61 41 62 # put into lib for now 42 cfa_cpplibdir = ${CFA_LIBDIR} 43 cfa_cpplib_PROGRAMS = driver/cfa-cpp 44 driver_cfa_cpp_SOURCES = ${SRC} 45 driver_cfa_cpp_LDADD = -ldl # yywrap 46 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14 47 driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic 63 cfa_cpplibdir = $(CFA_LIBDIR) 64 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp $(DEMANGLER) 65 EXTRA_PROGRAMS = demangler 66 ___driver_cfa_cpp_SOURCES = $(SRC) 67 ___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC) 68 69 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++14 $(TCMALLOCFLAG) 70 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 71 ARFLAGS = cr 72 73 demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete 74 75 demangler_LDADD = libdemangle.a -ldl # yywrap 76 77 noinst_LIBRARIES = $(LIBDEMANGLE) 78 EXTRA_LIBRARIES = libdemangle.a 79 libdemangle_a_SOURCES = $(SRCDEMANGLE) 48 80 49 81 MAINTAINERCLEANFILES += ${libdir}/${notdir ${cfa_cpplib_PROGRAMS}} -
src/Makefile.in
r7951100 rb067d9b 21 21 ############################################################################### 22 22 23 ######################### -*- Mode: Makefile-Gmake -*- ######################## 24 ############################################################################### 25 23 26 #SRC += ArgTweak/Rewriter.cc \ 24 27 # ArgTweak/Mutate.cc … … 59 62 ######################### -*- Mode: Makefile-Gmake -*- ######################## 60 63 ############################################################################### 64 65 ######################### -*- Mode: Makefile-Gmake -*- ######################## 66 ############################################################################### 67 61 68 62 69 VPATH = @srcdir@ … … 134 141 build_triplet = @build@ 135 142 host_triplet = @host@ 136 cfa_cpplib_PROGRAMS = driver/cfa-cpp$(EXEEXT) 143 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp$(EXEEXT) $(DEMANGLER) 144 EXTRA_PROGRAMS = demangler$(EXEEXT) 137 145 subdir = src 138 146 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 139 am__aclocal_m4_deps = $(top_srcdir)/configure.ac 147 am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \ 148 $(top_srcdir)/automake/ltoptions.m4 \ 149 $(top_srcdir)/automake/ltsugar.m4 \ 150 $(top_srcdir)/automake/ltversion.m4 \ 151 $(top_srcdir)/automake/lt~obsolete.m4 \ 152 $(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac 140 153 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 141 154 $(ACLOCAL_M4) … … 145 158 CONFIG_CLEAN_FILES = 146 159 CONFIG_CLEAN_VPATH_FILES = 160 LIBRARIES = $(noinst_LIBRARIES) 161 AM_V_AR = $(am__v_AR_@AM_V@) 162 am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) 163 am__v_AR_0 = @echo " AR " $@; 164 am__v_AR_1 = 165 libdemangle_a_AR = $(AR) $(ARFLAGS) 166 libdemangle_a_LIBADD = 167 am__dirstamp = $(am__leading_dot)dirstamp 168 am__objects_1 = AST/AssertAcyclic.$(OBJEXT) AST/Attribute.$(OBJEXT) \ 169 AST/Convert.$(OBJEXT) AST/Decl.$(OBJEXT) \ 170 AST/DeclReplacer.$(OBJEXT) AST/Expr.$(OBJEXT) \ 171 AST/GenericSubstitution.$(OBJEXT) AST/Init.$(OBJEXT) \ 172 AST/LinkageSpec.$(OBJEXT) AST/Node.$(OBJEXT) \ 173 AST/Pass.$(OBJEXT) AST/Print.$(OBJEXT) AST/Stmt.$(OBJEXT) \ 174 AST/SymbolTable.$(OBJEXT) AST/Type.$(OBJEXT) \ 175 AST/TypeEnvironment.$(OBJEXT) AST/TypeSubstitution.$(OBJEXT) 176 am__objects_2 = CodeGen/CodeGenerator.$(OBJEXT) \ 177 CodeGen/FixMain.$(OBJEXT) CodeGen/GenType.$(OBJEXT) \ 178 CodeGen/OperatorTable.$(OBJEXT) 179 am__objects_3 = Common/Assert.$(OBJEXT) Common/Eval.$(OBJEXT) \ 180 Common/PassVisitor.$(OBJEXT) Common/SemanticError.$(OBJEXT) \ 181 Common/Stats/Counter.$(OBJEXT) Common/Stats/Heap.$(OBJEXT) \ 182 Common/Stats/Stats.$(OBJEXT) Common/Stats/Time.$(OBJEXT) \ 183 Common/UniqueName.$(OBJEXT) 184 am__objects_4 = ControlStruct/ForExprMutator.$(OBJEXT) \ 185 ControlStruct/LabelFixer.$(OBJEXT) \ 186 ControlStruct/LabelGenerator.$(OBJEXT) \ 187 ControlStruct/MLEMutator.$(OBJEXT) \ 188 ControlStruct/Mutate.$(OBJEXT) 189 am__objects_5 = ResolvExpr/AdjustExprType.$(OBJEXT) \ 190 ResolvExpr/Alternative.$(OBJEXT) \ 191 ResolvExpr/AlternativeFinder.$(OBJEXT) \ 192 ResolvExpr/Candidate.$(OBJEXT) \ 193 ResolvExpr/CandidateFinder.$(OBJEXT) \ 194 ResolvExpr/CastCost.$(OBJEXT) ResolvExpr/CommonType.$(OBJEXT) \ 195 ResolvExpr/ConversionCost.$(OBJEXT) \ 196 ResolvExpr/CurrentObject.$(OBJEXT) \ 197 ResolvExpr/ExplodedActual.$(OBJEXT) \ 198 ResolvExpr/ExplodedArg.$(OBJEXT) \ 199 ResolvExpr/FindOpenVars.$(OBJEXT) ResolvExpr/Occurs.$(OBJEXT) \ 200 ResolvExpr/PolyCost.$(OBJEXT) \ 201 ResolvExpr/PtrsAssignable.$(OBJEXT) \ 202 ResolvExpr/PtrsCastable.$(OBJEXT) \ 203 ResolvExpr/RenameVars.$(OBJEXT) \ 204 ResolvExpr/ResolveAssertions.$(OBJEXT) \ 205 ResolvExpr/Resolver.$(OBJEXT) \ 206 ResolvExpr/ResolveTypeof.$(OBJEXT) \ 207 ResolvExpr/SatisfyAssertions.$(OBJEXT) \ 208 ResolvExpr/SpecCost.$(OBJEXT) \ 209 ResolvExpr/TypeEnvironment.$(OBJEXT) \ 210 ResolvExpr/Unify.$(OBJEXT) 211 am__objects_6 = SymTab/Autogen.$(OBJEXT) SymTab/FixFunction.$(OBJEXT) \ 212 SymTab/Indexer.$(OBJEXT) SymTab/Mangler.$(OBJEXT) \ 213 SymTab/ManglerCommon.$(OBJEXT) SymTab/Validate.$(OBJEXT) 214 am__objects_7 = SynTree/Type.$(OBJEXT) SynTree/VoidType.$(OBJEXT) \ 215 SynTree/BasicType.$(OBJEXT) SynTree/PointerType.$(OBJEXT) \ 216 SynTree/ArrayType.$(OBJEXT) SynTree/ReferenceType.$(OBJEXT) \ 217 SynTree/FunctionType.$(OBJEXT) \ 218 SynTree/ReferenceToType.$(OBJEXT) SynTree/TupleType.$(OBJEXT) \ 219 SynTree/TypeofType.$(OBJEXT) SynTree/AttrType.$(OBJEXT) \ 220 SynTree/VarArgsType.$(OBJEXT) SynTree/ZeroOneType.$(OBJEXT) \ 221 SynTree/Constant.$(OBJEXT) SynTree/Expression.$(OBJEXT) \ 222 SynTree/TupleExpr.$(OBJEXT) SynTree/CommaExpr.$(OBJEXT) \ 223 SynTree/TypeExpr.$(OBJEXT) SynTree/ApplicationExpr.$(OBJEXT) \ 224 SynTree/AddressExpr.$(OBJEXT) SynTree/Statement.$(OBJEXT) \ 225 SynTree/CompoundStmt.$(OBJEXT) SynTree/DeclStmt.$(OBJEXT) \ 226 SynTree/Declaration.$(OBJEXT) \ 227 SynTree/DeclarationWithType.$(OBJEXT) \ 228 SynTree/ObjectDecl.$(OBJEXT) SynTree/FunctionDecl.$(OBJEXT) \ 229 SynTree/AggregateDecl.$(OBJEXT) \ 230 SynTree/NamedTypeDecl.$(OBJEXT) SynTree/TypeDecl.$(OBJEXT) \ 231 SynTree/Initializer.$(OBJEXT) \ 232 SynTree/TypeSubstitution.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \ 233 SynTree/DeclReplacer.$(OBJEXT) 234 am__objects_8 = CompilationState.$(OBJEXT) $(am__objects_1) \ 235 $(am__objects_2) Concurrency/Keywords.$(OBJEXT) \ 236 $(am__objects_3) $(am__objects_4) GenPoly/GenPoly.$(OBJEXT) \ 237 GenPoly/Lvalue.$(OBJEXT) InitTweak/GenInit.$(OBJEXT) \ 238 InitTweak/InitTweak.$(OBJEXT) Parser/LinkageSpec.$(OBJEXT) \ 239 $(am__objects_5) $(am__objects_6) SymTab/Demangle.$(OBJEXT) \ 240 $(am__objects_7) Tuples/TupleAssignment.$(OBJEXT) \ 241 Tuples/TupleExpansion.$(OBJEXT) Tuples/Explode.$(OBJEXT) \ 242 Tuples/Tuples.$(OBJEXT) Validate/HandleAttributes.$(OBJEXT) \ 243 Validate/FindSpecialDecls.$(OBJEXT) 244 am_libdemangle_a_OBJECTS = $(am__objects_8) 245 libdemangle_a_OBJECTS = $(am_libdemangle_a_OBJECTS) 147 246 am__installdirs = "$(DESTDIR)$(cfa_cpplibdir)" 148 247 PROGRAMS = $(cfa_cpplib_PROGRAMS) 149 am__dirstamp = $(am__leading_dot)dirstamp 150 am__objects_1 = driver_cfa_cpp-main.$(OBJEXT) \ 151 driver_cfa_cpp-MakeLibCfa.$(OBJEXT) \ 152 CodeGen/driver_cfa_cpp-Generate.$(OBJEXT) \ 153 CodeGen/driver_cfa_cpp-CodeGenerator.$(OBJEXT) \ 154 CodeGen/driver_cfa_cpp-GenType.$(OBJEXT) \ 155 CodeGen/driver_cfa_cpp-FixNames.$(OBJEXT) \ 156 CodeGen/driver_cfa_cpp-FixMain.$(OBJEXT) \ 157 CodeGen/driver_cfa_cpp-OperatorTable.$(OBJEXT) \ 158 CodeTools/driver_cfa_cpp-DeclStats.$(OBJEXT) \ 159 CodeTools/driver_cfa_cpp-TrackLoc.$(OBJEXT) \ 160 Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT) \ 161 Concurrency/driver_cfa_cpp-Waitfor.$(OBJEXT) \ 162 Common/driver_cfa_cpp-SemanticError.$(OBJEXT) \ 163 Common/driver_cfa_cpp-UniqueName.$(OBJEXT) \ 164 Common/driver_cfa_cpp-DebugMalloc.$(OBJEXT) \ 165 Common/driver_cfa_cpp-Assert.$(OBJEXT) \ 166 Common/driver_cfa_cpp-Heap.$(OBJEXT) \ 167 ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT) \ 168 ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT) \ 169 ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT) \ 170 ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \ 171 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \ 172 ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT) \ 173 GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \ 174 GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \ 175 GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) \ 176 GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \ 177 GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT) \ 178 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \ 179 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \ 180 InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \ 181 InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT) \ 182 InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT) \ 183 InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT) \ 184 Parser/driver_cfa_cpp-parser.$(OBJEXT) \ 185 Parser/driver_cfa_cpp-lex.$(OBJEXT) \ 186 Parser/driver_cfa_cpp-TypedefTable.$(OBJEXT) \ 187 Parser/driver_cfa_cpp-ParseNode.$(OBJEXT) \ 188 Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT) \ 189 Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT) \ 190 Parser/driver_cfa_cpp-StatementNode.$(OBJEXT) \ 191 Parser/driver_cfa_cpp-InitializerNode.$(OBJEXT) \ 192 Parser/driver_cfa_cpp-TypeData.$(OBJEXT) \ 193 Parser/driver_cfa_cpp-LinkageSpec.$(OBJEXT) \ 194 Parser/driver_cfa_cpp-parserutility.$(OBJEXT) \ 195 ResolvExpr/driver_cfa_cpp-AlternativeFinder.$(OBJEXT) \ 196 ResolvExpr/driver_cfa_cpp-Alternative.$(OBJEXT) \ 197 ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT) \ 198 ResolvExpr/driver_cfa_cpp-PtrsAssignable.$(OBJEXT) \ 199 ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT) \ 200 ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT) \ 201 ResolvExpr/driver_cfa_cpp-CastCost.$(OBJEXT) \ 202 ResolvExpr/driver_cfa_cpp-PtrsCastable.$(OBJEXT) \ 203 ResolvExpr/driver_cfa_cpp-AdjustExprType.$(OBJEXT) \ 204 ResolvExpr/driver_cfa_cpp-AlternativePrinter.$(OBJEXT) \ 205 ResolvExpr/driver_cfa_cpp-Resolver.$(OBJEXT) \ 206 ResolvExpr/driver_cfa_cpp-ResolveTypeof.$(OBJEXT) \ 207 ResolvExpr/driver_cfa_cpp-RenameVars.$(OBJEXT) \ 208 ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT) \ 209 ResolvExpr/driver_cfa_cpp-PolyCost.$(OBJEXT) \ 210 ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \ 211 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \ 212 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \ 213 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT) \ 214 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \ 215 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \ 216 SymTab/driver_cfa_cpp-Validate.$(OBJEXT) \ 217 SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT) \ 218 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \ 219 SynTree/driver_cfa_cpp-Type.$(OBJEXT) \ 220 SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) \ 221 SynTree/driver_cfa_cpp-BasicType.$(OBJEXT) \ 222 SynTree/driver_cfa_cpp-PointerType.$(OBJEXT) \ 223 SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT) \ 224 SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT) \ 225 SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT) \ 226 SynTree/driver_cfa_cpp-ReferenceToType.$(OBJEXT) \ 227 SynTree/driver_cfa_cpp-TupleType.$(OBJEXT) \ 228 SynTree/driver_cfa_cpp-TypeofType.$(OBJEXT) \ 229 SynTree/driver_cfa_cpp-AttrType.$(OBJEXT) \ 230 SynTree/driver_cfa_cpp-VarArgsType.$(OBJEXT) \ 231 SynTree/driver_cfa_cpp-ZeroOneType.$(OBJEXT) \ 232 SynTree/driver_cfa_cpp-Constant.$(OBJEXT) \ 233 SynTree/driver_cfa_cpp-Expression.$(OBJEXT) \ 234 SynTree/driver_cfa_cpp-TupleExpr.$(OBJEXT) \ 235 SynTree/driver_cfa_cpp-CommaExpr.$(OBJEXT) \ 236 SynTree/driver_cfa_cpp-TypeExpr.$(OBJEXT) \ 237 SynTree/driver_cfa_cpp-ApplicationExpr.$(OBJEXT) \ 238 SynTree/driver_cfa_cpp-AddressExpr.$(OBJEXT) \ 239 SynTree/driver_cfa_cpp-Statement.$(OBJEXT) \ 240 SynTree/driver_cfa_cpp-CompoundStmt.$(OBJEXT) \ 241 SynTree/driver_cfa_cpp-DeclStmt.$(OBJEXT) \ 242 SynTree/driver_cfa_cpp-Declaration.$(OBJEXT) \ 243 SynTree/driver_cfa_cpp-DeclarationWithType.$(OBJEXT) \ 244 SynTree/driver_cfa_cpp-ObjectDecl.$(OBJEXT) \ 245 SynTree/driver_cfa_cpp-FunctionDecl.$(OBJEXT) \ 246 SynTree/driver_cfa_cpp-AggregateDecl.$(OBJEXT) \ 247 SynTree/driver_cfa_cpp-NamedTypeDecl.$(OBJEXT) \ 248 SynTree/driver_cfa_cpp-TypeDecl.$(OBJEXT) \ 249 SynTree/driver_cfa_cpp-Initializer.$(OBJEXT) \ 250 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \ 251 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \ 252 SynTree/driver_cfa_cpp-DeclReplacer.$(OBJEXT) \ 253 Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \ 254 Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT) \ 255 Tuples/driver_cfa_cpp-Explode.$(OBJEXT) \ 256 Virtual/driver_cfa_cpp-ExpandCasts.$(OBJEXT) 257 am_driver_cfa_cpp_OBJECTS = $(am__objects_1) 258 driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS) 259 driver_cfa_cpp_DEPENDENCIES = 260 driver_cfa_cpp_LINK = $(CXXLD) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) \ 261 $(driver_cfa_cpp_LDFLAGS) $(LDFLAGS) -o $@ 248 am__objects_9 = main.$(OBJEXT) MakeLibCfa.$(OBJEXT) \ 249 CompilationState.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ 250 CodeGen/Generate.$(OBJEXT) CodeGen/FixNames.$(OBJEXT) \ 251 CodeTools/DeclStats.$(OBJEXT) \ 252 CodeTools/ResolvProtoDump.$(OBJEXT) \ 253 CodeTools/TrackLoc.$(OBJEXT) Concurrency/Keywords.$(OBJEXT) \ 254 Concurrency/Waitfor.$(OBJEXT) $(am__objects_3) \ 255 Common/DebugMalloc.$(OBJEXT) $(am__objects_4) \ 256 ControlStruct/ExceptTranslate.$(OBJEXT) GenPoly/Box.$(OBJEXT) \ 257 GenPoly/GenPoly.$(OBJEXT) GenPoly/ScrubTyVars.$(OBJEXT) \ 258 GenPoly/Lvalue.$(OBJEXT) GenPoly/Specialize.$(OBJEXT) \ 259 GenPoly/FindFunction.$(OBJEXT) \ 260 GenPoly/InstantiateGeneric.$(OBJEXT) \ 261 InitTweak/GenInit.$(OBJEXT) InitTweak/FixInit.$(OBJEXT) \ 262 InitTweak/FixGlobalInit.$(OBJEXT) \ 263 InitTweak/InitTweak.$(OBJEXT) Parser/parser.$(OBJEXT) \ 264 Parser/lex.$(OBJEXT) Parser/TypedefTable.$(OBJEXT) \ 265 Parser/ParseNode.$(OBJEXT) Parser/DeclarationNode.$(OBJEXT) \ 266 Parser/ExpressionNode.$(OBJEXT) Parser/StatementNode.$(OBJEXT) \ 267 Parser/InitializerNode.$(OBJEXT) Parser/TypeData.$(OBJEXT) \ 268 Parser/LinkageSpec.$(OBJEXT) Parser/parserutility.$(OBJEXT) \ 269 $(am__objects_5) ResolvExpr/AlternativePrinter.$(OBJEXT) \ 270 $(am__objects_6) $(am__objects_7) \ 271 Tuples/TupleAssignment.$(OBJEXT) \ 272 Tuples/TupleExpansion.$(OBJEXT) Tuples/Explode.$(OBJEXT) \ 273 Tuples/Tuples.$(OBJEXT) Validate/HandleAttributes.$(OBJEXT) \ 274 Validate/FindSpecialDecls.$(OBJEXT) \ 275 Virtual/ExpandCasts.$(OBJEXT) 276 am____driver_cfa_cpp_OBJECTS = $(am__objects_9) 277 ___driver_cfa_cpp_OBJECTS = $(am____driver_cfa_cpp_OBJECTS) 278 am__DEPENDENCIES_1 = 279 ___driver_cfa_cpp_DEPENDENCIES = $(am__DEPENDENCIES_1) \ 280 $(am__DEPENDENCIES_1) 281 AM_V_lt = $(am__v_lt_@AM_V@) 282 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 283 am__v_lt_0 = --silent 284 am__v_lt_1 = 285 am_demangler_OBJECTS = SymTab/demangler.$(OBJEXT) 286 demangler_OBJECTS = $(am_demangler_OBJECTS) 287 demangler_DEPENDENCIES = libdemangle.a 262 288 AM_V_P = $(am__v_P_@AM_V@) 263 289 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) … … 276 302 am__depfiles_maybe = depfiles 277 303 am__mv = mv -f 278 AM_V_lt = $(am__v_lt_@AM_V@)279 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)280 am__v_lt_0 = --silent281 am__v_lt_1 =282 304 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ 283 305 $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 306 LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 307 $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ 308 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 309 $(AM_CXXFLAGS) $(CXXFLAGS) 284 310 AM_V_CXX = $(am__v_CXX_@AM_V@) 285 311 am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) … … 287 313 am__v_CXX_1 = 288 314 CXXLD = $(CXX) 289 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ 290 -o $@ 315 CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 316 $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ 317 $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 291 318 AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) 292 319 am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) 293 320 am__v_CXXLD_0 = @echo " CXXLD " $@; 294 321 am__v_CXXLD_1 = 295 @MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ ||296 322 LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) 323 LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 324 $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) 297 325 AM_V_LEX = $(am__v_LEX_@AM_V@) 298 326 am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) … … 300 328 am__v_LEX_1 = 301 329 YLWRAP = $(top_srcdir)/automake/ylwrap 302 @MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ ||303 330 am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ 304 331 -e s/c++$$/h++/ -e s/c$$/h/ 305 332 YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) 333 LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 334 $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) 306 335 AM_V_YACC = $(am__v_YACC_@AM_V@) 307 336 am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) … … 310 339 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 311 340 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 341 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 342 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ 343 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 344 $(AM_CFLAGS) $(CFLAGS) 312 345 AM_V_CC = $(am__v_CC_@AM_V@) 313 346 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) … … 315 348 am__v_CC_1 = 316 349 CCLD = $(CC) 317 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 350 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 351 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 352 $(AM_LDFLAGS) $(LDFLAGS) -o $@ 318 353 AM_V_CCLD = $(am__v_CCLD_@AM_V@) 319 354 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) 320 355 am__v_CCLD_0 = @echo " CCLD " $@; 321 356 am__v_CCLD_1 = 322 SOURCES = $(driver_cfa_cpp_SOURCES) 323 DIST_SOURCES = $(driver_cfa_cpp_SOURCES) 357 SOURCES = $(libdemangle_a_SOURCES) $(___driver_cfa_cpp_SOURCES) \ 358 $(demangler_SOURCES) 359 DIST_SOURCES = $(libdemangle_a_SOURCES) $(___driver_cfa_cpp_SOURCES) \ 360 $(demangler_SOURCES) 324 361 am__can_run_installinfo = \ 325 362 case $$AM_UPDATE_INFO_DIR in \ … … 327 364 *) (install-info --version) >/dev/null 2>&1;; \ 328 365 esac 329 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 366 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ 367 $(LISP)config.h.in 330 368 # Read a list of newline-separated strings from the standard input, 331 369 # and print each of them once, without duplicates. Input order is … … 346 384 ETAGS = etags 347 385 CTAGS = ctags 348 am__DIST_COMMON = $(srcdir)/ CodeGen/module.mk \386 am__DIST_COMMON = $(srcdir)/AST/module.mk $(srcdir)/CodeGen/module.mk \ 349 387 $(srcdir)/CodeTools/module.mk $(srcdir)/Common/module.mk \ 350 388 $(srcdir)/Concurrency/module.mk \ … … 353 391 $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk \ 354 392 $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk \ 355 $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk \ 356 $(top_srcdir)/automake/depcomp $(top_srcdir)/automake/ylwrap \ 357 Parser/lex.cc Parser/parser.cc Parser/parser.hh 393 $(srcdir)/Tuples/module.mk $(srcdir)/Validate/module.mk \ 394 $(srcdir)/Virtual/module.mk $(top_srcdir)/automake/depcomp \ 395 $(top_srcdir)/automake/ylwrap Parser/lex.cc Parser/parser.cc \ 396 Parser/parser.hh 358 397 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 359 398 ACLOCAL = @ACLOCAL@ 360 ALLOCA = @ALLOCA@361 399 AMTAR = @AMTAR@ 362 400 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 401 AR = @AR@ 363 402 AUTOCONF = @AUTOCONF@ 364 403 AUTOHEADER = @AUTOHEADER@ 365 404 AUTOMAKE = @AUTOMAKE@ 366 405 AWK = @AWK@ 367 B ACKEND_CC = @BACKEND_CC@406 BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@ 368 407 CC = @CC@ 369 408 CCAS = @CCAS@ … … 371 410 CCASFLAGS = @CCASFLAGS@ 372 411 CCDEPMODE = @CCDEPMODE@ 412 CFACC = @CFACC@ 413 CFACC_INSTALL = @CFACC_INSTALL@ 414 CFACPP = @CFACPP@ 373 415 CFA_BACKEND_CC = @CFA_BACKEND_CC@ 374 416 CFA_BINDIR = @CFA_BINDIR@ … … 382 424 CPPFLAGS = @CPPFLAGS@ 383 425 CXX = @CXX@ 426 CXXCPP = @CXXCPP@ 384 427 CXXDEPMODE = @CXXDEPMODE@ 385 428 CXXFLAGS = @CXXFLAGS@ 386 429 CYGPATH_W = @CYGPATH_W@ 387 430 DEFS = @DEFS@ 431 DEMANGLER = @DEMANGLER@ 388 432 DEPDIR = @DEPDIR@ 433 DLLTOOL = @DLLTOOL@ 434 DRIVER_DIR = @DRIVER_DIR@ 435 DSYMUTIL = @DSYMUTIL@ 436 DUMPBIN = @DUMPBIN@ 389 437 ECHO_C = @ECHO_C@ 390 438 ECHO_N = @ECHO_N@ … … 392 440 EGREP = @EGREP@ 393 441 EXEEXT = @EXEEXT@ 442 FGREP = @FGREP@ 394 443 GREP = @GREP@ 444 HAS_DISTCC = @HAS_DISTCC@ 445 HOST_FLAGS = @HOST_FLAGS@ 395 446 INSTALL = @INSTALL@ 396 447 INSTALL_DATA = @INSTALL_DATA@ … … 398 449 INSTALL_SCRIPT = @INSTALL_SCRIPT@ 399 450 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 451 LD = @LD@ 400 452 LDFLAGS = @LDFLAGS@ 401 453 LEX = @LEX@ 402 454 LEXLIB = @LEXLIB@ 403 455 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ 456 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 457 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 458 LIBDEMANGLE = @LIBDEMANGLE@ 404 459 LIBOBJS = @LIBOBJS@ 405 460 LIBS = @LIBS@ 461 LIBTOOL = @LIBTOOL@ 462 LIPO = @LIPO@ 463 LN_S = @LN_S@ 406 464 LTLIBOBJS = @LTLIBOBJS@ 407 MACHINE_TYPE = @MACHINE_TYPE@ 408 MAINT = @MAINT@ 465 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ 409 466 MAKEINFO = @MAKEINFO@ 467 MANIFEST_TOOL = @MANIFEST_TOOL@ 410 468 MKDIR_P = @MKDIR_P@ 469 NM = @NM@ 470 NMEDIT = @NMEDIT@ 471 OBJDUMP = @OBJDUMP@ 411 472 OBJEXT = @OBJEXT@ 473 OTOOL = @OTOOL@ 474 OTOOL64 = @OTOOL64@ 412 475 PACKAGE = @PACKAGE@ 413 476 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ … … 419 482 PATH_SEPARATOR = @PATH_SEPARATOR@ 420 483 RANLIB = @RANLIB@ 484 SED = @SED@ 421 485 SET_MAKE = @SET_MAKE@ 422 486 SHELL = @SHELL@ 423 487 STRIP = @STRIP@ 488 TARGET_HOSTS = @TARGET_HOSTS@ 424 489 VERSION = @VERSION@ 425 490 YACC = @YACC@ … … 429 494 abs_top_builddir = @abs_top_builddir@ 430 495 abs_top_srcdir = @abs_top_srcdir@ 496 ac_ct_AR = @ac_ct_AR@ 431 497 ac_ct_CC = @ac_ct_CC@ 432 498 ac_ct_CXX = @ac_ct_CXX@ 499 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 433 500 am__include = @am__include@ 434 501 am__leading_dot = @am__leading_dot@ … … 479 546 480 547 # create object files in directory with source files 481 AUTOMAKE_OPTIONS = subdir-objects482 SRC = main.cc MakeLibCfa.cc CodeGen/Generate.cc \ 483 CodeGen/CodeGenerator.cc CodeGen/GenType.cc\484 CodeGen/FixNames.cc CodeGen/FixMain.cc \485 Code Gen/OperatorTable.cc CodeTools/DeclStats.cc \548 AUTOMAKE_OPTIONS = foreign subdir-objects 549 ACLOCAL_AMFLAGS = -I automake 550 SRC = main.cc MakeLibCfa.cc CompilationState.cc $(SRC_AST) \ 551 $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/FixNames.cc \ 552 CodeTools/DeclStats.cc CodeTools/ResolvProtoDump.cc \ 486 553 CodeTools/TrackLoc.cc Concurrency/Keywords.cc \ 487 Concurrency/Waitfor.cc Common/SemanticError.cc \ 488 Common/UniqueName.cc Common/DebugMalloc.cc Common/Assert.cc \ 489 Common/Heap.cc ControlStruct/LabelGenerator.cc \ 490 ControlStruct/LabelFixer.cc ControlStruct/MLEMutator.cc \ 491 ControlStruct/Mutate.cc ControlStruct/ForExprMutator.cc \ 492 ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \ 493 GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \ 494 GenPoly/Specialize.cc GenPoly/FindFunction.cc \ 495 GenPoly/InstantiateGeneric.cc InitTweak/GenInit.cc \ 496 InitTweak/FixInit.cc InitTweak/FixGlobalInit.cc \ 497 InitTweak/InitTweak.cc Parser/parser.yy Parser/lex.ll \ 498 Parser/TypedefTable.cc Parser/ParseNode.cc \ 499 Parser/DeclarationNode.cc Parser/ExpressionNode.cc \ 500 Parser/StatementNode.cc Parser/InitializerNode.cc \ 501 Parser/TypeData.cc Parser/LinkageSpec.cc \ 502 Parser/parserutility.cc ResolvExpr/AlternativeFinder.cc \ 503 ResolvExpr/Alternative.cc ResolvExpr/Unify.cc \ 504 ResolvExpr/PtrsAssignable.cc ResolvExpr/CommonType.cc \ 505 ResolvExpr/ConversionCost.cc ResolvExpr/CastCost.cc \ 506 ResolvExpr/PtrsCastable.cc ResolvExpr/AdjustExprType.cc \ 507 ResolvExpr/AlternativePrinter.cc ResolvExpr/Resolver.cc \ 508 ResolvExpr/ResolveTypeof.cc ResolvExpr/RenameVars.cc \ 509 ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \ 510 ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \ 511 ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \ 512 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \ 513 SymTab/FixFunction.cc SymTab/Autogen.cc SynTree/Type.cc \ 514 SynTree/VoidType.cc SynTree/BasicType.cc \ 515 SynTree/PointerType.cc SynTree/ArrayType.cc \ 516 SynTree/ReferenceType.cc SynTree/FunctionType.cc \ 517 SynTree/ReferenceToType.cc SynTree/TupleType.cc \ 518 SynTree/TypeofType.cc SynTree/AttrType.cc \ 519 SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \ 520 SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \ 521 SynTree/CommaExpr.cc SynTree/TypeExpr.cc \ 522 SynTree/ApplicationExpr.cc SynTree/AddressExpr.cc \ 523 SynTree/Statement.cc SynTree/CompoundStmt.cc \ 524 SynTree/DeclStmt.cc SynTree/Declaration.cc \ 525 SynTree/DeclarationWithType.cc SynTree/ObjectDecl.cc \ 526 SynTree/FunctionDecl.cc SynTree/AggregateDecl.cc \ 527 SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \ 528 SynTree/Initializer.cc SynTree/TypeSubstitution.cc \ 529 SynTree/Attribute.cc SynTree/DeclReplacer.cc \ 554 Concurrency/Waitfor.cc $(SRC_COMMON) Common/DebugMalloc.cc \ 555 $(SRC_CONTROLSTRUCT) ControlStruct/ExceptTranslate.cc \ 556 GenPoly/Box.cc GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc \ 557 GenPoly/Lvalue.cc GenPoly/Specialize.cc \ 558 GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \ 559 InitTweak/GenInit.cc InitTweak/FixInit.cc \ 560 InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \ 561 Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \ 562 Parser/ParseNode.cc Parser/DeclarationNode.cc \ 563 Parser/ExpressionNode.cc Parser/StatementNode.cc \ 564 Parser/InitializerNode.cc Parser/TypeData.cc \ 565 Parser/LinkageSpec.cc Parser/parserutility.cc \ 566 $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc \ 567 $(SRC_SYMTAB) $(SRC_SYNTREE) Tuples/TupleAssignment.cc \ 568 Tuples/TupleExpansion.cc Tuples/Explode.cc Tuples/Tuples.cc \ 569 Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc \ 570 Virtual/ExpandCasts.cc 571 SRCDEMANGLE = CompilationState.cc $(SRC_AST) $(SRC_CODEGEN) \ 572 Concurrency/Keywords.cc $(SRC_COMMON) $(SRC_CONTROLSTRUCT) \ 573 GenPoly/GenPoly.cc GenPoly/Lvalue.cc InitTweak/GenInit.cc \ 574 InitTweak/InitTweak.cc Parser/LinkageSpec.cc $(SRC_RESOLVEXPR) \ 575 $(SRC_SYMTAB) SymTab/Demangle.cc $(SRC_SYNTREE) \ 530 576 Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \ 531 Tuples/Explode.cc Virtual/ExpandCasts.cc 532 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \ 533 ${cfa_cpplib_PROGRAMS}} 577 Tuples/Explode.cc Tuples/Tuples.cc \ 578 Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc 579 MAINTAINERCLEANFILES = ${libdir}/${notdir ${cfa_cpplib_PROGRAMS}} 580 MOSTLYCLEANFILES = Parser/lex.cc Parser/parser.cc Parser/parser.hh \ 581 Parser/parser.output 582 @WITH_LIBPROFILER_TRUE@LIBPROFILER = -lprofiler 583 @WITH_LIBTCMALLOC_TRUE@LIBTCMALLOC = -ltcmalloc 584 @WITH_LIBTCMALLOC_TRUE@TCMALLOCFLAG = -DTCMALLOC 585 SRC_AST = \ 586 AST/AssertAcyclic.cpp \ 587 AST/Attribute.cpp \ 588 AST/Convert.cpp \ 589 AST/Decl.cpp \ 590 AST/DeclReplacer.cpp \ 591 AST/Expr.cpp \ 592 AST/GenericSubstitution.cpp \ 593 AST/Init.cpp \ 594 AST/LinkageSpec.cpp \ 595 AST/Node.cpp \ 596 AST/Pass.cpp \ 597 AST/Print.cpp \ 598 AST/Stmt.cpp \ 599 AST/SymbolTable.cpp \ 600 AST/Type.cpp \ 601 AST/TypeEnvironment.cpp \ 602 AST/TypeSubstitution.cpp 603 604 SRC_CODEGEN = \ 605 CodeGen/CodeGenerator.cc \ 606 CodeGen/FixMain.cc \ 607 CodeGen/GenType.cc \ 608 CodeGen/OperatorTable.cc 609 610 SRC_COMMON = \ 611 Common/Assert.cc \ 612 Common/Eval.cc \ 613 Common/PassVisitor.cc \ 614 Common/SemanticError.cc \ 615 Common/Stats/Counter.cc \ 616 Common/Stats/Heap.cc \ 617 Common/Stats/Stats.cc \ 618 Common/Stats/Time.cc \ 619 Common/UniqueName.cc 620 621 SRC_CONTROLSTRUCT = \ 622 ControlStruct/ForExprMutator.cc \ 623 ControlStruct/LabelFixer.cc \ 624 ControlStruct/LabelGenerator.cc \ 625 ControlStruct/MLEMutator.cc \ 626 ControlStruct/Mutate.cc 627 534 628 BUILT_SOURCES = Parser/parser.hh 535 629 AM_YFLAGS = -d -t -v 536 537 # Is there a way to use a variable for the directory names? 630 SRC_RESOLVEXPR = \ 631 ResolvExpr/AdjustExprType.cc \ 632 ResolvExpr/Alternative.cc \ 633 ResolvExpr/AlternativeFinder.cc \ 634 ResolvExpr/Candidate.cpp \ 635 ResolvExpr/CandidateFinder.cpp \ 636 ResolvExpr/CastCost.cc \ 637 ResolvExpr/CommonType.cc \ 638 ResolvExpr/ConversionCost.cc \ 639 ResolvExpr/CurrentObject.cc \ 640 ResolvExpr/ExplodedActual.cc \ 641 ResolvExpr/ExplodedArg.cpp \ 642 ResolvExpr/FindOpenVars.cc \ 643 ResolvExpr/Occurs.cc \ 644 ResolvExpr/PolyCost.cc \ 645 ResolvExpr/PtrsAssignable.cc \ 646 ResolvExpr/PtrsCastable.cc \ 647 ResolvExpr/RenameVars.cc \ 648 ResolvExpr/ResolveAssertions.cc \ 649 ResolvExpr/Resolver.cc \ 650 ResolvExpr/ResolveTypeof.cc \ 651 ResolvExpr/SatisfyAssertions.cpp \ 652 ResolvExpr/SpecCost.cc \ 653 ResolvExpr/TypeEnvironment.cc \ 654 ResolvExpr/Unify.cc 655 656 SRC_SYMTAB = \ 657 SymTab/Autogen.cc \ 658 SymTab/FixFunction.cc \ 659 SymTab/Indexer.cc \ 660 SymTab/Mangler.cc \ 661 SymTab/ManglerCommon.cc \ 662 SymTab/Validate.cc 663 664 SRC_SYNTREE = \ 665 SynTree/Type.cc \ 666 SynTree/VoidType.cc \ 667 SynTree/BasicType.cc \ 668 SynTree/PointerType.cc \ 669 SynTree/ArrayType.cc \ 670 SynTree/ReferenceType.cc \ 671 SynTree/FunctionType.cc \ 672 SynTree/ReferenceToType.cc \ 673 SynTree/TupleType.cc \ 674 SynTree/TypeofType.cc \ 675 SynTree/AttrType.cc \ 676 SynTree/VarArgsType.cc \ 677 SynTree/ZeroOneType.cc \ 678 SynTree/Constant.cc \ 679 SynTree/Expression.cc \ 680 SynTree/TupleExpr.cc \ 681 SynTree/CommaExpr.cc \ 682 SynTree/TypeExpr.cc \ 683 SynTree/ApplicationExpr.cc \ 684 SynTree/AddressExpr.cc \ 685 SynTree/Statement.cc \ 686 SynTree/CompoundStmt.cc \ 687 SynTree/DeclStmt.cc \ 688 SynTree/Declaration.cc \ 689 SynTree/DeclarationWithType.cc \ 690 SynTree/ObjectDecl.cc \ 691 SynTree/FunctionDecl.cc \ 692 SynTree/AggregateDecl.cc \ 693 SynTree/NamedTypeDecl.cc \ 694 SynTree/TypeDecl.cc \ 695 SynTree/Initializer.cc \ 696 SynTree/TypeSubstitution.cc \ 697 SynTree/Attribute.cc \ 698 SynTree/DeclReplacer.cc 699 538 700 539 701 # put into lib for now 540 cfa_cpplibdir = ${CFA_LIBDIR} 541 driver_cfa_cpp_SOURCES = ${SRC} 542 driver_cfa_cpp_LDADD = -ldl # yywrap 543 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14 544 driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic 702 cfa_cpplibdir = $(CFA_LIBDIR) 703 ___driver_cfa_cpp_SOURCES = $(SRC) 704 ___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC) 705 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++14 $(TCMALLOCFLAG) 706 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 707 ARFLAGS = cr 708 demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete 709 demangler_LDADD = libdemangle.a -ldl # yywrap 710 noinst_LIBRARIES = $(LIBDEMANGLE) 711 EXTRA_LIBRARIES = libdemangle.a 712 libdemangle_a_SOURCES = $(SRCDEMANGLE) 545 713 all: $(BUILT_SOURCES) 546 714 $(MAKE) $(AM_MAKEFLAGS) all-am 547 715 548 716 .SUFFIXES: 549 .SUFFIXES: .cc . ll.o .obj .yy550 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk $(am__configure_deps)717 .SUFFIXES: .cc .cpp .ll .lo .o .obj .yy 718 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/AST/module.mk $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Validate/module.mk $(srcdir)/Virtual/module.mk $(am__configure_deps) 551 719 @for dep in $?; do \ 552 720 case '$(am__configure_deps)' in \ … … 568 736 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ 569 737 esac; 570 $(srcdir)/ CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk $(am__empty):738 $(srcdir)/AST/module.mk $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Validate/module.mk $(srcdir)/Virtual/module.mk $(am__empty): 571 739 572 740 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 573 741 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 574 742 575 $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@$(am__configure_deps)743 $(top_srcdir)/configure: $(am__configure_deps) 576 744 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 577 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@$(am__aclocal_m4_deps)745 $(ACLOCAL_M4): $(am__aclocal_m4_deps) 578 746 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 579 747 $(am__aclocal_m4_deps): 748 749 clean-noinstLIBRARIES: 750 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) 751 AST/$(am__dirstamp): 752 @$(MKDIR_P) AST 753 @: > AST/$(am__dirstamp) 754 AST/$(DEPDIR)/$(am__dirstamp): 755 @$(MKDIR_P) AST/$(DEPDIR) 756 @: > AST/$(DEPDIR)/$(am__dirstamp) 757 AST/AssertAcyclic.$(OBJEXT): AST/$(am__dirstamp) \ 758 AST/$(DEPDIR)/$(am__dirstamp) 759 AST/Attribute.$(OBJEXT): AST/$(am__dirstamp) \ 760 AST/$(DEPDIR)/$(am__dirstamp) 761 AST/Convert.$(OBJEXT): AST/$(am__dirstamp) \ 762 AST/$(DEPDIR)/$(am__dirstamp) 763 AST/Decl.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 764 AST/DeclReplacer.$(OBJEXT): AST/$(am__dirstamp) \ 765 AST/$(DEPDIR)/$(am__dirstamp) 766 AST/Expr.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 767 AST/GenericSubstitution.$(OBJEXT): AST/$(am__dirstamp) \ 768 AST/$(DEPDIR)/$(am__dirstamp) 769 AST/Init.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 770 AST/LinkageSpec.$(OBJEXT): AST/$(am__dirstamp) \ 771 AST/$(DEPDIR)/$(am__dirstamp) 772 AST/Node.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 773 AST/Pass.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 774 AST/Print.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 775 AST/Stmt.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 776 AST/SymbolTable.$(OBJEXT): AST/$(am__dirstamp) \ 777 AST/$(DEPDIR)/$(am__dirstamp) 778 AST/Type.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 779 AST/TypeEnvironment.$(OBJEXT): AST/$(am__dirstamp) \ 780 AST/$(DEPDIR)/$(am__dirstamp) 781 AST/TypeSubstitution.$(OBJEXT): AST/$(am__dirstamp) \ 782 AST/$(DEPDIR)/$(am__dirstamp) 783 CodeGen/$(am__dirstamp): 784 @$(MKDIR_P) CodeGen 785 @: > CodeGen/$(am__dirstamp) 786 CodeGen/$(DEPDIR)/$(am__dirstamp): 787 @$(MKDIR_P) CodeGen/$(DEPDIR) 788 @: > CodeGen/$(DEPDIR)/$(am__dirstamp) 789 CodeGen/CodeGenerator.$(OBJEXT): CodeGen/$(am__dirstamp) \ 790 CodeGen/$(DEPDIR)/$(am__dirstamp) 791 CodeGen/FixMain.$(OBJEXT): CodeGen/$(am__dirstamp) \ 792 CodeGen/$(DEPDIR)/$(am__dirstamp) 793 CodeGen/GenType.$(OBJEXT): CodeGen/$(am__dirstamp) \ 794 CodeGen/$(DEPDIR)/$(am__dirstamp) 795 CodeGen/OperatorTable.$(OBJEXT): CodeGen/$(am__dirstamp) \ 796 CodeGen/$(DEPDIR)/$(am__dirstamp) 797 Concurrency/$(am__dirstamp): 798 @$(MKDIR_P) Concurrency 799 @: > Concurrency/$(am__dirstamp) 800 Concurrency/$(DEPDIR)/$(am__dirstamp): 801 @$(MKDIR_P) Concurrency/$(DEPDIR) 802 @: > Concurrency/$(DEPDIR)/$(am__dirstamp) 803 Concurrency/Keywords.$(OBJEXT): Concurrency/$(am__dirstamp) \ 804 Concurrency/$(DEPDIR)/$(am__dirstamp) 805 Common/$(am__dirstamp): 806 @$(MKDIR_P) Common 807 @: > Common/$(am__dirstamp) 808 Common/$(DEPDIR)/$(am__dirstamp): 809 @$(MKDIR_P) Common/$(DEPDIR) 810 @: > Common/$(DEPDIR)/$(am__dirstamp) 811 Common/Assert.$(OBJEXT): Common/$(am__dirstamp) \ 812 Common/$(DEPDIR)/$(am__dirstamp) 813 Common/Eval.$(OBJEXT): Common/$(am__dirstamp) \ 814 Common/$(DEPDIR)/$(am__dirstamp) 815 Common/PassVisitor.$(OBJEXT): Common/$(am__dirstamp) \ 816 Common/$(DEPDIR)/$(am__dirstamp) 817 Common/SemanticError.$(OBJEXT): Common/$(am__dirstamp) \ 818 Common/$(DEPDIR)/$(am__dirstamp) 819 Common/Stats/$(am__dirstamp): 820 @$(MKDIR_P) Common/Stats 821 @: > Common/Stats/$(am__dirstamp) 822 Common/Stats/$(DEPDIR)/$(am__dirstamp): 823 @$(MKDIR_P) Common/Stats/$(DEPDIR) 824 @: > Common/Stats/$(DEPDIR)/$(am__dirstamp) 825 Common/Stats/Counter.$(OBJEXT): Common/Stats/$(am__dirstamp) \ 826 Common/Stats/$(DEPDIR)/$(am__dirstamp) 827 Common/Stats/Heap.$(OBJEXT): Common/Stats/$(am__dirstamp) \ 828 Common/Stats/$(DEPDIR)/$(am__dirstamp) 829 Common/Stats/Stats.$(OBJEXT): Common/Stats/$(am__dirstamp) \ 830 Common/Stats/$(DEPDIR)/$(am__dirstamp) 831 Common/Stats/Time.$(OBJEXT): Common/Stats/$(am__dirstamp) \ 832 Common/Stats/$(DEPDIR)/$(am__dirstamp) 833 Common/UniqueName.$(OBJEXT): Common/$(am__dirstamp) \ 834 Common/$(DEPDIR)/$(am__dirstamp) 835 ControlStruct/$(am__dirstamp): 836 @$(MKDIR_P) ControlStruct 837 @: > ControlStruct/$(am__dirstamp) 838 ControlStruct/$(DEPDIR)/$(am__dirstamp): 839 @$(MKDIR_P) ControlStruct/$(DEPDIR) 840 @: > ControlStruct/$(DEPDIR)/$(am__dirstamp) 841 ControlStruct/ForExprMutator.$(OBJEXT): ControlStruct/$(am__dirstamp) \ 842 ControlStruct/$(DEPDIR)/$(am__dirstamp) 843 ControlStruct/LabelFixer.$(OBJEXT): ControlStruct/$(am__dirstamp) \ 844 ControlStruct/$(DEPDIR)/$(am__dirstamp) 845 ControlStruct/LabelGenerator.$(OBJEXT): ControlStruct/$(am__dirstamp) \ 846 ControlStruct/$(DEPDIR)/$(am__dirstamp) 847 ControlStruct/MLEMutator.$(OBJEXT): ControlStruct/$(am__dirstamp) \ 848 ControlStruct/$(DEPDIR)/$(am__dirstamp) 849 ControlStruct/Mutate.$(OBJEXT): ControlStruct/$(am__dirstamp) \ 850 ControlStruct/$(DEPDIR)/$(am__dirstamp) 851 GenPoly/$(am__dirstamp): 852 @$(MKDIR_P) GenPoly 853 @: > GenPoly/$(am__dirstamp) 854 GenPoly/$(DEPDIR)/$(am__dirstamp): 855 @$(MKDIR_P) GenPoly/$(DEPDIR) 856 @: > GenPoly/$(DEPDIR)/$(am__dirstamp) 857 GenPoly/GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \ 858 GenPoly/$(DEPDIR)/$(am__dirstamp) 859 GenPoly/Lvalue.$(OBJEXT): GenPoly/$(am__dirstamp) \ 860 GenPoly/$(DEPDIR)/$(am__dirstamp) 861 InitTweak/$(am__dirstamp): 862 @$(MKDIR_P) InitTweak 863 @: > InitTweak/$(am__dirstamp) 864 InitTweak/$(DEPDIR)/$(am__dirstamp): 865 @$(MKDIR_P) InitTweak/$(DEPDIR) 866 @: > InitTweak/$(DEPDIR)/$(am__dirstamp) 867 InitTweak/GenInit.$(OBJEXT): InitTweak/$(am__dirstamp) \ 868 InitTweak/$(DEPDIR)/$(am__dirstamp) 869 InitTweak/InitTweak.$(OBJEXT): InitTweak/$(am__dirstamp) \ 870 InitTweak/$(DEPDIR)/$(am__dirstamp) 871 Parser/$(am__dirstamp): 872 @$(MKDIR_P) Parser 873 @: > Parser/$(am__dirstamp) 874 Parser/$(DEPDIR)/$(am__dirstamp): 875 @$(MKDIR_P) Parser/$(DEPDIR) 876 @: > Parser/$(DEPDIR)/$(am__dirstamp) 877 Parser/LinkageSpec.$(OBJEXT): Parser/$(am__dirstamp) \ 878 Parser/$(DEPDIR)/$(am__dirstamp) 879 ResolvExpr/$(am__dirstamp): 880 @$(MKDIR_P) ResolvExpr 881 @: > ResolvExpr/$(am__dirstamp) 882 ResolvExpr/$(DEPDIR)/$(am__dirstamp): 883 @$(MKDIR_P) ResolvExpr/$(DEPDIR) 884 @: > ResolvExpr/$(DEPDIR)/$(am__dirstamp) 885 ResolvExpr/AdjustExprType.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 886 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 887 ResolvExpr/Alternative.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 888 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 889 ResolvExpr/AlternativeFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 890 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 891 ResolvExpr/Candidate.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 892 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 893 ResolvExpr/CandidateFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 894 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 895 ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 896 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 897 ResolvExpr/CommonType.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 898 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 899 ResolvExpr/ConversionCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 900 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 901 ResolvExpr/CurrentObject.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 902 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 903 ResolvExpr/ExplodedActual.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 904 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 905 ResolvExpr/ExplodedArg.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 906 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 907 ResolvExpr/FindOpenVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 908 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 909 ResolvExpr/Occurs.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 910 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 911 ResolvExpr/PolyCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 912 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 913 ResolvExpr/PtrsAssignable.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 914 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 915 ResolvExpr/PtrsCastable.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 916 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 917 ResolvExpr/RenameVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 918 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 919 ResolvExpr/ResolveAssertions.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 920 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 921 ResolvExpr/Resolver.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 922 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 923 ResolvExpr/ResolveTypeof.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 924 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 925 ResolvExpr/SatisfyAssertions.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 926 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 927 ResolvExpr/SpecCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 928 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 929 ResolvExpr/TypeEnvironment.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 930 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 931 ResolvExpr/Unify.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 932 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 933 SymTab/$(am__dirstamp): 934 @$(MKDIR_P) SymTab 935 @: > SymTab/$(am__dirstamp) 936 SymTab/$(DEPDIR)/$(am__dirstamp): 937 @$(MKDIR_P) SymTab/$(DEPDIR) 938 @: > SymTab/$(DEPDIR)/$(am__dirstamp) 939 SymTab/Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \ 940 SymTab/$(DEPDIR)/$(am__dirstamp) 941 SymTab/FixFunction.$(OBJEXT): SymTab/$(am__dirstamp) \ 942 SymTab/$(DEPDIR)/$(am__dirstamp) 943 SymTab/Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \ 944 SymTab/$(DEPDIR)/$(am__dirstamp) 945 SymTab/Mangler.$(OBJEXT): SymTab/$(am__dirstamp) \ 946 SymTab/$(DEPDIR)/$(am__dirstamp) 947 SymTab/ManglerCommon.$(OBJEXT): SymTab/$(am__dirstamp) \ 948 SymTab/$(DEPDIR)/$(am__dirstamp) 949 SymTab/Validate.$(OBJEXT): SymTab/$(am__dirstamp) \ 950 SymTab/$(DEPDIR)/$(am__dirstamp) 951 SymTab/Demangle.$(OBJEXT): SymTab/$(am__dirstamp) \ 952 SymTab/$(DEPDIR)/$(am__dirstamp) 953 SynTree/$(am__dirstamp): 954 @$(MKDIR_P) SynTree 955 @: > SynTree/$(am__dirstamp) 956 SynTree/$(DEPDIR)/$(am__dirstamp): 957 @$(MKDIR_P) SynTree/$(DEPDIR) 958 @: > SynTree/$(DEPDIR)/$(am__dirstamp) 959 SynTree/Type.$(OBJEXT): SynTree/$(am__dirstamp) \ 960 SynTree/$(DEPDIR)/$(am__dirstamp) 961 SynTree/VoidType.$(OBJEXT): SynTree/$(am__dirstamp) \ 962 SynTree/$(DEPDIR)/$(am__dirstamp) 963 SynTree/BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \ 964 SynTree/$(DEPDIR)/$(am__dirstamp) 965 SynTree/PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \ 966 SynTree/$(DEPDIR)/$(am__dirstamp) 967 SynTree/ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \ 968 SynTree/$(DEPDIR)/$(am__dirstamp) 969 SynTree/ReferenceType.$(OBJEXT): SynTree/$(am__dirstamp) \ 970 SynTree/$(DEPDIR)/$(am__dirstamp) 971 SynTree/FunctionType.$(OBJEXT): SynTree/$(am__dirstamp) \ 972 SynTree/$(DEPDIR)/$(am__dirstamp) 973 SynTree/ReferenceToType.$(OBJEXT): SynTree/$(am__dirstamp) \ 974 SynTree/$(DEPDIR)/$(am__dirstamp) 975 SynTree/TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \ 976 SynTree/$(DEPDIR)/$(am__dirstamp) 977 SynTree/TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \ 978 SynTree/$(DEPDIR)/$(am__dirstamp) 979 SynTree/AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \ 980 SynTree/$(DEPDIR)/$(am__dirstamp) 981 SynTree/VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \ 982 SynTree/$(DEPDIR)/$(am__dirstamp) 983 SynTree/ZeroOneType.$(OBJEXT): SynTree/$(am__dirstamp) \ 984 SynTree/$(DEPDIR)/$(am__dirstamp) 985 SynTree/Constant.$(OBJEXT): SynTree/$(am__dirstamp) \ 986 SynTree/$(DEPDIR)/$(am__dirstamp) 987 SynTree/Expression.$(OBJEXT): SynTree/$(am__dirstamp) \ 988 SynTree/$(DEPDIR)/$(am__dirstamp) 989 SynTree/TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 990 SynTree/$(DEPDIR)/$(am__dirstamp) 991 SynTree/CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 992 SynTree/$(DEPDIR)/$(am__dirstamp) 993 SynTree/TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 994 SynTree/$(DEPDIR)/$(am__dirstamp) 995 SynTree/ApplicationExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 996 SynTree/$(DEPDIR)/$(am__dirstamp) 997 SynTree/AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 998 SynTree/$(DEPDIR)/$(am__dirstamp) 999 SynTree/Statement.$(OBJEXT): SynTree/$(am__dirstamp) \ 1000 SynTree/$(DEPDIR)/$(am__dirstamp) 1001 SynTree/CompoundStmt.$(OBJEXT): SynTree/$(am__dirstamp) \ 1002 SynTree/$(DEPDIR)/$(am__dirstamp) 1003 SynTree/DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \ 1004 SynTree/$(DEPDIR)/$(am__dirstamp) 1005 SynTree/Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \ 1006 SynTree/$(DEPDIR)/$(am__dirstamp) 1007 SynTree/DeclarationWithType.$(OBJEXT): SynTree/$(am__dirstamp) \ 1008 SynTree/$(DEPDIR)/$(am__dirstamp) 1009 SynTree/ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \ 1010 SynTree/$(DEPDIR)/$(am__dirstamp) 1011 SynTree/FunctionDecl.$(OBJEXT): SynTree/$(am__dirstamp) \ 1012 SynTree/$(DEPDIR)/$(am__dirstamp) 1013 SynTree/AggregateDecl.$(OBJEXT): SynTree/$(am__dirstamp) \ 1014 SynTree/$(DEPDIR)/$(am__dirstamp) 1015 SynTree/NamedTypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \ 1016 SynTree/$(DEPDIR)/$(am__dirstamp) 1017 SynTree/TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \ 1018 SynTree/$(DEPDIR)/$(am__dirstamp) 1019 SynTree/Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \ 1020 SynTree/$(DEPDIR)/$(am__dirstamp) 1021 SynTree/TypeSubstitution.$(OBJEXT): SynTree/$(am__dirstamp) \ 1022 SynTree/$(DEPDIR)/$(am__dirstamp) 1023 SynTree/Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \ 1024 SynTree/$(DEPDIR)/$(am__dirstamp) 1025 SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \ 1026 SynTree/$(DEPDIR)/$(am__dirstamp) 1027 Tuples/$(am__dirstamp): 1028 @$(MKDIR_P) Tuples 1029 @: > Tuples/$(am__dirstamp) 1030 Tuples/$(DEPDIR)/$(am__dirstamp): 1031 @$(MKDIR_P) Tuples/$(DEPDIR) 1032 @: > Tuples/$(DEPDIR)/$(am__dirstamp) 1033 Tuples/TupleAssignment.$(OBJEXT): Tuples/$(am__dirstamp) \ 1034 Tuples/$(DEPDIR)/$(am__dirstamp) 1035 Tuples/TupleExpansion.$(OBJEXT): Tuples/$(am__dirstamp) \ 1036 Tuples/$(DEPDIR)/$(am__dirstamp) 1037 Tuples/Explode.$(OBJEXT): Tuples/$(am__dirstamp) \ 1038 Tuples/$(DEPDIR)/$(am__dirstamp) 1039 Tuples/Tuples.$(OBJEXT): Tuples/$(am__dirstamp) \ 1040 Tuples/$(DEPDIR)/$(am__dirstamp) 1041 Validate/$(am__dirstamp): 1042 @$(MKDIR_P) Validate 1043 @: > Validate/$(am__dirstamp) 1044 Validate/$(DEPDIR)/$(am__dirstamp): 1045 @$(MKDIR_P) Validate/$(DEPDIR) 1046 @: > Validate/$(DEPDIR)/$(am__dirstamp) 1047 Validate/HandleAttributes.$(OBJEXT): Validate/$(am__dirstamp) \ 1048 Validate/$(DEPDIR)/$(am__dirstamp) 1049 Validate/FindSpecialDecls.$(OBJEXT): Validate/$(am__dirstamp) \ 1050 Validate/$(DEPDIR)/$(am__dirstamp) 1051 1052 libdemangle.a: $(libdemangle_a_OBJECTS) $(libdemangle_a_DEPENDENCIES) $(EXTRA_libdemangle_a_DEPENDENCIES) 1053 $(AM_V_at)-rm -f libdemangle.a 1054 $(AM_V_AR)$(libdemangle_a_AR) libdemangle.a $(libdemangle_a_OBJECTS) $(libdemangle_a_LIBADD) 1055 $(AM_V_at)$(RANLIB) libdemangle.a 580 1056 install-cfa_cpplibPROGRAMS: $(cfa_cpplib_PROGRAMS) 581 1057 @$(NORMAL_INSTALL) … … 588 1064 sed 's/$(EXEEXT)$$//' | \ 589 1065 while read p p1; do if test -f $$p \ 1066 || test -f $$p1 \ 590 1067 ; then echo "$$p"; echo "$$p"; else :; fi; \ 591 1068 done | \ … … 602 1079 if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ 603 1080 test -z "$$files" || { \ 604 echo " $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \605 $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \1081 echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \ 1082 $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \ 606 1083 } \ 607 1084 ; done … … 619 1096 620 1097 clean-cfa_cpplibPROGRAMS: 621 -test -z "$(cfa_cpplib_PROGRAMS)" || rm -f $(cfa_cpplib_PROGRAMS)622 CodeGen/$(am__dirstamp): 623 @$(MKDIR_P) CodeGen624 @: > CodeGen/$(am__dirstamp)625 CodeGen/$(DEPDIR)/$(am__dirstamp): 626 @$(MKDIR_P) CodeGen/$(DEPDIR)627 @: > CodeGen/$(DEPDIR)/$(am__dirstamp)628 CodeGen/ driver_cfa_cpp-Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \1098 @list='$(cfa_cpplib_PROGRAMS)'; test -n "$$list" || exit 0; \ 1099 echo " rm -f" $$list; \ 1100 rm -f $$list || exit $$?; \ 1101 test -n "$(EXEEXT)" || exit 0; \ 1102 list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ 1103 echo " rm -f" $$list; \ 1104 rm -f $$list 1105 CodeGen/Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \ 629 1106 CodeGen/$(DEPDIR)/$(am__dirstamp) 630 CodeGen/driver_cfa_cpp-CodeGenerator.$(OBJEXT): \ 631 CodeGen/$(am__dirstamp) CodeGen/$(DEPDIR)/$(am__dirstamp) 632 CodeGen/driver_cfa_cpp-GenType.$(OBJEXT): CodeGen/$(am__dirstamp) \ 1107 CodeGen/FixNames.$(OBJEXT): CodeGen/$(am__dirstamp) \ 633 1108 CodeGen/$(DEPDIR)/$(am__dirstamp) 634 CodeGen/driver_cfa_cpp-FixNames.$(OBJEXT): CodeGen/$(am__dirstamp) \635 CodeGen/$(DEPDIR)/$(am__dirstamp)636 CodeGen/driver_cfa_cpp-FixMain.$(OBJEXT): CodeGen/$(am__dirstamp) \637 CodeGen/$(DEPDIR)/$(am__dirstamp)638 CodeGen/driver_cfa_cpp-OperatorTable.$(OBJEXT): \639 CodeGen/$(am__dirstamp) CodeGen/$(DEPDIR)/$(am__dirstamp)640 1109 CodeTools/$(am__dirstamp): 641 1110 @$(MKDIR_P) CodeTools … … 644 1113 @$(MKDIR_P) CodeTools/$(DEPDIR) 645 1114 @: > CodeTools/$(DEPDIR)/$(am__dirstamp) 646 CodeTools/driver_cfa_cpp-DeclStats.$(OBJEXT): \ 647 CodeTools/$(am__dirstamp) CodeTools/$(DEPDIR)/$(am__dirstamp) 648 CodeTools/driver_cfa_cpp-TrackLoc.$(OBJEXT): \ 649 CodeTools/$(am__dirstamp) CodeTools/$(DEPDIR)/$(am__dirstamp) 650 Concurrency/$(am__dirstamp): 651 @$(MKDIR_P) Concurrency 652 @: > Concurrency/$(am__dirstamp) 653 Concurrency/$(DEPDIR)/$(am__dirstamp): 654 @$(MKDIR_P) Concurrency/$(DEPDIR) 655 @: > Concurrency/$(DEPDIR)/$(am__dirstamp) 656 Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT): \ 657 Concurrency/$(am__dirstamp) \ 1115 CodeTools/DeclStats.$(OBJEXT): CodeTools/$(am__dirstamp) \ 1116 CodeTools/$(DEPDIR)/$(am__dirstamp) 1117 CodeTools/ResolvProtoDump.$(OBJEXT): CodeTools/$(am__dirstamp) \ 1118 CodeTools/$(DEPDIR)/$(am__dirstamp) 1119 CodeTools/TrackLoc.$(OBJEXT): CodeTools/$(am__dirstamp) \ 1120 CodeTools/$(DEPDIR)/$(am__dirstamp) 1121 Concurrency/Waitfor.$(OBJEXT): Concurrency/$(am__dirstamp) \ 658 1122 Concurrency/$(DEPDIR)/$(am__dirstamp) 659 Concurrency/driver_cfa_cpp-Waitfor.$(OBJEXT): \ 660 Concurrency/$(am__dirstamp) \ 661 Concurrency/$(DEPDIR)/$(am__dirstamp) 662 Common/$(am__dirstamp): 663 @$(MKDIR_P) Common 664 @: > Common/$(am__dirstamp) 665 Common/$(DEPDIR)/$(am__dirstamp): 666 @$(MKDIR_P) Common/$(DEPDIR) 667 @: > Common/$(DEPDIR)/$(am__dirstamp) 668 Common/driver_cfa_cpp-SemanticError.$(OBJEXT): Common/$(am__dirstamp) \ 1123 Common/DebugMalloc.$(OBJEXT): Common/$(am__dirstamp) \ 669 1124 Common/$(DEPDIR)/$(am__dirstamp) 670 Common/driver_cfa_cpp-UniqueName.$(OBJEXT): Common/$(am__dirstamp) \ 671 Common/$(DEPDIR)/$(am__dirstamp) 672 Common/driver_cfa_cpp-DebugMalloc.$(OBJEXT): Common/$(am__dirstamp) \ 673 Common/$(DEPDIR)/$(am__dirstamp) 674 Common/driver_cfa_cpp-Assert.$(OBJEXT): Common/$(am__dirstamp) \ 675 Common/$(DEPDIR)/$(am__dirstamp) 676 Common/driver_cfa_cpp-Heap.$(OBJEXT): Common/$(am__dirstamp) \ 677 Common/$(DEPDIR)/$(am__dirstamp) 678 ControlStruct/$(am__dirstamp): 679 @$(MKDIR_P) ControlStruct 680 @: > ControlStruct/$(am__dirstamp) 681 ControlStruct/$(DEPDIR)/$(am__dirstamp): 682 @$(MKDIR_P) ControlStruct/$(DEPDIR) 683 @: > ControlStruct/$(DEPDIR)/$(am__dirstamp) 684 ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT): \ 1125 ControlStruct/ExceptTranslate.$(OBJEXT): \ 685 1126 ControlStruct/$(am__dirstamp) \ 686 1127 ControlStruct/$(DEPDIR)/$(am__dirstamp) 687 ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT): \ 688 ControlStruct/$(am__dirstamp) \ 689 ControlStruct/$(DEPDIR)/$(am__dirstamp) 690 ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT): \ 691 ControlStruct/$(am__dirstamp) \ 692 ControlStruct/$(DEPDIR)/$(am__dirstamp) 693 ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT): \ 694 ControlStruct/$(am__dirstamp) \ 695 ControlStruct/$(DEPDIR)/$(am__dirstamp) 696 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT): \ 697 ControlStruct/$(am__dirstamp) \ 698 ControlStruct/$(DEPDIR)/$(am__dirstamp) 699 ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT): \ 700 ControlStruct/$(am__dirstamp) \ 701 ControlStruct/$(DEPDIR)/$(am__dirstamp) 702 GenPoly/$(am__dirstamp): 703 @$(MKDIR_P) GenPoly 704 @: > GenPoly/$(am__dirstamp) 705 GenPoly/$(DEPDIR)/$(am__dirstamp): 706 @$(MKDIR_P) GenPoly/$(DEPDIR) 707 @: > GenPoly/$(DEPDIR)/$(am__dirstamp) 708 GenPoly/driver_cfa_cpp-Box.$(OBJEXT): GenPoly/$(am__dirstamp) \ 1128 GenPoly/Box.$(OBJEXT): GenPoly/$(am__dirstamp) \ 709 1129 GenPoly/$(DEPDIR)/$(am__dirstamp) 710 GenPoly/ driver_cfa_cpp-GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \1130 GenPoly/ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \ 711 1131 GenPoly/$(DEPDIR)/$(am__dirstamp) 712 GenPoly/ driver_cfa_cpp-ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \1132 GenPoly/Specialize.$(OBJEXT): GenPoly/$(am__dirstamp) \ 713 1133 GenPoly/$(DEPDIR)/$(am__dirstamp) 714 GenPoly/ driver_cfa_cpp-Lvalue.$(OBJEXT): GenPoly/$(am__dirstamp) \1134 GenPoly/FindFunction.$(OBJEXT): GenPoly/$(am__dirstamp) \ 715 1135 GenPoly/$(DEPDIR)/$(am__dirstamp) 716 GenPoly/ driver_cfa_cpp-Specialize.$(OBJEXT): GenPoly/$(am__dirstamp) \1136 GenPoly/InstantiateGeneric.$(OBJEXT): GenPoly/$(am__dirstamp) \ 717 1137 GenPoly/$(DEPDIR)/$(am__dirstamp) 718 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT): \ 719 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp) 720 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT): \ 721 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp) 722 InitTweak/$(am__dirstamp): 723 @$(MKDIR_P) InitTweak 724 @: > InitTweak/$(am__dirstamp) 725 InitTweak/$(DEPDIR)/$(am__dirstamp): 726 @$(MKDIR_P) InitTweak/$(DEPDIR) 727 @: > InitTweak/$(DEPDIR)/$(am__dirstamp) 728 InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT): InitTweak/$(am__dirstamp) \ 1138 InitTweak/FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \ 729 1139 InitTweak/$(DEPDIR)/$(am__dirstamp) 730 InitTweak/ driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \1140 InitTweak/FixGlobalInit.$(OBJEXT): InitTweak/$(am__dirstamp) \ 731 1141 InitTweak/$(DEPDIR)/$(am__dirstamp) 732 InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT): \733 InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)734 InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT): \735 InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)736 1142 Parser/parser.hh: Parser/parser.cc 737 1143 @if test ! -f $@; then rm -f Parser/parser.cc; else :; fi 738 1144 @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) Parser/parser.cc; else :; fi 739 Parser/$(am__dirstamp): 740 @$(MKDIR_P) Parser 741 @: > Parser/$(am__dirstamp) 742 Parser/$(DEPDIR)/$(am__dirstamp): 743 @$(MKDIR_P) Parser/$(DEPDIR) 744 @: > Parser/$(DEPDIR)/$(am__dirstamp) 745 Parser/driver_cfa_cpp-parser.$(OBJEXT): Parser/$(am__dirstamp) \ 1145 Parser/parser.$(OBJEXT): Parser/$(am__dirstamp) \ 746 1146 Parser/$(DEPDIR)/$(am__dirstamp) 747 Parser/ driver_cfa_cpp-lex.$(OBJEXT): Parser/$(am__dirstamp) \1147 Parser/lex.$(OBJEXT): Parser/$(am__dirstamp) \ 748 1148 Parser/$(DEPDIR)/$(am__dirstamp) 749 Parser/ driver_cfa_cpp-TypedefTable.$(OBJEXT): Parser/$(am__dirstamp) \1149 Parser/TypedefTable.$(OBJEXT): Parser/$(am__dirstamp) \ 750 1150 Parser/$(DEPDIR)/$(am__dirstamp) 751 Parser/ driver_cfa_cpp-ParseNode.$(OBJEXT): Parser/$(am__dirstamp) \1151 Parser/ParseNode.$(OBJEXT): Parser/$(am__dirstamp) \ 752 1152 Parser/$(DEPDIR)/$(am__dirstamp) 753 Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT): \ 754 Parser/$(am__dirstamp) Parser/$(DEPDIR)/$(am__dirstamp) 755 Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT): \ 756 Parser/$(am__dirstamp) Parser/$(DEPDIR)/$(am__dirstamp) 757 Parser/driver_cfa_cpp-StatementNode.$(OBJEXT): Parser/$(am__dirstamp) \ 1153 Parser/DeclarationNode.$(OBJEXT): Parser/$(am__dirstamp) \ 758 1154 Parser/$(DEPDIR)/$(am__dirstamp) 759 Parser/driver_cfa_cpp-InitializerNode.$(OBJEXT): \ 760 Parser/$(am__dirstamp) Parser/$(DEPDIR)/$(am__dirstamp) 761 Parser/driver_cfa_cpp-TypeData.$(OBJEXT): Parser/$(am__dirstamp) \ 1155 Parser/ExpressionNode.$(OBJEXT): Parser/$(am__dirstamp) \ 762 1156 Parser/$(DEPDIR)/$(am__dirstamp) 763 Parser/ driver_cfa_cpp-LinkageSpec.$(OBJEXT): Parser/$(am__dirstamp) \1157 Parser/StatementNode.$(OBJEXT): Parser/$(am__dirstamp) \ 764 1158 Parser/$(DEPDIR)/$(am__dirstamp) 765 Parser/ driver_cfa_cpp-parserutility.$(OBJEXT): Parser/$(am__dirstamp) \1159 Parser/InitializerNode.$(OBJEXT): Parser/$(am__dirstamp) \ 766 1160 Parser/$(DEPDIR)/$(am__dirstamp) 767 ResolvExpr/$(am__dirstamp): 768 @$(MKDIR_P) ResolvExpr 769 @: > ResolvExpr/$(am__dirstamp) 770 ResolvExpr/$(DEPDIR)/$(am__dirstamp): 771 @$(MKDIR_P) ResolvExpr/$(DEPDIR) 772 @: > ResolvExpr/$(DEPDIR)/$(am__dirstamp) 773 ResolvExpr/driver_cfa_cpp-AlternativeFinder.$(OBJEXT): \ 774 ResolvExpr/$(am__dirstamp) \ 775 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 776 ResolvExpr/driver_cfa_cpp-Alternative.$(OBJEXT): \ 777 ResolvExpr/$(am__dirstamp) \ 778 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 779 ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 780 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 781 ResolvExpr/driver_cfa_cpp-PtrsAssignable.$(OBJEXT): \ 782 ResolvExpr/$(am__dirstamp) \ 783 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 784 ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT): \ 785 ResolvExpr/$(am__dirstamp) \ 786 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 787 ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT): \ 788 ResolvExpr/$(am__dirstamp) \ 789 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 790 ResolvExpr/driver_cfa_cpp-CastCost.$(OBJEXT): \ 791 ResolvExpr/$(am__dirstamp) \ 792 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 793 ResolvExpr/driver_cfa_cpp-PtrsCastable.$(OBJEXT): \ 794 ResolvExpr/$(am__dirstamp) \ 795 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 796 ResolvExpr/driver_cfa_cpp-AdjustExprType.$(OBJEXT): \ 797 ResolvExpr/$(am__dirstamp) \ 798 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 799 ResolvExpr/driver_cfa_cpp-AlternativePrinter.$(OBJEXT): \ 800 ResolvExpr/$(am__dirstamp) \ 801 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 802 ResolvExpr/driver_cfa_cpp-Resolver.$(OBJEXT): \ 803 ResolvExpr/$(am__dirstamp) \ 804 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 805 ResolvExpr/driver_cfa_cpp-ResolveTypeof.$(OBJEXT): \ 806 ResolvExpr/$(am__dirstamp) \ 807 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 808 ResolvExpr/driver_cfa_cpp-RenameVars.$(OBJEXT): \ 809 ResolvExpr/$(am__dirstamp) \ 810 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 811 ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT): \ 812 ResolvExpr/$(am__dirstamp) \ 813 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 814 ResolvExpr/driver_cfa_cpp-PolyCost.$(OBJEXT): \ 815 ResolvExpr/$(am__dirstamp) \ 816 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 817 ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT): \ 818 ResolvExpr/$(am__dirstamp) \ 819 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 820 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT): \ 821 ResolvExpr/$(am__dirstamp) \ 822 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 823 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT): \ 824 ResolvExpr/$(am__dirstamp) \ 825 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 826 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT): \ 827 ResolvExpr/$(am__dirstamp) \ 828 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 829 SymTab/$(am__dirstamp): 830 @$(MKDIR_P) SymTab 831 @: > SymTab/$(am__dirstamp) 832 SymTab/$(DEPDIR)/$(am__dirstamp): 833 @$(MKDIR_P) SymTab/$(DEPDIR) 834 @: > SymTab/$(DEPDIR)/$(am__dirstamp) 835 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \ 836 SymTab/$(DEPDIR)/$(am__dirstamp) 837 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT): SymTab/$(am__dirstamp) \ 838 SymTab/$(DEPDIR)/$(am__dirstamp) 839 SymTab/driver_cfa_cpp-Validate.$(OBJEXT): SymTab/$(am__dirstamp) \ 840 SymTab/$(DEPDIR)/$(am__dirstamp) 841 SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT): SymTab/$(am__dirstamp) \ 842 SymTab/$(DEPDIR)/$(am__dirstamp) 843 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \ 844 SymTab/$(DEPDIR)/$(am__dirstamp) 845 SynTree/$(am__dirstamp): 846 @$(MKDIR_P) SynTree 847 @: > SynTree/$(am__dirstamp) 848 SynTree/$(DEPDIR)/$(am__dirstamp): 849 @$(MKDIR_P) SynTree/$(DEPDIR) 850 @: > SynTree/$(DEPDIR)/$(am__dirstamp) 851 SynTree/driver_cfa_cpp-Type.$(OBJEXT): SynTree/$(am__dirstamp) \ 852 SynTree/$(DEPDIR)/$(am__dirstamp) 853 SynTree/driver_cfa_cpp-VoidType.$(OBJEXT): SynTree/$(am__dirstamp) \ 854 SynTree/$(DEPDIR)/$(am__dirstamp) 855 SynTree/driver_cfa_cpp-BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \ 856 SynTree/$(DEPDIR)/$(am__dirstamp) 857 SynTree/driver_cfa_cpp-PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \ 858 SynTree/$(DEPDIR)/$(am__dirstamp) 859 SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \ 860 SynTree/$(DEPDIR)/$(am__dirstamp) 861 SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT): \ 862 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 863 SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT): \ 864 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 865 SynTree/driver_cfa_cpp-ReferenceToType.$(OBJEXT): \ 866 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 867 SynTree/driver_cfa_cpp-TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \ 868 SynTree/$(DEPDIR)/$(am__dirstamp) 869 SynTree/driver_cfa_cpp-TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \ 870 SynTree/$(DEPDIR)/$(am__dirstamp) 871 SynTree/driver_cfa_cpp-AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \ 872 SynTree/$(DEPDIR)/$(am__dirstamp) 873 SynTree/driver_cfa_cpp-VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \ 874 SynTree/$(DEPDIR)/$(am__dirstamp) 875 SynTree/driver_cfa_cpp-ZeroOneType.$(OBJEXT): SynTree/$(am__dirstamp) \ 876 SynTree/$(DEPDIR)/$(am__dirstamp) 877 SynTree/driver_cfa_cpp-Constant.$(OBJEXT): SynTree/$(am__dirstamp) \ 878 SynTree/$(DEPDIR)/$(am__dirstamp) 879 SynTree/driver_cfa_cpp-Expression.$(OBJEXT): SynTree/$(am__dirstamp) \ 880 SynTree/$(DEPDIR)/$(am__dirstamp) 881 SynTree/driver_cfa_cpp-TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 882 SynTree/$(DEPDIR)/$(am__dirstamp) 883 SynTree/driver_cfa_cpp-CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 884 SynTree/$(DEPDIR)/$(am__dirstamp) 885 SynTree/driver_cfa_cpp-TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 886 SynTree/$(DEPDIR)/$(am__dirstamp) 887 SynTree/driver_cfa_cpp-ApplicationExpr.$(OBJEXT): \ 888 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 889 SynTree/driver_cfa_cpp-AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \ 890 SynTree/$(DEPDIR)/$(am__dirstamp) 891 SynTree/driver_cfa_cpp-Statement.$(OBJEXT): SynTree/$(am__dirstamp) \ 892 SynTree/$(DEPDIR)/$(am__dirstamp) 893 SynTree/driver_cfa_cpp-CompoundStmt.$(OBJEXT): \ 894 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 895 SynTree/driver_cfa_cpp-DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \ 896 SynTree/$(DEPDIR)/$(am__dirstamp) 897 SynTree/driver_cfa_cpp-Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \ 898 SynTree/$(DEPDIR)/$(am__dirstamp) 899 SynTree/driver_cfa_cpp-DeclarationWithType.$(OBJEXT): \ 900 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 901 SynTree/driver_cfa_cpp-ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \ 902 SynTree/$(DEPDIR)/$(am__dirstamp) 903 SynTree/driver_cfa_cpp-FunctionDecl.$(OBJEXT): \ 904 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 905 SynTree/driver_cfa_cpp-AggregateDecl.$(OBJEXT): \ 906 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 907 SynTree/driver_cfa_cpp-NamedTypeDecl.$(OBJEXT): \ 908 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 909 SynTree/driver_cfa_cpp-TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \ 910 SynTree/$(DEPDIR)/$(am__dirstamp) 911 SynTree/driver_cfa_cpp-Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \ 912 SynTree/$(DEPDIR)/$(am__dirstamp) 913 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT): \ 914 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 915 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \ 916 SynTree/$(DEPDIR)/$(am__dirstamp) 917 SynTree/driver_cfa_cpp-DeclReplacer.$(OBJEXT): \ 918 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 919 Tuples/$(am__dirstamp): 920 @$(MKDIR_P) Tuples 921 @: > Tuples/$(am__dirstamp) 922 Tuples/$(DEPDIR)/$(am__dirstamp): 923 @$(MKDIR_P) Tuples/$(DEPDIR) 924 @: > Tuples/$(DEPDIR)/$(am__dirstamp) 925 Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT): \ 926 Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp) 927 Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT): \ 928 Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp) 929 Tuples/driver_cfa_cpp-Explode.$(OBJEXT): Tuples/$(am__dirstamp) \ 930 Tuples/$(DEPDIR)/$(am__dirstamp) 1161 Parser/TypeData.$(OBJEXT): Parser/$(am__dirstamp) \ 1162 Parser/$(DEPDIR)/$(am__dirstamp) 1163 Parser/parserutility.$(OBJEXT): Parser/$(am__dirstamp) \ 1164 Parser/$(DEPDIR)/$(am__dirstamp) 1165 ResolvExpr/AlternativePrinter.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 1166 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 931 1167 Virtual/$(am__dirstamp): 932 1168 @$(MKDIR_P) Virtual … … 935 1171 @$(MKDIR_P) Virtual/$(DEPDIR) 936 1172 @: > Virtual/$(DEPDIR)/$(am__dirstamp) 937 Virtual/ driver_cfa_cpp-ExpandCasts.$(OBJEXT): Virtual/$(am__dirstamp) \1173 Virtual/ExpandCasts.$(OBJEXT): Virtual/$(am__dirstamp) \ 938 1174 Virtual/$(DEPDIR)/$(am__dirstamp) 939 driver/$(am__dirstamp): 940 @$(MKDIR_P) driver 941 @: > driver/$(am__dirstamp) 942 943 driver/cfa-cpp$(EXEEXT): $(driver_cfa_cpp_OBJECTS) $(driver_cfa_cpp_DEPENDENCIES) $(EXTRA_driver_cfa_cpp_DEPENDENCIES) driver/$(am__dirstamp) 944 @rm -f driver/cfa-cpp$(EXEEXT) 945 $(AM_V_CXXLD)$(driver_cfa_cpp_LINK) $(driver_cfa_cpp_OBJECTS) $(driver_cfa_cpp_LDADD) $(LIBS) 1175 ../driver/$(am__dirstamp): 1176 @$(MKDIR_P) ../driver 1177 @: > ../driver/$(am__dirstamp) 1178 1179 ../driver/cfa-cpp$(EXEEXT): $(___driver_cfa_cpp_OBJECTS) $(___driver_cfa_cpp_DEPENDENCIES) $(EXTRA____driver_cfa_cpp_DEPENDENCIES) ../driver/$(am__dirstamp) 1180 @rm -f ../driver/cfa-cpp$(EXEEXT) 1181 $(AM_V_CXXLD)$(CXXLINK) $(___driver_cfa_cpp_OBJECTS) $(___driver_cfa_cpp_LDADD) $(LIBS) 1182 SymTab/demangler.$(OBJEXT): SymTab/$(am__dirstamp) \ 1183 SymTab/$(DEPDIR)/$(am__dirstamp) 1184 1185 demangler$(EXEEXT): $(demangler_OBJECTS) $(demangler_DEPENDENCIES) $(EXTRA_demangler_DEPENDENCIES) 1186 @rm -f demangler$(EXEEXT) 1187 $(AM_V_CXXLD)$(CXXLINK) $(demangler_OBJECTS) $(demangler_LDADD) $(LIBS) 946 1188 947 1189 mostlyclean-compile: 948 1190 -rm -f *.$(OBJEXT) 1191 -rm -f AST/*.$(OBJEXT) 949 1192 -rm -f CodeGen/*.$(OBJEXT) 950 1193 -rm -f CodeTools/*.$(OBJEXT) 951 1194 -rm -f Common/*.$(OBJEXT) 1195 -rm -f Common/Stats/*.$(OBJEXT) 952 1196 -rm -f Concurrency/*.$(OBJEXT) 953 1197 -rm -f ControlStruct/*.$(OBJEXT) … … 959 1203 -rm -f SynTree/*.$(OBJEXT) 960 1204 -rm -f Tuples/*.$(OBJEXT) 1205 -rm -f Validate/*.$(OBJEXT) 961 1206 -rm -f Virtual/*.$(OBJEXT) 962 1207 … … 964 1209 -rm -f *.tab.c 965 1210 966 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Po@am__quote@ 967 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_cfa_cpp-main.Po@am__quote@ 968 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Po@am__quote@ 969 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Po@am__quote@ 970 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Po@am__quote@ 971 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Po@am__quote@ 972 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Po@am__quote@ 973 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Po@am__quote@ 974 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Po@am__quote@ 975 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po@am__quote@ 976 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po@am__quote@ 977 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po@am__quote@ 978 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po@am__quote@ 979 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po@am__quote@ 980 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@ 981 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po@am__quote@ 982 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Po@am__quote@ 983 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po@am__quote@ 984 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po@am__quote@ 985 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@ 986 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po@am__quote@ 987 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po@am__quote@ 988 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@ 989 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@ 990 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@ 991 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@ 992 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@ 993 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@ 994 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@ 995 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@ 996 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po@am__quote@ 997 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@ 998 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po@am__quote@ 999 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po@am__quote@ 1000 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@ 1001 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po@am__quote@ 1002 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Po@am__quote@ 1003 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Po@am__quote@ 1004 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Po@am__quote@ 1005 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Po@am__quote@ 1006 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Po@am__quote@ 1007 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Po@am__quote@ 1008 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-lex.Po@am__quote@ 1009 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-parser.Po@am__quote@ 1010 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Po@am__quote@ 1011 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Po@am__quote@ 1012 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Po@am__quote@ 1013 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Po@am__quote@ 1014 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Po@am__quote@ 1015 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Po@am__quote@ 1016 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@ 1017 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@ 1018 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@ 1019 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po@am__quote@ 1020 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@ 1021 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@ 1022 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Po@am__quote@ 1023 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Po@am__quote@ 1024 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Po@am__quote@ 1025 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Po@am__quote@ 1026 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Po@am__quote@ 1027 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Po@am__quote@ 1028 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po@am__quote@ 1029 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@ 1030 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@ 1031 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@ 1032 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@ 1033 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po@am__quote@ 1034 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@ 1035 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@ 1036 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po@am__quote@ 1037 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Po@am__quote@ 1038 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Po@am__quote@ 1039 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po@am__quote@ 1040 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po@am__quote@ 1041 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po@am__quote@ 1042 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po@am__quote@ 1043 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Po@am__quote@ 1044 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Po@am__quote@ 1045 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Po@am__quote@ 1046 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Po@am__quote@ 1047 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Po@am__quote@ 1048 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Po@am__quote@ 1049 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Po@am__quote@ 1050 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Po@am__quote@ 1051 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po@am__quote@ 1052 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po@am__quote@ 1053 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po@am__quote@ 1054 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po@am__quote@ 1055 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po@am__quote@ 1056 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po@am__quote@ 1057 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po@am__quote@ 1058 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po@am__quote@ 1059 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po@am__quote@ 1060 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Po@am__quote@ 1061 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Po@am__quote@ 1062 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Po@am__quote@ 1063 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Po@am__quote@ 1064 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Po@am__quote@ 1065 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po@am__quote@ 1066 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po@am__quote@ 1067 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@ 1068 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po@am__quote@ 1069 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po@am__quote@ 1070 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po@am__quote@ 1071 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po@am__quote@ 1072 @AMDEP_TRUE@@am__include@ @am__quote@Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po@am__quote@ 1211 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CompilationState.Po@am__quote@ 1212 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MakeLibCfa.Po@am__quote@ 1213 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ 1214 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/AssertAcyclic.Po@am__quote@ 1215 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Attribute.Po@am__quote@ 1216 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Convert.Po@am__quote@ 1217 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Decl.Po@am__quote@ 1218 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/DeclReplacer.Po@am__quote@ 1219 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Expr.Po@am__quote@ 1220 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/GenericSubstitution.Po@am__quote@ 1221 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Init.Po@am__quote@ 1222 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/LinkageSpec.Po@am__quote@ 1223 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Node.Po@am__quote@ 1224 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Pass.Po@am__quote@ 1225 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Print.Po@am__quote@ 1226 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Stmt.Po@am__quote@ 1227 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/SymbolTable.Po@am__quote@ 1228 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Type.Po@am__quote@ 1229 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/TypeEnvironment.Po@am__quote@ 1230 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/TypeSubstitution.Po@am__quote@ 1231 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/CodeGenerator.Po@am__quote@ 1232 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/FixMain.Po@am__quote@ 1233 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/FixNames.Po@am__quote@ 1234 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/GenType.Po@am__quote@ 1235 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/Generate.Po@am__quote@ 1236 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/OperatorTable.Po@am__quote@ 1237 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/DeclStats.Po@am__quote@ 1238 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/ResolvProtoDump.Po@am__quote@ 1239 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/TrackLoc.Po@am__quote@ 1240 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/Assert.Po@am__quote@ 1241 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/DebugMalloc.Po@am__quote@ 1242 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/Eval.Po@am__quote@ 1243 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/PassVisitor.Po@am__quote@ 1244 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/SemanticError.Po@am__quote@ 1245 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/UniqueName.Po@am__quote@ 1246 @AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Counter.Po@am__quote@ 1247 @AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Heap.Po@am__quote@ 1248 @AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Stats.Po@am__quote@ 1249 @AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Time.Po@am__quote@ 1250 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/Keywords.Po@am__quote@ 1251 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/Waitfor.Po@am__quote@ 1252 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/ExceptTranslate.Po@am__quote@ 1253 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/ForExprMutator.Po@am__quote@ 1254 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/LabelFixer.Po@am__quote@ 1255 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/LabelGenerator.Po@am__quote@ 1256 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/MLEMutator.Po@am__quote@ 1257 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/Mutate.Po@am__quote@ 1258 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/Box.Po@am__quote@ 1259 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/FindFunction.Po@am__quote@ 1260 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/GenPoly.Po@am__quote@ 1261 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/InstantiateGeneric.Po@am__quote@ 1262 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/Lvalue.Po@am__quote@ 1263 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/ScrubTyVars.Po@am__quote@ 1264 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/Specialize.Po@am__quote@ 1265 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/FixGlobalInit.Po@am__quote@ 1266 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/FixInit.Po@am__quote@ 1267 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/GenInit.Po@am__quote@ 1268 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/InitTweak.Po@am__quote@ 1269 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/DeclarationNode.Po@am__quote@ 1270 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/ExpressionNode.Po@am__quote@ 1271 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/InitializerNode.Po@am__quote@ 1272 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/LinkageSpec.Po@am__quote@ 1273 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/ParseNode.Po@am__quote@ 1274 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/StatementNode.Po@am__quote@ 1275 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/TypeData.Po@am__quote@ 1276 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/TypedefTable.Po@am__quote@ 1277 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/lex.Po@am__quote@ 1278 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/parser.Po@am__quote@ 1279 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/parserutility.Po@am__quote@ 1280 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AdjustExprType.Po@am__quote@ 1281 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Alternative.Po@am__quote@ 1282 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativeFinder.Po@am__quote@ 1283 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativePrinter.Po@am__quote@ 1284 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Candidate.Po@am__quote@ 1285 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CandidateFinder.Po@am__quote@ 1286 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CastCost.Po@am__quote@ 1287 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CommonType.Po@am__quote@ 1288 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ConversionCost.Po@am__quote@ 1289 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CurrentObject.Po@am__quote@ 1290 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ExplodedActual.Po@am__quote@ 1291 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ExplodedArg.Po@am__quote@ 1292 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/FindOpenVars.Po@am__quote@ 1293 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Occurs.Po@am__quote@ 1294 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PolyCost.Po@am__quote@ 1295 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PtrsAssignable.Po@am__quote@ 1296 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PtrsCastable.Po@am__quote@ 1297 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/RenameVars.Po@am__quote@ 1298 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveAssertions.Po@am__quote@ 1299 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveTypeof.Po@am__quote@ 1300 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Resolver.Po@am__quote@ 1301 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SatisfyAssertions.Po@am__quote@ 1302 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SpecCost.Po@am__quote@ 1303 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/TypeEnvironment.Po@am__quote@ 1304 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Unify.Po@am__quote@ 1305 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Autogen.Po@am__quote@ 1306 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Demangle.Po@am__quote@ 1307 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/FixFunction.Po@am__quote@ 1308 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Indexer.Po@am__quote@ 1309 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Mangler.Po@am__quote@ 1310 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/ManglerCommon.Po@am__quote@ 1311 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Validate.Po@am__quote@ 1312 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/demangler.Po@am__quote@ 1313 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/AddressExpr.Po@am__quote@ 1314 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/AggregateDecl.Po@am__quote@ 1315 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ApplicationExpr.Po@am__quote@ 1316 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ArrayType.Po@am__quote@ 1317 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/AttrType.Po@am__quote@ 1318 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Attribute.Po@am__quote@ 1319 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/BasicType.Po@am__quote@ 1320 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/CommaExpr.Po@am__quote@ 1321 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/CompoundStmt.Po@am__quote@ 1322 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Constant.Po@am__quote@ 1323 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/DeclReplacer.Po@am__quote@ 1324 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/DeclStmt.Po@am__quote@ 1325 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Declaration.Po@am__quote@ 1326 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/DeclarationWithType.Po@am__quote@ 1327 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Expression.Po@am__quote@ 1328 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/FunctionDecl.Po@am__quote@ 1329 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/FunctionType.Po@am__quote@ 1330 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Initializer.Po@am__quote@ 1331 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/NamedTypeDecl.Po@am__quote@ 1332 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ObjectDecl.Po@am__quote@ 1333 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/PointerType.Po@am__quote@ 1334 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ReferenceToType.Po@am__quote@ 1335 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ReferenceType.Po@am__quote@ 1336 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Statement.Po@am__quote@ 1337 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleExpr.Po@am__quote@ 1338 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleType.Po@am__quote@ 1339 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Type.Po@am__quote@ 1340 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeDecl.Po@am__quote@ 1341 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeExpr.Po@am__quote@ 1342 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeSubstitution.Po@am__quote@ 1343 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeofType.Po@am__quote@ 1344 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/VarArgsType.Po@am__quote@ 1345 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/VoidType.Po@am__quote@ 1346 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ZeroOneType.Po@am__quote@ 1347 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/Explode.Po@am__quote@ 1348 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/TupleAssignment.Po@am__quote@ 1349 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/TupleExpansion.Po@am__quote@ 1350 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/Tuples.Po@am__quote@ 1351 @AMDEP_TRUE@@am__include@ @am__quote@Validate/$(DEPDIR)/FindSpecialDecls.Po@am__quote@ 1352 @AMDEP_TRUE@@am__include@ @am__quote@Validate/$(DEPDIR)/HandleAttributes.Po@am__quote@ 1353 @AMDEP_TRUE@@am__include@ @am__quote@Virtual/$(DEPDIR)/ExpandCasts.Po@am__quote@ 1073 1354 1074 1355 .cc.o: … … 1088 1369 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 1089 1370 1090 driver_cfa_cpp-main.o: main.cc 1091 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-main.o -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-main.Tpo -c -o driver_cfa_cpp-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc 1092 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-main.Tpo $(DEPDIR)/driver_cfa_cpp-main.Po 1093 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='main.cc' object='driver_cfa_cpp-main.o' libtool=no @AMDEPBACKSLASH@ 1371 .cc.lo: 1372 @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ 1373 @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 1374 @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo 1375 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ 1094 1376 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1095 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc 1096 1097 driver_cfa_cpp-main.obj: main.cc 1098 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-main.obj -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-main.Tpo -c -o driver_cfa_cpp-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi` 1099 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-main.Tpo $(DEPDIR)/driver_cfa_cpp-main.Po 1100 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='main.cc' object='driver_cfa_cpp-main.obj' libtool=no @AMDEPBACKSLASH@ 1377 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< 1378 1379 .cpp.o: 1380 @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ 1381 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 1382 @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po 1383 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 1101 1384 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1102 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi` 1103 1104 driver_cfa_cpp-MakeLibCfa.o: MakeLibCfa.cc 1105 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-MakeLibCfa.o -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo -c -o driver_cfa_cpp-MakeLibCfa.o `test -f 'MakeLibCfa.cc' || echo '$(srcdir)/'`MakeLibCfa.cc 1106 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Po 1107 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MakeLibCfa.cc' object='driver_cfa_cpp-MakeLibCfa.o' libtool=no @AMDEPBACKSLASH@ 1385 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< 1386 1387 .cpp.obj: 1388 @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ 1389 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ 1390 @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po 1391 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 1108 1392 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1109 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-MakeLibCfa.o `test -f 'MakeLibCfa.cc' || echo '$(srcdir)/'`MakeLibCfa.cc 1110 1111 driver_cfa_cpp-MakeLibCfa.obj: MakeLibCfa.cc 1112 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-MakeLibCfa.obj -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo -c -o driver_cfa_cpp-MakeLibCfa.obj `if test -f 'MakeLibCfa.cc'; then $(CYGPATH_W) 'MakeLibCfa.cc'; else $(CYGPATH_W) '$(srcdir)/MakeLibCfa.cc'; fi` 1113 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Po 1114 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MakeLibCfa.cc' object='driver_cfa_cpp-MakeLibCfa.obj' libtool=no @AMDEPBACKSLASH@ 1393 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 1394 1395 .cpp.lo: 1396 @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ 1397 @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 1398 @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo 1399 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ 1115 1400 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1116 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-MakeLibCfa.obj `if test -f 'MakeLibCfa.cc'; then $(CYGPATH_W) 'MakeLibCfa.cc'; else $(CYGPATH_W) '$(srcdir)/MakeLibCfa.cc'; fi` 1117 1118 CodeGen/driver_cfa_cpp-Generate.o: CodeGen/Generate.cc 1119 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-Generate.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo -c -o CodeGen/driver_cfa_cpp-Generate.o `test -f 'CodeGen/Generate.cc' || echo '$(srcdir)/'`CodeGen/Generate.cc 1120 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Po 1121 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/Generate.cc' object='CodeGen/driver_cfa_cpp-Generate.o' libtool=no @AMDEPBACKSLASH@ 1122 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1123 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-Generate.o `test -f 'CodeGen/Generate.cc' || echo '$(srcdir)/'`CodeGen/Generate.cc 1124 1125 CodeGen/driver_cfa_cpp-Generate.obj: CodeGen/Generate.cc 1126 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-Generate.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo -c -o CodeGen/driver_cfa_cpp-Generate.obj `if test -f 'CodeGen/Generate.cc'; then $(CYGPATH_W) 'CodeGen/Generate.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/Generate.cc'; fi` 1127 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Po 1128 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/Generate.cc' object='CodeGen/driver_cfa_cpp-Generate.obj' libtool=no @AMDEPBACKSLASH@ 1129 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1130 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-Generate.obj `if test -f 'CodeGen/Generate.cc'; then $(CYGPATH_W) 'CodeGen/Generate.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/Generate.cc'; fi` 1131 1132 CodeGen/driver_cfa_cpp-CodeGenerator.o: CodeGen/CodeGenerator.cc 1133 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-CodeGenerator.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo -c -o CodeGen/driver_cfa_cpp-CodeGenerator.o `test -f 'CodeGen/CodeGenerator.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator.cc 1134 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Po 1135 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/CodeGenerator.cc' object='CodeGen/driver_cfa_cpp-CodeGenerator.o' libtool=no @AMDEPBACKSLASH@ 1136 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1137 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-CodeGenerator.o `test -f 'CodeGen/CodeGenerator.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator.cc 1138 1139 CodeGen/driver_cfa_cpp-CodeGenerator.obj: CodeGen/CodeGenerator.cc 1140 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-CodeGenerator.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo -c -o CodeGen/driver_cfa_cpp-CodeGenerator.obj `if test -f 'CodeGen/CodeGenerator.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator.cc'; fi` 1141 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Po 1142 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/CodeGenerator.cc' object='CodeGen/driver_cfa_cpp-CodeGenerator.obj' libtool=no @AMDEPBACKSLASH@ 1143 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1144 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-CodeGenerator.obj `if test -f 'CodeGen/CodeGenerator.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator.cc'; fi` 1145 1146 CodeGen/driver_cfa_cpp-GenType.o: CodeGen/GenType.cc 1147 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-GenType.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo -c -o CodeGen/driver_cfa_cpp-GenType.o `test -f 'CodeGen/GenType.cc' || echo '$(srcdir)/'`CodeGen/GenType.cc 1148 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Po 1149 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/GenType.cc' object='CodeGen/driver_cfa_cpp-GenType.o' libtool=no @AMDEPBACKSLASH@ 1150 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1151 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-GenType.o `test -f 'CodeGen/GenType.cc' || echo '$(srcdir)/'`CodeGen/GenType.cc 1152 1153 CodeGen/driver_cfa_cpp-GenType.obj: CodeGen/GenType.cc 1154 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-GenType.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo -c -o CodeGen/driver_cfa_cpp-GenType.obj `if test -f 'CodeGen/GenType.cc'; then $(CYGPATH_W) 'CodeGen/GenType.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/GenType.cc'; fi` 1155 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Po 1156 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/GenType.cc' object='CodeGen/driver_cfa_cpp-GenType.obj' libtool=no @AMDEPBACKSLASH@ 1157 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1158 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-GenType.obj `if test -f 'CodeGen/GenType.cc'; then $(CYGPATH_W) 'CodeGen/GenType.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/GenType.cc'; fi` 1159 1160 CodeGen/driver_cfa_cpp-FixNames.o: CodeGen/FixNames.cc 1161 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixNames.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo -c -o CodeGen/driver_cfa_cpp-FixNames.o `test -f 'CodeGen/FixNames.cc' || echo '$(srcdir)/'`CodeGen/FixNames.cc 1162 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Po 1163 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/FixNames.cc' object='CodeGen/driver_cfa_cpp-FixNames.o' libtool=no @AMDEPBACKSLASH@ 1164 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1165 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixNames.o `test -f 'CodeGen/FixNames.cc' || echo '$(srcdir)/'`CodeGen/FixNames.cc 1166 1167 CodeGen/driver_cfa_cpp-FixNames.obj: CodeGen/FixNames.cc 1168 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixNames.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo -c -o CodeGen/driver_cfa_cpp-FixNames.obj `if test -f 'CodeGen/FixNames.cc'; then $(CYGPATH_W) 'CodeGen/FixNames.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixNames.cc'; fi` 1169 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Po 1170 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/FixNames.cc' object='CodeGen/driver_cfa_cpp-FixNames.obj' libtool=no @AMDEPBACKSLASH@ 1171 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1172 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixNames.obj `if test -f 'CodeGen/FixNames.cc'; then $(CYGPATH_W) 'CodeGen/FixNames.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixNames.cc'; fi` 1173 1174 CodeGen/driver_cfa_cpp-FixMain.o: CodeGen/FixMain.cc 1175 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixMain.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo -c -o CodeGen/driver_cfa_cpp-FixMain.o `test -f 'CodeGen/FixMain.cc' || echo '$(srcdir)/'`CodeGen/FixMain.cc 1176 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Po 1177 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/FixMain.cc' object='CodeGen/driver_cfa_cpp-FixMain.o' libtool=no @AMDEPBACKSLASH@ 1178 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1179 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixMain.o `test -f 'CodeGen/FixMain.cc' || echo '$(srcdir)/'`CodeGen/FixMain.cc 1180 1181 CodeGen/driver_cfa_cpp-FixMain.obj: CodeGen/FixMain.cc 1182 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixMain.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo -c -o CodeGen/driver_cfa_cpp-FixMain.obj `if test -f 'CodeGen/FixMain.cc'; then $(CYGPATH_W) 'CodeGen/FixMain.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixMain.cc'; fi` 1183 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Po 1184 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/FixMain.cc' object='CodeGen/driver_cfa_cpp-FixMain.obj' libtool=no @AMDEPBACKSLASH@ 1185 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1186 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixMain.obj `if test -f 'CodeGen/FixMain.cc'; then $(CYGPATH_W) 'CodeGen/FixMain.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixMain.cc'; fi` 1187 1188 CodeGen/driver_cfa_cpp-OperatorTable.o: CodeGen/OperatorTable.cc 1189 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-OperatorTable.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo -c -o CodeGen/driver_cfa_cpp-OperatorTable.o `test -f 'CodeGen/OperatorTable.cc' || echo '$(srcdir)/'`CodeGen/OperatorTable.cc 1190 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Po 1191 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/OperatorTable.cc' object='CodeGen/driver_cfa_cpp-OperatorTable.o' libtool=no @AMDEPBACKSLASH@ 1192 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1193 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-OperatorTable.o `test -f 'CodeGen/OperatorTable.cc' || echo '$(srcdir)/'`CodeGen/OperatorTable.cc 1194 1195 CodeGen/driver_cfa_cpp-OperatorTable.obj: CodeGen/OperatorTable.cc 1196 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-OperatorTable.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo -c -o CodeGen/driver_cfa_cpp-OperatorTable.obj `if test -f 'CodeGen/OperatorTable.cc'; then $(CYGPATH_W) 'CodeGen/OperatorTable.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/OperatorTable.cc'; fi` 1197 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Po 1198 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeGen/OperatorTable.cc' object='CodeGen/driver_cfa_cpp-OperatorTable.obj' libtool=no @AMDEPBACKSLASH@ 1199 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1200 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-OperatorTable.obj `if test -f 'CodeGen/OperatorTable.cc'; then $(CYGPATH_W) 'CodeGen/OperatorTable.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/OperatorTable.cc'; fi` 1201 1202 CodeTools/driver_cfa_cpp-DeclStats.o: CodeTools/DeclStats.cc 1203 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-DeclStats.o -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo -c -o CodeTools/driver_cfa_cpp-DeclStats.o `test -f 'CodeTools/DeclStats.cc' || echo '$(srcdir)/'`CodeTools/DeclStats.cc 1204 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Po 1205 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeTools/DeclStats.cc' object='CodeTools/driver_cfa_cpp-DeclStats.o' libtool=no @AMDEPBACKSLASH@ 1206 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1207 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-DeclStats.o `test -f 'CodeTools/DeclStats.cc' || echo '$(srcdir)/'`CodeTools/DeclStats.cc 1208 1209 CodeTools/driver_cfa_cpp-DeclStats.obj: CodeTools/DeclStats.cc 1210 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-DeclStats.obj -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo -c -o CodeTools/driver_cfa_cpp-DeclStats.obj `if test -f 'CodeTools/DeclStats.cc'; then $(CYGPATH_W) 'CodeTools/DeclStats.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/DeclStats.cc'; fi` 1211 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Po 1212 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeTools/DeclStats.cc' object='CodeTools/driver_cfa_cpp-DeclStats.obj' libtool=no @AMDEPBACKSLASH@ 1213 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1214 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-DeclStats.obj `if test -f 'CodeTools/DeclStats.cc'; then $(CYGPATH_W) 'CodeTools/DeclStats.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/DeclStats.cc'; fi` 1215 1216 CodeTools/driver_cfa_cpp-TrackLoc.o: CodeTools/TrackLoc.cc 1217 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-TrackLoc.o -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo -c -o CodeTools/driver_cfa_cpp-TrackLoc.o `test -f 'CodeTools/TrackLoc.cc' || echo '$(srcdir)/'`CodeTools/TrackLoc.cc 1218 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po 1219 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeTools/TrackLoc.cc' object='CodeTools/driver_cfa_cpp-TrackLoc.o' libtool=no @AMDEPBACKSLASH@ 1220 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1221 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-TrackLoc.o `test -f 'CodeTools/TrackLoc.cc' || echo '$(srcdir)/'`CodeTools/TrackLoc.cc 1222 1223 CodeTools/driver_cfa_cpp-TrackLoc.obj: CodeTools/TrackLoc.cc 1224 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-TrackLoc.obj -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo -c -o CodeTools/driver_cfa_cpp-TrackLoc.obj `if test -f 'CodeTools/TrackLoc.cc'; then $(CYGPATH_W) 'CodeTools/TrackLoc.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/TrackLoc.cc'; fi` 1225 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po 1226 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CodeTools/TrackLoc.cc' object='CodeTools/driver_cfa_cpp-TrackLoc.obj' libtool=no @AMDEPBACKSLASH@ 1227 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1228 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-TrackLoc.obj `if test -f 'CodeTools/TrackLoc.cc'; then $(CYGPATH_W) 'CodeTools/TrackLoc.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/TrackLoc.cc'; fi` 1229 1230 Concurrency/driver_cfa_cpp-Keywords.o: Concurrency/Keywords.cc 1231 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Keywords.o -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo -c -o Concurrency/driver_cfa_cpp-Keywords.o `test -f 'Concurrency/Keywords.cc' || echo '$(srcdir)/'`Concurrency/Keywords.cc 1232 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po 1233 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Concurrency/Keywords.cc' object='Concurrency/driver_cfa_cpp-Keywords.o' libtool=no @AMDEPBACKSLASH@ 1234 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1235 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Keywords.o `test -f 'Concurrency/Keywords.cc' || echo '$(srcdir)/'`Concurrency/Keywords.cc 1236 1237 Concurrency/driver_cfa_cpp-Keywords.obj: Concurrency/Keywords.cc 1238 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Keywords.obj -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo -c -o Concurrency/driver_cfa_cpp-Keywords.obj `if test -f 'Concurrency/Keywords.cc'; then $(CYGPATH_W) 'Concurrency/Keywords.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Keywords.cc'; fi` 1239 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po 1240 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Concurrency/Keywords.cc' object='Concurrency/driver_cfa_cpp-Keywords.obj' libtool=no @AMDEPBACKSLASH@ 1241 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1242 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Keywords.obj `if test -f 'Concurrency/Keywords.cc'; then $(CYGPATH_W) 'Concurrency/Keywords.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Keywords.cc'; fi` 1243 1244 Concurrency/driver_cfa_cpp-Waitfor.o: Concurrency/Waitfor.cc 1245 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Waitfor.o -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo -c -o Concurrency/driver_cfa_cpp-Waitfor.o `test -f 'Concurrency/Waitfor.cc' || echo '$(srcdir)/'`Concurrency/Waitfor.cc 1246 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Po 1247 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Concurrency/Waitfor.cc' object='Concurrency/driver_cfa_cpp-Waitfor.o' libtool=no @AMDEPBACKSLASH@ 1248 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1249 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Waitfor.o `test -f 'Concurrency/Waitfor.cc' || echo '$(srcdir)/'`Concurrency/Waitfor.cc 1250 1251 Concurrency/driver_cfa_cpp-Waitfor.obj: Concurrency/Waitfor.cc 1252 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Waitfor.obj -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo -c -o Concurrency/driver_cfa_cpp-Waitfor.obj `if test -f 'Concurrency/Waitfor.cc'; then $(CYGPATH_W) 'Concurrency/Waitfor.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Waitfor.cc'; fi` 1253 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Po 1254 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Concurrency/Waitfor.cc' object='Concurrency/driver_cfa_cpp-Waitfor.obj' libtool=no @AMDEPBACKSLASH@ 1255 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1256 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Waitfor.obj `if test -f 'Concurrency/Waitfor.cc'; then $(CYGPATH_W) 'Concurrency/Waitfor.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Waitfor.cc'; fi` 1257 1258 Common/driver_cfa_cpp-SemanticError.o: Common/SemanticError.cc 1259 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-SemanticError.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo -c -o Common/driver_cfa_cpp-SemanticError.o `test -f 'Common/SemanticError.cc' || echo '$(srcdir)/'`Common/SemanticError.cc 1260 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po 1261 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/SemanticError.cc' object='Common/driver_cfa_cpp-SemanticError.o' libtool=no @AMDEPBACKSLASH@ 1262 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1263 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-SemanticError.o `test -f 'Common/SemanticError.cc' || echo '$(srcdir)/'`Common/SemanticError.cc 1264 1265 Common/driver_cfa_cpp-SemanticError.obj: Common/SemanticError.cc 1266 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-SemanticError.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo -c -o Common/driver_cfa_cpp-SemanticError.obj `if test -f 'Common/SemanticError.cc'; then $(CYGPATH_W) 'Common/SemanticError.cc'; else $(CYGPATH_W) '$(srcdir)/Common/SemanticError.cc'; fi` 1267 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po 1268 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/SemanticError.cc' object='Common/driver_cfa_cpp-SemanticError.obj' libtool=no @AMDEPBACKSLASH@ 1269 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1270 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-SemanticError.obj `if test -f 'Common/SemanticError.cc'; then $(CYGPATH_W) 'Common/SemanticError.cc'; else $(CYGPATH_W) '$(srcdir)/Common/SemanticError.cc'; fi` 1271 1272 Common/driver_cfa_cpp-UniqueName.o: Common/UniqueName.cc 1273 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-UniqueName.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo -c -o Common/driver_cfa_cpp-UniqueName.o `test -f 'Common/UniqueName.cc' || echo '$(srcdir)/'`Common/UniqueName.cc 1274 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po 1275 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/UniqueName.cc' object='Common/driver_cfa_cpp-UniqueName.o' libtool=no @AMDEPBACKSLASH@ 1276 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1277 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-UniqueName.o `test -f 'Common/UniqueName.cc' || echo '$(srcdir)/'`Common/UniqueName.cc 1278 1279 Common/driver_cfa_cpp-UniqueName.obj: Common/UniqueName.cc 1280 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-UniqueName.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo -c -o Common/driver_cfa_cpp-UniqueName.obj `if test -f 'Common/UniqueName.cc'; then $(CYGPATH_W) 'Common/UniqueName.cc'; else $(CYGPATH_W) '$(srcdir)/Common/UniqueName.cc'; fi` 1281 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po 1282 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/UniqueName.cc' object='Common/driver_cfa_cpp-UniqueName.obj' libtool=no @AMDEPBACKSLASH@ 1283 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1284 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-UniqueName.obj `if test -f 'Common/UniqueName.cc'; then $(CYGPATH_W) 'Common/UniqueName.cc'; else $(CYGPATH_W) '$(srcdir)/Common/UniqueName.cc'; fi` 1285 1286 Common/driver_cfa_cpp-DebugMalloc.o: Common/DebugMalloc.cc 1287 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-DebugMalloc.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo -c -o Common/driver_cfa_cpp-DebugMalloc.o `test -f 'Common/DebugMalloc.cc' || echo '$(srcdir)/'`Common/DebugMalloc.cc 1288 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po 1289 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/DebugMalloc.cc' object='Common/driver_cfa_cpp-DebugMalloc.o' libtool=no @AMDEPBACKSLASH@ 1290 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1291 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-DebugMalloc.o `test -f 'Common/DebugMalloc.cc' || echo '$(srcdir)/'`Common/DebugMalloc.cc 1292 1293 Common/driver_cfa_cpp-DebugMalloc.obj: Common/DebugMalloc.cc 1294 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-DebugMalloc.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo -c -o Common/driver_cfa_cpp-DebugMalloc.obj `if test -f 'Common/DebugMalloc.cc'; then $(CYGPATH_W) 'Common/DebugMalloc.cc'; else $(CYGPATH_W) '$(srcdir)/Common/DebugMalloc.cc'; fi` 1295 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po 1296 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/DebugMalloc.cc' object='Common/driver_cfa_cpp-DebugMalloc.obj' libtool=no @AMDEPBACKSLASH@ 1297 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1298 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-DebugMalloc.obj `if test -f 'Common/DebugMalloc.cc'; then $(CYGPATH_W) 'Common/DebugMalloc.cc'; else $(CYGPATH_W) '$(srcdir)/Common/DebugMalloc.cc'; fi` 1299 1300 Common/driver_cfa_cpp-Assert.o: Common/Assert.cc 1301 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Assert.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo -c -o Common/driver_cfa_cpp-Assert.o `test -f 'Common/Assert.cc' || echo '$(srcdir)/'`Common/Assert.cc 1302 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po 1303 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/Assert.cc' object='Common/driver_cfa_cpp-Assert.o' libtool=no @AMDEPBACKSLASH@ 1304 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1305 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Assert.o `test -f 'Common/Assert.cc' || echo '$(srcdir)/'`Common/Assert.cc 1306 1307 Common/driver_cfa_cpp-Assert.obj: Common/Assert.cc 1308 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Assert.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo -c -o Common/driver_cfa_cpp-Assert.obj `if test -f 'Common/Assert.cc'; then $(CYGPATH_W) 'Common/Assert.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Assert.cc'; fi` 1309 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po 1310 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/Assert.cc' object='Common/driver_cfa_cpp-Assert.obj' libtool=no @AMDEPBACKSLASH@ 1311 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1312 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Assert.obj `if test -f 'Common/Assert.cc'; then $(CYGPATH_W) 'Common/Assert.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Assert.cc'; fi` 1313 1314 Common/driver_cfa_cpp-Heap.o: Common/Heap.cc 1315 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Heap.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo -c -o Common/driver_cfa_cpp-Heap.o `test -f 'Common/Heap.cc' || echo '$(srcdir)/'`Common/Heap.cc 1316 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po 1317 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/Heap.cc' object='Common/driver_cfa_cpp-Heap.o' libtool=no @AMDEPBACKSLASH@ 1318 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1319 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Heap.o `test -f 'Common/Heap.cc' || echo '$(srcdir)/'`Common/Heap.cc 1320 1321 Common/driver_cfa_cpp-Heap.obj: Common/Heap.cc 1322 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Heap.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo -c -o Common/driver_cfa_cpp-Heap.obj `if test -f 'Common/Heap.cc'; then $(CYGPATH_W) 'Common/Heap.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Heap.cc'; fi` 1323 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po 1324 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Common/Heap.cc' object='Common/driver_cfa_cpp-Heap.obj' libtool=no @AMDEPBACKSLASH@ 1325 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1326 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Heap.obj `if test -f 'Common/Heap.cc'; then $(CYGPATH_W) 'Common/Heap.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Heap.cc'; fi` 1327 1328 ControlStruct/driver_cfa_cpp-LabelGenerator.o: ControlStruct/LabelGenerator.cc 1329 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelGenerator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.o `test -f 'ControlStruct/LabelGenerator.cc' || echo '$(srcdir)/'`ControlStruct/LabelGenerator.cc 1330 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po 1331 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/LabelGenerator.cc' object='ControlStruct/driver_cfa_cpp-LabelGenerator.o' libtool=no @AMDEPBACKSLASH@ 1332 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1333 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.o `test -f 'ControlStruct/LabelGenerator.cc' || echo '$(srcdir)/'`ControlStruct/LabelGenerator.cc 1334 1335 ControlStruct/driver_cfa_cpp-LabelGenerator.obj: ControlStruct/LabelGenerator.cc 1336 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelGenerator.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.obj `if test -f 'ControlStruct/LabelGenerator.cc'; then $(CYGPATH_W) 'ControlStruct/LabelGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelGenerator.cc'; fi` 1337 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po 1338 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/LabelGenerator.cc' object='ControlStruct/driver_cfa_cpp-LabelGenerator.obj' libtool=no @AMDEPBACKSLASH@ 1339 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1340 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.obj `if test -f 'ControlStruct/LabelGenerator.cc'; then $(CYGPATH_W) 'ControlStruct/LabelGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelGenerator.cc'; fi` 1341 1342 ControlStruct/driver_cfa_cpp-LabelFixer.o: ControlStruct/LabelFixer.cc 1343 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelFixer.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelFixer.o `test -f 'ControlStruct/LabelFixer.cc' || echo '$(srcdir)/'`ControlStruct/LabelFixer.cc 1344 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po 1345 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/LabelFixer.cc' object='ControlStruct/driver_cfa_cpp-LabelFixer.o' libtool=no @AMDEPBACKSLASH@ 1346 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1347 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelFixer.o `test -f 'ControlStruct/LabelFixer.cc' || echo '$(srcdir)/'`ControlStruct/LabelFixer.cc 1348 1349 ControlStruct/driver_cfa_cpp-LabelFixer.obj: ControlStruct/LabelFixer.cc 1350 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelFixer.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelFixer.obj `if test -f 'ControlStruct/LabelFixer.cc'; then $(CYGPATH_W) 'ControlStruct/LabelFixer.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelFixer.cc'; fi` 1351 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po 1352 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/LabelFixer.cc' object='ControlStruct/driver_cfa_cpp-LabelFixer.obj' libtool=no @AMDEPBACKSLASH@ 1353 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1354 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelFixer.obj `if test -f 'ControlStruct/LabelFixer.cc'; then $(CYGPATH_W) 'ControlStruct/LabelFixer.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelFixer.cc'; fi` 1355 1356 ControlStruct/driver_cfa_cpp-MLEMutator.o: ControlStruct/MLEMutator.cc 1357 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-MLEMutator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-MLEMutator.o `test -f 'ControlStruct/MLEMutator.cc' || echo '$(srcdir)/'`ControlStruct/MLEMutator.cc 1358 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po 1359 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/MLEMutator.cc' object='ControlStruct/driver_cfa_cpp-MLEMutator.o' libtool=no @AMDEPBACKSLASH@ 1360 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1361 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-MLEMutator.o `test -f 'ControlStruct/MLEMutator.cc' || echo '$(srcdir)/'`ControlStruct/MLEMutator.cc 1362 1363 ControlStruct/driver_cfa_cpp-MLEMutator.obj: ControlStruct/MLEMutator.cc 1364 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-MLEMutator.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-MLEMutator.obj `if test -f 'ControlStruct/MLEMutator.cc'; then $(CYGPATH_W) 'ControlStruct/MLEMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/MLEMutator.cc'; fi` 1365 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po 1366 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/MLEMutator.cc' object='ControlStruct/driver_cfa_cpp-MLEMutator.obj' libtool=no @AMDEPBACKSLASH@ 1367 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1368 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-MLEMutator.obj `if test -f 'ControlStruct/MLEMutator.cc'; then $(CYGPATH_W) 'ControlStruct/MLEMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/MLEMutator.cc'; fi` 1369 1370 ControlStruct/driver_cfa_cpp-Mutate.o: ControlStruct/Mutate.cc 1371 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-Mutate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo -c -o ControlStruct/driver_cfa_cpp-Mutate.o `test -f 'ControlStruct/Mutate.cc' || echo '$(srcdir)/'`ControlStruct/Mutate.cc 1372 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po 1373 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/Mutate.cc' object='ControlStruct/driver_cfa_cpp-Mutate.o' libtool=no @AMDEPBACKSLASH@ 1374 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1375 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-Mutate.o `test -f 'ControlStruct/Mutate.cc' || echo '$(srcdir)/'`ControlStruct/Mutate.cc 1376 1377 ControlStruct/driver_cfa_cpp-Mutate.obj: ControlStruct/Mutate.cc 1378 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-Mutate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo -c -o ControlStruct/driver_cfa_cpp-Mutate.obj `if test -f 'ControlStruct/Mutate.cc'; then $(CYGPATH_W) 'ControlStruct/Mutate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/Mutate.cc'; fi` 1379 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po 1380 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/Mutate.cc' object='ControlStruct/driver_cfa_cpp-Mutate.obj' libtool=no @AMDEPBACKSLASH@ 1381 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1382 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-Mutate.obj `if test -f 'ControlStruct/Mutate.cc'; then $(CYGPATH_W) 'ControlStruct/Mutate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/Mutate.cc'; fi` 1383 1384 ControlStruct/driver_cfa_cpp-ForExprMutator.o: ControlStruct/ForExprMutator.cc 1385 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ForExprMutator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.o `test -f 'ControlStruct/ForExprMutator.cc' || echo '$(srcdir)/'`ControlStruct/ForExprMutator.cc 1386 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po 1387 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/ForExprMutator.cc' object='ControlStruct/driver_cfa_cpp-ForExprMutator.o' libtool=no @AMDEPBACKSLASH@ 1388 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1389 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.o `test -f 'ControlStruct/ForExprMutator.cc' || echo '$(srcdir)/'`ControlStruct/ForExprMutator.cc 1390 1391 ControlStruct/driver_cfa_cpp-ForExprMutator.obj: ControlStruct/ForExprMutator.cc 1392 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ForExprMutator.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi` 1393 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po 1394 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/ForExprMutator.cc' object='ControlStruct/driver_cfa_cpp-ForExprMutator.obj' libtool=no @AMDEPBACKSLASH@ 1395 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1396 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi` 1397 1398 ControlStruct/driver_cfa_cpp-ExceptTranslate.o: ControlStruct/ExceptTranslate.cc 1399 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc 1400 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po 1401 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.o' libtool=no @AMDEPBACKSLASH@ 1402 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1403 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc 1404 1405 ControlStruct/driver_cfa_cpp-ExceptTranslate.obj: ControlStruct/ExceptTranslate.cc 1406 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi` 1407 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po 1408 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.obj' libtool=no @AMDEPBACKSLASH@ 1409 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1410 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi` 1411 1412 GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc 1413 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc 1414 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po 1415 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/Box.cc' object='GenPoly/driver_cfa_cpp-Box.o' libtool=no @AMDEPBACKSLASH@ 1416 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1417 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc 1418 1419 GenPoly/driver_cfa_cpp-Box.obj: GenPoly/Box.cc 1420 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.obj `if test -f 'GenPoly/Box.cc'; then $(CYGPATH_W) 'GenPoly/Box.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Box.cc'; fi` 1421 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po 1422 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/Box.cc' object='GenPoly/driver_cfa_cpp-Box.obj' libtool=no @AMDEPBACKSLASH@ 1423 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1424 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Box.obj `if test -f 'GenPoly/Box.cc'; then $(CYGPATH_W) 'GenPoly/Box.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Box.cc'; fi` 1425 1426 GenPoly/driver_cfa_cpp-GenPoly.o: GenPoly/GenPoly.cc 1427 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-GenPoly.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo -c -o GenPoly/driver_cfa_cpp-GenPoly.o `test -f 'GenPoly/GenPoly.cc' || echo '$(srcdir)/'`GenPoly/GenPoly.cc 1428 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po 1429 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/GenPoly.cc' object='GenPoly/driver_cfa_cpp-GenPoly.o' libtool=no @AMDEPBACKSLASH@ 1430 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1431 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.o `test -f 'GenPoly/GenPoly.cc' || echo '$(srcdir)/'`GenPoly/GenPoly.cc 1432 1433 GenPoly/driver_cfa_cpp-GenPoly.obj: GenPoly/GenPoly.cc 1434 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-GenPoly.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi` 1435 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po 1436 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/GenPoly.cc' object='GenPoly/driver_cfa_cpp-GenPoly.obj' libtool=no @AMDEPBACKSLASH@ 1437 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1438 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi` 1439 1440 GenPoly/driver_cfa_cpp-ScrubTyVars.o: GenPoly/ScrubTyVars.cc 1441 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc 1442 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po 1443 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/ScrubTyVars.cc' object='GenPoly/driver_cfa_cpp-ScrubTyVars.o' libtool=no @AMDEPBACKSLASH@ 1444 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1445 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc 1446 1447 GenPoly/driver_cfa_cpp-ScrubTyVars.obj: GenPoly/ScrubTyVars.cc 1448 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.obj `if test -f 'GenPoly/ScrubTyVars.cc'; then $(CYGPATH_W) 'GenPoly/ScrubTyVars.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/ScrubTyVars.cc'; fi` 1449 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po 1450 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/ScrubTyVars.cc' object='GenPoly/driver_cfa_cpp-ScrubTyVars.obj' libtool=no @AMDEPBACKSLASH@ 1451 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1452 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.obj `if test -f 'GenPoly/ScrubTyVars.cc'; then $(CYGPATH_W) 'GenPoly/ScrubTyVars.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/ScrubTyVars.cc'; fi` 1453 1454 GenPoly/driver_cfa_cpp-Lvalue.o: GenPoly/Lvalue.cc 1455 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Lvalue.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo -c -o GenPoly/driver_cfa_cpp-Lvalue.o `test -f 'GenPoly/Lvalue.cc' || echo '$(srcdir)/'`GenPoly/Lvalue.cc 1456 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po 1457 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/Lvalue.cc' object='GenPoly/driver_cfa_cpp-Lvalue.o' libtool=no @AMDEPBACKSLASH@ 1458 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1459 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Lvalue.o `test -f 'GenPoly/Lvalue.cc' || echo '$(srcdir)/'`GenPoly/Lvalue.cc 1460 1461 GenPoly/driver_cfa_cpp-Lvalue.obj: GenPoly/Lvalue.cc 1462 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Lvalue.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo -c -o GenPoly/driver_cfa_cpp-Lvalue.obj `if test -f 'GenPoly/Lvalue.cc'; then $(CYGPATH_W) 'GenPoly/Lvalue.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Lvalue.cc'; fi` 1463 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po 1464 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/Lvalue.cc' object='GenPoly/driver_cfa_cpp-Lvalue.obj' libtool=no @AMDEPBACKSLASH@ 1465 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1466 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Lvalue.obj `if test -f 'GenPoly/Lvalue.cc'; then $(CYGPATH_W) 'GenPoly/Lvalue.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Lvalue.cc'; fi` 1467 1468 GenPoly/driver_cfa_cpp-Specialize.o: GenPoly/Specialize.cc 1469 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Specialize.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo -c -o GenPoly/driver_cfa_cpp-Specialize.o `test -f 'GenPoly/Specialize.cc' || echo '$(srcdir)/'`GenPoly/Specialize.cc 1470 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po 1471 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/Specialize.cc' object='GenPoly/driver_cfa_cpp-Specialize.o' libtool=no @AMDEPBACKSLASH@ 1472 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1473 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Specialize.o `test -f 'GenPoly/Specialize.cc' || echo '$(srcdir)/'`GenPoly/Specialize.cc 1474 1475 GenPoly/driver_cfa_cpp-Specialize.obj: GenPoly/Specialize.cc 1476 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Specialize.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo -c -o GenPoly/driver_cfa_cpp-Specialize.obj `if test -f 'GenPoly/Specialize.cc'; then $(CYGPATH_W) 'GenPoly/Specialize.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Specialize.cc'; fi` 1477 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po 1478 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/Specialize.cc' object='GenPoly/driver_cfa_cpp-Specialize.obj' libtool=no @AMDEPBACKSLASH@ 1479 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1480 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Specialize.obj `if test -f 'GenPoly/Specialize.cc'; then $(CYGPATH_W) 'GenPoly/Specialize.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Specialize.cc'; fi` 1481 1482 GenPoly/driver_cfa_cpp-FindFunction.o: GenPoly/FindFunction.cc 1483 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-FindFunction.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo -c -o GenPoly/driver_cfa_cpp-FindFunction.o `test -f 'GenPoly/FindFunction.cc' || echo '$(srcdir)/'`GenPoly/FindFunction.cc 1484 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po 1485 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/FindFunction.cc' object='GenPoly/driver_cfa_cpp-FindFunction.o' libtool=no @AMDEPBACKSLASH@ 1486 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1487 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.o `test -f 'GenPoly/FindFunction.cc' || echo '$(srcdir)/'`GenPoly/FindFunction.cc 1488 1489 GenPoly/driver_cfa_cpp-FindFunction.obj: GenPoly/FindFunction.cc 1490 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-FindFunction.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi` 1491 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po 1492 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/FindFunction.cc' object='GenPoly/driver_cfa_cpp-FindFunction.obj' libtool=no @AMDEPBACKSLASH@ 1493 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1494 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi` 1495 1496 GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc 1497 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc 1498 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po 1499 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.o' libtool=no @AMDEPBACKSLASH@ 1500 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1501 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc 1502 1503 GenPoly/driver_cfa_cpp-InstantiateGeneric.obj: GenPoly/InstantiateGeneric.cc 1504 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi` 1505 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po 1506 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.obj' libtool=no @AMDEPBACKSLASH@ 1507 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1508 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi` 1509 1510 InitTweak/driver_cfa_cpp-GenInit.o: InitTweak/GenInit.cc 1511 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-GenInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo -c -o InitTweak/driver_cfa_cpp-GenInit.o `test -f 'InitTweak/GenInit.cc' || echo '$(srcdir)/'`InitTweak/GenInit.cc 1512 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po 1513 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.o' libtool=no @AMDEPBACKSLASH@ 1514 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1515 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-GenInit.o `test -f 'InitTweak/GenInit.cc' || echo '$(srcdir)/'`InitTweak/GenInit.cc 1516 1517 InitTweak/driver_cfa_cpp-GenInit.obj: InitTweak/GenInit.cc 1518 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-GenInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo -c -o InitTweak/driver_cfa_cpp-GenInit.obj `if test -f 'InitTweak/GenInit.cc'; then $(CYGPATH_W) 'InitTweak/GenInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/GenInit.cc'; fi` 1519 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po 1520 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.obj' libtool=no @AMDEPBACKSLASH@ 1521 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1522 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-GenInit.obj `if test -f 'InitTweak/GenInit.cc'; then $(CYGPATH_W) 'InitTweak/GenInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/GenInit.cc'; fi` 1523 1524 InitTweak/driver_cfa_cpp-FixInit.o: InitTweak/FixInit.cc 1525 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc 1526 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po 1527 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.o' libtool=no @AMDEPBACKSLASH@ 1528 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1529 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc 1530 1531 InitTweak/driver_cfa_cpp-FixInit.obj: InitTweak/FixInit.cc 1532 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi` 1533 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po 1534 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.obj' libtool=no @AMDEPBACKSLASH@ 1535 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1536 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi` 1537 1538 InitTweak/driver_cfa_cpp-FixGlobalInit.o: InitTweak/FixGlobalInit.cc 1539 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc 1540 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po 1541 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.o' libtool=no @AMDEPBACKSLASH@ 1542 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1543 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc 1544 1545 InitTweak/driver_cfa_cpp-FixGlobalInit.obj: InitTweak/FixGlobalInit.cc 1546 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi` 1547 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po 1548 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.obj' libtool=no @AMDEPBACKSLASH@ 1549 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1550 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi` 1551 1552 InitTweak/driver_cfa_cpp-InitTweak.o: InitTweak/InitTweak.cc 1553 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc 1554 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po 1555 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.o' libtool=no @AMDEPBACKSLASH@ 1556 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1557 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc 1558 1559 InitTweak/driver_cfa_cpp-InitTweak.obj: InitTweak/InitTweak.cc 1560 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi` 1561 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po 1562 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.obj' libtool=no @AMDEPBACKSLASH@ 1563 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1564 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi` 1565 1566 Parser/driver_cfa_cpp-parser.o: Parser/parser.cc 1567 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc 1568 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parser.Po 1569 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/parser.cc' object='Parser/driver_cfa_cpp-parser.o' libtool=no @AMDEPBACKSLASH@ 1570 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1571 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc 1572 1573 Parser/driver_cfa_cpp-parser.obj: Parser/parser.cc 1574 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.obj `if test -f 'Parser/parser.cc'; then $(CYGPATH_W) 'Parser/parser.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parser.cc'; fi` 1575 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parser.Po 1576 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/parser.cc' object='Parser/driver_cfa_cpp-parser.obj' libtool=no @AMDEPBACKSLASH@ 1577 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1578 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parser.obj `if test -f 'Parser/parser.cc'; then $(CYGPATH_W) 'Parser/parser.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parser.cc'; fi` 1579 1580 Parser/driver_cfa_cpp-lex.o: Parser/lex.cc 1581 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-lex.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo -c -o Parser/driver_cfa_cpp-lex.o `test -f 'Parser/lex.cc' || echo '$(srcdir)/'`Parser/lex.cc 1582 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-lex.Po 1583 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/lex.cc' object='Parser/driver_cfa_cpp-lex.o' libtool=no @AMDEPBACKSLASH@ 1584 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1585 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-lex.o `test -f 'Parser/lex.cc' || echo '$(srcdir)/'`Parser/lex.cc 1586 1587 Parser/driver_cfa_cpp-lex.obj: Parser/lex.cc 1588 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-lex.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo -c -o Parser/driver_cfa_cpp-lex.obj `if test -f 'Parser/lex.cc'; then $(CYGPATH_W) 'Parser/lex.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/lex.cc'; fi` 1589 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-lex.Po 1590 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/lex.cc' object='Parser/driver_cfa_cpp-lex.obj' libtool=no @AMDEPBACKSLASH@ 1591 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1592 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-lex.obj `if test -f 'Parser/lex.cc'; then $(CYGPATH_W) 'Parser/lex.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/lex.cc'; fi` 1593 1594 Parser/driver_cfa_cpp-TypedefTable.o: Parser/TypedefTable.cc 1595 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypedefTable.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo -c -o Parser/driver_cfa_cpp-TypedefTable.o `test -f 'Parser/TypedefTable.cc' || echo '$(srcdir)/'`Parser/TypedefTable.cc 1596 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Po 1597 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/TypedefTable.cc' object='Parser/driver_cfa_cpp-TypedefTable.o' libtool=no @AMDEPBACKSLASH@ 1598 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1599 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypedefTable.o `test -f 'Parser/TypedefTable.cc' || echo '$(srcdir)/'`Parser/TypedefTable.cc 1600 1601 Parser/driver_cfa_cpp-TypedefTable.obj: Parser/TypedefTable.cc 1602 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypedefTable.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo -c -o Parser/driver_cfa_cpp-TypedefTable.obj `if test -f 'Parser/TypedefTable.cc'; then $(CYGPATH_W) 'Parser/TypedefTable.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypedefTable.cc'; fi` 1603 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Po 1604 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/TypedefTable.cc' object='Parser/driver_cfa_cpp-TypedefTable.obj' libtool=no @AMDEPBACKSLASH@ 1605 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1606 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypedefTable.obj `if test -f 'Parser/TypedefTable.cc'; then $(CYGPATH_W) 'Parser/TypedefTable.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypedefTable.cc'; fi` 1607 1608 Parser/driver_cfa_cpp-ParseNode.o: Parser/ParseNode.cc 1609 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ParseNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo -c -o Parser/driver_cfa_cpp-ParseNode.o `test -f 'Parser/ParseNode.cc' || echo '$(srcdir)/'`Parser/ParseNode.cc 1610 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Po 1611 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/ParseNode.cc' object='Parser/driver_cfa_cpp-ParseNode.o' libtool=no @AMDEPBACKSLASH@ 1612 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1613 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ParseNode.o `test -f 'Parser/ParseNode.cc' || echo '$(srcdir)/'`Parser/ParseNode.cc 1614 1615 Parser/driver_cfa_cpp-ParseNode.obj: Parser/ParseNode.cc 1616 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ParseNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo -c -o Parser/driver_cfa_cpp-ParseNode.obj `if test -f 'Parser/ParseNode.cc'; then $(CYGPATH_W) 'Parser/ParseNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ParseNode.cc'; fi` 1617 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Po 1618 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/ParseNode.cc' object='Parser/driver_cfa_cpp-ParseNode.obj' libtool=no @AMDEPBACKSLASH@ 1619 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1620 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ParseNode.obj `if test -f 'Parser/ParseNode.cc'; then $(CYGPATH_W) 'Parser/ParseNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ParseNode.cc'; fi` 1621 1622 Parser/driver_cfa_cpp-DeclarationNode.o: Parser/DeclarationNode.cc 1623 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-DeclarationNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo -c -o Parser/driver_cfa_cpp-DeclarationNode.o `test -f 'Parser/DeclarationNode.cc' || echo '$(srcdir)/'`Parser/DeclarationNode.cc 1624 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po 1625 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/DeclarationNode.cc' object='Parser/driver_cfa_cpp-DeclarationNode.o' libtool=no @AMDEPBACKSLASH@ 1626 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1627 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-DeclarationNode.o `test -f 'Parser/DeclarationNode.cc' || echo '$(srcdir)/'`Parser/DeclarationNode.cc 1628 1629 Parser/driver_cfa_cpp-DeclarationNode.obj: Parser/DeclarationNode.cc 1630 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-DeclarationNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo -c -o Parser/driver_cfa_cpp-DeclarationNode.obj `if test -f 'Parser/DeclarationNode.cc'; then $(CYGPATH_W) 'Parser/DeclarationNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/DeclarationNode.cc'; fi` 1631 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po 1632 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/DeclarationNode.cc' object='Parser/driver_cfa_cpp-DeclarationNode.obj' libtool=no @AMDEPBACKSLASH@ 1633 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1634 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-DeclarationNode.obj `if test -f 'Parser/DeclarationNode.cc'; then $(CYGPATH_W) 'Parser/DeclarationNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/DeclarationNode.cc'; fi` 1635 1636 Parser/driver_cfa_cpp-ExpressionNode.o: Parser/ExpressionNode.cc 1637 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ExpressionNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo -c -o Parser/driver_cfa_cpp-ExpressionNode.o `test -f 'Parser/ExpressionNode.cc' || echo '$(srcdir)/'`Parser/ExpressionNode.cc 1638 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po 1639 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/ExpressionNode.cc' object='Parser/driver_cfa_cpp-ExpressionNode.o' libtool=no @AMDEPBACKSLASH@ 1640 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1641 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ExpressionNode.o `test -f 'Parser/ExpressionNode.cc' || echo '$(srcdir)/'`Parser/ExpressionNode.cc 1642 1643 Parser/driver_cfa_cpp-ExpressionNode.obj: Parser/ExpressionNode.cc 1644 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ExpressionNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo -c -o Parser/driver_cfa_cpp-ExpressionNode.obj `if test -f 'Parser/ExpressionNode.cc'; then $(CYGPATH_W) 'Parser/ExpressionNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ExpressionNode.cc'; fi` 1645 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po 1646 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/ExpressionNode.cc' object='Parser/driver_cfa_cpp-ExpressionNode.obj' libtool=no @AMDEPBACKSLASH@ 1647 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1648 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ExpressionNode.obj `if test -f 'Parser/ExpressionNode.cc'; then $(CYGPATH_W) 'Parser/ExpressionNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ExpressionNode.cc'; fi` 1649 1650 Parser/driver_cfa_cpp-StatementNode.o: Parser/StatementNode.cc 1651 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-StatementNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo -c -o Parser/driver_cfa_cpp-StatementNode.o `test -f 'Parser/StatementNode.cc' || echo '$(srcdir)/'`Parser/StatementNode.cc 1652 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Po 1653 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/StatementNode.cc' object='Parser/driver_cfa_cpp-StatementNode.o' libtool=no @AMDEPBACKSLASH@ 1654 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1655 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-StatementNode.o `test -f 'Parser/StatementNode.cc' || echo '$(srcdir)/'`Parser/StatementNode.cc 1656 1657 Parser/driver_cfa_cpp-StatementNode.obj: Parser/StatementNode.cc 1658 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-StatementNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo -c -o Parser/driver_cfa_cpp-StatementNode.obj `if test -f 'Parser/StatementNode.cc'; then $(CYGPATH_W) 'Parser/StatementNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/StatementNode.cc'; fi` 1659 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Po 1660 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/StatementNode.cc' object='Parser/driver_cfa_cpp-StatementNode.obj' libtool=no @AMDEPBACKSLASH@ 1661 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1662 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-StatementNode.obj `if test -f 'Parser/StatementNode.cc'; then $(CYGPATH_W) 'Parser/StatementNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/StatementNode.cc'; fi` 1663 1664 Parser/driver_cfa_cpp-InitializerNode.o: Parser/InitializerNode.cc 1665 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-InitializerNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo -c -o Parser/driver_cfa_cpp-InitializerNode.o `test -f 'Parser/InitializerNode.cc' || echo '$(srcdir)/'`Parser/InitializerNode.cc 1666 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Po 1667 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/InitializerNode.cc' object='Parser/driver_cfa_cpp-InitializerNode.o' libtool=no @AMDEPBACKSLASH@ 1668 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1669 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-InitializerNode.o `test -f 'Parser/InitializerNode.cc' || echo '$(srcdir)/'`Parser/InitializerNode.cc 1670 1671 Parser/driver_cfa_cpp-InitializerNode.obj: Parser/InitializerNode.cc 1672 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-InitializerNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo -c -o Parser/driver_cfa_cpp-InitializerNode.obj `if test -f 'Parser/InitializerNode.cc'; then $(CYGPATH_W) 'Parser/InitializerNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/InitializerNode.cc'; fi` 1673 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Po 1674 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/InitializerNode.cc' object='Parser/driver_cfa_cpp-InitializerNode.obj' libtool=no @AMDEPBACKSLASH@ 1675 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1676 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-InitializerNode.obj `if test -f 'Parser/InitializerNode.cc'; then $(CYGPATH_W) 'Parser/InitializerNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/InitializerNode.cc'; fi` 1677 1678 Parser/driver_cfa_cpp-TypeData.o: Parser/TypeData.cc 1679 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypeData.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo -c -o Parser/driver_cfa_cpp-TypeData.o `test -f 'Parser/TypeData.cc' || echo '$(srcdir)/'`Parser/TypeData.cc 1680 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Po 1681 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/TypeData.cc' object='Parser/driver_cfa_cpp-TypeData.o' libtool=no @AMDEPBACKSLASH@ 1682 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1683 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypeData.o `test -f 'Parser/TypeData.cc' || echo '$(srcdir)/'`Parser/TypeData.cc 1684 1685 Parser/driver_cfa_cpp-TypeData.obj: Parser/TypeData.cc 1686 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypeData.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo -c -o Parser/driver_cfa_cpp-TypeData.obj `if test -f 'Parser/TypeData.cc'; then $(CYGPATH_W) 'Parser/TypeData.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypeData.cc'; fi` 1687 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Po 1688 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/TypeData.cc' object='Parser/driver_cfa_cpp-TypeData.obj' libtool=no @AMDEPBACKSLASH@ 1689 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1690 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypeData.obj `if test -f 'Parser/TypeData.cc'; then $(CYGPATH_W) 'Parser/TypeData.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypeData.cc'; fi` 1691 1692 Parser/driver_cfa_cpp-LinkageSpec.o: Parser/LinkageSpec.cc 1693 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-LinkageSpec.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo -c -o Parser/driver_cfa_cpp-LinkageSpec.o `test -f 'Parser/LinkageSpec.cc' || echo '$(srcdir)/'`Parser/LinkageSpec.cc 1694 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Po 1695 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/LinkageSpec.cc' object='Parser/driver_cfa_cpp-LinkageSpec.o' libtool=no @AMDEPBACKSLASH@ 1696 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1697 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-LinkageSpec.o `test -f 'Parser/LinkageSpec.cc' || echo '$(srcdir)/'`Parser/LinkageSpec.cc 1698 1699 Parser/driver_cfa_cpp-LinkageSpec.obj: Parser/LinkageSpec.cc 1700 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-LinkageSpec.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo -c -o Parser/driver_cfa_cpp-LinkageSpec.obj `if test -f 'Parser/LinkageSpec.cc'; then $(CYGPATH_W) 'Parser/LinkageSpec.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/LinkageSpec.cc'; fi` 1701 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Po 1702 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/LinkageSpec.cc' object='Parser/driver_cfa_cpp-LinkageSpec.obj' libtool=no @AMDEPBACKSLASH@ 1703 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1704 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-LinkageSpec.obj `if test -f 'Parser/LinkageSpec.cc'; then $(CYGPATH_W) 'Parser/LinkageSpec.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/LinkageSpec.cc'; fi` 1705 1706 Parser/driver_cfa_cpp-parserutility.o: Parser/parserutility.cc 1707 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parserutility.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo -c -o Parser/driver_cfa_cpp-parserutility.o `test -f 'Parser/parserutility.cc' || echo '$(srcdir)/'`Parser/parserutility.cc 1708 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Po 1709 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/parserutility.cc' object='Parser/driver_cfa_cpp-parserutility.o' libtool=no @AMDEPBACKSLASH@ 1710 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1711 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parserutility.o `test -f 'Parser/parserutility.cc' || echo '$(srcdir)/'`Parser/parserutility.cc 1712 1713 Parser/driver_cfa_cpp-parserutility.obj: Parser/parserutility.cc 1714 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parserutility.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo -c -o Parser/driver_cfa_cpp-parserutility.obj `if test -f 'Parser/parserutility.cc'; then $(CYGPATH_W) 'Parser/parserutility.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parserutility.cc'; fi` 1715 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Po 1716 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Parser/parserutility.cc' object='Parser/driver_cfa_cpp-parserutility.obj' libtool=no @AMDEPBACKSLASH@ 1717 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1718 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parserutility.obj `if test -f 'Parser/parserutility.cc'; then $(CYGPATH_W) 'Parser/parserutility.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parserutility.cc'; fi` 1719 1720 ResolvExpr/driver_cfa_cpp-AlternativeFinder.o: ResolvExpr/AlternativeFinder.cc 1721 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativeFinder.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.o `test -f 'ResolvExpr/AlternativeFinder.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativeFinder.cc 1722 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Po 1723 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/AlternativeFinder.cc' object='ResolvExpr/driver_cfa_cpp-AlternativeFinder.o' libtool=no @AMDEPBACKSLASH@ 1724 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1725 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.o `test -f 'ResolvExpr/AlternativeFinder.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativeFinder.cc 1726 1727 ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj: ResolvExpr/AlternativeFinder.cc 1728 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj `if test -f 'ResolvExpr/AlternativeFinder.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativeFinder.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativeFinder.cc'; fi` 1729 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Po 1730 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/AlternativeFinder.cc' object='ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj' libtool=no @AMDEPBACKSLASH@ 1731 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1732 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj `if test -f 'ResolvExpr/AlternativeFinder.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativeFinder.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativeFinder.cc'; fi` 1733 1734 ResolvExpr/driver_cfa_cpp-Alternative.o: ResolvExpr/Alternative.cc 1735 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Alternative.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo -c -o ResolvExpr/driver_cfa_cpp-Alternative.o `test -f 'ResolvExpr/Alternative.cc' || echo '$(srcdir)/'`ResolvExpr/Alternative.cc 1736 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Po 1737 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Alternative.cc' object='ResolvExpr/driver_cfa_cpp-Alternative.o' libtool=no @AMDEPBACKSLASH@ 1738 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1739 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Alternative.o `test -f 'ResolvExpr/Alternative.cc' || echo '$(srcdir)/'`ResolvExpr/Alternative.cc 1740 1741 ResolvExpr/driver_cfa_cpp-Alternative.obj: ResolvExpr/Alternative.cc 1742 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Alternative.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo -c -o ResolvExpr/driver_cfa_cpp-Alternative.obj `if test -f 'ResolvExpr/Alternative.cc'; then $(CYGPATH_W) 'ResolvExpr/Alternative.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Alternative.cc'; fi` 1743 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Po 1744 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Alternative.cc' object='ResolvExpr/driver_cfa_cpp-Alternative.obj' libtool=no @AMDEPBACKSLASH@ 1745 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1746 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Alternative.obj `if test -f 'ResolvExpr/Alternative.cc'; then $(CYGPATH_W) 'ResolvExpr/Alternative.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Alternative.cc'; fi` 1747 1748 ResolvExpr/driver_cfa_cpp-Unify.o: ResolvExpr/Unify.cc 1749 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Unify.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo -c -o ResolvExpr/driver_cfa_cpp-Unify.o `test -f 'ResolvExpr/Unify.cc' || echo '$(srcdir)/'`ResolvExpr/Unify.cc 1750 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po 1751 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Unify.cc' object='ResolvExpr/driver_cfa_cpp-Unify.o' libtool=no @AMDEPBACKSLASH@ 1752 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1753 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Unify.o `test -f 'ResolvExpr/Unify.cc' || echo '$(srcdir)/'`ResolvExpr/Unify.cc 1754 1755 ResolvExpr/driver_cfa_cpp-Unify.obj: ResolvExpr/Unify.cc 1756 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Unify.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo -c -o ResolvExpr/driver_cfa_cpp-Unify.obj `if test -f 'ResolvExpr/Unify.cc'; then $(CYGPATH_W) 'ResolvExpr/Unify.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Unify.cc'; fi` 1757 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po 1758 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Unify.cc' object='ResolvExpr/driver_cfa_cpp-Unify.obj' libtool=no @AMDEPBACKSLASH@ 1759 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1760 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Unify.obj `if test -f 'ResolvExpr/Unify.cc'; then $(CYGPATH_W) 'ResolvExpr/Unify.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Unify.cc'; fi` 1761 1762 ResolvExpr/driver_cfa_cpp-PtrsAssignable.o: ResolvExpr/PtrsAssignable.cc 1763 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsAssignable.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.o `test -f 'ResolvExpr/PtrsAssignable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsAssignable.cc 1764 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Po 1765 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/PtrsAssignable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsAssignable.o' libtool=no @AMDEPBACKSLASH@ 1766 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1767 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.o `test -f 'ResolvExpr/PtrsAssignable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsAssignable.cc 1768 1769 ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj: ResolvExpr/PtrsAssignable.cc 1770 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj `if test -f 'ResolvExpr/PtrsAssignable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsAssignable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsAssignable.cc'; fi` 1771 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Po 1772 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/PtrsAssignable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj' libtool=no @AMDEPBACKSLASH@ 1773 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1774 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj `if test -f 'ResolvExpr/PtrsAssignable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsAssignable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsAssignable.cc'; fi` 1775 1776 ResolvExpr/driver_cfa_cpp-CommonType.o: ResolvExpr/CommonType.cc 1777 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CommonType.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo -c -o ResolvExpr/driver_cfa_cpp-CommonType.o `test -f 'ResolvExpr/CommonType.cc' || echo '$(srcdir)/'`ResolvExpr/CommonType.cc 1778 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po 1779 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CommonType.cc' object='ResolvExpr/driver_cfa_cpp-CommonType.o' libtool=no @AMDEPBACKSLASH@ 1780 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1781 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CommonType.o `test -f 'ResolvExpr/CommonType.cc' || echo '$(srcdir)/'`ResolvExpr/CommonType.cc 1782 1783 ResolvExpr/driver_cfa_cpp-CommonType.obj: ResolvExpr/CommonType.cc 1784 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CommonType.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo -c -o ResolvExpr/driver_cfa_cpp-CommonType.obj `if test -f 'ResolvExpr/CommonType.cc'; then $(CYGPATH_W) 'ResolvExpr/CommonType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CommonType.cc'; fi` 1785 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po 1786 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CommonType.cc' object='ResolvExpr/driver_cfa_cpp-CommonType.obj' libtool=no @AMDEPBACKSLASH@ 1787 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1788 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CommonType.obj `if test -f 'ResolvExpr/CommonType.cc'; then $(CYGPATH_W) 'ResolvExpr/CommonType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CommonType.cc'; fi` 1789 1790 ResolvExpr/driver_cfa_cpp-ConversionCost.o: ResolvExpr/ConversionCost.cc 1791 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ConversionCost.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.o `test -f 'ResolvExpr/ConversionCost.cc' || echo '$(srcdir)/'`ResolvExpr/ConversionCost.cc 1792 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po 1793 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ConversionCost.cc' object='ResolvExpr/driver_cfa_cpp-ConversionCost.o' libtool=no @AMDEPBACKSLASH@ 1794 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1795 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.o `test -f 'ResolvExpr/ConversionCost.cc' || echo '$(srcdir)/'`ResolvExpr/ConversionCost.cc 1796 1797 ResolvExpr/driver_cfa_cpp-ConversionCost.obj: ResolvExpr/ConversionCost.cc 1798 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ConversionCost.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.obj `if test -f 'ResolvExpr/ConversionCost.cc'; then $(CYGPATH_W) 'ResolvExpr/ConversionCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ConversionCost.cc'; fi` 1799 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po 1800 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ConversionCost.cc' object='ResolvExpr/driver_cfa_cpp-ConversionCost.obj' libtool=no @AMDEPBACKSLASH@ 1801 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1802 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.obj `if test -f 'ResolvExpr/ConversionCost.cc'; then $(CYGPATH_W) 'ResolvExpr/ConversionCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ConversionCost.cc'; fi` 1803 1804 ResolvExpr/driver_cfa_cpp-CastCost.o: ResolvExpr/CastCost.cc 1805 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CastCost.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-CastCost.o `test -f 'ResolvExpr/CastCost.cc' || echo '$(srcdir)/'`ResolvExpr/CastCost.cc 1806 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Po 1807 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CastCost.cc' object='ResolvExpr/driver_cfa_cpp-CastCost.o' libtool=no @AMDEPBACKSLASH@ 1808 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1809 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CastCost.o `test -f 'ResolvExpr/CastCost.cc' || echo '$(srcdir)/'`ResolvExpr/CastCost.cc 1810 1811 ResolvExpr/driver_cfa_cpp-CastCost.obj: ResolvExpr/CastCost.cc 1812 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CastCost.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-CastCost.obj `if test -f 'ResolvExpr/CastCost.cc'; then $(CYGPATH_W) 'ResolvExpr/CastCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CastCost.cc'; fi` 1813 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Po 1814 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CastCost.cc' object='ResolvExpr/driver_cfa_cpp-CastCost.obj' libtool=no @AMDEPBACKSLASH@ 1815 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1816 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CastCost.obj `if test -f 'ResolvExpr/CastCost.cc'; then $(CYGPATH_W) 'ResolvExpr/CastCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CastCost.cc'; fi` 1817 1818 ResolvExpr/driver_cfa_cpp-PtrsCastable.o: ResolvExpr/PtrsCastable.cc 1819 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsCastable.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.o `test -f 'ResolvExpr/PtrsCastable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsCastable.cc 1820 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Po 1821 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/PtrsCastable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsCastable.o' libtool=no @AMDEPBACKSLASH@ 1822 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1823 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.o `test -f 'ResolvExpr/PtrsCastable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsCastable.cc 1824 1825 ResolvExpr/driver_cfa_cpp-PtrsCastable.obj: ResolvExpr/PtrsCastable.cc 1826 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsCastable.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.obj `if test -f 'ResolvExpr/PtrsCastable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsCastable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsCastable.cc'; fi` 1827 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Po 1828 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/PtrsCastable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsCastable.obj' libtool=no @AMDEPBACKSLASH@ 1829 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1830 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.obj `if test -f 'ResolvExpr/PtrsCastable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsCastable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsCastable.cc'; fi` 1831 1832 ResolvExpr/driver_cfa_cpp-AdjustExprType.o: ResolvExpr/AdjustExprType.cc 1833 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AdjustExprType.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.o `test -f 'ResolvExpr/AdjustExprType.cc' || echo '$(srcdir)/'`ResolvExpr/AdjustExprType.cc 1834 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Po 1835 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/AdjustExprType.cc' object='ResolvExpr/driver_cfa_cpp-AdjustExprType.o' libtool=no @AMDEPBACKSLASH@ 1836 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1837 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.o `test -f 'ResolvExpr/AdjustExprType.cc' || echo '$(srcdir)/'`ResolvExpr/AdjustExprType.cc 1838 1839 ResolvExpr/driver_cfa_cpp-AdjustExprType.obj: ResolvExpr/AdjustExprType.cc 1840 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AdjustExprType.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.obj `if test -f 'ResolvExpr/AdjustExprType.cc'; then $(CYGPATH_W) 'ResolvExpr/AdjustExprType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AdjustExprType.cc'; fi` 1841 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Po 1842 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/AdjustExprType.cc' object='ResolvExpr/driver_cfa_cpp-AdjustExprType.obj' libtool=no @AMDEPBACKSLASH@ 1843 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1844 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.obj `if test -f 'ResolvExpr/AdjustExprType.cc'; then $(CYGPATH_W) 'ResolvExpr/AdjustExprType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AdjustExprType.cc'; fi` 1845 1846 ResolvExpr/driver_cfa_cpp-AlternativePrinter.o: ResolvExpr/AlternativePrinter.cc 1847 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativePrinter.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.o `test -f 'ResolvExpr/AlternativePrinter.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativePrinter.cc 1848 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Po 1849 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/AlternativePrinter.cc' object='ResolvExpr/driver_cfa_cpp-AlternativePrinter.o' libtool=no @AMDEPBACKSLASH@ 1850 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1851 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.o `test -f 'ResolvExpr/AlternativePrinter.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativePrinter.cc 1852 1853 ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj: ResolvExpr/AlternativePrinter.cc 1854 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj `if test -f 'ResolvExpr/AlternativePrinter.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativePrinter.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativePrinter.cc'; fi` 1855 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Po 1856 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/AlternativePrinter.cc' object='ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj' libtool=no @AMDEPBACKSLASH@ 1857 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1858 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj `if test -f 'ResolvExpr/AlternativePrinter.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativePrinter.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativePrinter.cc'; fi` 1859 1860 ResolvExpr/driver_cfa_cpp-Resolver.o: ResolvExpr/Resolver.cc 1861 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Resolver.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo -c -o ResolvExpr/driver_cfa_cpp-Resolver.o `test -f 'ResolvExpr/Resolver.cc' || echo '$(srcdir)/'`ResolvExpr/Resolver.cc 1862 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Po 1863 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Resolver.cc' object='ResolvExpr/driver_cfa_cpp-Resolver.o' libtool=no @AMDEPBACKSLASH@ 1864 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1865 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Resolver.o `test -f 'ResolvExpr/Resolver.cc' || echo '$(srcdir)/'`ResolvExpr/Resolver.cc 1866 1867 ResolvExpr/driver_cfa_cpp-Resolver.obj: ResolvExpr/Resolver.cc 1868 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Resolver.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo -c -o ResolvExpr/driver_cfa_cpp-Resolver.obj `if test -f 'ResolvExpr/Resolver.cc'; then $(CYGPATH_W) 'ResolvExpr/Resolver.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Resolver.cc'; fi` 1869 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Po 1870 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Resolver.cc' object='ResolvExpr/driver_cfa_cpp-Resolver.obj' libtool=no @AMDEPBACKSLASH@ 1871 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1872 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Resolver.obj `if test -f 'ResolvExpr/Resolver.cc'; then $(CYGPATH_W) 'ResolvExpr/Resolver.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Resolver.cc'; fi` 1873 1874 ResolvExpr/driver_cfa_cpp-ResolveTypeof.o: ResolvExpr/ResolveTypeof.cc 1875 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ResolveTypeof.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.o `test -f 'ResolvExpr/ResolveTypeof.cc' || echo '$(srcdir)/'`ResolvExpr/ResolveTypeof.cc 1876 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Po 1877 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ResolveTypeof.cc' object='ResolvExpr/driver_cfa_cpp-ResolveTypeof.o' libtool=no @AMDEPBACKSLASH@ 1878 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1879 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.o `test -f 'ResolvExpr/ResolveTypeof.cc' || echo '$(srcdir)/'`ResolvExpr/ResolveTypeof.cc 1880 1881 ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj: ResolvExpr/ResolveTypeof.cc 1882 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj `if test -f 'ResolvExpr/ResolveTypeof.cc'; then $(CYGPATH_W) 'ResolvExpr/ResolveTypeof.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ResolveTypeof.cc'; fi` 1883 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Po 1884 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ResolveTypeof.cc' object='ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj' libtool=no @AMDEPBACKSLASH@ 1885 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1886 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj `if test -f 'ResolvExpr/ResolveTypeof.cc'; then $(CYGPATH_W) 'ResolvExpr/ResolveTypeof.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ResolveTypeof.cc'; fi` 1887 1888 ResolvExpr/driver_cfa_cpp-RenameVars.o: ResolvExpr/RenameVars.cc 1889 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-RenameVars.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-RenameVars.o `test -f 'ResolvExpr/RenameVars.cc' || echo '$(srcdir)/'`ResolvExpr/RenameVars.cc 1890 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Po 1891 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/RenameVars.cc' object='ResolvExpr/driver_cfa_cpp-RenameVars.o' libtool=no @AMDEPBACKSLASH@ 1892 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1893 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-RenameVars.o `test -f 'ResolvExpr/RenameVars.cc' || echo '$(srcdir)/'`ResolvExpr/RenameVars.cc 1894 1895 ResolvExpr/driver_cfa_cpp-RenameVars.obj: ResolvExpr/RenameVars.cc 1896 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-RenameVars.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-RenameVars.obj `if test -f 'ResolvExpr/RenameVars.cc'; then $(CYGPATH_W) 'ResolvExpr/RenameVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/RenameVars.cc'; fi` 1897 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Po 1898 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/RenameVars.cc' object='ResolvExpr/driver_cfa_cpp-RenameVars.obj' libtool=no @AMDEPBACKSLASH@ 1899 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1900 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-RenameVars.obj `if test -f 'ResolvExpr/RenameVars.cc'; then $(CYGPATH_W) 'ResolvExpr/RenameVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/RenameVars.cc'; fi` 1901 1902 ResolvExpr/driver_cfa_cpp-FindOpenVars.o: ResolvExpr/FindOpenVars.cc 1903 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-FindOpenVars.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.o `test -f 'ResolvExpr/FindOpenVars.cc' || echo '$(srcdir)/'`ResolvExpr/FindOpenVars.cc 1904 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po 1905 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/FindOpenVars.cc' object='ResolvExpr/driver_cfa_cpp-FindOpenVars.o' libtool=no @AMDEPBACKSLASH@ 1906 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1907 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.o `test -f 'ResolvExpr/FindOpenVars.cc' || echo '$(srcdir)/'`ResolvExpr/FindOpenVars.cc 1908 1909 ResolvExpr/driver_cfa_cpp-FindOpenVars.obj: ResolvExpr/FindOpenVars.cc 1910 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-FindOpenVars.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.obj `if test -f 'ResolvExpr/FindOpenVars.cc'; then $(CYGPATH_W) 'ResolvExpr/FindOpenVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/FindOpenVars.cc'; fi` 1911 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po 1912 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/FindOpenVars.cc' object='ResolvExpr/driver_cfa_cpp-FindOpenVars.obj' libtool=no @AMDEPBACKSLASH@ 1913 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1914 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.obj `if test -f 'ResolvExpr/FindOpenVars.cc'; then $(CYGPATH_W) 'ResolvExpr/FindOpenVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/FindOpenVars.cc'; fi` 1915 1916 ResolvExpr/driver_cfa_cpp-PolyCost.o: ResolvExpr/PolyCost.cc 1917 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PolyCost.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-PolyCost.o `test -f 'ResolvExpr/PolyCost.cc' || echo '$(srcdir)/'`ResolvExpr/PolyCost.cc 1918 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Po 1919 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/PolyCost.cc' object='ResolvExpr/driver_cfa_cpp-PolyCost.o' libtool=no @AMDEPBACKSLASH@ 1920 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1921 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PolyCost.o `test -f 'ResolvExpr/PolyCost.cc' || echo '$(srcdir)/'`ResolvExpr/PolyCost.cc 1922 1923 ResolvExpr/driver_cfa_cpp-PolyCost.obj: ResolvExpr/PolyCost.cc 1924 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PolyCost.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-PolyCost.obj `if test -f 'ResolvExpr/PolyCost.cc'; then $(CYGPATH_W) 'ResolvExpr/PolyCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PolyCost.cc'; fi` 1925 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Po 1926 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/PolyCost.cc' object='ResolvExpr/driver_cfa_cpp-PolyCost.obj' libtool=no @AMDEPBACKSLASH@ 1927 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1928 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PolyCost.obj `if test -f 'ResolvExpr/PolyCost.cc'; then $(CYGPATH_W) 'ResolvExpr/PolyCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PolyCost.cc'; fi` 1929 1930 ResolvExpr/driver_cfa_cpp-Occurs.o: ResolvExpr/Occurs.cc 1931 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Occurs.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo -c -o ResolvExpr/driver_cfa_cpp-Occurs.o `test -f 'ResolvExpr/Occurs.cc' || echo '$(srcdir)/'`ResolvExpr/Occurs.cc 1932 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po 1933 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Occurs.cc' object='ResolvExpr/driver_cfa_cpp-Occurs.o' libtool=no @AMDEPBACKSLASH@ 1934 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1935 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Occurs.o `test -f 'ResolvExpr/Occurs.cc' || echo '$(srcdir)/'`ResolvExpr/Occurs.cc 1936 1937 ResolvExpr/driver_cfa_cpp-Occurs.obj: ResolvExpr/Occurs.cc 1938 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Occurs.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo -c -o ResolvExpr/driver_cfa_cpp-Occurs.obj `if test -f 'ResolvExpr/Occurs.cc'; then $(CYGPATH_W) 'ResolvExpr/Occurs.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Occurs.cc'; fi` 1939 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po 1940 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/Occurs.cc' object='ResolvExpr/driver_cfa_cpp-Occurs.obj' libtool=no @AMDEPBACKSLASH@ 1941 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1942 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Occurs.obj `if test -f 'ResolvExpr/Occurs.cc'; then $(CYGPATH_W) 'ResolvExpr/Occurs.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Occurs.cc'; fi` 1943 1944 ResolvExpr/driver_cfa_cpp-TypeEnvironment.o: ResolvExpr/TypeEnvironment.cc 1945 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-TypeEnvironment.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.o `test -f 'ResolvExpr/TypeEnvironment.cc' || echo '$(srcdir)/'`ResolvExpr/TypeEnvironment.cc 1946 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po 1947 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/TypeEnvironment.cc' object='ResolvExpr/driver_cfa_cpp-TypeEnvironment.o' libtool=no @AMDEPBACKSLASH@ 1948 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1949 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.o `test -f 'ResolvExpr/TypeEnvironment.cc' || echo '$(srcdir)/'`ResolvExpr/TypeEnvironment.cc 1950 1951 ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj: ResolvExpr/TypeEnvironment.cc 1952 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi` 1953 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po 1954 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/TypeEnvironment.cc' object='ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj' libtool=no @AMDEPBACKSLASH@ 1955 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1956 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi` 1957 1958 ResolvExpr/driver_cfa_cpp-CurrentObject.o: ResolvExpr/CurrentObject.cc 1959 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc 1960 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po 1961 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.o' libtool=no @AMDEPBACKSLASH@ 1962 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1963 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc 1964 1965 ResolvExpr/driver_cfa_cpp-CurrentObject.obj: ResolvExpr/CurrentObject.cc 1966 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi` 1967 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po 1968 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.obj' libtool=no @AMDEPBACKSLASH@ 1969 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1970 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi` 1971 1972 ResolvExpr/driver_cfa_cpp-ExplodedActual.o: ResolvExpr/ExplodedActual.cc 1973 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc 1974 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po 1975 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.o' libtool=no @AMDEPBACKSLASH@ 1976 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1977 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc 1978 1979 ResolvExpr/driver_cfa_cpp-ExplodedActual.obj: ResolvExpr/ExplodedActual.cc 1980 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi` 1981 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po 1982 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.obj' libtool=no @AMDEPBACKSLASH@ 1983 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1984 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi` 1985 1986 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc 1987 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc 1988 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po 1989 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Indexer.cc' object='SymTab/driver_cfa_cpp-Indexer.o' libtool=no @AMDEPBACKSLASH@ 1990 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1991 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc 1992 1993 SymTab/driver_cfa_cpp-Indexer.obj: SymTab/Indexer.cc 1994 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.obj `if test -f 'SymTab/Indexer.cc'; then $(CYGPATH_W) 'SymTab/Indexer.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Indexer.cc'; fi` 1995 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po 1996 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Indexer.cc' object='SymTab/driver_cfa_cpp-Indexer.obj' libtool=no @AMDEPBACKSLASH@ 1997 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1998 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Indexer.obj `if test -f 'SymTab/Indexer.cc'; then $(CYGPATH_W) 'SymTab/Indexer.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Indexer.cc'; fi` 1999 2000 SymTab/driver_cfa_cpp-Mangler.o: SymTab/Mangler.cc 2001 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Mangler.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo -c -o SymTab/driver_cfa_cpp-Mangler.o `test -f 'SymTab/Mangler.cc' || echo '$(srcdir)/'`SymTab/Mangler.cc 2002 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po 2003 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Mangler.cc' object='SymTab/driver_cfa_cpp-Mangler.o' libtool=no @AMDEPBACKSLASH@ 2004 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2005 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Mangler.o `test -f 'SymTab/Mangler.cc' || echo '$(srcdir)/'`SymTab/Mangler.cc 2006 2007 SymTab/driver_cfa_cpp-Mangler.obj: SymTab/Mangler.cc 2008 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Mangler.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo -c -o SymTab/driver_cfa_cpp-Mangler.obj `if test -f 'SymTab/Mangler.cc'; then $(CYGPATH_W) 'SymTab/Mangler.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Mangler.cc'; fi` 2009 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po 2010 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Mangler.cc' object='SymTab/driver_cfa_cpp-Mangler.obj' libtool=no @AMDEPBACKSLASH@ 2011 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2012 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Mangler.obj `if test -f 'SymTab/Mangler.cc'; then $(CYGPATH_W) 'SymTab/Mangler.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Mangler.cc'; fi` 2013 2014 SymTab/driver_cfa_cpp-Validate.o: SymTab/Validate.cc 2015 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Validate.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo -c -o SymTab/driver_cfa_cpp-Validate.o `test -f 'SymTab/Validate.cc' || echo '$(srcdir)/'`SymTab/Validate.cc 2016 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po 2017 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Validate.cc' object='SymTab/driver_cfa_cpp-Validate.o' libtool=no @AMDEPBACKSLASH@ 2018 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2019 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Validate.o `test -f 'SymTab/Validate.cc' || echo '$(srcdir)/'`SymTab/Validate.cc 2020 2021 SymTab/driver_cfa_cpp-Validate.obj: SymTab/Validate.cc 2022 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Validate.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo -c -o SymTab/driver_cfa_cpp-Validate.obj `if test -f 'SymTab/Validate.cc'; then $(CYGPATH_W) 'SymTab/Validate.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Validate.cc'; fi` 2023 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po 2024 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Validate.cc' object='SymTab/driver_cfa_cpp-Validate.obj' libtool=no @AMDEPBACKSLASH@ 2025 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2026 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Validate.obj `if test -f 'SymTab/Validate.cc'; then $(CYGPATH_W) 'SymTab/Validate.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Validate.cc'; fi` 2027 2028 SymTab/driver_cfa_cpp-FixFunction.o: SymTab/FixFunction.cc 2029 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-FixFunction.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo -c -o SymTab/driver_cfa_cpp-FixFunction.o `test -f 'SymTab/FixFunction.cc' || echo '$(srcdir)/'`SymTab/FixFunction.cc 2030 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po 2031 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/FixFunction.cc' object='SymTab/driver_cfa_cpp-FixFunction.o' libtool=no @AMDEPBACKSLASH@ 2032 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2033 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-FixFunction.o `test -f 'SymTab/FixFunction.cc' || echo '$(srcdir)/'`SymTab/FixFunction.cc 2034 2035 SymTab/driver_cfa_cpp-FixFunction.obj: SymTab/FixFunction.cc 2036 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-FixFunction.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo -c -o SymTab/driver_cfa_cpp-FixFunction.obj `if test -f 'SymTab/FixFunction.cc'; then $(CYGPATH_W) 'SymTab/FixFunction.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/FixFunction.cc'; fi` 2037 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po 2038 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/FixFunction.cc' object='SymTab/driver_cfa_cpp-FixFunction.obj' libtool=no @AMDEPBACKSLASH@ 2039 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2040 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-FixFunction.obj `if test -f 'SymTab/FixFunction.cc'; then $(CYGPATH_W) 'SymTab/FixFunction.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/FixFunction.cc'; fi` 2041 2042 SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc 2043 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc 2044 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po 2045 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.o' libtool=no @AMDEPBACKSLASH@ 2046 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2047 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc 2048 2049 SymTab/driver_cfa_cpp-Autogen.obj: SymTab/Autogen.cc 2050 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi` 2051 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po 2052 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.obj' libtool=no @AMDEPBACKSLASH@ 2053 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2054 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi` 2055 2056 SynTree/driver_cfa_cpp-Type.o: SynTree/Type.cc 2057 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Type.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo -c -o SynTree/driver_cfa_cpp-Type.o `test -f 'SynTree/Type.cc' || echo '$(srcdir)/'`SynTree/Type.cc 2058 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Po 2059 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Type.cc' object='SynTree/driver_cfa_cpp-Type.o' libtool=no @AMDEPBACKSLASH@ 2060 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2061 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Type.o `test -f 'SynTree/Type.cc' || echo '$(srcdir)/'`SynTree/Type.cc 2062 2063 SynTree/driver_cfa_cpp-Type.obj: SynTree/Type.cc 2064 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Type.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo -c -o SynTree/driver_cfa_cpp-Type.obj `if test -f 'SynTree/Type.cc'; then $(CYGPATH_W) 'SynTree/Type.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Type.cc'; fi` 2065 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Po 2066 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Type.cc' object='SynTree/driver_cfa_cpp-Type.obj' libtool=no @AMDEPBACKSLASH@ 2067 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2068 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Type.obj `if test -f 'SynTree/Type.cc'; then $(CYGPATH_W) 'SynTree/Type.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Type.cc'; fi` 2069 2070 SynTree/driver_cfa_cpp-VoidType.o: SynTree/VoidType.cc 2071 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VoidType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo -c -o SynTree/driver_cfa_cpp-VoidType.o `test -f 'SynTree/VoidType.cc' || echo '$(srcdir)/'`SynTree/VoidType.cc 2072 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po 2073 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/VoidType.cc' object='SynTree/driver_cfa_cpp-VoidType.o' libtool=no @AMDEPBACKSLASH@ 2074 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2075 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VoidType.o `test -f 'SynTree/VoidType.cc' || echo '$(srcdir)/'`SynTree/VoidType.cc 2076 2077 SynTree/driver_cfa_cpp-VoidType.obj: SynTree/VoidType.cc 2078 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VoidType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo -c -o SynTree/driver_cfa_cpp-VoidType.obj `if test -f 'SynTree/VoidType.cc'; then $(CYGPATH_W) 'SynTree/VoidType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VoidType.cc'; fi` 2079 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po 2080 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/VoidType.cc' object='SynTree/driver_cfa_cpp-VoidType.obj' libtool=no @AMDEPBACKSLASH@ 2081 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2082 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VoidType.obj `if test -f 'SynTree/VoidType.cc'; then $(CYGPATH_W) 'SynTree/VoidType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VoidType.cc'; fi` 2083 2084 SynTree/driver_cfa_cpp-BasicType.o: SynTree/BasicType.cc 2085 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-BasicType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo -c -o SynTree/driver_cfa_cpp-BasicType.o `test -f 'SynTree/BasicType.cc' || echo '$(srcdir)/'`SynTree/BasicType.cc 2086 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po 2087 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/BasicType.cc' object='SynTree/driver_cfa_cpp-BasicType.o' libtool=no @AMDEPBACKSLASH@ 2088 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2089 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-BasicType.o `test -f 'SynTree/BasicType.cc' || echo '$(srcdir)/'`SynTree/BasicType.cc 2090 2091 SynTree/driver_cfa_cpp-BasicType.obj: SynTree/BasicType.cc 2092 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-BasicType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo -c -o SynTree/driver_cfa_cpp-BasicType.obj `if test -f 'SynTree/BasicType.cc'; then $(CYGPATH_W) 'SynTree/BasicType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/BasicType.cc'; fi` 2093 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po 2094 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/BasicType.cc' object='SynTree/driver_cfa_cpp-BasicType.obj' libtool=no @AMDEPBACKSLASH@ 2095 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2096 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-BasicType.obj `if test -f 'SynTree/BasicType.cc'; then $(CYGPATH_W) 'SynTree/BasicType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/BasicType.cc'; fi` 2097 2098 SynTree/driver_cfa_cpp-PointerType.o: SynTree/PointerType.cc 2099 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-PointerType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo -c -o SynTree/driver_cfa_cpp-PointerType.o `test -f 'SynTree/PointerType.cc' || echo '$(srcdir)/'`SynTree/PointerType.cc 2100 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po 2101 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/PointerType.cc' object='SynTree/driver_cfa_cpp-PointerType.o' libtool=no @AMDEPBACKSLASH@ 2102 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2103 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-PointerType.o `test -f 'SynTree/PointerType.cc' || echo '$(srcdir)/'`SynTree/PointerType.cc 2104 2105 SynTree/driver_cfa_cpp-PointerType.obj: SynTree/PointerType.cc 2106 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-PointerType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo -c -o SynTree/driver_cfa_cpp-PointerType.obj `if test -f 'SynTree/PointerType.cc'; then $(CYGPATH_W) 'SynTree/PointerType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/PointerType.cc'; fi` 2107 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po 2108 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/PointerType.cc' object='SynTree/driver_cfa_cpp-PointerType.obj' libtool=no @AMDEPBACKSLASH@ 2109 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2110 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-PointerType.obj `if test -f 'SynTree/PointerType.cc'; then $(CYGPATH_W) 'SynTree/PointerType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/PointerType.cc'; fi` 2111 2112 SynTree/driver_cfa_cpp-ArrayType.o: SynTree/ArrayType.cc 2113 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ArrayType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo -c -o SynTree/driver_cfa_cpp-ArrayType.o `test -f 'SynTree/ArrayType.cc' || echo '$(srcdir)/'`SynTree/ArrayType.cc 2114 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Po 2115 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ArrayType.cc' object='SynTree/driver_cfa_cpp-ArrayType.o' libtool=no @AMDEPBACKSLASH@ 2116 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2117 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ArrayType.o `test -f 'SynTree/ArrayType.cc' || echo '$(srcdir)/'`SynTree/ArrayType.cc 2118 2119 SynTree/driver_cfa_cpp-ArrayType.obj: SynTree/ArrayType.cc 2120 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ArrayType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo -c -o SynTree/driver_cfa_cpp-ArrayType.obj `if test -f 'SynTree/ArrayType.cc'; then $(CYGPATH_W) 'SynTree/ArrayType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ArrayType.cc'; fi` 2121 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Po 2122 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ArrayType.cc' object='SynTree/driver_cfa_cpp-ArrayType.obj' libtool=no @AMDEPBACKSLASH@ 2123 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2124 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ArrayType.obj `if test -f 'SynTree/ArrayType.cc'; then $(CYGPATH_W) 'SynTree/ArrayType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ArrayType.cc'; fi` 2125 2126 SynTree/driver_cfa_cpp-ReferenceType.o: SynTree/ReferenceType.cc 2127 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc 2128 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po 2129 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.o' libtool=no @AMDEPBACKSLASH@ 2130 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2131 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc 2132 2133 SynTree/driver_cfa_cpp-ReferenceType.obj: SynTree/ReferenceType.cc 2134 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi` 2135 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po 2136 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.obj' libtool=no @AMDEPBACKSLASH@ 2137 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2138 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi` 2139 2140 SynTree/driver_cfa_cpp-FunctionType.o: SynTree/FunctionType.cc 2141 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo -c -o SynTree/driver_cfa_cpp-FunctionType.o `test -f 'SynTree/FunctionType.cc' || echo '$(srcdir)/'`SynTree/FunctionType.cc 2142 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po 2143 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/FunctionType.cc' object='SynTree/driver_cfa_cpp-FunctionType.o' libtool=no @AMDEPBACKSLASH@ 2144 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2145 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionType.o `test -f 'SynTree/FunctionType.cc' || echo '$(srcdir)/'`SynTree/FunctionType.cc 2146 2147 SynTree/driver_cfa_cpp-FunctionType.obj: SynTree/FunctionType.cc 2148 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo -c -o SynTree/driver_cfa_cpp-FunctionType.obj `if test -f 'SynTree/FunctionType.cc'; then $(CYGPATH_W) 'SynTree/FunctionType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionType.cc'; fi` 2149 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po 2150 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/FunctionType.cc' object='SynTree/driver_cfa_cpp-FunctionType.obj' libtool=no @AMDEPBACKSLASH@ 2151 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2152 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionType.obj `if test -f 'SynTree/FunctionType.cc'; then $(CYGPATH_W) 'SynTree/FunctionType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionType.cc'; fi` 2153 2154 SynTree/driver_cfa_cpp-ReferenceToType.o: SynTree/ReferenceToType.cc 2155 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceToType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceToType.o `test -f 'SynTree/ReferenceToType.cc' || echo '$(srcdir)/'`SynTree/ReferenceToType.cc 2156 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po 2157 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ReferenceToType.cc' object='SynTree/driver_cfa_cpp-ReferenceToType.o' libtool=no @AMDEPBACKSLASH@ 2158 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2159 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceToType.o `test -f 'SynTree/ReferenceToType.cc' || echo '$(srcdir)/'`SynTree/ReferenceToType.cc 2160 2161 SynTree/driver_cfa_cpp-ReferenceToType.obj: SynTree/ReferenceToType.cc 2162 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceToType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceToType.obj `if test -f 'SynTree/ReferenceToType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceToType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceToType.cc'; fi` 2163 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po 2164 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ReferenceToType.cc' object='SynTree/driver_cfa_cpp-ReferenceToType.obj' libtool=no @AMDEPBACKSLASH@ 2165 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2166 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceToType.obj `if test -f 'SynTree/ReferenceToType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceToType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceToType.cc'; fi` 2167 2168 SynTree/driver_cfa_cpp-TupleType.o: SynTree/TupleType.cc 2169 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo -c -o SynTree/driver_cfa_cpp-TupleType.o `test -f 'SynTree/TupleType.cc' || echo '$(srcdir)/'`SynTree/TupleType.cc 2170 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Po 2171 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TupleType.cc' object='SynTree/driver_cfa_cpp-TupleType.o' libtool=no @AMDEPBACKSLASH@ 2172 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2173 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleType.o `test -f 'SynTree/TupleType.cc' || echo '$(srcdir)/'`SynTree/TupleType.cc 2174 2175 SynTree/driver_cfa_cpp-TupleType.obj: SynTree/TupleType.cc 2176 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo -c -o SynTree/driver_cfa_cpp-TupleType.obj `if test -f 'SynTree/TupleType.cc'; then $(CYGPATH_W) 'SynTree/TupleType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleType.cc'; fi` 2177 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Po 2178 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TupleType.cc' object='SynTree/driver_cfa_cpp-TupleType.obj' libtool=no @AMDEPBACKSLASH@ 2179 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2180 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleType.obj `if test -f 'SynTree/TupleType.cc'; then $(CYGPATH_W) 'SynTree/TupleType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleType.cc'; fi` 2181 2182 SynTree/driver_cfa_cpp-TypeofType.o: SynTree/TypeofType.cc 2183 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeofType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo -c -o SynTree/driver_cfa_cpp-TypeofType.o `test -f 'SynTree/TypeofType.cc' || echo '$(srcdir)/'`SynTree/TypeofType.cc 2184 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po 2185 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeofType.cc' object='SynTree/driver_cfa_cpp-TypeofType.o' libtool=no @AMDEPBACKSLASH@ 2186 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2187 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeofType.o `test -f 'SynTree/TypeofType.cc' || echo '$(srcdir)/'`SynTree/TypeofType.cc 2188 2189 SynTree/driver_cfa_cpp-TypeofType.obj: SynTree/TypeofType.cc 2190 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeofType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo -c -o SynTree/driver_cfa_cpp-TypeofType.obj `if test -f 'SynTree/TypeofType.cc'; then $(CYGPATH_W) 'SynTree/TypeofType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeofType.cc'; fi` 2191 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po 2192 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeofType.cc' object='SynTree/driver_cfa_cpp-TypeofType.obj' libtool=no @AMDEPBACKSLASH@ 2193 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2194 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeofType.obj `if test -f 'SynTree/TypeofType.cc'; then $(CYGPATH_W) 'SynTree/TypeofType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeofType.cc'; fi` 2195 2196 SynTree/driver_cfa_cpp-AttrType.o: SynTree/AttrType.cc 2197 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AttrType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo -c -o SynTree/driver_cfa_cpp-AttrType.o `test -f 'SynTree/AttrType.cc' || echo '$(srcdir)/'`SynTree/AttrType.cc 2198 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po 2199 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AttrType.cc' object='SynTree/driver_cfa_cpp-AttrType.o' libtool=no @AMDEPBACKSLASH@ 2200 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2201 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AttrType.o `test -f 'SynTree/AttrType.cc' || echo '$(srcdir)/'`SynTree/AttrType.cc 2202 2203 SynTree/driver_cfa_cpp-AttrType.obj: SynTree/AttrType.cc 2204 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AttrType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo -c -o SynTree/driver_cfa_cpp-AttrType.obj `if test -f 'SynTree/AttrType.cc'; then $(CYGPATH_W) 'SynTree/AttrType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AttrType.cc'; fi` 2205 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po 2206 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AttrType.cc' object='SynTree/driver_cfa_cpp-AttrType.obj' libtool=no @AMDEPBACKSLASH@ 2207 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2208 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AttrType.obj `if test -f 'SynTree/AttrType.cc'; then $(CYGPATH_W) 'SynTree/AttrType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AttrType.cc'; fi` 2209 2210 SynTree/driver_cfa_cpp-VarArgsType.o: SynTree/VarArgsType.cc 2211 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VarArgsType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo -c -o SynTree/driver_cfa_cpp-VarArgsType.o `test -f 'SynTree/VarArgsType.cc' || echo '$(srcdir)/'`SynTree/VarArgsType.cc 2212 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po 2213 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/VarArgsType.cc' object='SynTree/driver_cfa_cpp-VarArgsType.o' libtool=no @AMDEPBACKSLASH@ 2214 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2215 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VarArgsType.o `test -f 'SynTree/VarArgsType.cc' || echo '$(srcdir)/'`SynTree/VarArgsType.cc 2216 2217 SynTree/driver_cfa_cpp-VarArgsType.obj: SynTree/VarArgsType.cc 2218 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VarArgsType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo -c -o SynTree/driver_cfa_cpp-VarArgsType.obj `if test -f 'SynTree/VarArgsType.cc'; then $(CYGPATH_W) 'SynTree/VarArgsType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VarArgsType.cc'; fi` 2219 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po 2220 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/VarArgsType.cc' object='SynTree/driver_cfa_cpp-VarArgsType.obj' libtool=no @AMDEPBACKSLASH@ 2221 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2222 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VarArgsType.obj `if test -f 'SynTree/VarArgsType.cc'; then $(CYGPATH_W) 'SynTree/VarArgsType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VarArgsType.cc'; fi` 2223 2224 SynTree/driver_cfa_cpp-ZeroOneType.o: SynTree/ZeroOneType.cc 2225 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ZeroOneType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo -c -o SynTree/driver_cfa_cpp-ZeroOneType.o `test -f 'SynTree/ZeroOneType.cc' || echo '$(srcdir)/'`SynTree/ZeroOneType.cc 2226 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po 2227 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ZeroOneType.cc' object='SynTree/driver_cfa_cpp-ZeroOneType.o' libtool=no @AMDEPBACKSLASH@ 2228 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2229 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ZeroOneType.o `test -f 'SynTree/ZeroOneType.cc' || echo '$(srcdir)/'`SynTree/ZeroOneType.cc 2230 2231 SynTree/driver_cfa_cpp-ZeroOneType.obj: SynTree/ZeroOneType.cc 2232 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ZeroOneType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo -c -o SynTree/driver_cfa_cpp-ZeroOneType.obj `if test -f 'SynTree/ZeroOneType.cc'; then $(CYGPATH_W) 'SynTree/ZeroOneType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ZeroOneType.cc'; fi` 2233 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po 2234 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ZeroOneType.cc' object='SynTree/driver_cfa_cpp-ZeroOneType.obj' libtool=no @AMDEPBACKSLASH@ 2235 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2236 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ZeroOneType.obj `if test -f 'SynTree/ZeroOneType.cc'; then $(CYGPATH_W) 'SynTree/ZeroOneType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ZeroOneType.cc'; fi` 2237 2238 SynTree/driver_cfa_cpp-Constant.o: SynTree/Constant.cc 2239 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Constant.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo -c -o SynTree/driver_cfa_cpp-Constant.o `test -f 'SynTree/Constant.cc' || echo '$(srcdir)/'`SynTree/Constant.cc 2240 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Po 2241 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Constant.cc' object='SynTree/driver_cfa_cpp-Constant.o' libtool=no @AMDEPBACKSLASH@ 2242 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2243 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Constant.o `test -f 'SynTree/Constant.cc' || echo '$(srcdir)/'`SynTree/Constant.cc 2244 2245 SynTree/driver_cfa_cpp-Constant.obj: SynTree/Constant.cc 2246 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Constant.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo -c -o SynTree/driver_cfa_cpp-Constant.obj `if test -f 'SynTree/Constant.cc'; then $(CYGPATH_W) 'SynTree/Constant.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Constant.cc'; fi` 2247 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Po 2248 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Constant.cc' object='SynTree/driver_cfa_cpp-Constant.obj' libtool=no @AMDEPBACKSLASH@ 2249 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2250 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Constant.obj `if test -f 'SynTree/Constant.cc'; then $(CYGPATH_W) 'SynTree/Constant.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Constant.cc'; fi` 2251 2252 SynTree/driver_cfa_cpp-Expression.o: SynTree/Expression.cc 2253 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Expression.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo -c -o SynTree/driver_cfa_cpp-Expression.o `test -f 'SynTree/Expression.cc' || echo '$(srcdir)/'`SynTree/Expression.cc 2254 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Po 2255 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Expression.cc' object='SynTree/driver_cfa_cpp-Expression.o' libtool=no @AMDEPBACKSLASH@ 2256 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2257 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Expression.o `test -f 'SynTree/Expression.cc' || echo '$(srcdir)/'`SynTree/Expression.cc 2258 2259 SynTree/driver_cfa_cpp-Expression.obj: SynTree/Expression.cc 2260 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Expression.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo -c -o SynTree/driver_cfa_cpp-Expression.obj `if test -f 'SynTree/Expression.cc'; then $(CYGPATH_W) 'SynTree/Expression.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Expression.cc'; fi` 2261 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Po 2262 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Expression.cc' object='SynTree/driver_cfa_cpp-Expression.obj' libtool=no @AMDEPBACKSLASH@ 2263 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2264 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Expression.obj `if test -f 'SynTree/Expression.cc'; then $(CYGPATH_W) 'SynTree/Expression.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Expression.cc'; fi` 2265 2266 SynTree/driver_cfa_cpp-TupleExpr.o: SynTree/TupleExpr.cc 2267 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo -c -o SynTree/driver_cfa_cpp-TupleExpr.o `test -f 'SynTree/TupleExpr.cc' || echo '$(srcdir)/'`SynTree/TupleExpr.cc 2268 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po 2269 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TupleExpr.cc' object='SynTree/driver_cfa_cpp-TupleExpr.o' libtool=no @AMDEPBACKSLASH@ 2270 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2271 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleExpr.o `test -f 'SynTree/TupleExpr.cc' || echo '$(srcdir)/'`SynTree/TupleExpr.cc 2272 2273 SynTree/driver_cfa_cpp-TupleExpr.obj: SynTree/TupleExpr.cc 2274 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo -c -o SynTree/driver_cfa_cpp-TupleExpr.obj `if test -f 'SynTree/TupleExpr.cc'; then $(CYGPATH_W) 'SynTree/TupleExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleExpr.cc'; fi` 2275 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po 2276 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TupleExpr.cc' object='SynTree/driver_cfa_cpp-TupleExpr.obj' libtool=no @AMDEPBACKSLASH@ 2277 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2278 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleExpr.obj `if test -f 'SynTree/TupleExpr.cc'; then $(CYGPATH_W) 'SynTree/TupleExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleExpr.cc'; fi` 2279 2280 SynTree/driver_cfa_cpp-CommaExpr.o: SynTree/CommaExpr.cc 2281 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CommaExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo -c -o SynTree/driver_cfa_cpp-CommaExpr.o `test -f 'SynTree/CommaExpr.cc' || echo '$(srcdir)/'`SynTree/CommaExpr.cc 2282 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po 2283 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/CommaExpr.cc' object='SynTree/driver_cfa_cpp-CommaExpr.o' libtool=no @AMDEPBACKSLASH@ 2284 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2285 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CommaExpr.o `test -f 'SynTree/CommaExpr.cc' || echo '$(srcdir)/'`SynTree/CommaExpr.cc 2286 2287 SynTree/driver_cfa_cpp-CommaExpr.obj: SynTree/CommaExpr.cc 2288 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CommaExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo -c -o SynTree/driver_cfa_cpp-CommaExpr.obj `if test -f 'SynTree/CommaExpr.cc'; then $(CYGPATH_W) 'SynTree/CommaExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CommaExpr.cc'; fi` 2289 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po 2290 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/CommaExpr.cc' object='SynTree/driver_cfa_cpp-CommaExpr.obj' libtool=no @AMDEPBACKSLASH@ 2291 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2292 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CommaExpr.obj `if test -f 'SynTree/CommaExpr.cc'; then $(CYGPATH_W) 'SynTree/CommaExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CommaExpr.cc'; fi` 2293 2294 SynTree/driver_cfa_cpp-TypeExpr.o: SynTree/TypeExpr.cc 2295 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo -c -o SynTree/driver_cfa_cpp-TypeExpr.o `test -f 'SynTree/TypeExpr.cc' || echo '$(srcdir)/'`SynTree/TypeExpr.cc 2296 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Po 2297 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeExpr.cc' object='SynTree/driver_cfa_cpp-TypeExpr.o' libtool=no @AMDEPBACKSLASH@ 2298 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2299 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeExpr.o `test -f 'SynTree/TypeExpr.cc' || echo '$(srcdir)/'`SynTree/TypeExpr.cc 2300 2301 SynTree/driver_cfa_cpp-TypeExpr.obj: SynTree/TypeExpr.cc 2302 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo -c -o SynTree/driver_cfa_cpp-TypeExpr.obj `if test -f 'SynTree/TypeExpr.cc'; then $(CYGPATH_W) 'SynTree/TypeExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeExpr.cc'; fi` 2303 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Po 2304 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeExpr.cc' object='SynTree/driver_cfa_cpp-TypeExpr.obj' libtool=no @AMDEPBACKSLASH@ 2305 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2306 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeExpr.obj `if test -f 'SynTree/TypeExpr.cc'; then $(CYGPATH_W) 'SynTree/TypeExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeExpr.cc'; fi` 2307 2308 SynTree/driver_cfa_cpp-ApplicationExpr.o: SynTree/ApplicationExpr.cc 2309 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ApplicationExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo -c -o SynTree/driver_cfa_cpp-ApplicationExpr.o `test -f 'SynTree/ApplicationExpr.cc' || echo '$(srcdir)/'`SynTree/ApplicationExpr.cc 2310 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Po 2311 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ApplicationExpr.cc' object='SynTree/driver_cfa_cpp-ApplicationExpr.o' libtool=no @AMDEPBACKSLASH@ 2312 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2313 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ApplicationExpr.o `test -f 'SynTree/ApplicationExpr.cc' || echo '$(srcdir)/'`SynTree/ApplicationExpr.cc 2314 2315 SynTree/driver_cfa_cpp-ApplicationExpr.obj: SynTree/ApplicationExpr.cc 2316 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ApplicationExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo -c -o SynTree/driver_cfa_cpp-ApplicationExpr.obj `if test -f 'SynTree/ApplicationExpr.cc'; then $(CYGPATH_W) 'SynTree/ApplicationExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ApplicationExpr.cc'; fi` 2317 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Po 2318 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ApplicationExpr.cc' object='SynTree/driver_cfa_cpp-ApplicationExpr.obj' libtool=no @AMDEPBACKSLASH@ 2319 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2320 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ApplicationExpr.obj `if test -f 'SynTree/ApplicationExpr.cc'; then $(CYGPATH_W) 'SynTree/ApplicationExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ApplicationExpr.cc'; fi` 2321 2322 SynTree/driver_cfa_cpp-AddressExpr.o: SynTree/AddressExpr.cc 2323 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddressExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo -c -o SynTree/driver_cfa_cpp-AddressExpr.o `test -f 'SynTree/AddressExpr.cc' || echo '$(srcdir)/'`SynTree/AddressExpr.cc 2324 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po 2325 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AddressExpr.cc' object='SynTree/driver_cfa_cpp-AddressExpr.o' libtool=no @AMDEPBACKSLASH@ 2326 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2327 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddressExpr.o `test -f 'SynTree/AddressExpr.cc' || echo '$(srcdir)/'`SynTree/AddressExpr.cc 2328 2329 SynTree/driver_cfa_cpp-AddressExpr.obj: SynTree/AddressExpr.cc 2330 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddressExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo -c -o SynTree/driver_cfa_cpp-AddressExpr.obj `if test -f 'SynTree/AddressExpr.cc'; then $(CYGPATH_W) 'SynTree/AddressExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddressExpr.cc'; fi` 2331 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po 2332 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AddressExpr.cc' object='SynTree/driver_cfa_cpp-AddressExpr.obj' libtool=no @AMDEPBACKSLASH@ 2333 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2334 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddressExpr.obj `if test -f 'SynTree/AddressExpr.cc'; then $(CYGPATH_W) 'SynTree/AddressExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddressExpr.cc'; fi` 2335 2336 SynTree/driver_cfa_cpp-Statement.o: SynTree/Statement.cc 2337 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Statement.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo -c -o SynTree/driver_cfa_cpp-Statement.o `test -f 'SynTree/Statement.cc' || echo '$(srcdir)/'`SynTree/Statement.cc 2338 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po 2339 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Statement.cc' object='SynTree/driver_cfa_cpp-Statement.o' libtool=no @AMDEPBACKSLASH@ 2340 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2341 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Statement.o `test -f 'SynTree/Statement.cc' || echo '$(srcdir)/'`SynTree/Statement.cc 2342 2343 SynTree/driver_cfa_cpp-Statement.obj: SynTree/Statement.cc 2344 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Statement.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo -c -o SynTree/driver_cfa_cpp-Statement.obj `if test -f 'SynTree/Statement.cc'; then $(CYGPATH_W) 'SynTree/Statement.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Statement.cc'; fi` 2345 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po 2346 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Statement.cc' object='SynTree/driver_cfa_cpp-Statement.obj' libtool=no @AMDEPBACKSLASH@ 2347 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2348 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Statement.obj `if test -f 'SynTree/Statement.cc'; then $(CYGPATH_W) 'SynTree/Statement.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Statement.cc'; fi` 2349 2350 SynTree/driver_cfa_cpp-CompoundStmt.o: SynTree/CompoundStmt.cc 2351 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CompoundStmt.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo -c -o SynTree/driver_cfa_cpp-CompoundStmt.o `test -f 'SynTree/CompoundStmt.cc' || echo '$(srcdir)/'`SynTree/CompoundStmt.cc 2352 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Po 2353 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/CompoundStmt.cc' object='SynTree/driver_cfa_cpp-CompoundStmt.o' libtool=no @AMDEPBACKSLASH@ 2354 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2355 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CompoundStmt.o `test -f 'SynTree/CompoundStmt.cc' || echo '$(srcdir)/'`SynTree/CompoundStmt.cc 2356 2357 SynTree/driver_cfa_cpp-CompoundStmt.obj: SynTree/CompoundStmt.cc 2358 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CompoundStmt.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo -c -o SynTree/driver_cfa_cpp-CompoundStmt.obj `if test -f 'SynTree/CompoundStmt.cc'; then $(CYGPATH_W) 'SynTree/CompoundStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CompoundStmt.cc'; fi` 2359 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Po 2360 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/CompoundStmt.cc' object='SynTree/driver_cfa_cpp-CompoundStmt.obj' libtool=no @AMDEPBACKSLASH@ 2361 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2362 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CompoundStmt.obj `if test -f 'SynTree/CompoundStmt.cc'; then $(CYGPATH_W) 'SynTree/CompoundStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CompoundStmt.cc'; fi` 2363 2364 SynTree/driver_cfa_cpp-DeclStmt.o: SynTree/DeclStmt.cc 2365 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclStmt.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo -c -o SynTree/driver_cfa_cpp-DeclStmt.o `test -f 'SynTree/DeclStmt.cc' || echo '$(srcdir)/'`SynTree/DeclStmt.cc 2366 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Po 2367 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/DeclStmt.cc' object='SynTree/driver_cfa_cpp-DeclStmt.o' libtool=no @AMDEPBACKSLASH@ 2368 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2369 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclStmt.o `test -f 'SynTree/DeclStmt.cc' || echo '$(srcdir)/'`SynTree/DeclStmt.cc 2370 2371 SynTree/driver_cfa_cpp-DeclStmt.obj: SynTree/DeclStmt.cc 2372 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclStmt.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo -c -o SynTree/driver_cfa_cpp-DeclStmt.obj `if test -f 'SynTree/DeclStmt.cc'; then $(CYGPATH_W) 'SynTree/DeclStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclStmt.cc'; fi` 2373 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Po 2374 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/DeclStmt.cc' object='SynTree/driver_cfa_cpp-DeclStmt.obj' libtool=no @AMDEPBACKSLASH@ 2375 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2376 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclStmt.obj `if test -f 'SynTree/DeclStmt.cc'; then $(CYGPATH_W) 'SynTree/DeclStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclStmt.cc'; fi` 2377 2378 SynTree/driver_cfa_cpp-Declaration.o: SynTree/Declaration.cc 2379 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Declaration.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo -c -o SynTree/driver_cfa_cpp-Declaration.o `test -f 'SynTree/Declaration.cc' || echo '$(srcdir)/'`SynTree/Declaration.cc 2380 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Po 2381 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Declaration.cc' object='SynTree/driver_cfa_cpp-Declaration.o' libtool=no @AMDEPBACKSLASH@ 2382 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2383 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Declaration.o `test -f 'SynTree/Declaration.cc' || echo '$(srcdir)/'`SynTree/Declaration.cc 2384 2385 SynTree/driver_cfa_cpp-Declaration.obj: SynTree/Declaration.cc 2386 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Declaration.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo -c -o SynTree/driver_cfa_cpp-Declaration.obj `if test -f 'SynTree/Declaration.cc'; then $(CYGPATH_W) 'SynTree/Declaration.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Declaration.cc'; fi` 2387 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Po 2388 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Declaration.cc' object='SynTree/driver_cfa_cpp-Declaration.obj' libtool=no @AMDEPBACKSLASH@ 2389 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2390 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Declaration.obj `if test -f 'SynTree/Declaration.cc'; then $(CYGPATH_W) 'SynTree/Declaration.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Declaration.cc'; fi` 2391 2392 SynTree/driver_cfa_cpp-DeclarationWithType.o: SynTree/DeclarationWithType.cc 2393 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclarationWithType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo -c -o SynTree/driver_cfa_cpp-DeclarationWithType.o `test -f 'SynTree/DeclarationWithType.cc' || echo '$(srcdir)/'`SynTree/DeclarationWithType.cc 2394 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Po 2395 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/DeclarationWithType.cc' object='SynTree/driver_cfa_cpp-DeclarationWithType.o' libtool=no @AMDEPBACKSLASH@ 2396 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2397 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclarationWithType.o `test -f 'SynTree/DeclarationWithType.cc' || echo '$(srcdir)/'`SynTree/DeclarationWithType.cc 2398 2399 SynTree/driver_cfa_cpp-DeclarationWithType.obj: SynTree/DeclarationWithType.cc 2400 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclarationWithType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo -c -o SynTree/driver_cfa_cpp-DeclarationWithType.obj `if test -f 'SynTree/DeclarationWithType.cc'; then $(CYGPATH_W) 'SynTree/DeclarationWithType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclarationWithType.cc'; fi` 2401 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Po 2402 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/DeclarationWithType.cc' object='SynTree/driver_cfa_cpp-DeclarationWithType.obj' libtool=no @AMDEPBACKSLASH@ 2403 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2404 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclarationWithType.obj `if test -f 'SynTree/DeclarationWithType.cc'; then $(CYGPATH_W) 'SynTree/DeclarationWithType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclarationWithType.cc'; fi` 2405 2406 SynTree/driver_cfa_cpp-ObjectDecl.o: SynTree/ObjectDecl.cc 2407 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ObjectDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo -c -o SynTree/driver_cfa_cpp-ObjectDecl.o `test -f 'SynTree/ObjectDecl.cc' || echo '$(srcdir)/'`SynTree/ObjectDecl.cc 2408 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po 2409 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ObjectDecl.cc' object='SynTree/driver_cfa_cpp-ObjectDecl.o' libtool=no @AMDEPBACKSLASH@ 2410 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2411 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ObjectDecl.o `test -f 'SynTree/ObjectDecl.cc' || echo '$(srcdir)/'`SynTree/ObjectDecl.cc 2412 2413 SynTree/driver_cfa_cpp-ObjectDecl.obj: SynTree/ObjectDecl.cc 2414 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ObjectDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo -c -o SynTree/driver_cfa_cpp-ObjectDecl.obj `if test -f 'SynTree/ObjectDecl.cc'; then $(CYGPATH_W) 'SynTree/ObjectDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ObjectDecl.cc'; fi` 2415 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po 2416 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/ObjectDecl.cc' object='SynTree/driver_cfa_cpp-ObjectDecl.obj' libtool=no @AMDEPBACKSLASH@ 2417 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2418 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ObjectDecl.obj `if test -f 'SynTree/ObjectDecl.cc'; then $(CYGPATH_W) 'SynTree/ObjectDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ObjectDecl.cc'; fi` 2419 2420 SynTree/driver_cfa_cpp-FunctionDecl.o: SynTree/FunctionDecl.cc 2421 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo -c -o SynTree/driver_cfa_cpp-FunctionDecl.o `test -f 'SynTree/FunctionDecl.cc' || echo '$(srcdir)/'`SynTree/FunctionDecl.cc 2422 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Po 2423 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/FunctionDecl.cc' object='SynTree/driver_cfa_cpp-FunctionDecl.o' libtool=no @AMDEPBACKSLASH@ 2424 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2425 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionDecl.o `test -f 'SynTree/FunctionDecl.cc' || echo '$(srcdir)/'`SynTree/FunctionDecl.cc 2426 2427 SynTree/driver_cfa_cpp-FunctionDecl.obj: SynTree/FunctionDecl.cc 2428 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo -c -o SynTree/driver_cfa_cpp-FunctionDecl.obj `if test -f 'SynTree/FunctionDecl.cc'; then $(CYGPATH_W) 'SynTree/FunctionDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionDecl.cc'; fi` 2429 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Po 2430 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/FunctionDecl.cc' object='SynTree/driver_cfa_cpp-FunctionDecl.obj' libtool=no @AMDEPBACKSLASH@ 2431 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2432 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionDecl.obj `if test -f 'SynTree/FunctionDecl.cc'; then $(CYGPATH_W) 'SynTree/FunctionDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionDecl.cc'; fi` 2433 2434 SynTree/driver_cfa_cpp-AggregateDecl.o: SynTree/AggregateDecl.cc 2435 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AggregateDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo -c -o SynTree/driver_cfa_cpp-AggregateDecl.o `test -f 'SynTree/AggregateDecl.cc' || echo '$(srcdir)/'`SynTree/AggregateDecl.cc 2436 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po 2437 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AggregateDecl.cc' object='SynTree/driver_cfa_cpp-AggregateDecl.o' libtool=no @AMDEPBACKSLASH@ 2438 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2439 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AggregateDecl.o `test -f 'SynTree/AggregateDecl.cc' || echo '$(srcdir)/'`SynTree/AggregateDecl.cc 2440 2441 SynTree/driver_cfa_cpp-AggregateDecl.obj: SynTree/AggregateDecl.cc 2442 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AggregateDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo -c -o SynTree/driver_cfa_cpp-AggregateDecl.obj `if test -f 'SynTree/AggregateDecl.cc'; then $(CYGPATH_W) 'SynTree/AggregateDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AggregateDecl.cc'; fi` 2443 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po 2444 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AggregateDecl.cc' object='SynTree/driver_cfa_cpp-AggregateDecl.obj' libtool=no @AMDEPBACKSLASH@ 2445 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2446 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AggregateDecl.obj `if test -f 'SynTree/AggregateDecl.cc'; then $(CYGPATH_W) 'SynTree/AggregateDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AggregateDecl.cc'; fi` 2447 2448 SynTree/driver_cfa_cpp-NamedTypeDecl.o: SynTree/NamedTypeDecl.cc 2449 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-NamedTypeDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.o `test -f 'SynTree/NamedTypeDecl.cc' || echo '$(srcdir)/'`SynTree/NamedTypeDecl.cc 2450 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po 2451 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/NamedTypeDecl.cc' object='SynTree/driver_cfa_cpp-NamedTypeDecl.o' libtool=no @AMDEPBACKSLASH@ 2452 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2453 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.o `test -f 'SynTree/NamedTypeDecl.cc' || echo '$(srcdir)/'`SynTree/NamedTypeDecl.cc 2454 2455 SynTree/driver_cfa_cpp-NamedTypeDecl.obj: SynTree/NamedTypeDecl.cc 2456 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-NamedTypeDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.obj `if test -f 'SynTree/NamedTypeDecl.cc'; then $(CYGPATH_W) 'SynTree/NamedTypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/NamedTypeDecl.cc'; fi` 2457 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po 2458 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/NamedTypeDecl.cc' object='SynTree/driver_cfa_cpp-NamedTypeDecl.obj' libtool=no @AMDEPBACKSLASH@ 2459 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2460 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.obj `if test -f 'SynTree/NamedTypeDecl.cc'; then $(CYGPATH_W) 'SynTree/NamedTypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/NamedTypeDecl.cc'; fi` 2461 2462 SynTree/driver_cfa_cpp-TypeDecl.o: SynTree/TypeDecl.cc 2463 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-TypeDecl.o `test -f 'SynTree/TypeDecl.cc' || echo '$(srcdir)/'`SynTree/TypeDecl.cc 2464 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Po 2465 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeDecl.cc' object='SynTree/driver_cfa_cpp-TypeDecl.o' libtool=no @AMDEPBACKSLASH@ 2466 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2467 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeDecl.o `test -f 'SynTree/TypeDecl.cc' || echo '$(srcdir)/'`SynTree/TypeDecl.cc 2468 2469 SynTree/driver_cfa_cpp-TypeDecl.obj: SynTree/TypeDecl.cc 2470 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-TypeDecl.obj `if test -f 'SynTree/TypeDecl.cc'; then $(CYGPATH_W) 'SynTree/TypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeDecl.cc'; fi` 2471 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Po 2472 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeDecl.cc' object='SynTree/driver_cfa_cpp-TypeDecl.obj' libtool=no @AMDEPBACKSLASH@ 2473 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2474 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeDecl.obj `if test -f 'SynTree/TypeDecl.cc'; then $(CYGPATH_W) 'SynTree/TypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeDecl.cc'; fi` 2475 2476 SynTree/driver_cfa_cpp-Initializer.o: SynTree/Initializer.cc 2477 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Initializer.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo -c -o SynTree/driver_cfa_cpp-Initializer.o `test -f 'SynTree/Initializer.cc' || echo '$(srcdir)/'`SynTree/Initializer.cc 2478 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po 2479 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Initializer.cc' object='SynTree/driver_cfa_cpp-Initializer.o' libtool=no @AMDEPBACKSLASH@ 2480 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2481 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Initializer.o `test -f 'SynTree/Initializer.cc' || echo '$(srcdir)/'`SynTree/Initializer.cc 2482 2483 SynTree/driver_cfa_cpp-Initializer.obj: SynTree/Initializer.cc 2484 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Initializer.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo -c -o SynTree/driver_cfa_cpp-Initializer.obj `if test -f 'SynTree/Initializer.cc'; then $(CYGPATH_W) 'SynTree/Initializer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Initializer.cc'; fi` 2485 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po 2486 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Initializer.cc' object='SynTree/driver_cfa_cpp-Initializer.obj' libtool=no @AMDEPBACKSLASH@ 2487 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2488 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Initializer.obj `if test -f 'SynTree/Initializer.cc'; then $(CYGPATH_W) 'SynTree/Initializer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Initializer.cc'; fi` 2489 2490 SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc 2491 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeSubstitution.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo -c -o SynTree/driver_cfa_cpp-TypeSubstitution.o `test -f 'SynTree/TypeSubstitution.cc' || echo '$(srcdir)/'`SynTree/TypeSubstitution.cc 2492 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Po 2493 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeSubstitution.cc' object='SynTree/driver_cfa_cpp-TypeSubstitution.o' libtool=no @AMDEPBACKSLASH@ 2494 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2495 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeSubstitution.o `test -f 'SynTree/TypeSubstitution.cc' || echo '$(srcdir)/'`SynTree/TypeSubstitution.cc 2496 2497 SynTree/driver_cfa_cpp-TypeSubstitution.obj: SynTree/TypeSubstitution.cc 2498 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeSubstitution.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo -c -o SynTree/driver_cfa_cpp-TypeSubstitution.obj `if test -f 'SynTree/TypeSubstitution.cc'; then $(CYGPATH_W) 'SynTree/TypeSubstitution.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeSubstitution.cc'; fi` 2499 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Po 2500 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/TypeSubstitution.cc' object='SynTree/driver_cfa_cpp-TypeSubstitution.obj' libtool=no @AMDEPBACKSLASH@ 2501 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2502 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeSubstitution.obj `if test -f 'SynTree/TypeSubstitution.cc'; then $(CYGPATH_W) 'SynTree/TypeSubstitution.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeSubstitution.cc'; fi` 2503 2504 SynTree/driver_cfa_cpp-Attribute.o: SynTree/Attribute.cc 2505 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Attribute.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo -c -o SynTree/driver_cfa_cpp-Attribute.o `test -f 'SynTree/Attribute.cc' || echo '$(srcdir)/'`SynTree/Attribute.cc 2506 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po 2507 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Attribute.cc' object='SynTree/driver_cfa_cpp-Attribute.o' libtool=no @AMDEPBACKSLASH@ 2508 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2509 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.o `test -f 'SynTree/Attribute.cc' || echo '$(srcdir)/'`SynTree/Attribute.cc 2510 2511 SynTree/driver_cfa_cpp-Attribute.obj: SynTree/Attribute.cc 2512 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Attribute.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi` 2513 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po 2514 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/Attribute.cc' object='SynTree/driver_cfa_cpp-Attribute.obj' libtool=no @AMDEPBACKSLASH@ 2515 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2516 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi` 2517 2518 SynTree/driver_cfa_cpp-DeclReplacer.o: SynTree/DeclReplacer.cc 2519 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclReplacer.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo -c -o SynTree/driver_cfa_cpp-DeclReplacer.o `test -f 'SynTree/DeclReplacer.cc' || echo '$(srcdir)/'`SynTree/DeclReplacer.cc 2520 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Po 2521 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/DeclReplacer.cc' object='SynTree/driver_cfa_cpp-DeclReplacer.o' libtool=no @AMDEPBACKSLASH@ 2522 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2523 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclReplacer.o `test -f 'SynTree/DeclReplacer.cc' || echo '$(srcdir)/'`SynTree/DeclReplacer.cc 2524 2525 SynTree/driver_cfa_cpp-DeclReplacer.obj: SynTree/DeclReplacer.cc 2526 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclReplacer.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo -c -o SynTree/driver_cfa_cpp-DeclReplacer.obj `if test -f 'SynTree/DeclReplacer.cc'; then $(CYGPATH_W) 'SynTree/DeclReplacer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclReplacer.cc'; fi` 2527 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Po 2528 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/DeclReplacer.cc' object='SynTree/driver_cfa_cpp-DeclReplacer.obj' libtool=no @AMDEPBACKSLASH@ 2529 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2530 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclReplacer.obj `if test -f 'SynTree/DeclReplacer.cc'; then $(CYGPATH_W) 'SynTree/DeclReplacer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclReplacer.cc'; fi` 2531 2532 Tuples/driver_cfa_cpp-TupleAssignment.o: Tuples/TupleAssignment.cc 2533 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleAssignment.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo -c -o Tuples/driver_cfa_cpp-TupleAssignment.o `test -f 'Tuples/TupleAssignment.cc' || echo '$(srcdir)/'`Tuples/TupleAssignment.cc 2534 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po 2535 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Tuples/TupleAssignment.cc' object='Tuples/driver_cfa_cpp-TupleAssignment.o' libtool=no @AMDEPBACKSLASH@ 2536 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2537 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleAssignment.o `test -f 'Tuples/TupleAssignment.cc' || echo '$(srcdir)/'`Tuples/TupleAssignment.cc 2538 2539 Tuples/driver_cfa_cpp-TupleAssignment.obj: Tuples/TupleAssignment.cc 2540 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleAssignment.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo -c -o Tuples/driver_cfa_cpp-TupleAssignment.obj `if test -f 'Tuples/TupleAssignment.cc'; then $(CYGPATH_W) 'Tuples/TupleAssignment.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleAssignment.cc'; fi` 2541 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po 2542 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Tuples/TupleAssignment.cc' object='Tuples/driver_cfa_cpp-TupleAssignment.obj' libtool=no @AMDEPBACKSLASH@ 2543 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2544 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleAssignment.obj `if test -f 'Tuples/TupleAssignment.cc'; then $(CYGPATH_W) 'Tuples/TupleAssignment.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleAssignment.cc'; fi` 2545 2546 Tuples/driver_cfa_cpp-TupleExpansion.o: Tuples/TupleExpansion.cc 2547 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc 2548 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po 2549 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.o' libtool=no @AMDEPBACKSLASH@ 2550 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2551 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc 2552 2553 Tuples/driver_cfa_cpp-TupleExpansion.obj: Tuples/TupleExpansion.cc 2554 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi` 2555 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po 2556 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.obj' libtool=no @AMDEPBACKSLASH@ 2557 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2558 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi` 2559 2560 Tuples/driver_cfa_cpp-Explode.o: Tuples/Explode.cc 2561 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-Explode.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo -c -o Tuples/driver_cfa_cpp-Explode.o `test -f 'Tuples/Explode.cc' || echo '$(srcdir)/'`Tuples/Explode.cc 2562 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po 2563 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Tuples/Explode.cc' object='Tuples/driver_cfa_cpp-Explode.o' libtool=no @AMDEPBACKSLASH@ 2564 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2565 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-Explode.o `test -f 'Tuples/Explode.cc' || echo '$(srcdir)/'`Tuples/Explode.cc 2566 2567 Tuples/driver_cfa_cpp-Explode.obj: Tuples/Explode.cc 2568 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-Explode.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo -c -o Tuples/driver_cfa_cpp-Explode.obj `if test -f 'Tuples/Explode.cc'; then $(CYGPATH_W) 'Tuples/Explode.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/Explode.cc'; fi` 2569 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po 2570 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Tuples/Explode.cc' object='Tuples/driver_cfa_cpp-Explode.obj' libtool=no @AMDEPBACKSLASH@ 2571 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2572 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-Explode.obj `if test -f 'Tuples/Explode.cc'; then $(CYGPATH_W) 'Tuples/Explode.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/Explode.cc'; fi` 2573 2574 Virtual/driver_cfa_cpp-ExpandCasts.o: Virtual/ExpandCasts.cc 2575 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Virtual/driver_cfa_cpp-ExpandCasts.o -MD -MP -MF Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo -c -o Virtual/driver_cfa_cpp-ExpandCasts.o `test -f 'Virtual/ExpandCasts.cc' || echo '$(srcdir)/'`Virtual/ExpandCasts.cc 2576 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po 2577 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Virtual/ExpandCasts.cc' object='Virtual/driver_cfa_cpp-ExpandCasts.o' libtool=no @AMDEPBACKSLASH@ 2578 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2579 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Virtual/driver_cfa_cpp-ExpandCasts.o `test -f 'Virtual/ExpandCasts.cc' || echo '$(srcdir)/'`Virtual/ExpandCasts.cc 2580 2581 Virtual/driver_cfa_cpp-ExpandCasts.obj: Virtual/ExpandCasts.cc 2582 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Virtual/driver_cfa_cpp-ExpandCasts.obj -MD -MP -MF Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo -c -o Virtual/driver_cfa_cpp-ExpandCasts.obj `if test -f 'Virtual/ExpandCasts.cc'; then $(CYGPATH_W) 'Virtual/ExpandCasts.cc'; else $(CYGPATH_W) '$(srcdir)/Virtual/ExpandCasts.cc'; fi` 2583 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po 2584 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Virtual/ExpandCasts.cc' object='Virtual/driver_cfa_cpp-ExpandCasts.obj' libtool=no @AMDEPBACKSLASH@ 2585 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2586 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Virtual/driver_cfa_cpp-ExpandCasts.obj `if test -f 'Virtual/ExpandCasts.cc'; then $(CYGPATH_W) 'Virtual/ExpandCasts.cc'; else $(CYGPATH_W) '$(srcdir)/Virtual/ExpandCasts.cc'; fi` 1401 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< 2587 1402 2588 1403 .ll.cc: … … 2591 1406 .yy.cc: 2592 1407 $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) 1408 1409 mostlyclean-libtool: 1410 -rm -f *.lo 1411 1412 clean-libtool: 1413 -rm -rf .libs _libs 1414 -rm -rf ../driver/.libs ../driver/_libs 2593 1415 2594 1416 ID: $(am__tagged_files) … … 2677 1499 check: $(BUILT_SOURCES) 2678 1500 $(MAKE) $(AM_MAKEFLAGS) check-am 2679 all-am: Makefile $( PROGRAMS)1501 all-am: Makefile $(LIBRARIES) $(PROGRAMS) 2680 1502 installdirs: 2681 1503 for dir in "$(DESTDIR)$(cfa_cpplibdir)"; do \ … … 2703 1525 fi 2704 1526 mostlyclean-generic: 1527 -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) 2705 1528 2706 1529 clean-generic: … … 2709 1532 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 2710 1533 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) 1534 -rm -f ../driver/$(am__dirstamp) 1535 -rm -f AST/$(DEPDIR)/$(am__dirstamp) 1536 -rm -f AST/$(am__dirstamp) 2711 1537 -rm -f CodeGen/$(DEPDIR)/$(am__dirstamp) 2712 1538 -rm -f CodeGen/$(am__dirstamp) … … 2715 1541 -rm -f Common/$(DEPDIR)/$(am__dirstamp) 2716 1542 -rm -f Common/$(am__dirstamp) 1543 -rm -f Common/Stats/$(DEPDIR)/$(am__dirstamp) 1544 -rm -f Common/Stats/$(am__dirstamp) 2717 1545 -rm -f Concurrency/$(DEPDIR)/$(am__dirstamp) 2718 1546 -rm -f Concurrency/$(am__dirstamp) … … 2733 1561 -rm -f Tuples/$(DEPDIR)/$(am__dirstamp) 2734 1562 -rm -f Tuples/$(am__dirstamp) 1563 -rm -f Validate/$(DEPDIR)/$(am__dirstamp) 1564 -rm -f Validate/$(am__dirstamp) 2735 1565 -rm -f Virtual/$(DEPDIR)/$(am__dirstamp) 2736 1566 -rm -f Virtual/$(am__dirstamp) 2737 -rm -f driver/$(am__dirstamp)2738 1567 2739 1568 maintainer-clean-generic: … … 2747 1576 clean: clean-am 2748 1577 2749 clean-am: clean-cfa_cpplibPROGRAMS clean-generic mostlyclean-am 1578 clean-am: clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \ 1579 clean-noinstLIBRARIES mostlyclean-am 2750 1580 2751 1581 distclean: distclean-am 2752 -rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Virtual/$(DEPDIR)1582 -rm -rf ./$(DEPDIR) AST/$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Common/Stats/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Validate/$(DEPDIR) Virtual/$(DEPDIR) 2753 1583 -rm -f Makefile 2754 1584 distclean-am: clean-am distclean-compile distclean-generic \ … … 2796 1626 2797 1627 maintainer-clean: maintainer-clean-am 2798 -rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Virtual/$(DEPDIR)1628 -rm -rf ./$(DEPDIR) AST/$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Common/Stats/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Validate/$(DEPDIR) Virtual/$(DEPDIR) 2799 1629 -rm -f Makefile 2800 1630 maintainer-clean-am: distclean-am maintainer-clean-generic … … 2802 1632 mostlyclean: mostlyclean-am 2803 1633 2804 mostlyclean-am: mostlyclean-compile mostlyclean-generic 1634 mostlyclean-am: mostlyclean-compile mostlyclean-generic \ 1635 mostlyclean-libtool 2805 1636 2806 1637 pdf: pdf-am … … 2817 1648 2818 1649 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ 2819 clean-cfa_cpplibPROGRAMS clean-generic cscopelist-am ctags \ 2820 ctags-am distclean distclean-compile distclean-generic \ 1650 clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \ 1651 clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ 1652 distclean-compile distclean-generic distclean-libtool \ 2821 1653 distclean-tags distdir dvi dvi-am html html-am info info-am \ 2822 1654 install install-am install-cfa_cpplibPROGRAMS install-data \ … … 2827 1659 installcheck-am installdirs maintainer-clean \ 2828 1660 maintainer-clean-generic mostlyclean mostlyclean-compile \ 2829 mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ 2830 uninstall-am uninstall-cfa_cpplibPROGRAMS 1661 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ 1662 tags tags-am uninstall uninstall-am \ 1663 uninstall-cfa_cpplibPROGRAMS 2831 1664 2832 1665 .PRECIOUS: Makefile 2833 1666 1667 1668 $(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h 1669 1670 $(srcdir)/AST/Type.hpp : BasicTypes-gen.cc 1671 ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra 1672 @./BasicTypes-gen 1673 @rm BasicTypes-gen 2834 1674 2835 1675 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
src/Parser/DeclarationNode.cc
r7951100 rb067d9b 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Ju n 7 12:08:55 201813 // Update Count : 1 07912 // Last Modified On : Thu Jul 25 22:17:10 2019 13 // Update Count : 1116 14 14 // 15 15 … … 41 41 42 42 // These must harmonize with the corresponding DeclarationNode enumerations. 43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "int128", "float80", "float128", "NoBasicTypeNames" }; 44 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "_Imaginary", "NoComplexTypeNames" }; 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 45 47 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" }; 46 48 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" }; 47 49 const char * DeclarationNode::aggregateNames[] = { "struct", "union", "trait", "coroutine", "monitor", "thread", "NoAggregateNames" }; 48 50 const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" }; 49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", " zero_t", "one_t", "NoBuiltinTypeNames" };51 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" }; 50 52 51 53 UniqueName DeclarationNode::anonymous( "__anonymous" ); … … 54 56 55 57 DeclarationNode::DeclarationNode() : 56 builtin( NoBuiltinType ), 57 type( nullptr ), 58 bitfieldWidth( nullptr ), 59 hasEllipsis( false ), 60 linkage( ::linkage ), 61 asmName( nullptr ), 62 initializer( nullptr ), 63 extension( false ), 64 asmStmt( nullptr ) { 58 linkage( ::linkage ) { 65 59 66 60 // variable.name = nullptr; … … 104 98 newnode->builtin = NoBuiltinType; 105 99 newnode->type = maybeClone( type ); 100 newnode->inLine = inLine; 106 101 newnode->storageClasses = storageClasses; 107 102 newnode->funcSpecs = funcSpecs; … … 131 126 } // DeclarationNode::clone 132 127 133 void DeclarationNode::print( std::ostream & os, int indent ) const {128 void DeclarationNode::print( std::ostream & os, int indent ) const { 134 129 os << string( indent, ' ' ); 135 130 if ( name ) { … … 167 162 } 168 163 169 void DeclarationNode::printList( std::ostream & os, int indent ) const {164 void DeclarationNode::printList( std::ostream & os, int indent ) const { 170 165 ParseNode::printList( os, indent ); 171 166 if ( hasEllipsis ) { … … 254 249 } // DeclarationNode::newFromTypedef 255 250 251 DeclarationNode * DeclarationNode::newFromGlobalScope() { 252 DeclarationNode * newnode = new DeclarationNode; 253 newnode->type = new TypeData( TypeData::GlobalScope ); 254 return newnode; 255 } 256 257 DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) { 258 DeclarationNode * newnode = new DeclarationNode; 259 newnode->type = new TypeData( TypeData::Qualified ); 260 newnode->type->qualified.parent = parent->type; 261 newnode->type->qualified.child = child->type; 262 parent->type = nullptr; 263 child->type = nullptr; 264 delete parent; 265 delete child; 266 return newnode; 267 } 268 256 269 DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 257 assert( name );258 270 DeclarationNode * newnode = new DeclarationNode; 259 271 newnode->type = new TypeData( TypeData::Aggregate ); 260 272 newnode->type->aggregate.kind = kind; 261 newnode->type->aggregate.name = name;273 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 262 274 newnode->type->aggregate.actuals = actuals; 263 275 newnode->type->aggregate.fields = fields; … … 265 277 newnode->type->aggregate.tagged = false; 266 278 newnode->type->aggregate.parent = nullptr; 279 newnode->type->aggregate.anon = name == nullptr; 267 280 return newnode; 268 281 } // DeclarationNode::newAggregate 269 282 270 283 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) { 271 assert( name );272 284 DeclarationNode * newnode = new DeclarationNode; 273 285 newnode->type = new TypeData( TypeData::Enum ); 274 newnode->type->enumeration.name = name ;286 newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 275 287 newnode->type->enumeration.constants = constants; 276 288 newnode->type->enumeration.body = body; 289 newnode->type->enumeration.anon = name == nullptr; 277 290 return newnode; 278 291 } // DeclarationNode::newEnum … … 391 404 } 392 405 393 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr ) {394 DeclarationNode * newnode = new DeclarationNode; 395 newnode->type = new TypeData( TypeData::Typeof );406 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) { 407 DeclarationNode * newnode = new DeclarationNode; 408 newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof ); 396 409 newnode->type->typeexpr = expr; 397 410 return newnode; … … 405 418 return newnode; 406 419 } // DeclarationNode::newBuiltinType 407 408 DeclarationNode * DeclarationNode::newAttr( const string * name, ExpressionNode * expr ) {409 DeclarationNode * newnode = new DeclarationNode;410 newnode->type = nullptr;411 // newnode->attr.name = name;412 newnode->name = name;413 newnode->attr.expr = expr;414 return newnode;415 }416 417 DeclarationNode * DeclarationNode::newAttr( const string * name, DeclarationNode * type ) {418 DeclarationNode * newnode = new DeclarationNode;419 newnode->type = nullptr;420 // newnode->attr.name = name;421 newnode->name = name;422 newnode->attr.type = type;423 return newnode;424 }425 420 426 421 DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) { … … 503 498 } // DeclarationNode::copySpecifiers 504 499 505 static void addQualifiersToType( TypeData *&src, TypeData * dst ) { 506 if ( src->forall && dst->kind == TypeData::Function ) { 507 if ( dst->forall ) { 508 dst->forall->appendList( src->forall ); 509 } else { 510 dst->forall = src->forall; 511 } // if 512 src->forall = nullptr; 513 } // if 500 static void addQualifiersToType( TypeData *& src, TypeData * dst ) { 514 501 if ( dst->base ) { 515 502 addQualifiersToType( src, dst->base ); … … 564 551 } // addQualifiers 565 552 566 static void addTypeToType( TypeData *& src, TypeData *&dst ) {553 static void addTypeToType( TypeData *& src, TypeData *& dst ) { 567 554 if ( src->forall && dst->kind == TypeData::Function ) { 568 555 if ( dst->forall ) { … … 955 942 } 956 943 957 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {944 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 958 945 SemanticErrorException errors; 959 946 std::back_insert_iterator< std::list< Declaration * > > out( outputList ); … … 961 948 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 962 949 try { 950 bool extracted = false; 951 bool anon = false; 963 952 if ( DeclarationNode * extr = cur->extractAggregate() ) { 964 953 // handle the case where a structure declaration is contained within an object or type declaration 965 954 Declaration * decl = extr->build(); 966 955 if ( decl ) { 956 // hoist the structure declaration 967 957 decl->location = cur->location; 968 958 * out++ = decl; 959 960 // need to remember the cases where a declaration contains an anonymous aggregate definition 961 extracted = true; 962 assert( extr->type ); 963 if ( extr->type->kind == TypeData::Aggregate ) { 964 anon = extr->type->aggregate.anon; 965 } else if ( extr->type->kind == TypeData::Enum ) { 966 // xxx - is it useful to have an implicit anonymous enum member? 967 anon = extr->type->enumeration.anon; 968 } 969 969 } // if 970 970 delete extr; … … 973 973 Declaration * decl = cur->build(); 974 974 if ( decl ) { 975 decl->location = cur->location; 976 * out++ = decl; 975 // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.: 976 // struct S { 977 // struct T { int x; }; // no anonymous member 978 // struct { int y; }; // anonymous member 979 // struct T; // anonymous member 980 // }; 981 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 982 if ( decl->name == "" ) { 983 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) { 984 if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) { 985 if ( aggr->name.find("anonymous") == std::string::npos ) { 986 if ( ! cur->get_inLine() ) { 987 // temporary: warn about anonymous member declarations of named types, since 988 // this conflicts with the syntax for the forward declaration of an anonymous type 989 SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() ); 990 } // if 991 } // if 992 } // if 993 } // if 994 } // if 995 decl->location = cur->location; 996 *out++ = decl; 997 } // if 977 998 } // if 978 } catch( SemanticErrorException & e ) {999 } catch( SemanticErrorException & e ) { 979 1000 errors.append( e ); 980 1001 } // try 981 } // while1002 } // for 982 1003 983 1004 if ( ! errors.isEmpty() ) { … … 986 1007 } // buildList 987 1008 988 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList ) { 1009 // currently only builds assertions, function parameters, and return values 1010 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) { 989 1011 SemanticErrorException errors; 990 1012 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList ); … … 993 1015 try { 994 1016 Declaration * decl = cur->build(); 995 if ( decl ) { 996 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 997 dwt->location = cur->location; 998 * out++ = dwt; 999 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 1000 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() ); 1001 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1002 obj->location = cur->location; 1003 * out++ = obj; 1004 delete agg; 1005 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 1006 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() ); 1007 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1008 obj->location = cur->location; 1009 * out++ = obj; 1010 } // if 1017 assert( decl ); 1018 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 1019 dwt->location = cur->location; 1020 * out++ = dwt; 1021 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 1022 // e.g., int foo(struct S) {} 1023 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name ); 1024 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1025 obj->location = cur->location; 1026 * out++ = obj; 1027 delete agg; 1028 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 1029 // e.g., int foo(union U) {} 1030 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name ); 1031 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1032 obj->location = cur->location; 1033 * out++ = obj; 1034 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) { 1035 // e.g., int foo(enum E) {} 1036 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name ); 1037 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1038 obj->location = cur->location; 1039 * out++ = obj; 1011 1040 } // if 1012 } catch( SemanticErrorException & e ) {1041 } catch( SemanticErrorException & e ) { 1013 1042 errors.append( e ); 1014 1043 } // try … … 1020 1049 } // buildList 1021 1050 1022 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {1051 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1023 1052 SemanticErrorException errors; 1024 1053 std::back_insert_iterator< std::list< Type * > > out( outputList ); … … 1028 1057 try { 1029 1058 * out++ = cur->buildType(); 1030 } catch( SemanticErrorException & e ) {1059 } catch( SemanticErrorException & e ) { 1031 1060 errors.append( e ); 1032 1061 } // try … … 1064 1093 if ( type->kind != TypeData::Function && funcSpecs.any() ) { 1065 1094 SemanticError( this, "invalid function specifier for " ); 1095 } // if 1096 // Forall qualifier can only appear on a function/aggregate definition/declaration. 1097 // 1098 // forall int f(); // allowed 1099 // forall int g( int i ); // allowed 1100 // forall int i; // disallowed 1101 if ( type->kind != TypeData::Function && type->forall ) { 1102 SemanticError( this, "invalid type qualifier for " ); 1066 1103 } // if 1067 1104 bool isDelete = initializer && initializer->get_isDelete(); -
src/Parser/ExpressionNode.cc
r7951100 rb067d9b 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 4 21:24:45 201813 // Update Count : 80212 // Last Modified On : Sun Aug 4 20:57:55 2019 13 // Update Count : 978 14 14 // 15 15 … … 51 51 extern const Type::Qualifiers noQualifiers; // no qualifiers on constants 52 52 53 static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } 54 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 55 static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; } 56 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 53 // static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } 54 // static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; } 55 // static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 57 56 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; } 58 57 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; } 58 static inline bool checkF80( char c ) { return c == 'w' || c == 'W'; } 59 static inline bool checkF128( char c ) { return c == 'q' || c == 'Q'; } 60 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 59 61 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; } 60 62 static inline bool checkB( char c ) { return c == 'b' || c == 'B'; } 61 63 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 62 63 static const char * lnthsInt[2][6] = { 64 { "int8_t", "int16_t", "int32_t", "int64_t", "size_t", }, 65 { "uint8_t", "uint16_t", "uint32_t", "uint64_t", "size_t", } 66 }; // lnthsInt 67 68 static inline void checkLNInt( string & str, int & lnth, int & size ) { 69 string::size_type posn = str.find_first_of( "lL" ), start = posn; 70 if ( posn == string::npos ) return; 71 size = 4; // assume largest size 72 posn += 1; // advance to size 73 if ( str[posn] == '8' ) { // 8 74 lnth = 0; 75 } else if ( str[posn] == '1' ) { 76 posn += 1; 77 if ( str[posn] == '6' ) { // 16 78 lnth = 1; 64 // static inline bool checkN( char c ) { return c == 'n' || c == 'N'; } 65 66 void lnthSuffix( string & str, int & type, int & ltype ) { 67 string::size_type posn = str.find_last_of( "lL" ); 68 69 if ( posn == string::npos ) return; // no suffix 70 if ( posn == str.length() - 1 ) { type = 3; return; } // no length => long 71 72 string::size_type next = posn + 1; // advance to length 73 if ( str[next] == '3' ) { // 32 74 type = ltype = 2; 75 } else if ( str[next] == '6' ) { // 64 76 type = ltype = 3; 77 } else if ( str[next] == '8' ) { // 8 78 type = ltype = 1; 79 } else if ( str[next] == '1' ) { 80 if ( str[next + 1] == '6' ) { // 16 81 type = ltype = 0; 79 82 } else { // 128 80 posn += 1; 81 lnth = 5; 82 } // if 83 } else { 84 if ( str[posn] == '3' ) { // 32 85 lnth = 2; 86 } else if ( str[posn] == '6' ) { // 64 87 lnth = 3; 88 } else { 89 assertf( false, "internal error, bad integral length %s", str.c_str() ); 90 } // if 91 posn += 1; 92 } // if 93 str.erase( start, posn - start + 1 ); // remove length suffix 94 } // checkLNInt 83 type = 5; ltype = 6; 84 } // if 85 } // if 86 // remove "lL" for these cases because it may not imply long 87 str.erase( posn ); // remove length 88 } // lnthSuffix 89 90 void valueToType( unsigned long long int & v, bool dec, int & type, bool & Unsigned ) { 91 // use value to determine type 92 if ( v <= INT_MAX ) { // signed int 93 type = 2; 94 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 95 type = 2; 96 Unsigned = true; // unsigned 97 } else if ( v <= LONG_MAX ) { // signed long int 98 type = 3; 99 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 100 type = 3; 101 Unsigned = true; // unsigned long int 102 } else if ( v <= LLONG_MAX ) { // signed long long int 103 type = 4; 104 } else { // unsigned long long int 105 type = 4; 106 Unsigned = true; // unsigned long long int 107 } // if 108 } // valueToType 95 109 96 110 Expression * build_constantInteger( string & str ) { 97 111 static const BasicType::Kind kind[2][6] = { 98 // short (h) must be before char (hh) 112 // short (h) must be before char (hh) because shorter type has the longer suffix 99 113 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, }, 100 114 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, }, 101 115 }; 102 116 103 bool dec = true, Unsigned = false; // decimal, unsigned constant 104 int size; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 105 int lnth = -1; // literal length 117 static const char * lnthsInt[2][6] = { 118 { "int16_t", "int8_t", "int32_t", "int64_t", "size_t", "uintptr_t", }, 119 { "uint16_t", "uint8_t", "uint32_t", "uint64_t", "size_t", "uintptr_t", }, 120 }; // lnthsInt 106 121 107 122 unsigned long long int v; // converted integral value 108 123 size_t last = str.length() - 1; // last subscript of constant 109 124 Expression * ret; 125 //string fred( str ); 126 127 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 128 int ltype = -1; // 0 => 16 bits, 1 => 8 bits, 2 => 32 bits, 3 => 64 bits, 4 => size_t, 5 => intptr, 6 => pointer 129 bool dec = true, Unsigned = false; // decimal, unsigned constant 110 130 111 131 // special constants … … 119 139 } // if 120 140 121 // Cannot be "0"141 // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate 122 142 123 143 if ( str[0] == '0' ) { // radix character ? … … 127 147 //printf( "%llx %llu\n", v, v ); 128 148 } else if ( checkB( str[1] ) ) { // binary constant ? 129 v = 0; 130 for ( unsigned int i = 2;; i += 1 ) { // compute value149 v = 0; // compute value 150 for ( unsigned int i = 2;; ) { // ignore prefix 131 151 if ( str[i] == '1' ) v |= 1; 132 if ( i == last ) break; 152 i += 1; 153 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 133 154 v <<= 1; 134 155 } // for 135 //printf( "% llx %llu\n", v, v );156 //printf( "%#llx %llu\n", v, v ); 136 157 } else { // octal constant 137 158 sscanf( (char *)str.c_str(), "%llo", &v ); 138 //printf( "% llo %llu\n", v, v );159 //printf( "%#llo %llu\n", v, v ); 139 160 } // if 140 161 } else { // decimal constant ? 141 162 sscanf( (char *)str.c_str(), "%llu", &v ); 142 //printf( "%llu %llu\n", v, v ); 143 } // if 144 145 if ( v <= INT_MAX ) { // signed int 146 size = 2; 147 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 148 size = 2; 149 Unsigned = true; // unsigned 150 } else if ( v <= LONG_MAX ) { // signed long int 151 size = 3; 152 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 153 size = 3; 154 Unsigned = true; // unsigned long int 155 } else if ( v <= LLONG_MAX ) { // signed long long int 156 size = 4; 157 } else { // unsigned long long int 158 size = 4; 159 Unsigned = true; // unsigned long long int 160 } // if 161 162 // At least one digit in integer constant, so safe to backup while looking for suffix. 163 164 if ( checkU( str[last] ) ) { // suffix 'u' ? 165 Unsigned = true; 166 if ( checkL( str[last - 1] ) ) { // suffix 'l' ? 167 size = 3; 168 if ( checkL( str[last - 2] ) ) { // suffix "ll" ? 169 size = 4; 163 //printf( "%llu\n", v ); 164 } // if 165 166 string::size_type posn; 167 168 if ( isdigit( str[last] ) ) { // no suffix ? 169 lnthSuffix( str, type, ltype ); // could have length suffix 170 if ( type == -1 ) { // no suffix 171 valueToType( v, dec, type, Unsigned ); 172 } // if 173 } else { 174 // At least one digit in integer constant, so safe to backup while looking for suffix. 175 176 posn = str.find_last_of( "pP" ); 177 if ( posn != string::npos ) { valueToType( v, dec, type, Unsigned ); ltype = 5; str.erase( posn, 1 ); goto FINI; } 178 179 posn = str.find_last_of( "zZ" ); 180 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; } 181 182 // 'u' can appear before or after length suffix 183 if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true; 184 185 posn = str.rfind( "hh" ); 186 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 187 188 posn = str.rfind( "HH" ); 189 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 190 191 posn = str.find_last_of( "hH" ); 192 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; } 193 194 posn = str.find_last_of( "nN" ); 195 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; } 196 197 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; } 198 199 lnthSuffix( str, type, ltype ); // must be after check for "ll" 200 if ( type == -1 ) { // only 'u' suffix ? 201 valueToType( v, dec, type, Unsigned ); 202 } // if 203 FINI: ; 204 } // if 205 206 //if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); } 207 assert( 0 <= type && type <= 6 ); 208 209 // Constant type is correct for overload resolving. 210 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) ); 211 if ( Unsigned && type < 2 ) { // hh or h, less than int ? 212 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 213 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 214 } else if ( ltype != -1 ) { // explicit length ? 215 if ( ltype == 6 ) { // int128, (int128)constant 216 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 217 } else { // explicit length, (length_type)constant 218 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false ); 219 if ( ltype == 5 ) { // pointer, intptr( (uintptr_t)constant ) 220 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) ); 170 221 } // if 171 } else if ( checkH( str[last - 1] ) ) { // suffix 'h' ? 172 size = 0; 173 if ( checkH( str[last - 2] ) ) { // suffix "hh" ? 174 size = 1; 175 } // if 176 str.erase( last - size - 1, size + 1 ); // remove 'h'/"hh" 177 } else { // suffix "ln" ? 178 checkLNInt( str, lnth, size ); 179 } // if 180 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ? 181 size = 3; 182 if ( checkL( str[last - 1] ) ) { // suffix 'll' ? 183 size = 4; 184 if ( checkU( str[last - 2] ) ) { // suffix 'u' ? 185 Unsigned = true; 186 } // if 187 } else if ( checkU( str[last - 1] ) ) { // suffix 'u' ? 188 Unsigned = true; 189 } // if 190 } else if ( checkH( str[ last ] ) ) { // suffix 'h' ? 191 size = 0; 192 if ( checkH( str[last - 1] ) ) { // suffix "hh" ? 193 size = 1; 194 if ( checkU( str[last - 2] ) ) { // suffix 'u' ? 195 Unsigned = true; 196 } // if 197 } else if ( checkU( str[last - 1] ) ) { // suffix 'u' ? 198 Unsigned = true; 199 } // if 200 str.erase( last - size, size + 1 ); // remove 'h'/"hh" 201 } else if ( checkZ( str[last] ) ) { // suffix 'z' ? 202 lnth = 4; 203 str.erase( last, 1 ); // remove 'z' 204 } else { // suffix "ln" ? 205 checkLNInt( str, lnth, size ); 206 } // if 207 208 assert( 0 <= size && size < 6 ); 209 // Constant type is correct for overload resolving. 210 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) ); 211 if ( Unsigned && size < 2 ) { // hh or h, less than int ? 212 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 213 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false ); 214 } else if ( lnth != -1 ) { // explicit length ? 215 if ( lnth == 5 ) { // int128 ? 216 size = 5; 217 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false ); 218 } else { 219 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ), false ); 220 } // if 221 } // if 222 CLEANUP: 223 222 } // if 223 } // if 224 225 CLEANUP: ; 224 226 delete &str; // created by lex 225 227 return ret; … … 227 229 228 230 229 static inline void checkLNFloat( string & str, int & lnth, int & size ) { 230 string::size_type posn = str.find_first_of( "lL" ), start = posn; 231 static inline void checkFnxFloat( string & str, size_t last, bool & explnth, int & type ) { 232 string::size_type posn; 233 // floating-point constant has minimum of 2 characters, 1. or .1, so safe to look ahead 234 if ( str[1] == 'x' ) { // hex ? 235 posn = str.find_last_of( "pP" ); // back for exponent (must have) 236 posn = str.find_first_of( "fF", posn + 1 ); // forward for size (fF allowed in hex constant) 237 } else { 238 posn = str.find_last_of( "fF" ); // back for size (fF not allowed) 239 } // if 231 240 if ( posn == string::npos ) return; 232 size = 2; // assume largest size 233 lnth = 0; 241 explnth = true; 234 242 posn += 1; // advance to size 235 243 if ( str[posn] == '3' ) { // 32 236 size = 0; 244 if ( str[last] != 'x' ) type = 6; 245 else type = 7; 237 246 } else if ( str[posn] == '6' ) { // 64 238 size = 1; 239 } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128 240 size = 2; 241 if ( str[posn] == '1' ) posn += 1; 247 if ( str[last] != 'x' ) type = 8; 248 else type = 9; 249 } else if ( str[posn] == '8' ) { // 80 250 type = 3; 251 } else if ( str[posn] == '1' ) { // 16/128 252 if ( str[posn + 1] == '6' ) { // 16 253 type = 5; 254 } else { // 128 255 if ( str[last] != 'x' ) type = 10; 256 else type = 11; 257 } // if 242 258 } else { 243 259 assertf( false, "internal error, bad floating point length %s", str.c_str() ); 244 260 } // if 245 posn += 1; 246 str.erase( start, posn - start + 1 ); // remove length suffix 247 } // checkLNFloat 261 } // checkFnxFloat 248 262 249 263 250 264 Expression * build_constantFloat( string & str ) { 251 static const BasicType::Kind kind[2][ 3] = {252 { BasicType::Float, BasicType::Double, BasicType::LongDouble },253 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },265 static const BasicType::Kind kind[2][12] = { 266 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x }, 267 { 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 }, 254 268 }; 255 269 256 bool complx = false; // real, complex 257 int size = 1; // 0 => float, 1 => double, 2 => long double 258 int lnth = -1; // literal length 259 // floating-point constant has minimum of 2 characters: 1. or .1 270 // floating-point constant has minimum of 2 characters 1. or .1 260 271 size_t last = str.length() - 1; 261 272 double v; 273 int type; // 0 => float, 1 => double, 3 => long double, ... 274 bool complx = false; // real, complex 275 bool explnth = false; // explicit literal length 262 276 263 277 sscanf( str.c_str(), "%lg", &v ); … … 269 283 270 284 if ( checkF( str[last] ) ) { // float ? 271 size = 0;285 type = 0; 272 286 } else if ( checkD( str[last] ) ) { // double ? 273 size = 1;287 type = 1; 274 288 } else if ( checkL( str[last] ) ) { // long double ? 275 size = 2; 289 type = 2; 290 } else if ( checkF80( str[last] ) ) { // __float80 ? 291 type = 3; 292 } else if ( checkF128( str[last] ) ) { // __float128 ? 293 type = 4; 276 294 } else { 277 size = 1; // double (default) 278 checkLNFloat( str, lnth, size ); 279 } // if 295 type = 1; // double (default if no suffix) 296 checkFnxFloat( str, last, explnth, type ); 297 } // if 298 280 299 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ? 281 300 complx = true; 282 301 } // if 283 302 284 assert( 0 <= size && size < 3);285 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][ size] ), str, v ) );286 if ( lnth != -1) { // explicit length ?287 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][ size] ), false );303 assert( 0 <= type && type < 12 ); 304 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) ); 305 if ( explnth ) { // explicit length ? 306 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false ); 288 307 } // if 289 308 … … 338 357 new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"' 339 358 false, false ); 340 Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value359 Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) ); 341 360 if ( units.length() != 0 ) { 342 361 ret = new UntypedExpr( new NameExpr( units ), { ret } ); -
src/Parser/LinkageSpec.cc
r7951100 rb067d9b 10 10 // Created On : Sat May 16 13:22:09 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 7 11:11:00 201713 // Update Count : 2 512 // Last Modified On : Thr Spt 12 15:59:00 2018 13 // Update Count : 26 14 14 // 15 15 … … 23 23 24 24 namespace LinkageSpec { 25 26 Spec linkageCheck( CodeLocation location, const string * spec ) {27 assert( spec );28 unique_ptr<const string> guard( spec ); // allocated by lexer29 if ( *spec == "\"Cforall\"" ) {30 return Cforall;31 } else if ( *spec == "\"C\"" ) {32 return C;33 } else if ( *spec == "\"BuiltinC\"" ) {34 return BuiltinC;35 } else {36 SemanticError( location, "Invalid linkage specifier " + *spec );37 } // if38 }39 25 40 26 Spec linkageUpdate( CodeLocation location, Spec old_spec, const string * cmd ) { -
src/Parser/LinkageSpec.h
r7951100 rb067d9b 10 10 // Created On : Sat May 16 13:24:28 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:32:16 201713 // Update Count : 1 412 // Last Modified On : Wed Jul 10 16:02:34 2019 13 // Update Count : 18 14 14 // 15 15 … … 22 22 namespace LinkageSpec { 23 23 // All linkage specs are some combination of these flags: 24 enum { 25 Mangle = 1 << 0, 26 Generate = 1 << 1, 27 Overrideable = 1 << 2, 28 Builtin = 1 << 3, 29 GccBuiltin = 1 << 4, 30 31 NoOfSpecs = 1 << 5, 32 }; 24 enum { Mangle = 1 << 0, Generate = 1 << 1, Overrideable = 1 << 2, Builtin = 1 << 3, GccBuiltin = 1 << 4, NoOfSpecs = 1 << 5, }; 33 25 34 26 union Spec { … … 42 34 }; 43 35 constexpr Spec( unsigned int val ) : val( val ) {} 44 constexpr Spec( Spec const &other ) : val( other.val ) {} 36 constexpr Spec( Spec const & other ) : val( other.val ) {} 37 constexpr Spec & operator=( const Spec & ) = default; 45 38 // Operators may go here. 46 39 // Supports == and != 47 constexpr operator unsigned int () const { return val; }40 constexpr operator unsigned int() const { return val; } 48 41 }; 49 42 50 43 51 Spec linkageCheck( CodeLocation location, const std::string * );52 // Returns the Spec with the given name (limited to C, Cforall & BuiltinC)53 44 Spec linkageUpdate( CodeLocation location, Spec old_spec, const std::string * cmd ); 54 45 /* If cmd = "C" returns a Spec that is old_spec with is_mangled = false -
src/Parser/ParseNode.h
r7951100 rb067d9b 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 6 16:17:18 201813 // Update Count : 8 4312 // Last Modified On : Thu Jul 25 22:17:10 2019 13 // Update Count : 876 14 14 // 15 15 … … 68 68 } 69 69 70 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}71 virtual void printList( std::ostream & os, int indent = 0 ) const {70 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {} 71 virtual void printList( std::ostream & os, int indent = 0 ) const { 72 72 print( os, indent ); 73 73 if ( next ) next->print( os, indent ); … … 103 103 InitializerNode * next_init() const { return kids; } 104 104 105 void print( std::ostream & os, int indent = 0 ) const;105 void print( std::ostream & os, int indent = 0 ) const; 106 106 void printOneLine( std::ostream & ) const; 107 107 … … 127 127 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; } 128 128 129 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {130 os << expr.get() << std::endl;131 } 132 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}129 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override { 130 os << expr.get(); 131 } 132 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {} 133 133 134 134 template<typename T> … … 136 136 137 137 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); } 138 139 std::unique_ptr<Expression> expr; // public because of lifetime implications 138 140 private: 139 141 bool extension = false; 140 std::unique_ptr<Expression> expr;141 142 }; // ExpressionNode 142 143 … … 205 206 class DeclarationNode : public ParseNode { 206 207 public: 207 // These enumerations must harmonize with their names. 208 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType }; 208 // These enumerations must harmonize with their names in DeclarationNode.cc. 209 enum BasicType { Void, Bool, Char, Int, Int128, 210 Float, Double, LongDouble, uuFloat80, uuFloat128, 211 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType }; 209 212 static const char * basicTypeNames[]; 210 enum ComplexType { Complex, Imaginary, NoComplexType };213 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message 211 214 static const char * complexTypeNames[]; 212 215 enum Signedness { Signed, Unsigned, NoSignedness }; … … 218 221 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass }; 219 222 static const char * typeClassNames[]; 220 enum BuiltinType { Valist, Zero, One, NoBuiltinType };223 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType }; 221 224 static const char * builtinTypeNames[]; 222 225 … … 231 234 static DeclarationNode * newForall( DeclarationNode * ); 232 235 static DeclarationNode * newFromTypedef( const std::string * ); 236 static DeclarationNode * newFromGlobalScope(); 237 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * ); 233 238 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ); 234 239 static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ); … … 246 251 static DeclarationNode * newBitfield( ExpressionNode * size ); 247 252 static DeclarationNode * newTuple( DeclarationNode * members ); 248 static DeclarationNode * newTypeof( ExpressionNode * expr ); 249 static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes 250 static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes 253 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false ); 251 254 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes 252 255 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement … … 288 291 } 289 292 290 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;291 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;293 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; 294 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; 292 295 293 296 Declaration * build() const; … … 301 304 bool get_extension() const { return extension; } 302 305 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; } 306 307 bool get_inLine() const { return inLine; } 308 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; } 303 309 public: 304 310 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); } … … 325 331 StaticAssert_t assert; 326 332 327 BuiltinType builtin; 328 329 TypeData * type; 330 333 BuiltinType builtin = NoBuiltinType; 334 335 TypeData * type = nullptr; 336 337 bool inLine = false; 331 338 Type::FuncSpecifiers funcSpecs; 332 339 Type::StorageClasses storageClasses; 333 340 334 ExpressionNode * bitfieldWidth ;341 ExpressionNode * bitfieldWidth = nullptr; 335 342 std::unique_ptr<ExpressionNode> enumeratorValue; 336 bool hasEllipsis ;343 bool hasEllipsis = false; 337 344 LinkageSpec::Spec linkage; 338 Expression * asmName ;345 Expression * asmName = nullptr; 339 346 std::list< Attribute * > attributes; 340 InitializerNode * initializer ;347 InitializerNode * initializer = nullptr; 341 348 bool extension = false; 342 349 std::string error; 343 StatementNode * asmStmt ;350 StatementNode * asmStmt = nullptr; 344 351 345 352 static UniqueName anonymous; … … 375 382 virtual StatementNode * append_last_case( StatementNode * ); 376 383 377 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {384 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override { 378 385 os << stmt.get() << std::endl; 379 386 } … … 384 391 Statement * build_expr( ExpressionNode * ctl ); 385 392 386 struct IfCt l {387 IfCt l( DeclarationNode * decl, ExpressionNode * condition ) :393 struct IfCtrl { 394 IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) : 388 395 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {} 389 396 … … 392 399 }; 393 400 394 struct ForCt l {395 ForCt l( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :401 struct ForCtrl { 402 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) : 396 403 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {} 397 ForCt l( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :404 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) : 398 405 init( new StatementNode( decl ) ), condition( condition ), change( change ) {} 399 406 … … 403 410 }; 404 411 405 Expression * build_if_control( IfCt l * ctl, std::list< Statement * > & init );406 Statement * build_if( IfCt l * ctl, StatementNode * then_stmt, StatementNode * else_stmt );412 Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init ); 413 Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ); 407 414 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ); 408 415 Statement * build_case( ExpressionNode * ctl ); 409 416 Statement * build_default(); 410 Statement * build_while( IfCt l * ctl, StatementNode * stmt );417 Statement * build_while( IfCtrl * ctl, StatementNode * stmt ); 411 418 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt ); 412 Statement * build_for( ForCt l * forctl, StatementNode * stmt );419 Statement * build_for( ForCtrl * forctl, StatementNode * stmt ); 413 420 Statement * build_branch( BranchStmt::Type kind ); 414 421 Statement * build_branch( std::string * identifier, BranchStmt::Type kind ); … … 428 435 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 429 436 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 430 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );437 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ); 431 438 432 439 //############################################################################## 433 440 434 441 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args > 435 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {442 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) { 436 443 SemanticErrorException errors; 437 444 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList ); … … 447 454 assertf(false, "buildList unknown type"); 448 455 } // if 449 } catch( SemanticErrorException & e ) {456 } catch( SemanticErrorException & e ) { 450 457 errors.append( e ); 451 458 } // try … … 458 465 459 466 // in DeclarationNode.cc 460 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );461 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );462 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );467 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ); 468 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ); 469 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ); 463 470 464 471 template< typename SynTreeType, typename NodeType > 465 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {472 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) { 466 473 buildList( firstNode, outputList ); 467 474 delete firstNode; -
src/Parser/StatementNode.cc
r7951100 rb067d9b 10 10 // Created On : Sat May 16 14:59:41 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jun 5 08:58:34201813 // Update Count : 36 212 // Last Modified On : Sat Aug 4 09:39:25 2018 13 // Update Count : 363 14 14 // 15 15 … … 78 78 } // build_expr 79 79 80 Expression * build_if_control( IfCt l * ctl, std::list< Statement * > & init ) {80 Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init ) { 81 81 if ( ctl->init != 0 ) { 82 82 buildMoveList( ctl->init, init ); … … 100 100 } // build_if_control 101 101 102 Statement * build_if( IfCt l * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {102 Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) { 103 103 Statement * thenb, * elseb = nullptr; 104 104 std::list< Statement * > branches; … … 145 145 } // build_default 146 146 147 Statement * build_while( IfCt l * ctl, StatementNode * stmt ) {147 Statement * build_while( IfCtrl * ctl, StatementNode * stmt ) { 148 148 std::list< Statement * > branches; 149 149 buildMoveList< Statement, StatementNode >( stmt, branches ); … … 164 164 } // build_do_while 165 165 166 Statement * build_for( ForCt l * forctl, StatementNode * stmt ) {166 Statement * build_for( ForCtrl * forctl, StatementNode * stmt ) { 167 167 std::list< Statement * > branches; 168 168 buildMoveList< Statement, StatementNode >( stmt, branches ); … … 317 317 } // build_waitfor_timeout 318 318 319 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {319 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) { 320 320 std::list< Expression * > e; 321 321 buildMoveList( exprs, e ); 322 322 Statement * s = maybeMoveBuild<Statement>( stmt ); 323 return new WithStmt( e, s);323 return new DeclStmt( new WithStmt( e, s ) ); 324 324 } // build_with 325 325 -
src/Parser/TypeData.cc
r7951100 rb067d9b 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 6 17:40:33 201813 // Update Count : 6 0412 // Last Modified On : Wed Feb 13 18:16:23 2019 13 // Update Count : 649 14 14 // 15 15 … … 37 37 case Reference: 38 38 case EnumConstant: 39 case GlobalScope: 39 40 // nothing else to initialize 40 41 break; … … 62 63 enumeration.constants = nullptr; 63 64 enumeration.body = false; 65 enumeration.anon = false; 64 66 break; 65 67 case Aggregate: … … 73 75 aggregate.tagged = false; 74 76 aggregate.parent = nullptr; 77 aggregate.anon = false; 75 78 break; 76 79 case AggregateInst: … … 78 81 aggInst.aggregate = nullptr; 79 82 aggInst.params = nullptr; 80 aggInst.hoistType = false; ;83 aggInst.hoistType = false; 81 84 break; 82 85 case Symbolic: … … 93 96 break; 94 97 case Typeof: 98 case Basetypeof: 95 99 // typeexpr = new Typeof_t; 96 100 typeexpr = nullptr; … … 98 102 case Builtin: 99 103 // builtin = new Builtin_t; 104 case Qualified: 105 qualified.parent = nullptr; 106 qualified.child = nullptr; 100 107 break; 101 108 } // switch … … 112 119 case Reference: 113 120 case EnumConstant: 121 case GlobalScope: 114 122 // nothing to destroy 115 123 break; … … 159 167 break; 160 168 case Typeof: 169 case Basetypeof: 161 170 // delete typeexpr->expr; 162 171 delete typeexpr; … … 165 174 // delete builtin; 166 175 break; 176 case Qualified: 177 delete qualified.parent; 178 delete qualified.child; 167 179 } // switch 168 180 } // TypeData::~TypeData … … 180 192 case Pointer: 181 193 case Reference: 194 case GlobalScope: 182 195 // nothing else to copy 183 196 break; … … 207 220 newtype->aggregate.fields = maybeClone( aggregate.fields ); 208 221 newtype->aggregate.body = aggregate.body; 222 newtype->aggregate.anon = aggregate.anon; 209 223 newtype->aggregate.tagged = aggregate.tagged; 210 224 newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr; … … 219 233 newtype->enumeration.constants = maybeClone( enumeration.constants ); 220 234 newtype->enumeration.body = enumeration.body; 235 newtype->enumeration.anon = enumeration.anon; 221 236 break; 222 237 case Symbolic: … … 232 247 break; 233 248 case Typeof: 249 case Basetypeof: 234 250 newtype->typeexpr = maybeClone( typeexpr ); 235 251 break; … … 237 253 assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One ); 238 254 newtype->builtintype = builtintype; 255 break; 256 case Qualified: 257 newtype->qualified.parent = maybeClone( qualified.parent ); 258 newtype->qualified.child = maybeClone( qualified.child ); 239 259 break; 240 260 } // switch … … 254 274 255 275 switch ( kind ) { 256 case Unknown: 257 os << "entity of unknown type "; 276 case Basic: 277 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " "; 278 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " "; 279 if ( complextype == DeclarationNode::NoComplexType ) { // basic type 280 assert( basictype != DeclarationNode::NoBasicType ); 281 os << DeclarationNode::basicTypeNames[ basictype ] << " "; 282 } else { // complex type 283 // handle double _Complex 284 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " "; 285 os << DeclarationNode::complexTypeNames[ complextype ] << " "; 286 } // if 258 287 break; 259 288 case Pointer: … … 264 293 } // if 265 294 break; 266 case EnumConstant: 267 os << "enumeration constant "; 268 break; 269 case Basic: 270 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " "; 271 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " "; 272 assert( basictype != DeclarationNode::NoBasicType ); 273 os << DeclarationNode::basicTypeNames[ basictype ] << " "; 274 if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " "; 295 case Reference: 296 os << "reference "; 297 if ( base ) { 298 os << "to "; 299 base->print( os, indent ); 300 } // if 275 301 break; 276 302 case Array: … … 296 322 function.params->printList( os, indent + 4 ); 297 323 } else { 298 os << string( indent + 2, ' ' ) << "with no parameters " << endl;324 os << string( indent + 2, ' ' ) << "with no parameters" << endl; 299 325 } // if 300 326 if ( function.idList ) { … … 321 347 os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl; 322 348 if ( aggregate.params ) { 323 os << string( indent + 2, ' ' ) << "with type parameters " << endl;349 os << string( indent + 2, ' ' ) << "with type parameters" << endl; 324 350 aggregate.params->printList( os, indent + 4 ); 325 351 } // if 326 352 if ( aggregate.actuals ) { 327 os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;353 os << string( indent + 2, ' ' ) << "instantiated with actual parameters" << endl; 328 354 aggregate.actuals->printList( os, indent + 4 ); 329 355 } // if 330 356 if ( aggregate.fields ) { 331 os << string( indent + 2, ' ' ) << "with members " << endl;357 os << string( indent + 2, ' ' ) << "with members" << endl; 332 358 aggregate.fields->printList( os, indent + 4 ); 333 359 } // if 334 360 if ( aggregate.body ) { 335 os << string( indent + 2, ' ' ) << " with body " << endl;361 os << string( indent + 2, ' ' ) << " with body" << endl; 336 362 } // if 337 363 break; … … 344 370 } // if 345 371 if ( aggInst.params ) { 346 os << string( indent + 2, ' ' ) << "with parameters " << endl;372 os << string( indent + 2, ' ' ) << "with parameters" << endl; 347 373 aggInst.params->printList( os, indent + 2 ); 348 374 } // if … … 355 381 } // if 356 382 if ( enumeration.body ) { 357 os << string( indent + 2, ' ' ) << " with body " << endl; 358 } // if 359 break; 360 case SymbolicInst: 361 os << "instance of type " << *symbolic.name; 362 if ( symbolic.actuals ) { 363 os << " with parameters" << endl; 364 symbolic.actuals->printList( os, indent + 2 ); 365 } // if 383 os << string( indent + 2, ' ' ) << " with body" << endl; 384 } // if 385 break; 386 case EnumConstant: 387 os << "enumeration constant "; 366 388 break; 367 389 case Symbolic: … … 385 407 } // if 386 408 break; 409 case SymbolicInst: 410 os << *symbolic.name; 411 if ( symbolic.actuals ) { 412 os << "("; 413 symbolic.actuals->printList( os, indent + 2 ); 414 os << ")"; 415 } // if 416 break; 387 417 case Tuple: 388 418 os << "tuple "; 389 419 if ( tuple ) { 390 os << "with members " << endl;420 os << "with members" << endl; 391 421 tuple->printList( os, indent + 2 ); 392 422 } // if 393 423 break; 424 case Basetypeof: 425 os << "base-"; 426 #if defined(__GNUC__) && __GNUC__ >= 7 427 __attribute__((fallthrough)); 428 #endif 394 429 case Typeof: 395 430 os << "type-of expression "; … … 400 435 case Builtin: 401 436 os << DeclarationNode::builtinTypeNames[builtintype]; 437 break; 438 case GlobalScope: 439 break; 440 case Qualified: 441 qualified.parent->print( os ); 442 os << "."; 443 qualified.child->print( os ); 444 break; 445 case Unknown: 446 os << "entity of unknown type "; 402 447 break; 403 448 default: … … 406 451 } // switch 407 452 } // TypeData::print 453 454 const std::string * TypeData::leafName() const { 455 switch ( kind ) { 456 case Unknown: 457 case Pointer: 458 case Reference: 459 case EnumConstant: 460 case GlobalScope: 461 case Array: 462 case Basic: 463 case Function: 464 case AggregateInst: 465 case Tuple: 466 case Typeof: 467 case Basetypeof: 468 case Builtin: 469 assertf(false, "Tried to get leaf name from kind without a name: %d", kind); 470 break; 471 case Aggregate: 472 return aggregate.name; 473 case Enum: 474 return enumeration.name; 475 case Symbolic: 476 case SymbolicInst: 477 return symbolic.name; 478 case Qualified: 479 return qualified.child->leafName(); 480 } // switch 481 assert(false); 482 } 408 483 409 484 … … 447 522 switch ( td->kind ) { 448 523 case TypeData::Unknown: 449 // fill in implicit int450 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );524 // fill in implicit int 525 return new BasicType( buildQualifiers( td ), BasicType::SignedInt ); 451 526 case TypeData::Basic: 452 return buildBasicType( td );527 return buildBasicType( td ); 453 528 case TypeData::Pointer: 454 return buildPointer( td );529 return buildPointer( td ); 455 530 case TypeData::Array: 456 return buildArray( td );531 return buildArray( td ); 457 532 case TypeData::Reference: 458 return buildReference( td );533 return buildReference( td ); 459 534 case TypeData::Function: 460 return buildFunction( td );535 return buildFunction( td ); 461 536 case TypeData::AggregateInst: 462 return buildAggInst( td );537 return buildAggInst( td ); 463 538 case TypeData::EnumConstant: 464 // the name gets filled in later -- by SymTab::Validate465 return new EnumInstType( buildQualifiers( td ), "" );539 // the name gets filled in later -- by SymTab::Validate 540 return new EnumInstType( buildQualifiers( td ), "" ); 466 541 case TypeData::SymbolicInst: 467 return buildSymbolicInst( td );;542 return buildSymbolicInst( td ); 468 543 case TypeData::Tuple: 469 return buildTuple( td );544 return buildTuple( td ); 470 545 case TypeData::Typeof: 471 return buildTypeof( td ); 546 case TypeData::Basetypeof: 547 return buildTypeof( td ); 472 548 case TypeData::Builtin: 473 if(td->builtintype == DeclarationNode::Zero) { 474 return new ZeroType( noQualifiers ); 475 } 476 else if(td->builtintype == DeclarationNode::One) { 477 return new OneType( noQualifiers ); 478 } 479 else { 480 return new VarArgsType( buildQualifiers( td ) ); 481 } 549 if (td->builtintype == DeclarationNode::Zero) { 550 return new ZeroType( noQualifiers ); 551 } 552 else if (td->builtintype == DeclarationNode::One) { 553 return new OneType( noQualifiers ); 554 } 555 else { 556 return new VarArgsType( buildQualifiers( td ) ); 557 } 558 case TypeData::GlobalScope: 559 return new GlobalScopeType(); 560 case TypeData::Qualified: 561 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) ); 482 562 case TypeData::Symbolic: 483 563 case TypeData::Enum: 484 564 case TypeData::Aggregate: 485 assert( false );565 assert( false ); 486 566 } // switch 567 487 568 return nullptr; 488 569 } // typebuild … … 585 666 586 667 case DeclarationNode::Float: 587 case DeclarationNode::Float80:588 case DeclarationNode::Float128:589 668 case DeclarationNode::Double: 590 669 case DeclarationNode::LongDouble: // not set until below 591 static BasicType::Kind floattype[3][3] = { 592 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 593 { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary }, 594 { BasicType::Float, BasicType::Double, BasicType::LongDouble }, 670 case DeclarationNode::uuFloat80: 671 case DeclarationNode::uuFloat128: 672 case DeclarationNode::uFloat16: 673 case DeclarationNode::uFloat32: 674 case DeclarationNode::uFloat32x: 675 case DeclarationNode::uFloat64: 676 case DeclarationNode::uFloat64x: 677 case DeclarationNode::uFloat128: 678 case DeclarationNode::uFloat128x: 679 static BasicType::Kind floattype[2][12] = { 680 { 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, }, 681 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x, }, 595 682 }; 596 683 … … 605 692 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 606 693 } // if 694 if ( td->complextype == DeclarationNode::Imaginary ) { 695 genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype ); 696 } // if 697 if ( (td->basictype == DeclarationNode::uuFloat80 || td->basictype == DeclarationNode::uuFloat128) && td->complextype == DeclarationNode::Complex ) { // gcc unsupported 698 genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype ); 699 } // if 607 700 if ( td->length == DeclarationNode::Long ) { 608 701 const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble; 609 702 } // if 610 703 611 if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {612 // if ( td->complextype != DeclarationNode::NoComplexType ) {613 // genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );614 // }615 if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;616 else ret = BasicType::Float128;617 break;618 }619 620 704 ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ]; 705 //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, DeclarationNode::Float, ret ); 621 706 break; 622 707 … … 858 943 859 944 TypeofType * buildTypeof( const TypeData * td ) { 860 assert( td->kind == TypeData::Typeof );945 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof ); 861 946 assert( td->typeexpr ); 862 947 // assert( td->typeexpr->expr ); 863 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() ); 948 return new TypeofType{ 949 buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof }; 864 950 } // buildTypeof 865 951 … … 893 979 assert( td->kind == TypeData::Function ); 894 980 FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis ); 895 buildList( td->function.params, ft-> get_parameters());896 buildForall( td->forall, ft-> get_forall());981 buildList( td->function.params, ft->parameters ); 982 buildForall( td->forall, ft->forall ); 897 983 if ( td->base ) { 898 984 switch ( td->base->kind ) { 899 985 case TypeData::Tuple: 900 buildList( td->base->tuple, ft-> get_returnVals());986 buildList( td->base->tuple, ft->returnVals ); 901 987 break; 902 988 default: -
src/Parser/TypeData.h
r7951100 rb067d9b 10 10 // Created On : Sat May 16 15:18:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 22 15:21:23201813 // Update Count : 19 112 // Last Modified On : Thu Nov 1 20:56:46 2018 13 // Update Count : 196 14 14 // 15 15 … … 26 26 27 27 struct TypeData { 28 enum Kind { Basic, Pointer, Array, Reference, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,29 SymbolicInst, Tuple, Typeof, B uiltin, Unknown };28 enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic, 29 SymbolicInst, Tuple, Typeof, Basetypeof, Builtin, GlobalScope, Qualified, Unknown }; 30 30 31 31 struct Aggregate_t { 32 32 DeclarationNode::Aggregate kind; 33 const std::string * name ;34 DeclarationNode * params ;35 ExpressionNode * actuals ; // holds actual parameters later applied to AggInst36 DeclarationNode * fields ;33 const std::string * name = nullptr; 34 DeclarationNode * params = nullptr; 35 ExpressionNode * actuals = nullptr; // holds actual parameters later applied to AggInst 36 DeclarationNode * fields = nullptr; 37 37 bool body; 38 bool anon; 38 39 39 40 bool tagged; 40 const std::string * parent ;41 const std::string * parent = nullptr; 41 42 }; 42 43 43 44 struct AggInst_t { 44 TypeData * aggregate ;45 ExpressionNode * params ;45 TypeData * aggregate = nullptr; 46 ExpressionNode * params = nullptr; 46 47 bool hoistType; 47 48 }; 48 49 49 50 struct Array_t { 50 ExpressionNode * dimension ;51 ExpressionNode * dimension = nullptr; 51 52 bool isVarLen; 52 53 bool isStatic; … … 54 55 55 56 struct Enumeration_t { 56 const std::string * name ;57 DeclarationNode * constants ;57 const std::string * name = nullptr; 58 DeclarationNode * constants = nullptr; 58 59 bool body; 60 bool anon; 59 61 }; 60 62 61 63 struct Function_t { 62 mutable DeclarationNode * params ; // mutables modified in buildKRFunction63 mutable DeclarationNode * idList ; // old-style64 mutable DeclarationNode * oldDeclList ;65 StatementNode * body ;66 ExpressionNode * withExprs ;// expressions from function's with_clause64 mutable DeclarationNode * params = nullptr; // mutables modified in buildKRFunction 65 mutable DeclarationNode * idList = nullptr; // old-style 66 mutable DeclarationNode * oldDeclList = nullptr; 67 StatementNode * body = nullptr; 68 ExpressionNode * withExprs = nullptr; // expressions from function's with_clause 67 69 }; 68 70 69 71 struct Symbolic_t { 70 const std::string * name ;72 const std::string * name = nullptr; 71 73 bool isTypedef; // false => TYPEGENname, true => TYPEDEFname 72 DeclarationNode * params; 73 ExpressionNode * actuals; 74 DeclarationNode * assertions; 74 DeclarationNode * params = nullptr; 75 ExpressionNode * actuals = nullptr; 76 DeclarationNode * assertions = nullptr; 77 }; 78 79 struct Qualified_t { // qualified type S.T 80 TypeData * parent = nullptr; 81 TypeData * child = nullptr; 75 82 }; 76 83 … … 86 93 87 94 Type::Qualifiers qualifiers; 88 DeclarationNode * forall ;95 DeclarationNode * forall = nullptr; 89 96 90 // Basic_t basic;91 97 Aggregate_t aggregate; 92 98 AggInst_t aggInst; 93 99 Array_t array; 94 100 Enumeration_t enumeration; 95 // Variable_t variable;96 101 Function_t function; 97 102 Symbolic_t symbolic; 98 DeclarationNode * tuple; 99 ExpressionNode * typeexpr; 103 Qualified_t qualified; 104 DeclarationNode * tuple = nullptr; 105 ExpressionNode * typeexpr = nullptr; 100 106 101 107 TypeData( Kind k = Unknown ); … … 103 109 void print( std::ostream &, int indent = 0 ) const; 104 110 TypeData * clone() const; 111 112 const std::string * leafName() const; 105 113 }; 106 114 … … 120 128 TupleType * buildTuple( const TypeData * ); 121 129 TypeofType * buildTypeof( const TypeData * ); 122 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() ); 130 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, 131 Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() ); 123 132 FunctionType * buildFunction( const TypeData * ); 124 133 void buildKRFunction( const TypeData::Function_t & function ); -
src/Parser/TypedefTable.cc
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypedefTable.cc -- 7 // TypedefTable.cc -- 8 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 7 13:17:56201813 // Update Count : 19212 // Last Modified On : Wed Jul 25 15:32:35 2018 13 // Update Count : 258 14 14 // 15 15 … … 51 51 } // TypedefTable::exists 52 52 53 bool TypedefTable::existsCurr( const string & identifier ) { 54 return kindTable.findAt( kindTable.currentScope() - 1, identifier ) != kindTable.end(); 55 } // TypedefTable::exists 56 53 57 int TypedefTable::isKind( const string & identifier ) const { 54 58 KindTable::const_iterator posn = kindTable.find( identifier ); … … 77 81 auto scope = kindTable.currentScope(); 78 82 debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl ); 79 auto ret = kindTable.insertAt( scope, identifier, kind ); 80 if ( ! ret.second ) ret.first->second = kind; // exists => update 83 kindTable.insertAt( scope, identifier, kind ); 81 84 } // TypedefTable::addToScope 82 85 83 86 void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 84 a ssert( kindTable.currentScope() >= 1 );85 auto scope = kindTable.currentScope() - 1;86 debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );87 auto scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level; 88 // auto scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level; 89 debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl ); 87 90 auto ret = kindTable.insertAt( scope, identifier, kind ); 88 if ( ! ret.second ) ret.first->second = kind; // exists => update91 if ( ! ret.second ) ret.first->second = kind; // exists => update 89 92 } // TypedefTable::addToEnclosingScope 90 93 91 94 void TypedefTable::enterScope() { 92 kindTable.beginScope(); 93 debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl ); 94 debugPrint( print() ); 95 kindTable.beginScope( (Note){ 0, false } ); 96 debugPrint( cerr << "Entering scope " << kindTable.currentScope() << " level " << level << endl; print() ); 95 97 } // TypedefTable::enterScope 96 98 97 99 void TypedefTable::leaveScope() { 98 debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl ); 99 debugPrint( print() ); 100 debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl; print() ); 100 101 kindTable.endScope(); 101 102 } // TypedefTable::leaveScope 102 103 104 void TypedefTable::up( bool forall ) { 105 level += 1; 106 kindTable.getNote( kindTable.currentScope() ) = (Note){ level, forall || getEnclForall() }; 107 debugPrint( cerr << "Up " << " level " << level << " note " << kindTable.getNote( level ).level << ", " << kindTable.getNote( level ).forall << endl; ); 108 } // TypedefTable::up 109 110 void TypedefTable::down() { 111 level -= 1; 112 debugPrint( cerr << "Down " << " level " << level << " note " << kindTable.getNote( level ).level << endl; ); 113 } // TypedefTable::down 114 103 115 void TypedefTable::print( void ) const { 104 116 KindTable::size_type scope = kindTable.currentScope(); 105 debugPrint( cerr << "[" << scope << "] " );117 debugPrint( cerr << "[" << scope << "] " << kindTable.getNote( scope ).level << ", " << kindTable.getNote( scope ).forall << ":" ); 106 118 for ( KindTable::const_iterator i = kindTable.begin(); i != kindTable.end(); i++ ) { 107 119 while ( i.get_level() != scope ) { 108 120 --scope; 109 debugPrint( cerr << endl << "[" << scope << "] " );121 debugPrint( cerr << endl << "[" << scope << "] " << kindTable.getNote( scope ).level << ", " << kindTable.getNote( scope ).forall << ":" ); 110 122 } // while 111 123 debugPrint( cerr << " " << (*i).first << ":" << kindName( (*i).second ) ); … … 113 125 while ( scope > 0 ) { 114 126 --scope; 115 debugPrint( cerr << endl << "[" << scope << "] " );116 } 127 debugPrint( cerr << endl << "[" << scope << "] " << kindTable.getNote( scope ).level << ", " << kindTable.getNote( scope ).forall << ":" ); 128 } // while 117 129 debugPrint( cerr << endl ); 118 } 130 } // TypedefTable::print 119 131 120 132 // Local Variables: // -
src/Parser/TypedefTable.h
r7951100 rb067d9b 10 10 // Created On : Sat May 16 15:24:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 7 12:10:17201813 // Update Count : 8512 // Last Modified On : Wed Jul 25 15:33:55 2018 13 // Update Count : 114 14 14 // 15 15 … … 23 23 24 24 class TypedefTable { 25 typedef ScopedMap< std::string, int > KindTable; 25 struct Note { size_t level; bool forall; }; 26 typedef ScopedMap< std::string, int, Note > KindTable; 26 27 KindTable kindTable; 28 unsigned int level = 0; 27 29 public: 28 30 ~TypedefTable(); 29 31 30 32 bool exists( const std::string & identifier ); 33 bool existsCurr( const std::string & identifier ); 31 34 int isKind( const std::string & identifier ) const; 32 35 void makeTypedef( const std::string & name, int kind = TYPEDEFname ); 33 36 void addToScope( const std::string & identifier, int kind, const char * ); 34 37 void addToEnclosingScope( const std::string & identifier, int kind, const char * ); 38 bool getEnclForall() { return kindTable.getNote( kindTable.currentScope() - 1 ).forall; } 35 39 36 40 void enterScope(); 37 41 void leaveScope(); 42 43 void up( bool ); 44 void down(); 38 45 39 46 void print( void ) const; -
src/Parser/lex.ll
r7951100 rb067d9b 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Thu Jun 7 08:27:40 201813 * Update Count : 67912 * Last Modified On : Sun Aug 4 20:53:47 2019 13 * Update Count : 719 14 14 */ 15 15 … … 25 25 //**************************** Includes and Defines **************************** 26 26 27 // trigger before each matching rule's action 28 #define YY_USER_ACTION \ 29 yylloc.first_line = yylineno; \ 30 yylloc.first_column = column; \ 31 column += yyleng; \ 32 yylloc.last_column = column; \ 33 yylloc.last_line = yylineno; \ 34 yylloc.filename = yyfilename ? yyfilename : ""; 27 35 unsigned int column = 0; // position of the end of the last token parsed 28 #define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : ""; // trigger before each matching rule's action29 36 30 37 #include <string> … … 32 39 using namespace std; 33 40 41 #include "config.h" // configure info 34 42 #include "ParseNode.h" 35 43 #include "TypedefTable.h" … … 49 57 #define NUMERIC_RETURN(x) rm_underscore(); RETURN_VAL( x ) // numeric constant 50 58 #define KEYWORD_RETURN(x) RETURN_CHAR( x ) // keyword 51 #define QKEYWORD_RETURN(x) typedefTable.isKind( yytext ); RETURN_VAL(x);// quasi-keyword59 #define QKEYWORD_RETURN(x) RETURN_VAL(x); // quasi-keyword 52 60 #define IDENTIFIER_RETURN() RETURN_VAL( typedefTable.isKind( yytext ) ) 53 #define ATTRIBUTE_RETURN() RETURN_VAL( ATTR_IDENTIFIER ) 61 62 #ifdef HAVE_KEYWORDS_FLOATXX // GCC >= 7 => keyword, otherwise typedef 63 #define FLOATXX(v) KEYWORD_RETURN(v); 64 #else 65 #define FLOATXX(v) IDENTIFIER_RETURN(); 66 #endif // HAVE_KEYWORDS_FLOATXX 54 67 55 68 void rm_underscore() { … … 79 92 identifier ([a-zA-Z_$]|{universal_char})([0-9a-zA-Z_$]|{universal_char})* 80 93 81 // attribute identifier, GCC: $ in identifier82 attr_identifier "@"{identifier}83 84 94 // numeric constants, CFA: '_' in constant 85 95 hex_quad {hex}("_"?{hex}){3} 86 96 size_opt (8|16|32|64|128)? 87 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hH]) 88 integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))? 97 // CFA: explicit l8/l16/l32/l64/l128, char 'hh', short 'h', int 'n' 98 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hHnN]) 99 // CFA: size_t 'z', pointer 'p', which define a sign and length 100 integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]|[pP]))? 89 101 90 102 octal_digits ({octal})|({octal}({octal}|"_")*{octal}) … … 105 117 // GCC: D (double) and iI (imaginary) suffixes, and DL (long double) 106 118 exponent "_"?[eE]"_"?[+-]?{decimal_digits} 107 floating_size 32|64|80|128108 floating_length ([fFdDlL ]|[lL]{floating_size})119 floating_size 16|32|32x|64|64x|80|128|128x 120 floating_length ([fFdDlLwWqQ]|[fF]{floating_size}) 109 121 floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length}) 110 122 floating_suffix_opt ("_"?({floating_suffix}|"DL"))? … … 202 214 __attribute__ { KEYWORD_RETURN(ATTRIBUTE); } // GCC 203 215 auto { KEYWORD_RETURN(AUTO); } 216 __auto_type { KEYWORD_RETURN(AUTO_TYPE); } 217 basetypeof { KEYWORD_RETURN(BASETYPEOF); } // CFA 204 218 _Bool { KEYWORD_RETURN(BOOL); } // C99 205 219 break { KEYWORD_RETURN(BREAK); } … … 209 223 char { KEYWORD_RETURN(CHAR); } 210 224 choose { KEYWORD_RETURN(CHOOSE); } // CFA 225 coerce { KEYWORD_RETURN(COERCE); } // CFA 211 226 _Complex { KEYWORD_RETURN(COMPLEX); } // C99 212 227 __complex { KEYWORD_RETURN(COMPLEX); } // GCC … … 232 247 finally { KEYWORD_RETURN(FINALLY); } // CFA 233 248 float { KEYWORD_RETURN(FLOAT); } 234 _Float32 { KEYWORD_RETURN(FLOAT); } // GCC 235 _Float32x { KEYWORD_RETURN(FLOAT); } // GCC 236 _Float64 { KEYWORD_RETURN(DOUBLE); } // GCC 237 _Float64x { KEYWORD_RETURN(DOUBLE); } // GCC 238 __float80 { KEYWORD_RETURN(FLOAT80); } // GCC 239 float80 { KEYWORD_RETURN(FLOAT80); } // GCC 240 _Float128 { KEYWORD_RETURN(FLOAT128); } // GCC 241 _Float128x { KEYWORD_RETURN(FLOAT128); } // GCC 242 __float128 { KEYWORD_RETURN(FLOAT128); } // GCC 243 float128 { KEYWORD_RETURN(FLOAT128); } // GCC 249 __float80 { KEYWORD_RETURN(uuFLOAT80); } // GCC 250 float80 { KEYWORD_RETURN(uuFLOAT80); } // GCC 251 __float128 { KEYWORD_RETURN(uuFLOAT128); } // GCC 252 float128 { KEYWORD_RETURN(uuFLOAT128); } // GCC 253 _Float16 { FLOATXX(uFLOAT16); } // GCC 254 _Float32 { FLOATXX(uFLOAT32); } // GCC 255 _Float32x { FLOATXX(uFLOAT32X); } // GCC 256 _Float64 { FLOATXX(uFLOAT64); } // GCC 257 _Float64x { FLOATXX(uFLOAT64X); } // GCC 258 _Float128 { FLOATXX(uFLOAT128); } // GCC 259 _Float128x { FLOATXX(uFLOAT128); } // GCC 244 260 for { KEYWORD_RETURN(FOR); } 245 261 forall { KEYWORD_RETURN(FORALL); } // CFA 246 262 fortran { KEYWORD_RETURN(FORTRAN); } 247 263 ftype { KEYWORD_RETURN(FTYPE); } // CFA 264 generator { KEYWORD_RETURN(GENERATOR); } // CFA 248 265 _Generic { KEYWORD_RETURN(GENERIC); } // C11 249 266 goto { KEYWORD_RETURN(GOTO); } … … 256 273 __inline__ { KEYWORD_RETURN(INLINE); } // GCC 257 274 int { KEYWORD_RETURN(INT); } 275 int128 { KEYWORD_RETURN(INT128); } // CFA 258 276 __int128 { KEYWORD_RETURN(INT128); } // GCC 259 int128{ KEYWORD_RETURN(INT128); } // GCC277 __int128_t { KEYWORD_RETURN(INT128); } // GCC 260 278 __label__ { KEYWORD_RETURN(LABEL); } // GCC 261 279 long { KEYWORD_RETURN(LONG); } … … 272 290 __restrict__ { KEYWORD_RETURN(RESTRICT); } // GCC 273 291 return { KEYWORD_RETURN(RETURN); } 292 /* resume { KEYWORD_RETURN(RESUME); } // CFA */ 274 293 short { KEYWORD_RETURN(SHORT); } 275 294 signed { KEYWORD_RETURN(SIGNED); } … … 280 299 _Static_assert { KEYWORD_RETURN(STATICASSERT); } // C11 281 300 struct { KEYWORD_RETURN(STRUCT); } 301 /* suspend { KEYWORD_RETURN(SUSPEND); } // CFA */ 282 302 switch { KEYWORD_RETURN(SWITCH); } 283 303 thread { KEYWORD_RETURN(THREAD); } // C11 … … 294 314 __typeof__ { KEYWORD_RETURN(TYPEOF); } // GCC 295 315 union { KEYWORD_RETURN(UNION); } 316 __uint128_t { KEYWORD_RETURN(UINT128); } // GCC 296 317 unsigned { KEYWORD_RETURN(UNSIGNED); } 297 318 __builtin_va_list { KEYWORD_RETURN(VALIST); } // GCC … … 313 334 IDENTIFIER_RETURN(); 314 335 } 315 {attr_identifier} { ATTRIBUTE_RETURN(); }316 336 317 337 /* numeric constants */ … … 404 424 405 425 "@=" { NAMEDOP_RETURN(ATassign); } // CFA 426 "~=" { NAMEDOP_RETURN(ErangeUpEq); } // CFA 427 "-~" { NAMEDOP_RETURN(ErangeDown); } // CFA 428 "-~=" { NAMEDOP_RETURN(ErangeDownEq); } // CFA 406 429 407 430 /* CFA, operator identifier */ … … 457 480 void yyerror( const char * errmsg ) { 458 481 SemanticErrorThrow = true; 459 c out<< (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1482 cerr << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1 460 483 << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl; 461 484 } -
src/Parser/module.mk
r7951100 rb067d9b 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Peter A. Buhr … … 31 31 Parser/parserutility.cc 32 32 33 MAINTAINERCLEANFILES += Parser/parser.output 33 SRCDEMANGLE += \ 34 Parser/LinkageSpec.cc 35 36 37 MOSTLYCLEANFILES += Parser/lex.cc Parser/parser.cc Parser/parser.hh Parser/parser.output -
src/Parser/parser.yy
r7951100 rb067d9b 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 7 10:07:12 201813 // Update Count : 352712 // Last Modified On : Sun Aug 4 21:48:23 2019 13 // Update Count : 4364 14 14 // 15 15 … … 99 99 // distribute declaration_specifier across all declared variables, e.g., static, const, __attribute__. 100 100 DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( specifier ); 101 //cur->addType( specifier ); 102 for ( cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 101 for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) { 103 102 cl->cloneBaseType( cur ); 104 103 } // for 105 104 declList->addType( cl ); 106 // delete cl;107 105 return declList; 108 106 } // distAttr … … 114 112 } // for 115 113 } // distExt 114 115 void distInl( DeclarationNode * declaration ) { 116 // distribute EXTENSION across all declarations 117 for ( DeclarationNode *iter = declaration; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 118 iter->set_inLine( true ); 119 } // for 120 } // distInl 121 122 void distQual( DeclarationNode * declaration, DeclarationNode * qualifiers ) { 123 // distribute qualifiers across all non-variable declarations in a distribution statemement 124 for ( DeclarationNode * iter = declaration; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 125 // SKULLDUGGERY: Distributions are parsed inside out, so qualifiers are added to declarations inside out. Since 126 // addQualifiers appends to the back of the list, the forall clauses are in the wrong order (right to left). To 127 // get the qualifiers in the correct order and still use addQualifiers (otherwise, 90% of addQualifiers has to 128 // be copied to add to front), the appropriate forall pointers are interchanged before calling addQualifiers. 129 DeclarationNode * clone = qualifiers->clone(); 130 if ( qualifiers->type ) { // forall clause ? (handles SC) 131 if ( iter->type->kind == TypeData::Aggregate ) { // struct/union ? 132 swap( clone->type->forall, iter->type->aggregate.params ); 133 iter->addQualifiers( clone ); 134 } else if ( iter->type->kind == TypeData::AggregateInst && iter->type->aggInst.aggregate->aggregate.body ) { // struct/union ? 135 // Create temporary node to hold aggregate, call addQualifiers as above, then put nodes back together. 136 DeclarationNode newnode; 137 swap( newnode.type, iter->type->aggInst.aggregate ); 138 swap( clone->type->forall, newnode.type->aggregate.params ); 139 newnode.addQualifiers( clone ); 140 swap( newnode.type, iter->type->aggInst.aggregate ); 141 } else if ( iter->type->kind == TypeData::Function ) { // routines ? 142 swap( clone->type->forall, iter->type->forall ); 143 iter->addQualifiers( clone ); 144 } // if 145 } else { // just SC qualifiers 146 iter->addQualifiers( clone ); 147 } // if 148 } // for 149 delete qualifiers; 150 } // distQual 116 151 117 152 // There is an ambiguity for inline generic-routine return-types and generic routines. … … 136 171 } // build_postfix_name 137 172 138 bool forall = false, xxx = false; // aggregate have one or more forall qualifiers ? 173 DeclarationNode * fieldDecl( DeclarationNode * typeSpec, DeclarationNode * fieldList ) { 174 if ( ! fieldList ) { // field declarator ? 175 if ( ! ( typeSpec->type && (typeSpec->type->kind == TypeData::Aggregate || typeSpec->type->kind == TypeData::Enum) ) ) { 176 stringstream ss; 177 typeSpec->type->print( ss ); 178 SemanticWarning( yylloc, Warning::SuperfluousDecl, ss.str().c_str() ); 179 return nullptr; 180 } // if 181 fieldList = DeclarationNode::newName( nullptr ); 182 } // if 183 return distAttr( typeSpec, fieldList ); // mark all fields in list 184 } // fieldDecl 185 186 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 187 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); 188 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 189 type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); 190 } // if 191 return new ForCtrl( 192 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 193 // NULL comp/inc => leave blank 194 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0, 195 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 196 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0 ); 197 } // forCtrl 198 199 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 200 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) { 201 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 202 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) { 203 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) { 204 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 205 } else { 206 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr; 207 } // if 208 } else { 209 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr; 210 } // if 211 } // forCtrl 212 213 214 bool forall = false, yyy = false; // aggregate have one or more forall qualifiers ? 139 215 140 216 // https://www.gnu.org/software/bison/manual/bison.html#Location-Type … … 156 232 157 233 // Types declaration for productions 158 %union 159 { 234 %union { 160 235 Token tok; 161 236 ParseNode * pn; … … 167 242 WaitForStmt * wfs; 168 243 Expression * constant; 169 IfCtl * ifctl; 170 ForCtl * fctl; 244 IfCtrl * ifctl; 245 ForCtrl * fctl; 246 enum OperKinds compop; 171 247 LabelNode * label; 172 248 InitializerNode * in; … … 189 265 %token RESTRICT // C99 190 266 %token ATOMIC // C11 191 %token FORALL MUTEX VIRTUAL // CFA267 %token FORALL MUTEX VIRTUAL COERCE // CFA 192 268 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 193 269 %token BOOL COMPLEX IMAGINARY // C99 194 %token INT128 FLOAT80 FLOAT128 // GCC 270 %token INT128 UINT128 uuFLOAT80 uuFLOAT128 // GCC 271 %token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC 195 272 %token ZERO_T ONE_T // CFA 196 273 %token VALIST // GCC 197 %token TYPEOF LABEL // GCC 274 %token AUTO_TYPE // GCC 275 %token TYPEOF BASETYPEOF LABEL // GCC 198 276 %token ENUM STRUCT UNION 199 277 %token EXCEPTION // CFA 200 %token COROUTINE MONITOR THREAD// CFA278 %token GENERATOR COROUTINE MONITOR THREAD // CFA 201 279 %token OTYPE FTYPE DTYPE TTYPE TRAIT // CFA 202 280 %token SIZEOF OFFSETOF 281 // %token SUSPEND RESUME // CFA 203 282 %token ATTRIBUTE EXTENSION // GCC 204 283 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN … … 210 289 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDEFname TYPEGENname 211 290 %token<tok> TIMEOUT WOR 212 %token<tok> ATTR_IDENTIFIER ATTR_TYPEDEFname ATTR_TYPEGENname213 291 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral 214 292 %token<tok> DIRECTIVE … … 231 309 %token ANDassign ERassign ORassign // &= ^= |= 232 310 311 %token ErangeUpEq ErangeDown ErangeDownEq // ~= -~ -~= 233 312 %token ATassign // @= 234 313 235 %type<tok> identifier no_attr_identifier236 %type<tok> identifier_or_type_name no_attr_identifier_or_type_nameattr_name314 %type<tok> identifier 315 %type<tok> identifier_or_type_name attr_name 237 316 %type<tok> quasi_keyword 238 317 %type<constant> string_literal … … 252 331 %type<en> argument_expression_list argument_expression default_initialize_opt 253 332 %type<ifctl> if_control_expression 254 %type<fctl> for_control_expression 333 %type<fctl> for_control_expression for_control_expression_list 334 %type<compop> inclexcl 255 335 %type<en> subrange 256 336 %type<decl> asm_name_opt 257 %type<en> asm_operands_opt asm_operands_listasm_operand337 %type<en> asm_operands_opt asm_operands_list asm_operand 258 338 %type<label> label_list 259 339 %type<en> asm_clobbers_list_opt 260 340 %type<flag> asm_volatile_opt 261 341 %type<en> handler_predicate_opt 262 %type<genexpr> generic_association generic_assoc_list342 %type<genexpr> generic_association generic_assoc_list 263 343 264 344 // statements … … 304 384 %type<en> enumerator_value_opt 305 385 306 %type<decl> exception_declaration external_definition external_definition_list external_definition_list_no_pop_push external_definition_list_opt 307 308 %type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list 309 %type<en> field field_list field_name fraction_constants_opt 386 %type<decl> external_definition external_definition_list external_definition_list_opt 387 388 %type<decl> exception_declaration 389 390 %type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract 391 %type<en> field field_name_list field_name fraction_constants_opt 310 392 311 393 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 320 402 %type<decl> cfa_array_parameter_1st_dimension 321 403 322 %type<decl> cfa_trait_declaring_list cfa_declaration cfa_field_declaring_list 404 %type<decl> cfa_trait_declaring_list cfa_declaration cfa_field_declaring_list cfa_field_abstract_list 323 405 %type<decl> cfa_function_declaration cfa_function_return cfa_function_specifier 324 406 … … 355 437 %type<decl> type_parameter type_parameter_list type_initializer_opt 356 438 357 %type<en> type_ list439 %type<en> type_parameters_opt type_list 358 440 359 441 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 390 472 // Foo ( *fp )( int ); 391 473 // `---' matches start of TYPEGENname '(' 392 // Must be:474 // must be: 393 475 // Foo( int ) ( *fp )( int ); 476 // The same problem occurs here: 477 // forall( otype T ) struct Foo { T v; } ( *fp )( int ); 478 // must be: 479 // forall( otype T ) struct Foo { T v; } ( int ) ( *fp )( int ); 394 480 395 481 // Order of these lines matters (low-to-high precedence). 396 482 %precedence TYPEGENname 483 %precedence '}' 397 484 %precedence '(' 485 486 // %precedence RESUME 487 // %precedence '{' 488 // %precedence ')' 398 489 399 490 %locations // support location tracking for error messages … … 457 548 identifier: 458 549 IDENTIFIER 459 | ATTR_IDENTIFIER // CFA460 550 | quasi_keyword 461 ; 462 463 no_attr_identifier: 464 IDENTIFIER 465 | quasi_keyword 551 | '@' // CFA 552 { Token tok = { new string( DeclarationNode::anonymous.newName() ), yylval.tok.loc }; $$ = tok; } 466 553 ; 467 554 … … 502 589 | '(' comma_expression ')' '`' IDENTIFIER // CFA, postfix call 503 590 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); } 504 | type_name '.' no_attr_identifier // CFA, nested type 505 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 506 { $$ = nullptr; } 507 | type_name '.' '[' field_list ']' // CFA, nested type / tuple field selector 508 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 509 { $$ = nullptr; } 591 | type_name '.' identifier // CFA, nested type 592 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 593 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 594 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 510 595 | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11 511 596 { … … 514 599 $$ = new ExpressionNode( $5 ); 515 600 } 601 // | RESUME '(' comma_expression ')' 602 // { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; } 603 // | RESUME '(' comma_expression ')' compound_statement 604 // { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; } 516 605 ; 517 606 … … 553 642 | postfix_expression '(' argument_expression_list ')' 554 643 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 555 | postfix_expression '.' no_attr_identifier644 | postfix_expression '.' identifier 556 645 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 557 646 | postfix_expression '.' INTEGERconstant // CFA, tuple index … … 559 648 | postfix_expression FLOATING_FRACTIONconstant // CFA, tuple index 560 649 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); } 561 | postfix_expression '.' '[' field_ list ']'// CFA, tuple field selector650 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 562 651 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 563 | postfix_expression ARROW no_attr_identifier 564 { 565 $$ = new ExpressionNode( build_pfieldSel( $1, *$3 == "0" || *$3 == "1" ? build_constantInteger( *$3 ) : build_varref( $3 ) ) ); 566 } 652 | postfix_expression ARROW identifier 653 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 567 654 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 568 655 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); } 569 | postfix_expression ARROW '[' field_ list ']'// CFA, tuple field selector656 | postfix_expression ARROW '[' field_name_list ']' // CFA, tuple field selector 570 657 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 571 658 | postfix_expression ICR … … 586 673 587 674 argument_expression_list: 588 argument_expression 675 // empty 676 { $$ = nullptr; } 677 | argument_expression 589 678 | argument_expression_list ',' argument_expression 590 679 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 592 681 593 682 argument_expression: 594 // empty 595 { $$ = nullptr; } 596 // | '@' // use default argument 597 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } 683 '@' // CFA, default parameter 684 { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; } 685 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } 598 686 | assignment_expression 599 687 ; 600 688 601 field_ list:// CFA, tuple field selector689 field_name_list: // CFA, tuple field selector 602 690 field 603 | field_ list ',' field{ $$ = (ExpressionNode *)$1->set_last( $3 ); }691 | field_name_list ',' field { $$ = (ExpressionNode *)$1->set_last( $3 ); } 604 692 ; 605 693 … … 608 696 | FLOATING_DECIMALconstant field 609 697 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); } 610 | FLOATING_DECIMALconstant '[' field_ list ']'698 | FLOATING_DECIMALconstant '[' field_name_list ']' 611 699 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); } 612 700 | field_name '.' field 613 701 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 614 | field_name '.' '[' field_ list ']'702 | field_name '.' '[' field_name_list ']' 615 703 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 616 704 | field_name ARROW field 617 705 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 618 | field_name ARROW '[' field_ list ']'706 | field_name ARROW '[' field_name_list ']' 619 707 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 620 708 ; … … 625 713 | FLOATINGconstant fraction_constants_opt 626 714 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); } 627 | no_attr_identifier fraction_constants_opt715 | identifier fraction_constants_opt 628 716 { 629 717 $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); … … 683 771 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 684 772 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); } 685 | OFFSETOF '(' type_no_function ',' no_attr_identifier ')'773 | OFFSETOF '(' type_no_function ',' identifier ')' 686 774 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); } 687 | ATTR_IDENTIFIER688 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuild< Expression >( (ExpressionNode *)nullptr ) ) ); }689 | ATTR_IDENTIFIER '(' argument_expression ')'690 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuild< Expression >( $3 ) ) ); }691 | ATTR_IDENTIFIER '(' type ')'692 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuildType( $3 ) ) ); }693 775 ; 694 776 … … 711 793 | '(' type_no_function ')' cast_expression 712 794 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 795 // keyword cast cannot be grouped because of reduction in aggregate_key 796 | '(' GENERATOR '&' ')' cast_expression // CFA 797 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); } 713 798 | '(' COROUTINE '&' ')' cast_expression // CFA 714 799 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); } … … 722 807 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 723 808 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); } 809 | '(' RETURN type_no_function ')' cast_expression // CFA 810 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; } 811 | '(' COERCE type_no_function ')' cast_expression // CFA 812 { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; } 813 | '(' qualifier_cast_list ')' cast_expression // CFA 814 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 724 815 // | '(' type_no_function ')' tuple 725 816 // { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 817 ; 818 819 qualifier_cast_list: 820 cast_modifier type_qualifier_name 821 | cast_modifier MUTEX 822 | qualifier_cast_list cast_modifier type_qualifier_name 823 | qualifier_cast_list cast_modifier MUTEX 824 ; 825 826 cast_modifier: 827 '-' 828 | '+' 726 829 ; 727 830 … … 904 1007 905 1008 labeled_statement: 906 // labels cannot be identifiers 0 or 1 or ATTR_IDENTIFIER1009 // labels cannot be identifiers 0 or 1 907 1010 identifier_or_type_name ':' attribute_list_opt statement 908 { 909 $$ = $4->add_label( $1, $3 ); 910 } 1011 { $$ = $4->add_label( $1, $3 ); } 911 1012 ; 912 1013 … … 924 1025 statement_decl 925 1026 | statement_decl_list statement_decl 926 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; }}1027 { assert( $1 ); $1->set_last( $2 ); $$ = $1; } 927 1028 ; 928 1029 … … 931 1032 { $$ = new StatementNode( $1 ); } 932 1033 | EXTENSION declaration // GCC 933 { 934 distExt( $2 ); 935 $$ = new StatementNode( $2 ); 936 } 1034 { distExt( $2 ); $$ = new StatementNode( $2 ); } 937 1035 | function_definition 938 1036 { $$ = new StatementNode( $1 ); } 939 1037 | EXTENSION function_definition // GCC 940 { 941 distExt( $2 ); 942 $$ = new StatementNode( $2 ); 943 } 1038 { distExt( $2 ); $$ = new StatementNode( $2 ); } 944 1039 | statement 945 1040 ; … … 948 1043 statement 949 1044 | statement_list_nodecl statement 950 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; }}1045 { assert( $1 ); $1->set_last( $2 ); $$ = $1; } 951 1046 ; 952 1047 … … 992 1087 if_control_expression: 993 1088 comma_expression 994 { $$ = new IfCt l( nullptr, $1 ); }1089 { $$ = new IfCtrl( nullptr, $1 ); } 995 1090 | c_declaration // no semi-colon 996 { $$ = new IfCt l( $1, nullptr ); }1091 { $$ = new IfCtrl( $1, nullptr ); } 997 1092 | cfa_declaration // no semi-colon 998 { $$ = new IfCt l( $1, nullptr ); }1093 { $$ = new IfCtrl( $1, nullptr ); } 999 1094 | declaration comma_expression // semi-colon separated 1000 { $$ = new IfCt l( $1, $2 ); }1095 { $$ = new IfCtrl( $1, $2 ); } 1001 1096 ; 1002 1097 … … 1054 1149 WHILE '(' push if_control_expression ')' statement pop 1055 1150 { $$ = new StatementNode( build_while( $4, $6 ) ); } 1151 | WHILE '(' ')' statement // CFA => while ( 1 ) 1152 { $$ = new StatementNode( build_while( new IfCtrl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), $4 ) ); } 1056 1153 | DO statement WHILE '(' comma_expression ')' ';' 1057 1154 { $$ = new StatementNode( build_do_while( $5, $2 ) ); } 1058 | FOR '(' push for_control_expression ')' statement pop 1155 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1156 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), $2 ) ); } 1157 | FOR '(' push for_control_expression_list ')' statement pop 1059 1158 { $$ = new StatementNode( build_for( $4, $6 ) ); } 1159 | FOR '(' ')' statement // CFA => for ( ;; ) 1160 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), $4 ) ); } 1161 ; 1162 1163 for_control_expression_list: 1164 for_control_expression 1165 | for_control_expression_list ':' for_control_expression 1166 // ForCtrl + ForCtrl: 1167 // init + init => multiple declaration statements that are hoisted 1168 // condition + condition => (expression) && (expression) 1169 // change + change => (expression), (expression) 1170 { 1171 $1->init->set_last( $3->init ); 1172 if ( $1->condition ) { 1173 if ( $3->condition ) { 1174 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) ); 1175 } // if 1176 } else $1->condition = $3->condition; 1177 if ( $1->change ) { 1178 if ( $3->change ) { 1179 $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) ); 1180 } // if 1181 } else $1->change = $3->change; 1182 $$ = $1; 1183 } 1060 1184 ; 1061 1185 1062 1186 for_control_expression: 1063 comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt 1064 { $$ = new ForCtl( $1, $3, $5 ); } 1065 | declaration comma_expression_opt ';' comma_expression_opt // C99 1066 { $$ = new ForCtl( $1, $2, $4 ); } 1187 ';' comma_expression_opt ';' comma_expression_opt 1188 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); } 1189 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1190 { $$ = new ForCtrl( $1, $3, $5 ); } 1191 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1192 { $$ = new ForCtrl( $1, $2, $4 ); } 1193 1194 | comma_expression // CFA 1195 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1196 OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1197 | comma_expression inclexcl comma_expression // CFA 1198 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1199 | comma_expression inclexcl comma_expression '~' comma_expression // CFA 1200 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); } 1201 | comma_expression ';' comma_expression // CFA 1202 { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1203 OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1204 | comma_expression ';' comma_expression inclexcl comma_expression // CFA 1205 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1206 | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA 1207 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1208 1209 // There is a S/R conflicit if ~ and -~ are factored out. 1210 | comma_expression ';' comma_expression '~' '@' // CFA 1211 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1212 | comma_expression ';' comma_expression ErangeDown '@' // CFA 1213 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1214 | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA 1215 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); } 1216 | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA 1217 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); } 1218 | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA 1219 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); } 1220 ; 1221 1222 inclexcl: 1223 '~' 1224 { $$ = OperKinds::LThan; } 1225 | ErangeUpEq 1226 { $$ = OperKinds::LEThan; } 1227 | ErangeDown 1228 { $$ = OperKinds::GThan; } 1229 | ErangeDownEq 1230 { $$ = OperKinds::GEThan; } 1067 1231 ; 1068 1232 … … 1097 1261 | RETURN comma_expression_opt ';' 1098 1262 { $$ = new StatementNode( build_return( $2 ) ); } 1099 | RETURN '{' initializer_list_opt comma_opt '}' 1263 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1100 1264 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1265 // | SUSPEND ';' 1266 // { SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; } 1267 // | SUSPEND compound_statement ';' 1268 // { SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; } 1101 1269 | THROW assignment_expression_opt ';' // handles rethrow 1102 1270 { $$ = new StatementNode( build_throw( $2 ) ); } … … 1136 1304 1137 1305 waitfor: 1138 WAITFOR '(' identifier ')' 1139 { 1140 $$ = new ExpressionNode( new NameExpr( *$3 ) ); 1141 delete $3; 1142 } 1143 | WAITFOR '(' identifier ',' argument_expression_list ')' 1144 { 1145 $$ = new ExpressionNode( new NameExpr( *$3 ) ); 1146 $$->set_last( $5 ); 1147 delete $3; 1148 } 1306 WAITFOR '(' cast_expression ')' 1307 { $$ = $3; } 1308 | WAITFOR '(' cast_expression ',' argument_expression_list ')' 1309 { $$ = (ExpressionNode *)$3->set_last( $5 ); } 1149 1310 ; 1150 1311 … … 1163 1324 { $$ = build_waitfor_timeout( nullptr, $3, $1 ); } 1164 1325 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1326 | when_clause_opt timeout statement WOR ELSE statement 1327 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1165 1328 | when_clause_opt timeout statement WOR when_clause ELSE statement 1166 1329 { $$ = build_waitfor_timeout( $2, $3, $1, $7, $5 ); } … … 1184 1347 1185 1348 handler_clause: 1186 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop1349 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1187 1350 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1188 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop1351 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1189 1352 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); } 1190 1353 ; … … 1212 1375 | type_specifier_nobody variable_abstract_declarator 1213 1376 { $$ = $2->addType( $1 ); } 1214 | cfa_abstract_declarator_tuple no_attr_identifier// CFA1377 | cfa_abstract_declarator_tuple identifier // CFA 1215 1378 { $$ = $1->addName( $2 ); } 1216 1379 | cfa_abstract_declarator_tuple // CFA … … 1276 1439 1277 1440 label_list: 1278 no_attr_identifier1441 identifier 1279 1442 { 1280 1443 $$ = new LabelNode(); $$->labels.push_back( *$1 ); 1281 1444 delete $1; // allocated by lexer 1282 1445 } 1283 | label_list ',' no_attr_identifier1446 | label_list ',' identifier 1284 1447 { 1285 1448 $$ = $1; $1->labels.push_back( *$3 ); … … 1326 1489 1327 1490 local_label_list: // GCC, local label 1328 no_attr_identifier_or_type_name1329 | local_label_list ',' no_attr_identifier_or_type_name1491 identifier_or_type_name 1492 | local_label_list ',' identifier_or_type_name 1330 1493 ; 1331 1494 … … 1449 1612 $$ = $2->addTypedef(); 1450 1613 } 1451 | cfa_typedef_declaration pop ',' push no_attr_identifier1614 | cfa_typedef_declaration pop ',' push identifier 1452 1615 { 1453 1616 typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "3" ); … … 1489 1652 typedef_expression: 1490 1653 // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression 1491 TYPEDEF no_attr_identifier '=' assignment_expression1654 TYPEDEF identifier '=' assignment_expression 1492 1655 { 1493 1656 // $$ = DeclarationNode::newName( 0 ); // unimplemented 1494 1657 SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr; 1495 1658 } 1496 | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression1659 | typedef_expression pop ',' push identifier '=' assignment_expression 1497 1660 { 1498 1661 // $$ = DeclarationNode::newName( 0 ); // unimplemented … … 1663 1826 | INT128 1664 1827 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 ); } 1828 | UINT128 1829 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ); } 1665 1830 | FLOAT 1666 1831 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); } 1667 | FLOAT801668 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float80 ); }1669 | FLOAT1281670 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float128 ); }1671 1832 | DOUBLE 1672 1833 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); } 1834 | uuFLOAT80 1835 { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat80 ); } 1836 | uuFLOAT128 1837 { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat128 ); } 1838 | uFLOAT16 1839 { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat16 ); } 1840 | uFLOAT32 1841 { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32 ); } 1842 | uFLOAT32X 1843 { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32x ); } 1844 | uFLOAT64 1845 { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64 ); } 1846 | uFLOAT64X 1847 { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64x ); } 1848 | uFLOAT128 1849 { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat128 ); } 1673 1850 | COMPLEX // C99 1674 1851 { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); } … … 1685 1862 | VALIST // GCC, __builtin_va_list 1686 1863 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); } 1864 | AUTO_TYPE 1865 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::AutoType ); } 1687 1866 ; 1688 1867 … … 1718 1897 1719 1898 indirect_type: 1720 TYPEOF '(' type ')' // GCC: typeof( x) y;1899 TYPEOF '(' type ')' // GCC: typeof( x ) y; 1721 1900 { $$ = $3; } 1722 | TYPEOF '(' comma_expression ')' // GCC: typeof( a+b) y;1901 | TYPEOF '(' comma_expression ')' // GCC: typeof( a+b ) y; 1723 1902 { $$ = DeclarationNode::newTypeof( $3 ); } 1724 | ATTR_TYPEGENname '(' type ')' // CFA: e.g., @type(x) y;1725 { $$ = DeclarationNode::new Attr( $1, $3); }1726 | ATTR_TYPEGENname '(' comma_expression ')' // CFA: e.g., @type(a+b) y;1727 { $$ = DeclarationNode::new Attr( $1, $3); }1903 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 1904 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 1905 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 1906 { $$ = DeclarationNode::newTypeof( $3, true ); } 1728 1907 | ZERO_T // CFA 1729 1908 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); } … … 1749 1928 { $$ = $3->addQualifiers( $1 ); } 1750 1929 | sue_type_specifier type_qualifier 1751 { $$ = $1->addQualifiers( $2 ); } 1930 { 1931 if ( $2->type != nullptr && $2->type->forall ) forall = true; // remember generic type 1932 $$ = $1->addQualifiers( $2 ); 1933 } 1752 1934 ; 1753 1935 … … 1792 1974 { $$ = DeclarationNode::newFromTypedef( $1 ); } 1793 1975 | '.' TYPEDEFname 1794 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }1976 { $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), DeclarationNode::newFromTypedef( $2 ) ); } 1795 1977 | type_name '.' TYPEDEFname 1796 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }1978 { $$ = DeclarationNode::newQualifiedType( $1, DeclarationNode::newFromTypedef( $3 ) ); } 1797 1979 | typegen_name 1798 1980 | '.' typegen_name 1799 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }1981 { $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), $2 ); } 1800 1982 | type_name '.' typegen_name 1801 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }1983 { $$ = DeclarationNode::newQualifiedType( $1, $3 ); } 1802 1984 ; 1803 1985 … … 1821 2003 ; 1822 2004 2005 fred: 2006 // empty 2007 { yyy = false; } 2008 ; 2009 1823 2010 aggregate_type: // struct, union 1824 aggregate_key attribute_list_opt '{' field_declaration_list_opt '}' 1825 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); } 1826 | aggregate_key attribute_list_opt no_attr_identifier 1827 { 1828 typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); // create typedef 1829 //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update 2011 aggregate_key attribute_list_opt 2012 { forall = false; } // reset 2013 '{' field_declaration_list_opt '}' type_parameters_opt 2014 { $$ = DeclarationNode::newAggregate( $1, nullptr, $7, $5, true )->addQualifiers( $2 ); } 2015 | aggregate_key attribute_list_opt identifier fred 2016 { 2017 typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef 1830 2018 forall = false; // reset 1831 2019 } 1832 '{' field_declaration_list_opt '}' 1833 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }1834 | aggregate_key attribute_list_opt type_name 1835 { 1836 typedefTable.makeTypedef( *$3->type->symbolic.name, forall ? TYPEGENname : TYPEDEFname ); // create typedef1837 //if ( forall ) typedefTable.changeKind( *$3->type->symbolic.name, TYPEGENname ); // possibly update2020 '{' field_declaration_list_opt '}' type_parameters_opt 2021 { $$ = DeclarationNode::newAggregate( $1, $3, $9, $7, true )->addQualifiers( $2 ); } 2022 | aggregate_key attribute_list_opt type_name fred 2023 { 2024 // for type_name can be a qualified type name S.T, in which case only the last name in the chain needs a typedef (other names in the chain should already have one) 2025 typedefTable.makeTypedef( *$3->type->leafName(), forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef 1838 2026 forall = false; // reset 1839 2027 } 1840 '{' field_declaration_list_opt '}' 1841 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $6, true )->addQualifiers( $2 ); } 1842 | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA 1843 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); } 2028 '{' field_declaration_list_opt '}' type_parameters_opt 2029 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $9, $7, true )->addQualifiers( $2 ); } 1844 2030 | aggregate_type_nobody 1845 2031 ; 1846 2032 2033 type_parameters_opt: 2034 // empty 2035 { $$ = nullptr; } %prec '}' 2036 | '(' type_list ')' 2037 { $$ = $2; } 2038 ; 2039 1847 2040 aggregate_type_nobody: // struct, union - {...} 1848 aggregate_key attribute_list_opt no_attr_identifier 1849 { 1850 typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); 1851 //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update 2041 aggregate_key attribute_list_opt identifier fred 2042 { 2043 typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); 1852 2044 forall = false; // reset 1853 2045 $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 ); 1854 2046 } 1855 | aggregate_key attribute_list_opt type_name 1856 { 2047 | aggregate_key attribute_list_opt type_name fred 2048 { 2049 forall = false; // reset 1857 2050 // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is 1858 2051 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and … … 1867 2060 aggregate_key: 1868 2061 STRUCT 1869 { $$ = DeclarationNode::Struct; }2062 { yyy = true; $$ = DeclarationNode::Struct; } 1870 2063 | UNION 1871 { $$ = DeclarationNode::Union; }2064 { yyy = true; $$ = DeclarationNode::Union; } 1872 2065 | EXCEPTION 1873 { $$ = DeclarationNode::Exception; } 2066 { yyy = true; $$ = DeclarationNode::Exception; } 2067 | GENERATOR 2068 { yyy = true; $$ = DeclarationNode::Coroutine; } 1874 2069 | COROUTINE 1875 { $$ = DeclarationNode::Coroutine; }2070 { yyy = true; $$ = DeclarationNode::Coroutine; } 1876 2071 | MONITOR 1877 { $$ = DeclarationNode::Monitor; }2072 { yyy = true; $$ = DeclarationNode::Monitor; } 1878 2073 | THREAD 1879 { $$ = DeclarationNode::Thread; }2074 { yyy = true; $$ = DeclarationNode::Thread; } 1880 2075 ; 1881 2076 … … 1888 2083 1889 2084 field_declaration: 1890 type_specifier field_declaring_list ';' 1891 { $$ = distAttr( $1, $2 ); } 1892 | EXTENSION type_specifier field_declaring_list ';' // GCC 1893 { distExt( $3 ); $$ = distAttr( $2, $3 ); } // mark all fields in list 2085 type_specifier field_declaring_list_opt ';' 2086 { $$ = fieldDecl( $1, $2 ); } 2087 | EXTENSION type_specifier field_declaring_list_opt ';' // GCC 2088 { $$ = fieldDecl( $2, $3 ); distExt( $$ ); } 2089 | INLINE type_specifier field_abstract_list_opt ';' // CFA 2090 { 2091 if ( ! $3 ) { // field declarator ? 2092 $3 = DeclarationNode::newName( nullptr ); 2093 } // if 2094 $3->inLine = true; 2095 $$ = distAttr( $2, $3 ); // mark all fields in list 2096 distInl( $3 ); 2097 } 1894 2098 | typedef_declaration ';' // CFA 1895 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }1896 2099 | cfa_field_declaring_list ';' // CFA, new style field declaration 1897 2100 | EXTENSION cfa_field_declaring_list ';' // GCC 1898 2101 { distExt( $2 ); $$ = $2; } // mark all fields in list 2102 | INLINE cfa_field_abstract_list ';' // CFA, new style field declaration 2103 { $$ = $2; } // mark all fields in list 1899 2104 | cfa_typedef_declaration ';' // CFA 1900 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }1901 2105 | static_assert // C11 1902 2106 ; 1903 2107 1904 cfa_field_declaring_list: // CFA, new style field declaration 1905 cfa_abstract_declarator_tuple // CFA, no field name 1906 | cfa_abstract_declarator_tuple no_attr_identifier_or_type_name 1907 { $$ = $1->addName( $2 ); } 1908 | cfa_field_declaring_list ',' no_attr_identifier_or_type_name 1909 { $$ = $1->appendList( $1->cloneType( $3 ) ); } 1910 | cfa_field_declaring_list ',' // CFA, no field name 1911 { $$ = $1->appendList( $1->cloneType( 0 ) ); } 1912 ; 1913 1914 field_declaring_list: 1915 field_declarator_opt 1916 | field_declaring_list ',' attribute_list_opt field_declarator_opt 2108 field_declaring_list_opt: 2109 // empty 2110 { $$ = nullptr; } 2111 | field_declarator 2112 | field_declaring_list_opt ',' attribute_list_opt field_declarator 1917 2113 { $$ = $1->appendList( $4->addQualifiers( $3 ) ); } 1918 2114 ; 1919 2115 1920 field_declarator_opt: 1921 // empty 1922 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name 1923 // '@' 1924 // { $$ = DeclarationNode::newName( new string( DeclarationNode::anonymous.newName() ) ); } // CFA, no field name 1925 | bit_subrange_size // no field name 2116 field_declarator: 2117 bit_subrange_size // C special case, no field name 1926 2118 { $$ = DeclarationNode::newBitfield( $1 ); } 1927 2119 | variable_declarator bit_subrange_size_opt 1928 // A semantic check is required to ensure bit_subrange only appears on base type int.2120 // A semantic check is required to ensure bit_subrange only appears on integral types. 1929 2121 { $$ = $1->addBitfield( $2 ); } 1930 2122 | variable_type_redeclarator bit_subrange_size_opt 1931 // A semantic check is required to ensure bit_subrange only appears on base type int.2123 // A semantic check is required to ensure bit_subrange only appears on integral types. 1932 2124 { $$ = $1->addBitfield( $2 ); } 1933 | variable_abstract_declarator // CFA, no field name 2125 ; 2126 2127 field_abstract_list_opt: 2128 // empty 2129 { $$ = nullptr; } 2130 | field_abstract 2131 | field_abstract_list_opt ',' attribute_list_opt field_abstract 2132 { $$ = $1->appendList( $4->addQualifiers( $3 ) ); } 2133 ; 2134 2135 field_abstract: 2136 // no bit fields 2137 variable_abstract_declarator 2138 ; 2139 2140 cfa_field_declaring_list: // CFA, new style field declaration 2141 // bit-fields are handled by C declarations 2142 cfa_abstract_declarator_tuple identifier_or_type_name 2143 { $$ = $1->addName( $2 ); } 2144 | cfa_field_declaring_list ',' identifier_or_type_name 2145 { $$ = $1->appendList( $1->cloneType( $3 ) ); } 2146 ; 2147 2148 cfa_field_abstract_list: // CFA, new style field declaration 2149 // bit-fields are handled by C declarations 2150 cfa_abstract_declarator_tuple 2151 | cfa_field_abstract_list ',' 2152 { $$ = $1->appendList( $1->cloneType( 0 ) ); } 1934 2153 ; 1935 2154 … … 1941 2160 1942 2161 bit_subrange_size: 1943 ':' constant_expression2162 ':' assignment_expression 1944 2163 { $$ = $2; } 1945 2164 ; … … 1947 2166 enum_type: // enum 1948 2167 ENUM attribute_list_opt '{' enumerator_list comma_opt '}' 1949 { $$ = DeclarationNode::newEnum( n ew string( DeclarationNode::anonymous.newName() ), $4, true )->addQualifiers( $2 ); }1950 | ENUM attribute_list_opt no_attr_identifier2168 { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); } 2169 | ENUM attribute_list_opt identifier 1951 2170 { typedefTable.makeTypedef( *$3 ); } 1952 2171 '{' enumerator_list comma_opt '}' … … 1959 2178 1960 2179 enum_type_nobody: // enum - {...} 1961 ENUM attribute_list_opt no_attr_identifier2180 ENUM attribute_list_opt identifier 1962 2181 { 1963 2182 typedefTable.makeTypedef( *$3 ); … … 1972 2191 1973 2192 enumerator_list: 1974 no_attr_identifier_or_type_name enumerator_value_opt2193 identifier_or_type_name enumerator_value_opt 1975 2194 { $$ = DeclarationNode::newEnumConstant( $1, $2 ); } 1976 | enumerator_list ',' no_attr_identifier_or_type_name enumerator_value_opt2195 | enumerator_list ',' identifier_or_type_name enumerator_value_opt 1977 2196 { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); } 1978 2197 ; … … 2082 2301 2083 2302 identifier_list: // K&R-style parameter list => no types 2084 no_attr_identifier2303 identifier 2085 2304 { $$ = DeclarationNode::newName( $1 ); } 2086 | identifier_list ',' no_attr_identifier2305 | identifier_list ',' identifier 2087 2306 { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); } 2088 2307 ; … … 2090 2309 identifier_or_type_name: 2091 2310 identifier 2092 | TYPEDEFname2093 | TYPEGENname2094 ;2095 2096 no_attr_identifier_or_type_name:2097 no_attr_identifier2098 2311 | TYPEDEFname 2099 2312 | TYPEGENname … … 2150 2363 designation: 2151 2364 designator_list ':' // C99, CFA uses ":" instead of "=" 2152 | no_attr_identifier ':'// GCC, field name2365 | identifier ':' // GCC, field name 2153 2366 { $$ = new ExpressionNode( build_varref( $1 ) ); } 2154 2367 ; … … 2162 2375 2163 2376 designator: 2164 '.' no_attr_identifier// C99, field name2377 '.' identifier // C99, field name 2165 2378 { $$ = new ExpressionNode( build_varref( $2 ) ); } 2166 2379 | '[' push assignment_expression pop ']' // C99, single array element … … 2171 2384 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2172 2385 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $3 ), maybeMoveBuild< Expression >( $5 ) ) ); } 2173 | '.' '[' push field_ list pop ']'// CFA, tuple field selector2386 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2174 2387 { $$ = $4; } 2175 2388 ; … … 2207 2420 2208 2421 type_parameter: // CFA 2209 type_class no_attr_identifier_or_type_name2422 type_class identifier_or_type_name 2210 2423 { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); } 2211 2424 type_initializer_opt assertion_list_opt … … 2240 2453 2241 2454 assertion: // CFA 2242 '|' no_attr_identifier_or_type_name '(' type_list ')'2455 '|' identifier_or_type_name '(' type_list ')' 2243 2456 { $$ = DeclarationNode::newTraitUse( $2, $4 ); } 2244 2457 | '|' '{' push trait_declaration_list pop '}' … … 2252 2465 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 2253 2466 | assignment_expression 2467 { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $1->build()) ); $$ = nullptr; } 2254 2468 | type_list ',' type 2255 2469 { $$ = (ExpressionNode *)( $1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) ) ); } 2256 2470 | type_list ',' assignment_expression 2257 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } 2471 { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $3->build()) ); $$ = nullptr; } 2472 // { $$ = (ExpressionNode *)( $1->set_last( $3 )); } 2258 2473 ; 2259 2474 … … 2275 2490 2276 2491 type_declarator_name: // CFA 2277 no_attr_identifier_or_type_name2492 identifier_or_type_name 2278 2493 { 2279 2494 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 2280 2495 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 2281 2496 } 2282 | no_attr_identifier_or_type_name '(' type_parameter_list ')'2497 | identifier_or_type_name '(' type_parameter_list ')' 2283 2498 { 2284 2499 typedefTable.addToEnclosingScope( *$1, TYPEGENname, "11" ); … … 2288 2503 2289 2504 trait_specifier: // CFA 2290 TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' '}'2505 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 2291 2506 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); } 2292 | TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'2507 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 2293 2508 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 2294 2509 ; … … 2322 2537 2323 2538 translation_unit: 2324 // empty 2325 {} // empty input file 2539 // empty, input file 2326 2540 | external_definition_list 2327 2541 { parseTree = parseTree ? parseTree->appendList( $1 ) : $1; } … … 2331 2545 push external_definition pop 2332 2546 { $$ = $2; } 2333 | external_definition_list 2334 { forall = xxx; } 2335 push external_definition pop 2336 { $$ = $1 ? $1->appendList( $4 ) : $4; } 2337 ; 2338 2339 // SKULLDUGGERY: Declarations in extern "X" and distribution need to be added to the current lexical scope. 2340 // However, external_definition_list creates a new scope around each external_definition, but the pop loses all the 2341 // types in the extern "X" and distribution at the end of the block. This version of external_definition_list does 2342 2343 // not do push/pop for declarations at the level of the extern "X" and distribution block. Any recursive uses of 2344 // external_definition_list within the extern "X" and distribution block correctly pushes/pops for that scope level. 2345 external_definition_list_no_pop_push: 2346 external_definition 2347 | external_definition_list_no_pop_push 2348 { forall = xxx; } 2349 external_definition 2547 | external_definition_list push external_definition pop 2350 2548 { $$ = $1 ? $1->appendList( $3 ) : $3; } 2351 2549 ; … … 2354 2552 // empty 2355 2553 { $$ = nullptr; } 2356 | external_definition_list_no_pop_push 2554 | external_definition_list 2555 ; 2556 2557 up: 2558 { typedefTable.up( forall ); forall = false; } 2559 ; 2560 2561 down: 2562 { typedefTable.down(); } 2357 2563 ; 2358 2564 … … 2374 2580 linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 ); 2375 2581 } 2376 '{' external_definition_list_opt'}'2582 '{' up external_definition_list_opt down '}' 2377 2583 { 2378 2584 linkage = linkageStack.top(); 2379 2585 linkageStack.pop(); 2586 $$ = $6; 2587 } 2588 | type_qualifier_list 2589 { 2590 if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 2591 if ( $1->type->forall ) forall = true; // remember generic type 2592 } 2593 '{' up external_definition_list_opt down '}' // CFA, namespace 2594 { 2595 distQual( $5, $1 ); 2596 forall = false; 2380 2597 $$ = $5; 2381 2598 } 2382 | type_qualifier_list2383 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type2384 '{' external_definition_list_opt '}' // CFA, namespace2385 {2386 for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {2387 if ( isMangled( iter->linkage ) ) { // ignore extern "C"2388 iter->addQualifiers( $1->clone() );2389 } // if2390 } // for2391 xxx = false;2392 delete $1;2393 $$ = $4;2394 }2395 2599 | declaration_qualifier_list 2396 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type 2397 '{' external_definition_list_opt '}' // CFA, namespace 2398 { 2399 for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2400 if ( isMangled( iter->linkage ) ) { // ignore extern "C" 2401 iter->addQualifiers( $1->clone() ); 2402 } // if 2403 } // for 2404 xxx = false; 2405 delete $1; 2406 $$ = $4; 2600 { 2601 if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 2602 if ( $1->type && $1->type->forall ) forall = true; // remember generic type 2603 } 2604 '{' up external_definition_list_opt down '}' // CFA, namespace 2605 { 2606 distQual( $5, $1 ); 2607 forall = false; 2608 $$ = $5; 2407 2609 } 2408 2610 | declaration_qualifier_list type_qualifier_list 2409 2611 { 2410 // forall must be in the type_qualifier_list 2411 if ( $2->type->forall ) xxx = forall = true; // remember generic type 2412 } 2413 '{' external_definition_list_opt '}' // CFA, namespace 2414 { 2415 for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2416 if ( isMangled( iter->linkage ) && isMangled( $2->linkage ) ) { // ignore extern "C" 2417 iter->addQualifiers( $1->clone() ); 2418 iter->addQualifiers( $2->clone() ); 2419 } // if 2420 } // for 2421 xxx = false; 2422 delete $1; 2423 delete $2; 2424 $$ = $5; 2612 if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 2613 if ( ($1->type && $1->type->forall) || $2->type->forall ) forall = true; // remember generic type 2614 } 2615 '{' up external_definition_list_opt down '}' // CFA, namespace 2616 { 2617 distQual( $6, $1->addQualifiers( $2 ) ); 2618 forall = false; 2619 $$ = $6; 2425 2620 } 2426 2621 ; … … 2732 2927 typedef 2733 2928 // hide type name in enclosing scope by variable name 2734 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" ); } 2929 { 2930 // if ( ! typedefTable.existsCurr( *$1->name ) ) { 2931 typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" ); 2932 // } else { 2933 // SemanticError( yylloc, string("'") + *$1->name + "' redeclared as different kind of symbol." ); $$ = nullptr; 2934 // } // if 2935 } 2735 2936 | '(' paren_type ')' 2736 2937 { $$ = $2; } … … 2743 2944 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 2744 2945 | '(' type_ptr ')' attribute_list_opt 2745 { $$ = $2->addQualifiers( $4 ); } 2946 { $$ = $2->addQualifiers( $4 ); } // redundant parenthesis 2746 2947 ; 2747 2948 -
src/ResolvExpr/AdjustExprType.cc
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AdjustExprType .cc --7 // AdjustExprType_old.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 14 14 // 15 15 16 #include "AST/Node.hpp" 17 #include "AST/Pass.hpp" 18 #include "AST/SymbolTable.hpp" 19 #include "AST/Type.hpp" 20 #include "AST/TypeEnvironment.hpp" 16 21 #include "Common/PassVisitor.h" 17 22 #include "SymTab/Indexer.h" // for Indexer … … 22 27 23 28 namespace ResolvExpr { 24 class AdjustExprType : public WithShortCircuiting { 25 public: 26 AdjustExprType( const TypeEnvironment & env, const SymTab::Indexer & indexer ); 29 30 namespace { 31 class AdjustExprType_old final : public WithShortCircuiting { 32 public: 33 AdjustExprType_old( const TypeEnvironment & env, const SymTab::Indexer & indexer ); 27 34 void premutate( VoidType * ) { visit_children = false; } 28 35 void premutate( BasicType * ) { visit_children = false; } … … 40 47 void premutate( OneType * ) { visit_children = false; } 41 48 42 Type * postmutate( ArrayType * arrayType );43 Type * postmutate( FunctionType * functionType );44 Type * postmutate( TypeInstType * aggregateUseType );49 Type * postmutate( ArrayType * arrayType ); 50 Type * postmutate( FunctionType * functionType ); 51 Type * postmutate( TypeInstType * aggregateUseType ); 45 52 46 private:53 private: 47 54 const TypeEnvironment & env; 48 55 const SymTab::Indexer & indexer; 49 56 }; 50 57 51 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 52 PassVisitor<AdjustExprType> adjuster( env, indexer ); 53 Type *newType = type->acceptMutator( adjuster ); 54 type = newType; 55 } 56 57 void adjustExprType( Type *& type ) { 58 TypeEnvironment env; 59 SymTab::Indexer indexer; 60 adjustExprType( type, env, indexer ); 61 } 62 63 AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer ) 58 AdjustExprType_old::AdjustExprType_old( const TypeEnvironment &env, const SymTab::Indexer &indexer ) 64 59 : env( env ), indexer( indexer ) { 65 60 } 66 61 67 Type * AdjustExprType ::postmutate( ArrayType * arrayType ) {68 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };62 Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) { 63 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base }; 69 64 arrayType->base = nullptr; 70 65 delete arrayType; … … 72 67 } 73 68 74 Type * AdjustExprType ::postmutate( FunctionType * functionType ) {69 Type * AdjustExprType_old::postmutate( FunctionType * functionType ) { 75 70 return new PointerType{ Type::Qualifiers(), functionType }; 76 71 } 77 72 78 Type * AdjustExprType ::postmutate( TypeInstType * typeInst ) {79 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {73 Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) { 74 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 80 75 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 81 76 return new PointerType{ Type::Qualifiers(), typeInst }; 82 77 } 83 } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {84 if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {78 } else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) { 79 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) { 85 80 if ( tyDecl->get_kind() == TypeDecl::Ftype ) { 86 81 return new PointerType{ Type::Qualifiers(), typeInst }; … … 90 85 return typeInst; 91 86 } 87 } // anonymous namespace 88 89 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 90 PassVisitor<AdjustExprType_old> adjuster( env, indexer ); 91 Type * newType = type->acceptMutator( adjuster ); 92 type = newType; 93 } 94 95 void adjustExprType( Type *& type ) { 96 TypeEnvironment env; 97 SymTab::Indexer indexer; 98 adjustExprType( type, env, indexer ); 99 } 100 101 namespace { 102 struct AdjustExprType_new final : public ast::WithShortCircuiting { 103 const ast::TypeEnvironment & tenv; 104 const ast::SymbolTable & symtab; 105 106 AdjustExprType_new( const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 107 : tenv( e ), symtab( syms ) {} 108 109 void premutate( const ast::VoidType * ) { visit_children = false; } 110 void premutate( const ast::BasicType * ) { visit_children = false; } 111 void premutate( const ast::PointerType * ) { visit_children = false; } 112 void premutate( const ast::ArrayType * ) { visit_children = false; } 113 void premutate( const ast::FunctionType * ) { visit_children = false; } 114 void premutate( const ast::StructInstType * ) { visit_children = false; } 115 void premutate( const ast::UnionInstType * ) { visit_children = false; } 116 void premutate( const ast::EnumInstType * ) { visit_children = false; } 117 void premutate( const ast::TraitInstType * ) { visit_children = false; } 118 void premutate( const ast::TypeInstType * ) { visit_children = false; } 119 void premutate( const ast::TupleType * ) { visit_children = false; } 120 void premutate( const ast::VarArgsType * ) { visit_children = false; } 121 void premutate( const ast::ZeroType * ) { visit_children = false; } 122 void premutate( const ast::OneType * ) { visit_children = false; } 123 124 const ast::Type * postmutate( const ast::ArrayType * at ) { 125 return new ast::PointerType{ at->base, at->qualifiers }; 126 } 127 128 const ast::Type * postmutate( const ast::FunctionType * ft ) { 129 return new ast::PointerType{ ft }; 130 } 131 132 const ast::Type * postmutate( const ast::TypeInstType * inst ) { 133 // replace known function-type-variables with pointer-to-function 134 if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) { 135 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) { 136 return new ast::PointerType{ inst }; 137 } 138 } else if ( const ast::NamedTypeDecl * ntDecl = symtab.lookupType( inst->name ) ) { 139 if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( ntDecl ) ) { 140 if ( tyDecl->kind == ast::TypeVar::Ftype ) { 141 return new ast::PointerType{ inst }; 142 } 143 } 144 } 145 return inst; 146 } 147 }; 148 } // anonymous namespace 149 150 const ast::Type * adjustExprType( 151 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 152 ) { 153 ast::Pass<AdjustExprType_new> adjuster{ env, symtab }; 154 return type->accept( adjuster ); 155 } 156 92 157 } // namespace ResolvExpr 93 158 -
src/ResolvExpr/Alternative.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:44:23 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat May 16 23:54:23 201513 // Update Count : 211 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Thu Oct 11 10:55:00 2018 13 // Update Count : 3 14 14 // 15 15 … … 20 20 #include <utility> // for move 21 21 22 #include "Common/utility.h" // for maybeClone22 #include "Common/utility.h" // for cloneAll 23 23 #include "ResolvExpr/Cost.h" // for Cost, Cost::zero, operator<< 24 24 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment … … 27 27 28 28 namespace ResolvExpr { 29 Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ) {} 29 Alternative::Alternative() 30 : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ), env(), openVars(), need() {} 30 31 31 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost ) 32 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ) {} 32 Alternative::Alternative( Expression *expr, const TypeEnvironment &env ) 33 : cost( Cost::zero ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars(), need() {} 34 35 Alternative::Alternative( const Alternative &o, Expression *expr, const Cost &cost ) 36 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( o.env ), openVars( o.openVars ), 37 need() { cloneAll( o.need, need ); } 33 38 34 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost ) 35 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {} 39 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 40 const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost ) 41 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ), 42 need() { cloneAll( oneed, need ); } 36 43 37 Alternative::Alternative( const Alternative &other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ), env( other.env ) { 38 } 44 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 45 const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost, 46 const Cost &cvtCost ) 47 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ), 48 need() { cloneAll( oneed, need ); } 49 50 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 51 const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost) 52 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ), 53 need() { cloneAll( oneed, need ); } 54 55 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 56 const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost, 57 const Cost& cvtCost ) 58 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ), 59 need() { cloneAll( oneed, need ); } 60 61 Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 62 AssertionSet &&needSet, const Cost &cost ) 63 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( std::move(env) ), 64 openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {} 65 66 Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 67 AssertionSet &&needSet, const Cost &cost, const Cost &cvtCost ) 68 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( std::move(env) ), 69 openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {} 70 71 Alternative::Alternative( const Alternative &other ) 72 : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ), 73 env( other.env ), openVars( other.openVars ), need() { cloneAll( other.need, need ); } 39 74 40 75 Alternative &Alternative::operator=( const Alternative &other ) { … … 45 80 expr = maybeClone( other.expr ); 46 81 env = other.env; 82 openVars = other.openVars; 83 need.clear(); 84 cloneAll( other.need, need ); 47 85 return *this; 48 86 } 49 87 50 Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( std::move( other.env ) ) { 51 other.expr = nullptr; 52 } 88 Alternative::Alternative( Alternative && other ) 89 : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), 90 env( std::move( other.env ) ), openVars( std::move( other.openVars ) ), 91 need( std::move( other.need ) ) { other.expr = nullptr; } 53 92 54 93 Alternative & Alternative::operator=( Alternative && other ) { … … 59 98 expr = other.expr; 60 99 env = std::move( other.env ); 100 openVars = std::move( other.openVars ); 101 need = std::move( other.need ); 61 102 other.expr = nullptr; 62 103 return *this; … … 64 105 65 106 Alternative::~Alternative() { 107 for ( AssertionItem& n : need ) { delete n.decl; } 66 108 delete expr; 67 109 } … … 78 120 os << "Null expression!" << std::endl; 79 121 } // if 80 os << indent << "Environment: ";122 os << indent << "Environment:"; 81 123 env.print( os, indent+1 ); 82 124 os << std::endl; 83 }84 85 void splice( AltList& dst, AltList& src ) {86 dst.reserve( dst.size() + src.size() );87 for ( Alternative& alt : src ) {88 dst.push_back( std::move(alt) );89 }90 src.clear();91 }92 93 void spliceBegin( AltList& dst, AltList& src ) {94 splice( src, dst );95 dst.swap( src );96 125 } 97 126 -
src/ResolvExpr/Alternative.h
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:45:43 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:36:36 201713 // Update Count : 311 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Thu Oct 11 10:55:00 2018 13 // Update Count : 4 14 14 // 15 15 … … 20 20 21 21 #include "Cost.h" // for Cost 22 #include "TypeEnvironment.h" // for TypeEnvironment 22 #include "TypeEnvironment.h" // for TypeEnvironment, AssertionSetValue 23 24 #include "Common/utility.h" // for maybeClone 23 25 24 26 class Expression; 25 27 26 28 namespace ResolvExpr { 29 /// One assertion to resolve 30 struct AssertionItem { 31 const DeclarationWithType* decl; 32 AssertionSetValue info; 33 34 AssertionItem() = default; 35 AssertionItem( const DeclarationWithType* decl, const AssertionSetValue& info ) 36 : decl(decl), info(info) {} 37 AssertionItem( const AssertionSet::value_type& e ) : decl(e.first), info(e.second) {} 38 operator AssertionSet::value_type () const { return { decl, info }; } 39 40 // to support cloneAll 41 AssertionItem clone() const { return { maybeClone(decl), info }; } 42 }; 43 /// A list of unresolved assertions 44 using AssertionList = std::vector<AssertionItem>; 45 46 /// Clones an assertion list into an assertion set 47 static inline void cloneAll( const AssertionList& src, AssertionSet& dst ) { 48 for ( const AssertionItem& item : src ) { 49 dst.emplace( maybeClone(item.decl), item.info ); 50 } 51 } 52 53 /// Clones an assertion set into an assertion list 54 static inline void cloneAll( const AssertionSet& src, AssertionList& dst ) { 55 dst.reserve( dst.size() + src.size() ); 56 for ( const auto& entry : src ) { 57 dst.emplace_back( maybeClone(entry.first), entry.second ); 58 } 59 } 60 61 /// Clones an assertion list into an assertion list 62 static inline void cloneAll( const AssertionList& src, AssertionList& dst ) { 63 dst.reserve( dst.size() + src.size() ); 64 for ( const AssertionItem& item : src ) { 65 dst.emplace_back( maybeClone(item.decl), item.info ); 66 } 67 } 68 69 /// One option for resolution of an expression 27 70 struct Alternative { 28 71 Alternative(); 29 Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost ); 30 Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost, const Cost &cvtCost ); 72 Alternative( Expression *expr, const TypeEnvironment &env ); 73 Alternative( const Alternative &o, Expression *expr, const Cost &cost ); 74 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet& openVars, 75 const AssertionList& need, const Cost &cost ); 76 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet& openVars, 77 const AssertionList& need, const Cost &cost, const Cost &cvtCost ); 78 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars, 79 const AssertionSet &need, const Cost &cost); 80 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars, 81 const AssertionSet &need, const Cost &cost, const Cost& cvtCost ); 82 Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 83 AssertionSet &&need, const Cost &cost ); 84 Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 85 AssertionSet &&need, const Cost &cost, const Cost &cvtCost ); 31 86 Alternative( const Alternative &other ); 32 87 Alternative &operator=( const Alternative &other ); … … 44 99 } 45 100 46 Cost cost; 47 Cost cvtCost; 48 Expression *expr; 49 TypeEnvironment env; 101 /// Sorts by cost 102 bool operator< ( const Alternative& o ) const { return cost < o.cost; } 103 104 Cost cost; ///< Cost of the whole expression 105 Cost cvtCost; ///< Cost of conversions to the satisfying expression 106 Expression *expr; ///< Satisfying expression 107 TypeEnvironment env; ///< Containing type environment 108 OpenVarSet openVars; ///< Open variables for environment 109 AssertionList need; ///< Assertions which need to be resolved 50 110 }; 51 111 52 112 typedef std::vector< Alternative > AltList; 53 54 /// Moves all elements from src to the end of dst55 void splice( AltList& dst, AltList& src );56 57 /// Moves all elements from src to the beginning of dst58 void spliceBegin( AltList& dst, AltList& src );59 113 60 114 static inline std::ostream & operator<<(std::ostream & os, const ResolvExpr::Alternative & alt) { -
src/ResolvExpr/AlternativeFinder.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:52:08 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Feb 17 11:19:39 201813 // Update Count : 3 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:35:00 2019 13 // Update Count : 38 14 14 // 15 15 … … 25 25 #include <vector> // for vector 26 26 27 #include "CompilationState.h" // for resolvep 27 28 #include "Alternative.h" // for AltList, Alternative 28 29 #include "AlternativeFinder.h" 30 #include "AST/Expr.hpp" 31 #include "AST/SymbolTable.hpp" 32 #include "AST/Type.hpp" 29 33 #include "Common/SemanticError.h" // for SemanticError 30 34 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation … … 33 37 #include "InitTweak/InitTweak.h" // for getFunctionName 34 38 #include "RenameVars.h" // for RenameVars, global_renamer 39 #include "ResolveAssertions.h" // for resolveAssertions 35 40 #include "ResolveTypeof.h" // for resolveTypeof 36 41 #include "Resolver.h" // for resolveStmtExpr … … 49 54 #include "typeops.h" // for adjustExprType, polyCost, castCost 50 55 51 extern bool resolvep;52 56 #define PRINT( text ) if ( resolvep ) { text } 53 57 //#define DEBUG_COST 54 55 using std::move;56 57 /// copies any copyable type58 template<typename T>59 T copy(const T& x) { return x; }60 58 61 59 namespace ResolvExpr { … … 81 79 void postvisit( OffsetofExpr * offsetofExpr ); 82 80 void postvisit( OffsetPackExpr * offsetPackExpr ); 83 void postvisit( AttrExpr * attrExpr );84 81 void postvisit( LogicalExpr * logicalExpr ); 85 82 void postvisit( ConditionalExpr * conditionalExpr ); … … 102 99 void addAnonConversions( const Alternative & alt ); 103 100 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 104 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );101 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative &alt, const Cost &newCost, const std::string & name ); 105 102 /// Adds alternatives for member expressions where the left side has tuple type 106 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression *member );103 void addTupleMembers( TupleType *tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member ); 107 104 /// Adds alternatives for offsetof expressions, given the base type and name of the member 108 105 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); … … 112 109 /// Finds matching alternatives for a function, given a set of arguments 113 110 template<typename OutputIterator> 114 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs & args, OutputIterator out );115 /// Checks if assertion parameters match for a newalternative111 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs_old& args, OutputIterator out ); 112 /// Sets up parameter inference for an output alternative 116 113 template< typename OutputIterator > 117 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );114 void inferParameters( Alternative &newAlt, OutputIterator out ); 118 115 private: 119 116 AlternativeFinder & altFinder; … … 133 130 134 131 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) { 135 Indenter indent = { Indenter::tabsize,indentAmt };132 Indenter indent = { indentAmt }; 136 133 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 137 134 i->print( os, indent ); … … 176 173 selected[ mangleName ] = current; 177 174 } else if ( candidate->cost == mapPlace->second.candidate->cost ) { 178 PRINT( 179 std::cerr << "marking ambiguous" << std::endl; 180 ) 181 mapPlace->second.isAmbiguous = true; 175 // if one of the candidates contains a deleted identifier, can pick the other, since 176 // deleted expressions should not be ambiguous if there is another option that is at least as good 177 if ( findDeletedExpr( candidate->expr ) ) { 178 // do nothing 179 PRINT( std::cerr << "candidate is deleted" << std::endl; ) 180 } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) { 181 PRINT( std::cerr << "current is deleted" << std::endl; ) 182 selected[ mangleName ] = current; 183 } else { 184 PRINT( 185 std::cerr << "marking ambiguous" << std::endl; 186 ) 187 mapPlace->second.isAmbiguous = true; 188 } 182 189 } else { 183 190 PRINT( … … 234 241 } 235 242 236 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast) {243 void AlternativeFinder::find( Expression *expr, ResolvMode mode ) { 237 244 PassVisitor<Finder> finder( *this ); 238 245 expr->accept( finder ); 239 if ( failFast && alternatives.empty() ) {246 if ( mode.failFast && alternatives.empty() ) { 240 247 PRINT( 241 248 std::cerr << "No reasonable alternatives for expression " << expr << std::endl; … … 243 250 SemanticError( expr, "No reasonable alternatives for expression " ); 244 251 } 245 if ( prune ) { 252 if ( mode.satisfyAssns || mode.prune ) { 253 // trim candidates just to those where the assertions resolve 254 // - necessary pre-requisite to pruning 255 AltList candidates; 256 std::list<std::string> errors; 257 for ( unsigned i = 0; i < alternatives.size(); ++i ) { 258 resolveAssertions( alternatives[i], indexer, candidates, errors ); 259 } 260 // fail early if none such 261 if ( mode.failFast && candidates.empty() ) { 262 std::ostringstream stream; 263 stream << "No alternatives with satisfiable assertions for " << expr << "\n"; 264 // << "Alternatives with failing assertions are:\n"; 265 // printAlts( alternatives, stream, 1 ); 266 for ( const auto& err : errors ) { 267 stream << err; 268 } 269 SemanticError( expr->location, stream.str() ); 270 } 271 // reset alternatives 272 alternatives = std::move( candidates ); 273 } 274 if ( mode.prune ) { 246 275 auto oldsize = alternatives.size(); 247 276 PRINT( … … 251 280 AltList pruned; 252 281 pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned ) ); 253 if ( failFast && pruned.empty() ) {282 if ( mode.failFast && pruned.empty() ) { 254 283 std::ostringstream stream; 255 284 AltList winners; … … 270 299 } 271 300 // adjust types after pruning so that types substituted by pruneAlternatives are correctly adjusted 272 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i) {273 if ( adjust) {274 adjustExprType( i ->expr->get_result(), i->env, indexer );301 if ( mode.adjust ) { 302 for ( Alternative& i : alternatives ) { 303 adjustExprType( i.expr->get_result(), i.env, indexer ); 275 304 } 276 305 } … … 284 313 285 314 void AlternativeFinder::findWithAdjustment( Expression *expr ) { 286 find( expr, true);315 find( expr, ResolvMode::withAdjustment() ); 287 316 } 288 317 289 318 void AlternativeFinder::findWithoutPrune( Expression * expr ) { 290 find( expr, true, false);319 find( expr, ResolvMode::withoutPrune() ); 291 320 } 292 321 293 322 void AlternativeFinder::maybeFind( Expression * expr ) { 294 find( expr, true, true, false);323 find( expr, ResolvMode::withoutFailFast() ); 295 324 } 296 325 … … 306 335 } 307 336 308 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {309 addAggMembers( structInst, aggrExpr.get(), alt .cost+Cost::safe, alt.env, "" );310 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {311 addAggMembers( unionInst, aggrExpr.get(), alt .cost+Cost::safe, alt.env, "" );337 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 338 addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 339 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) { 340 addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 312 341 } // if 313 342 } 314 343 315 344 template< typename StructOrUnionType > 316 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {345 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) { 317 346 std::list< Declaration* > members; 318 347 aggInst->lookup( name, members ); 319 348 320 349 for ( Declaration * decl : members ) { 321 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {350 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 322 351 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 323 352 // can't construct in place and use vector::back 324 Alternative newAlt ( new MemberExpr( dwt, expr->clone() ), env, newCost );353 Alternative newAlt{ alt, new MemberExpr{ dwt, expr->clone() }, newCost }; 325 354 renameTypes( newAlt.expr ); 326 355 addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression. … … 332 361 } 333 362 334 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {363 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) { 335 364 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 336 365 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning 337 // xxx - this should be improved by memoizing the value of constant exprs 338 // during parsing and reusing that information here. 339 std::stringstream ss( constantExpr->get_constant()->get_value() ); 340 int val = 0; 366 auto val = constantExpr->intValue(); 341 367 std::string tmp; 342 if ( ss >> val && ! (ss >> tmp) ) { 343 if ( val >= 0 && (unsigned int)val < tupleType->size() ) { 344 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) ); 345 } // if 368 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 369 alternatives.push_back( Alternative{ 370 alt, new TupleIndexExpr( expr->clone(), val ), newCost } ); 346 371 } // if 347 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {348 // xxx - temporary hack until 0/1 are int constants349 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {350 std::stringstream ss( nameExpr->get_name() );351 int val;352 ss >> val;353 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );354 }355 372 } // if 356 373 } 357 374 358 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 359 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) ); 360 } 361 362 Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 375 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) { 376 alternatives.push_back( Alternative{ applicationExpr->clone(), env } ); 377 } 378 379 Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue, 380 const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 363 381 PRINT( 364 382 std::cerr << std::endl << "converting "; … … 370 388 std::cerr << std::endl; 371 389 ) 372 Cost convCost = conversionCost( actualType, formalType, indexer, env );390 Cost convCost = conversionCost( actualType, formalType, actualIsLvalue, indexer, env ); 373 391 PRINT( 374 392 std::cerr << std::endl << "cost is " << convCost << std::endl; … … 385 403 386 404 Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 387 Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env ); 405 Cost convCost = computeConversionCost( 406 actualExpr->result, formalType, actualExpr->get_lvalue(), indexer, env ); 388 407 389 408 // if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion. … … 413 432 Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 414 433 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( alt.expr ); 415 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr-> get_function()->get_result());416 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer-> get_base());434 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result ); 435 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base ); 417 436 418 437 Cost convCost = Cost::zero; 419 std::list< DeclarationWithType* >& formals = function-> get_parameters();438 std::list< DeclarationWithType* >& formals = function->parameters; 420 439 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 421 std::list< Expression* >& actuals = appExpr-> get_args();422 423 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr) {424 Type * actualType = (*actualExpr)->get_result();440 std::list< Expression* >& actuals = appExpr->args; 441 442 for ( Expression*& actualExpr : actuals ) { 443 Type * actualType = actualExpr->result; 425 444 PRINT( 426 445 std::cerr << "actual expression:" << std::endl; 427 (*actualExpr)->print( std::cerr, 8 );446 actualExpr->print( std::cerr, 8 ); 428 447 std::cerr << "--- results are" << std::endl; 429 448 actualType->print( std::cerr, 8 ); 430 449 ) 431 450 if ( formal == formals.end() ) { 432 if ( function-> get_isVarArgs()) {451 if ( function->isVarArgs ) { 433 452 convCost.incUnsafe(); 434 453 PRINT( std::cerr << "end of formals with varargs function: inc unsafe: " << convCost << std::endl; ; ) 435 454 // convert reference-typed expressions to value-typed expressions 436 referenceToRvalueConversion( *actualExpr, convCost );455 referenceToRvalueConversion( actualExpr, convCost ); 437 456 continue; 438 457 } else { … … 440 459 } 441 460 } 461 if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( actualExpr ) ) { 462 // default arguments should be free - don't include conversion cost. 463 // Unwrap them here because they are not relevant to the rest of the system. 464 actualExpr = def->expr; 465 ++formal; 466 continue; 467 } 468 // mark conversion cost to formal and also specialization cost of formal type 442 469 Type * formalType = (*formal)->get_type(); 443 convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env ); 470 convCost += computeExpressionConversionCost( actualExpr, formalType, indexer, alt.env ); 471 convCost.decSpec( specCost( formalType ) ); 444 472 ++formal; // can't be in for-loop update because of the continue 445 473 } … … 448 476 } 449 477 450 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 451 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 478 // specialization cost of return types can't be accounted for directly, it disables 479 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 480 // 481 // forall(otype OS) { 482 // void ?|?(OS&, int); // with newline 483 // OS& ?|?(OS&, int); // no newline, always chosen due to more specialization 484 // } 485 486 // mark type variable and specialization cost of forall clause 487 convCost.incVar( function->forall.size() ); 488 for ( TypeDecl* td : function->forall ) { 489 convCost.decSpec( td->assertions.size() ); 452 490 } 453 491 … … 462 500 needAssertions[ *assert ].isUsed = true; 463 501 } 464 /// needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() ); 465 } 466 } 467 468 static const int recursionLimit = /*10*/ 4; ///< Limit to depth of recursion satisfaction 469 470 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { 471 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) { 472 if ( i->second.isUsed ) { 473 indexer.addId( i->first ); 474 } 475 } 476 } 477 478 template< typename ForwardIterator, typename OutputIterator > 479 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) { 480 if ( begin == end ) { 481 if ( newNeed.empty() ) { 482 PRINT( 483 std::cerr << "all assertions satisfied, output alternative: "; 484 newAlt.print( std::cerr ); 485 std::cerr << std::endl; 486 ); 487 *out++ = newAlt; 488 return; 489 } else if ( level >= recursionLimit ) { 490 SemanticError( newAlt.expr->location, "Too many recursive assertions" ); 491 } else { 492 AssertionSet newerNeed; 493 PRINT( 494 std::cerr << "recursing with new set:" << std::endl; 495 printAssertionSet( newNeed, std::cerr, 8 ); 496 ) 497 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out ); 498 return; 499 } 500 } 501 502 ForwardIterator cur = begin++; 503 if ( ! cur->second.isUsed ) { 504 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out ); 505 return; // xxx - should this continue? previously this wasn't here, and it looks like it should be 506 } 507 DeclarationWithType *curDecl = cur->first; 508 509 PRINT( 510 std::cerr << "inferRecursive: assertion is "; 511 curDecl->print( std::cerr ); 512 std::cerr << std::endl; 513 ) 514 std::list< SymTab::Indexer::IdData > candidates; 515 decls.lookupId( curDecl->get_name(), candidates ); 516 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 517 for ( const auto & data : candidates ) { 518 DeclarationWithType * candidate = data.id; 519 PRINT( 520 std::cerr << "inferRecursive: candidate is "; 521 candidate->print( std::cerr ); 522 std::cerr << std::endl; 523 ) 524 525 AssertionSet newHave, newerNeed( newNeed ); 526 TypeEnvironment newEnv( newAlt.env ); 527 OpenVarSet newOpenVars( openVars ); 528 Type *adjType = candidate->get_type()->clone(); 529 adjustExprType( adjType, newEnv, indexer ); 530 renameTyVars( adjType ); 531 PRINT( 532 std::cerr << "unifying "; 533 curDecl->get_type()->print( std::cerr ); 534 std::cerr << " with "; 535 adjType->print( std::cerr ); 536 std::cerr << std::endl; 537 ) 538 if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) { 539 PRINT( 540 std::cerr << "success!" << std::endl; 541 ) 542 SymTab::Indexer newDecls( decls ); 543 addToIndexer( newHave, newDecls ); 544 Alternative newerAlt( newAlt ); 545 newerAlt.env = newEnv; 546 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 547 548 // everything with an empty idChain was pulled in by the current assertion. 549 // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found. 550 for ( auto & a : newerNeed ) { 551 if ( a.second.idChain.empty() ) { 552 a.second.idChain = cur->second.idChain; 553 a.second.idChain.push_back( curDecl->get_uniqueId() ); 554 } 555 } 556 557 Expression *varExpr = data.combine( newerAlt.cvtCost ); 558 delete varExpr->get_result(); 559 varExpr->set_result( adjType->clone() ); 560 PRINT( 561 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; 562 curDecl->print( std::cerr ); 563 std::cerr << " with declaration " << candidate->get_uniqueId() << " "; 564 candidate->print( std::cerr ); 565 std::cerr << std::endl; 566 ) 567 // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter). 568 InferredParams * inferParameters = &newerAlt.expr->get_inferParams(); 569 for ( UniqueId id : cur->second.idChain ) { 570 inferParameters = (*inferParameters)[ id ].inferParams.get(); 571 } 572 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 573 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 574 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out ); 575 } else { 576 delete adjType; 577 } 578 } 579 } 502 } 503 } 504 505 /// Unique identifier for matching expression resolutions to their requesting expression (located in CandidateFinder.cpp) 506 extern UniqueId globalResnSlot; 580 507 581 508 template< typename OutputIterator > 582 void AlternativeFinder::Finder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) { 583 // PRINT( 584 // std::cerr << "inferParameters: assertions needed are" << std::endl; 585 // printAll( need, std::cerr, 8 ); 586 // ) 587 SymTab::Indexer decls( indexer ); 588 // PRINT( 589 // std::cerr << "============= original indexer" << std::endl; 590 // indexer.print( std::cerr ); 591 // std::cerr << "============= new indexer" << std::endl; 592 // decls.print( std::cerr ); 593 // ) 594 addToIndexer( have, decls ); 595 AssertionSet newNeed; 596 PRINT( 597 std::cerr << "env is: " << std::endl; 598 newAlt.env.print( std::cerr, 0 ); 599 std::cerr << std::endl; 600 ) 601 602 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out ); 603 // PRINT( 604 // std::cerr << "declaration 14 is "; 605 // Declaration::declFromId 606 // *out++ = newAlt; 607 // ) 509 void AlternativeFinder::Finder::inferParameters( Alternative &newAlt, OutputIterator out ) { 510 // Set need bindings for any unbound assertions 511 UniqueId crntResnSlot = 0; // matching ID for this expression's assertions 512 for ( auto& assn : newAlt.need ) { 513 // skip already-matched assertions 514 if ( assn.info.resnSlot != 0 ) continue; 515 // assign slot for expression if needed 516 if ( crntResnSlot == 0 ) { crntResnSlot = ++globalResnSlot; } 517 // fix slot to assertion 518 assn.info.resnSlot = crntResnSlot; 519 } 520 // pair slot to expression 521 if ( crntResnSlot != 0 ) { newAlt.expr->resnSlots.push_back( crntResnSlot ); } 522 523 // add to output list, assertion resolution is deferred 524 *out++ = newAlt; 608 525 } 609 526 … … 611 528 ConstantExpr* getDefaultValue( Initializer* init ) { 612 529 if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) { 613 if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) { 614 return dynamic_cast<ConstantExpr*>( ce->get_arg() ); 530 if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) { 531 return dynamic_cast<ConstantExpr*>( ce->arg ); 532 } else { 533 return dynamic_cast<ConstantExpr*>( si->value ); 615 534 } 616 535 } … … 659 578 660 579 /// Gets the list of exploded alternatives for this pack 661 const ExplodedActual& getExpl( const ExplodedArgs & args ) const {580 const ExplodedActual& getExpl( const ExplodedArgs_old& args ) const { 662 581 return args[nextArg-1][explAlt]; 663 582 } … … 683 602 /// Instantiates an argument to match a formal, returns false if no results left 684 603 bool instantiateArgument( Type* formalType, Initializer* initializer, 685 const ExplodedArgs & args, std::vector<ArgPack>& results, std::size_t& genStart,604 const ExplodedArgs_old& args, std::vector<ArgPack>& results, std::size_t& genStart, 686 605 const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 687 606 if ( TupleType * tupleType = dynamic_cast<TupleType*>( formalType ) ) { … … 873 792 indexer ) ) { 874 793 results.emplace_back( 875 i, cnstExpr, move(env), move(need), move(have),794 i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have), 876 795 move(openVars), nextArg, nTuples ); 877 796 } … … 944 863 } 945 864 // build and validate new alternative 946 Alternative newAlt ( appExpr, result.env, cost );865 Alternative newAlt{ appExpr, result.env, result.openVars, result.need, cost }; 947 866 PRINT( 948 867 std::cerr << "instantiate function success: " << appExpr << std::endl; … … 950 869 printAssertionSet( result.need, std::cerr, 8 ); 951 870 ) 952 inferParameters( result.need, result.have, newAlt, result.openVars, out );871 inferParameters( newAlt, out ); 953 872 } 954 873 955 874 template<typename OutputIterator> 956 875 void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func, 957 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {876 FunctionType *funcType, const ExplodedArgs_old &args, OutputIterator out ) { 958 877 OpenVarSet funcOpenVars; 959 878 AssertionSet funcNeed, funcHave; … … 1065 984 funcFinder.findWithAdjustment( untypedExpr->function ); 1066 985 // if there are no function alternatives, then proceeding is a waste of time. 986 // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary. 1067 987 if ( funcFinder.alternatives.empty() ) return; 1068 988 … … 1086 1006 1087 1007 // pre-explode arguments 1088 ExplodedArgs argExpansions;1008 ExplodedArgs_old argExpansions; 1089 1009 argExpansions.reserve( argAlternatives.size() ); 1090 1010 … … 1092 1012 argExpansions.emplace_back(); 1093 1013 auto& argE = argExpansions.back(); 1094 argE.reserve( arg.alternatives.size() );1014 // argE.reserve( arg.alternatives.size() ); 1095 1015 1096 1016 for ( const Alternative& actual : arg ) { … … 1178 1098 std::cerr << "bindings are:" << std::endl; 1179 1099 withFunc.env.print( std::cerr, 8 ); 1100 std::cerr << "cost is: " << withFunc.cost << std::endl; 1180 1101 std::cerr << "cost of conversion is:" << cvtCost << std::endl; 1181 1102 ) … … 1193 1114 1194 1115 // function may return struct or union value, in which case we need to add alternatives 1195 // for implicit conversions to each of the anonymous members, must happen after findMinCost1116 // for implicit conversions to each of the anonymous members, must happen after findMinCost 1196 1117 // since anon conversions are never the cheapest expression 1197 1118 for ( const Alternative & alt : winners ) { … … 1216 1137 bool isLvalue( Expression *expr ) { 1217 1138 // xxx - recurse into tuples? 1218 return expr->result && ( expr-> result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );1139 return expr->result && ( expr->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) ); 1219 1140 } 1220 1141 … … 1225 1146 if ( isLvalue( alt.expr ) ) { 1226 1147 alternatives.push_back( 1227 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );1148 Alternative{ alt, new AddressExpr( alt.expr->clone() ), alt.cost } ); 1228 1149 } // if 1229 1150 } // for … … 1231 1152 1232 1153 void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) { 1233 alternatives.push_back( Alternative{ expr->clone(), env , Cost::zero} );1154 alternatives.push_back( Alternative{ expr->clone(), env } ); 1234 1155 } 1235 1156 … … 1267 1188 assert( toType ); 1268 1189 toType = resolveTypeof( toType, indexer ); 1190 assert(!dynamic_cast<TypeofType *>(toType)); 1269 1191 SymTab::validateType( toType, &indexer ); 1270 1192 adjustExprType( toType, env, indexer ); … … 1276 1198 AltList candidates; 1277 1199 for ( Alternative & alt : finder.alternatives ) { 1278 AssertionSet needAssertions, haveAssertions; 1279 OpenVarSet openVars; 1200 AssertionSet needAssertions( alt.need.begin(), alt.need.end() ); 1201 AssertionSet haveAssertions; 1202 OpenVarSet openVars{ alt.openVars }; 1280 1203 1281 1204 alt.env.extractOpenVars( openVars ); … … 1292 1215 unify( castExpr->result, alt.expr->result, alt.env, needAssertions, 1293 1216 haveAssertions, openVars, indexer ); 1294 Cost thisCost = castCost( alt.expr->result, castExpr->result, indexer,1295 alt.env );1217 Cost thisCost = castCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(), 1218 indexer, alt.env ); 1296 1219 PRINT( 1297 1220 std::cerr << "working on cast with result: " << castExpr->result << std::endl; … … 1305 1228 // count one safe conversion for each value that is thrown away 1306 1229 thisCost.incSafe( discardedValues ); 1307 Alternative newAlt ( restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), alt.env,1308 alt.cost, thisCost );1309 inferParameters( needAssertions, haveAssertions, newAlt, openVars,1310 back_inserter( candidates ) );1230 Alternative newAlt{ 1231 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1232 alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost }; 1233 inferParameters( newAlt, back_inserter( candidates ) ); 1311 1234 } // if 1312 1235 } // for … … 1321 1244 1322 1245 void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) { 1323 assertf( castExpr->get_result(), "Implic atevirtual cast targets not yet supported." );1246 assertf( castExpr->get_result(), "Implicit virtual cast targets not yet supported." ); 1324 1247 AlternativeFinder finder( indexer, env ); 1325 1248 // don't prune here, since it's guaranteed all alternatives will have the same type 1326 1249 finder.findWithoutPrune( castExpr->get_arg() ); 1327 1250 for ( Alternative & alt : finder.alternatives ) { 1328 alternatives.push_back( Alternative (1329 new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),1330 alt. env, alt.cost ));1251 alternatives.push_back( Alternative{ 1252 alt, new VirtualCastExpr{ alt.expr->clone(), castExpr->get_result()->clone() }, 1253 alt.cost } ); 1331 1254 } 1332 1255 } … … 1335 1258 /// Gets name from untyped member expression (member must be NameExpr) 1336 1259 const std::string& get_member_name( UntypedMemberExpr *memberExpr ) { 1260 if ( dynamic_cast< ConstantExpr * >( memberExpr->get_member() ) ) { 1261 SemanticError( memberExpr, "Indexed access to struct fields unsupported: " ); 1262 } // if 1337 1263 NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() ); 1338 1264 assert( nameExpr ); … … 1353 1279 // find member of the given type 1354 1280 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 1355 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1281 addAggMembers( structInst, aggrExpr, *agg, cost, get_member_name(memberExpr) ); 1356 1282 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 1357 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1283 addAggMembers( unionInst, aggrExpr, *agg, cost, get_member_name(memberExpr) ); 1358 1284 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) { 1359 addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );1285 addTupleMembers( tupleType, aggrExpr, *agg, cost, memberExpr->get_member() ); 1360 1286 } // if 1361 1287 } // for … … 1363 1289 1364 1290 void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) { 1365 alternatives.push_back( Alternative ( memberExpr->clone(), env, Cost::zero ));1291 alternatives.push_back( Alternative{ memberExpr->clone(), env } ); 1366 1292 } 1367 1293 … … 1376 1302 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 1377 1303 // can't construct in place and use vector::back 1378 Alternative newAlt ( newExpr, env, Cost::zero, cost );1304 Alternative newAlt{ newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost }; 1379 1305 PRINT( 1380 1306 std::cerr << "decl is "; … … 1394 1320 // not sufficient to clone here, because variable's type may have changed 1395 1321 // since the VariableExpr was originally created. 1396 alternatives.push_back( Alternative ( new VariableExpr( variableExpr->var ), env, Cost::zero ));1322 alternatives.push_back( Alternative{ new VariableExpr{ variableExpr->var }, env } ); 1397 1323 } 1398 1324 1399 1325 void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) { 1400 alternatives.push_back( Alternative ( constantExpr->clone(), env, Cost::zero ));1326 alternatives.push_back( Alternative{ constantExpr->clone(), env } ); 1401 1327 } 1402 1328 … … 1404 1330 if ( sizeofExpr->get_isType() ) { 1405 1331 Type * newType = sizeofExpr->get_type()->clone(); 1406 alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) ); 1332 alternatives.push_back( Alternative{ 1333 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1407 1334 } else { 1408 1335 // find all alternatives for the argument to sizeof … … 1418 1345 Alternative &choice = winners.front(); 1419 1346 referenceToRvalueConversion( choice.expr, choice.cost ); 1420 alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1347 alternatives.push_back( Alternative{ 1348 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1421 1349 } // if 1422 1350 } … … 1425 1353 if ( alignofExpr->get_isType() ) { 1426 1354 Type * newType = alignofExpr->get_type()->clone(); 1427 alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) ); 1355 alternatives.push_back( Alternative{ 1356 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1428 1357 } else { 1429 1358 // find all alternatives for the argument to sizeof … … 1439 1368 Alternative &choice = winners.front(); 1440 1369 referenceToRvalueConversion( choice.expr, choice.cost ); 1441 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1370 alternatives.push_back( Alternative{ 1371 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1442 1372 } // if 1443 1373 } … … 1449 1379 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1450 1380 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1451 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) ); 1381 alternatives.push_back( Alternative{ 1382 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1452 1383 renameTypes( alternatives.back().expr ); 1453 1384 } else { … … 1468 1399 1469 1400 void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) { 1470 alternatives.push_back( Alternative ( offsetofExpr->clone(), env, Cost::zero ));1401 alternatives.push_back( Alternative{ offsetofExpr->clone(), env } ); 1471 1402 } 1472 1403 1473 1404 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1474 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) ); 1475 } 1476 1477 namespace { 1478 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1479 // assume no polymorphism 1480 // assume no implicit conversions 1481 assert( function->get_parameters().size() == 1 ); 1482 PRINT( 1483 std::cerr << "resolvAttr: funcDecl is "; 1484 data.id->print( std::cerr ); 1485 std::cerr << " argType is "; 1486 argType->print( std::cerr ); 1487 std::cerr << std::endl; 1488 ) 1489 const SymTab::Indexer & indexer = finder.get_indexer(); 1490 AltList & alternatives = finder.get_alternatives(); 1491 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1492 Cost cost = Cost::zero; 1493 Expression * newExpr = data.combine( cost ); 1494 alternatives.push_back( Alternative( new AttrExpr( newExpr, argType->clone() ), env, Cost::zero, cost ) ); 1495 for ( DeclarationWithType * retVal : function->returnVals ) { 1496 alternatives.back().expr->result = retVal->get_type()->clone(); 1497 } // for 1498 } // if 1499 } 1500 } 1501 1502 void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) { 1503 // assume no 'pointer-to-attribute' 1504 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1505 assert( nameExpr ); 1506 std::list< SymTab::Indexer::IdData > attrList; 1507 indexer.lookupId( nameExpr->get_name(), attrList ); 1508 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1509 for ( auto & data : attrList ) { 1510 DeclarationWithType * id = data.id; 1511 // check if the type is function 1512 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) { 1513 // assume exactly one parameter 1514 if ( function->get_parameters().size() == 1 ) { 1515 if ( attrExpr->get_isType() ) { 1516 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); 1517 } else { 1518 AlternativeFinder finder( indexer, env ); 1519 finder.find( attrExpr->get_expr() ); 1520 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1521 if ( choice->expr->get_result()->size() == 1 ) { 1522 resolveAttr(data, function, choice->expr->get_result(), choice->env, altFinder ); 1523 } // fi 1524 } // for 1525 } // if 1526 } // if 1527 } // if 1528 } // for 1529 } else { 1530 for ( auto & data : attrList ) { 1531 Cost cost = Cost::zero; 1532 Expression * newExpr = data.combine( cost ); 1533 alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) ); 1534 renameTypes( alternatives.back().expr ); 1535 } // for 1536 } // if 1537 } 1538 1539 void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) { 1405 alternatives.push_back( Alternative{ offsetPackExpr->clone(), env } ); 1406 } 1407 1408 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) { 1540 1409 AlternativeFinder firstFinder( indexer, env ); 1541 1410 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1546 1415 for ( const Alternative & first : firstFinder.alternatives ) { 1547 1416 for ( const Alternative & second : secondFinder.alternatives ) { 1548 TypeEnvironment compositeEnv; 1549 compositeEnv.simpleCombine( first.env ); 1417 TypeEnvironment compositeEnv{ first.env }; 1550 1418 compositeEnv.simpleCombine( second.env ); 1551 1552 LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() ); 1553 alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) ); 1419 OpenVarSet openVars{ first.openVars }; 1420 mergeOpenVars( openVars, second.openVars ); 1421 AssertionSet need; 1422 cloneAll( first.need, need ); 1423 cloneAll( second.need, need ); 1424 1425 LogicalExpr *newExpr = new LogicalExpr{ 1426 first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() }; 1427 alternatives.push_back( Alternative{ 1428 newExpr, std::move(compositeEnv), std::move(openVars), 1429 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1554 1430 } 1555 1431 } … … 1572 1448 for ( const Alternative & second : secondFinder.alternatives ) { 1573 1449 for ( const Alternative & third : thirdFinder.alternatives ) { 1574 TypeEnvironment compositeEnv; 1575 compositeEnv.simpleCombine( first.env ); 1450 TypeEnvironment compositeEnv{ first.env }; 1576 1451 compositeEnv.simpleCombine( second.env ); 1577 1452 compositeEnv.simpleCombine( third.env ); 1453 OpenVarSet openVars{ first.openVars }; 1454 mergeOpenVars( openVars, second.openVars ); 1455 mergeOpenVars( openVars, third.openVars ); 1456 AssertionSet need; 1457 cloneAll( first.need, need ); 1458 cloneAll( second.need, need ); 1459 cloneAll( third.need, need ); 1460 AssertionSet have; 1578 1461 1579 1462 // unify true and false types, then infer parameters to produce new alternatives 1580 OpenVarSet openVars;1581 AssertionSet needAssertions, haveAssertions;1582 Alternative newAlt( 0, compositeEnv, first.cost + second.cost + third.cost );1583 1463 Type* commonType = nullptr; 1584 if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1585 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() ); 1464 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1465 need, have, openVars, indexer, commonType ) ) { 1466 ConditionalExpr *newExpr = new ConditionalExpr{ 1467 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1586 1468 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1587 1469 // convert both options to the conditional result type 1588 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env ); 1589 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env ); 1590 newAlt.expr = newExpr; 1591 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); 1470 Cost cost = first.cost + second.cost + third.cost; 1471 cost += computeExpressionConversionCost( 1472 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1473 cost += computeExpressionConversionCost( 1474 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1475 // output alternative 1476 Alternative newAlt{ 1477 newExpr, std::move(compositeEnv), std::move(openVars), 1478 AssertionList( need.begin(), need.end() ), cost }; 1479 inferParameters( newAlt, back_inserter( alternatives ) ); 1592 1480 } // if 1593 1481 } // for … … 1602 1490 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1603 1491 for ( const Alternative & alt : secondFinder.alternatives ) { 1604 alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) ); 1492 alternatives.push_back( Alternative{ 1493 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1605 1494 } // for 1606 1495 delete newFirstArg; … … 1617 1506 for ( const Alternative & first : firstFinder.alternatives ) { 1618 1507 for ( const Alternative & second : secondFinder.alternatives ) { 1619 TypeEnvironment compositeEnv; 1620 compositeEnv.simpleCombine( first.env ); 1508 TypeEnvironment compositeEnv{ first.env }; 1621 1509 compositeEnv.simpleCombine( second.env ); 1622 OpenVarSet openVars; 1623 AssertionSet needAssertions, haveAssertions; 1624 Alternative newAlt( 0, compositeEnv, first.cost + second.cost ); 1510 OpenVarSet openVars{ first.openVars }; 1511 mergeOpenVars( openVars, second.openVars ); 1512 AssertionSet need; 1513 cloneAll( first.need, need ); 1514 cloneAll( second.need, need ); 1515 AssertionSet have; 1516 1625 1517 Type* commonType = nullptr; 1626 if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1627 RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() ); 1518 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1519 openVars, indexer, commonType ) ) { 1520 RangeExpr * newExpr = 1521 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1628 1522 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1629 newAlt.expr = newExpr; 1630 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); 1523 Alternative newAlt{ 1524 newExpr, std::move(compositeEnv), std::move(openVars), 1525 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1526 inferParameters( newAlt, back_inserter( alternatives ) ); 1631 1527 } // if 1632 1528 } // for … … 1646 1542 1647 1543 TypeEnvironment compositeEnv; 1648 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 1649 alternatives.push_back( 1650 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } ); 1544 OpenVarSet openVars; 1545 AssertionSet need; 1546 for ( const Alternative& alt : alts ) { 1547 compositeEnv.simpleCombine( alt.env ); 1548 mergeOpenVars( openVars, alt.openVars ); 1549 cloneAll( alt.need, need ); 1550 } 1551 1552 alternatives.push_back( Alternative{ 1553 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1554 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1651 1555 } // for 1652 1556 } 1653 1557 1654 1558 void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) { 1655 alternatives.push_back( Alternative ( tupleExpr->clone(), env, Cost::zero ));1559 alternatives.push_back( Alternative{ tupleExpr->clone(), env } ); 1656 1560 } 1657 1561 1658 1562 void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1659 alternatives.push_back( Alternative ( impCpCtorExpr->clone(), env, Cost::zero ));1563 alternatives.push_back( Alternative{ impCpCtorExpr->clone(), env } ); 1660 1564 } 1661 1565 … … 1666 1570 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1667 1571 for ( Alternative & alt : finder.alternatives ) { 1668 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) ); 1572 alternatives.push_back( Alternative{ 1573 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1669 1574 } 1670 1575 } 1671 1576 1672 1577 void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) { 1673 alternatives.push_back( Alternative ( tupleExpr->clone(), env, Cost::zero ));1578 alternatives.push_back( Alternative{ tupleExpr->clone(), env } ); 1674 1579 } 1675 1580 1676 1581 void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) { 1677 alternatives.push_back( Alternative ( tupleAssignExpr->clone(), env, Cost::zero ));1582 alternatives.push_back( Alternative{ tupleAssignExpr->clone(), env } ); 1678 1583 } 1679 1584 … … 1684 1589 // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked" 1685 1590 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() ); 1686 alternatives.push_back( Alternative ( newUnqExpr, alt.env, alt.cost ));1591 alternatives.push_back( Alternative{ alt, newUnqExpr, alt.cost } ); 1687 1592 } 1688 1593 } … … 1692 1597 ResolvExpr::resolveStmtExpr( newStmtExpr, indexer ); 1693 1598 // xxx - this env is almost certainly wrong, and needs to somehow contain the combined environments from all of the statements in the stmtExpr... 1694 alternatives.push_back( Alternative ( newStmtExpr, env, Cost::zero ));1599 alternatives.push_back( Alternative{ newStmtExpr, env } ); 1695 1600 } 1696 1601 … … 1714 1619 for ( Alternative & alt : finder.get_alternatives() ) { 1715 1620 TypeEnvironment newEnv( alt.env ); 1716 AssertionSet needAssertions, haveAssertions; 1717 OpenVarSet openVars; // find things in env that don't have a "representative type" and claim those are open vars? 1621 AssertionSet need; 1622 cloneAll( alt.need, need ); 1623 AssertionSet have; 1624 OpenVarSet openVars( alt.openVars ); 1625 // xxx - find things in env that don't have a "representative type" and claim 1626 // those are open vars? 1718 1627 PRINT( 1719 1628 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1720 1629 ) 1721 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1722 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1723 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1724 // to. 1630 // It's possible that a cast can throw away some values in a multiply-valued 1631 // expression. (An example is a cast-to-void, which casts from one value to 1632 // zero.) Figure out the prefix of the subexpression results that are cast 1633 // directly. The candidate is invalid if it has fewer results than there are 1634 // types to cast to. 1725 1635 int discardedValues = alt.expr->result->size() - toType->size(); 1726 1636 if ( discardedValues < 0 ) continue; 1727 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1728 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1637 // xxx - may need to go into tuple types and extract relevant types and use 1638 // unifyList. Note that currently, this does not allow casting a tuple to an 1639 // atomic type (e.g. (int)([1, 2, 3])) 1640 1729 1641 // unification run for side-effects 1730 unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?? 1731 1732 Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv ); 1642 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); 1643 // xxx - do some inspecting on this line... why isn't result bound to initAlt.type? 1644 1645 Cost thisCost = castCost( alt.expr->result, toType, alt.expr->get_lvalue(), 1646 indexer, newEnv ); 1733 1647 if ( thisCost != Cost::infinity ) { 1734 1648 // count one safe conversion for each value that is thrown away 1735 1649 thisCost.incSafe( discardedValues ); 1736 Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ); 1737 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 1650 Alternative newAlt{ 1651 new InitExpr{ 1652 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1653 std::move(newEnv), std::move(openVars), 1654 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1655 inferParameters( newAlt, back_inserter( candidates ) ); 1738 1656 } 1739 1657 } -
src/ResolvExpr/AlternativeFinder.h
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:56:12 2015 11 // Last Modified By : A ndrew Beach12 // Last Modified On : Wed Jul 26 11:24:00 201713 // Update Count : 411 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Oct -5 10:01:00 2018 13 // Update Count : 5 14 14 // 15 15 … … 24 24 #include "ResolvExpr/Cost.h" // for Cost, Cost::infinity 25 25 #include "ResolvExpr/TypeEnvironment.h" // for AssertionSet, OpenVarSet 26 #include "ResolvMode.h" // for ResolvMode 26 27 #include "SynTree/Visitor.h" // for Visitor 27 28 #include "SynTree/SynTree.h" // for Visitor Nodes … … 36 37 /// First index is which argument, second index is which alternative for that argument, 37 38 /// third index is which exploded element of that alternative 38 using ExplodedArgs = std::vector< std::vector< ExplodedActual > >;39 using ExplodedArgs_old = std::vector< std::vector< ExplodedActual > >; 39 40 40 41 class AlternativeFinder { … … 68 69 } 69 70 70 void find( Expression *expr, bool adjust = false, bool prune = true, bool failFast = true);71 void find( Expression *expr, ResolvMode mode = ResolvMode{} ); 71 72 /// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types 72 73 void findWithAdjustment( Expression *expr ); -
src/ResolvExpr/CastCost.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 06:57:43 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Feb 2 15:34:36 201613 // Update Count : 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:12:00 2019 13 // Update Count : 8 14 14 // 15 15 16 16 #include <cassert> // for assert 17 17 18 #include "AST/Print.hpp" 19 #include "AST/SymbolTable.hpp" 20 #include "AST/Type.hpp" 21 #include "AST/TypeEnvironment.hpp" 18 22 #include "ConversionCost.h" // for ConversionCost 19 23 #include "Cost.h" // for Cost, Cost::infinity … … 31 35 32 36 namespace ResolvExpr { 33 struct CastCost : public ConversionCost {37 struct CastCost_old : public ConversionCost { 34 38 public: 35 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 39 CastCost_old( const Type * dest, bool srcIsLvalue, 40 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 36 41 37 42 using ConversionCost::previsit; 38 43 using ConversionCost::postvisit; 39 void postvisit( BasicType * basicType );40 void postvisit( PointerType * pointerType );44 void postvisit( const BasicType * basicType ); 45 void postvisit( const PointerType * pointerType ); 41 46 }; 42 47 43 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 44 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 45 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 48 Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue, 49 const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 50 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 46 52 if ( eqvClass->type ) { 47 return castCost( src, eqvClass->type, indexer, env );53 return castCost( src, eqvClass->type, srcIsLvalue, indexer, env ); 48 54 } else { 49 55 return Cost::infinity; 50 56 } 51 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name()) ) {57 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 52 58 // all typedefs should be gone by this point 53 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );59 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType ); 54 60 if ( type->base ) { 55 return castCost( src, type->base, indexer, env ) + Cost::safe;61 return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe; 56 62 } // if 57 63 } // if … … 70 76 PRINT( std::cerr << "compatible!" << std::endl; ) 71 77 return Cost::zero; 72 } else if ( dynamic_cast< VoidType* >( dest ) ) {78 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 73 79 return Cost::safe; 74 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {80 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 75 81 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 76 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1,Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {82 return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 77 83 return ptrsCastable( t1, t2, env, indexer ); 78 84 }); 79 85 } else { 80 PassVisitor<CastCost> converter( dest, indexer, env, castCost ); 86 PassVisitor<CastCost_old> converter( 87 dest, srcIsLvalue, indexer, env, 88 (Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & )) 89 castCost ); 81 90 src->accept( converter ); 82 91 if ( converter.pass.get_cost() == Cost::infinity ) { … … 89 98 } 90 99 91 CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 92 : ConversionCost( dest, indexer, env, costFunc ) { 93 } 94 95 void CastCost::postvisit( BasicType *basicType ) { 96 PointerType *destAsPointer = dynamic_cast< PointerType* >( dest ); 100 CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue, 101 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 102 : ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) { 103 } 104 105 void CastCost_old::postvisit( const BasicType * basicType ) { 106 const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest ); 97 107 if ( destAsPointer && basicType->isInteger() ) { 98 // necessary for, e.g. unsigned long => void *108 // necessary for, e.g. unsigned long => void * 99 109 cost = Cost::unsafe; 100 110 } else { 101 cost = conversionCost( basicType, dest, indexer, env );111 cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env ); 102 112 } // if 103 113 } 104 114 105 void CastCost ::postvisit( PointerType *pointerType ) {106 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {107 if ( pointerType-> get_qualifiers() <= destAsPtr->get_qualifiers()&& typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {115 void CastCost_old::postvisit( const PointerType * pointerType ) { 116 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 117 if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 108 118 cost = Cost::safe; 109 119 } else { … … 118 128 } // if 119 129 } // if 120 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {130 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 121 131 if ( destAsBasic->isInteger() ) { 122 // necessary for, e.g. void * => unsigned long132 // necessary for, e.g. void * => unsigned long 123 133 cost = Cost::unsafe; 124 134 } // if 125 135 } 126 136 } 137 138 namespace { 139 struct CastCost_new : public ConversionCost_new { 140 using ConversionCost_new::previsit; 141 using ConversionCost_new::postvisit; 142 143 CastCost_new( 144 const ast::Type * dst, const ast::SymbolTable & symtab, 145 const ast::TypeEnvironment & env, CostCalculation costFunc ) 146 : ConversionCost_new( dst, symtab, env, costFunc ) {} 147 148 void postvisit( const ast::BasicType * basicType ) { 149 auto ptr = dynamic_cast< const ast::PointerType * >( dst ); 150 if ( ptr && basicType->isInteger() ) { 151 // needed for, e.g. unsigned long => void * 152 cost = Cost::unsafe; 153 } else { 154 cost = conversionCost( basicType, dst, symtab, env ); 155 } 156 } 157 158 void postvisit( const ast::PointerType * pointerType ) { 159 if ( auto ptr = dynamic_cast< const ast::PointerType * >( dst ) ) { 160 if ( 161 pointerType->qualifiers <= ptr->qualifiers 162 && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env ) 163 ) { 164 cost = Cost::safe; 165 } else { 166 ast::TypeEnvironment newEnv{ env }; 167 if ( auto wParams = pointerType->base.as< ast::ParameterizedType >() ) { 168 newEnv.add( wParams->forall ); 169 } 170 int castResult = ptrsCastable( pointerType->base, ptr->base, symtab, newEnv ); 171 if ( castResult > 0 ) { 172 cost = Cost::safe; 173 } else if ( castResult < 0 ) { 174 cost = Cost::infinity; 175 } 176 } 177 } else if ( auto basic = dynamic_cast< const ast::BasicType * >( dst ) ) { 178 if ( basic->isInteger() ) { 179 // necessary for, e.g. void * => unsigned long 180 cost = Cost::unsafe; 181 } 182 } 183 } 184 }; 185 } // anonymous namespace 186 187 Cost castCost( 188 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 189 const ast::TypeEnvironment & env 190 ) { 191 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 192 if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name ) ) { 193 // check cast cost against bound type, if present 194 if ( eqvClass->bound ) { 195 return castCost( src, eqvClass->bound, symtab, env ); 196 } else { 197 return Cost::infinity; 198 } 199 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( typeInst->name ) ) { 200 // all typedefs should be gone by now 201 auto type = strict_dynamic_cast< const ast::TypeDecl * >( named ); 202 if ( type->base ) { 203 return castCost( src, type->base, symtab, env ) + Cost::safe; 204 } 205 } 206 } 207 208 PRINT( 209 std::cerr << "castCost ::: src is "; 210 ast::print( std::cerr, src ); 211 std::cerr << std::endl << "dest is "; 212 ast::print( std::cerr, dst ); 213 std::cerr << std::endl << "env is" << std::endl; 214 ast::print( std::cerr, env, 2 ); 215 ) 216 217 if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) { 218 PRINT( std::cerr << "compatible!" << std::endl; ) 219 return Cost::zero; 220 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) { 221 return Cost::safe; 222 } else if ( auto refType = dynamic_cast< const ast::ReferenceType * >( dst ) ) { 223 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 224 #warning cast on ptrsCastable artifact of having two functions, remove when port done 225 return convertToReferenceCost( 226 src, refType, symtab, env, 227 ( int (*)( 228 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 229 const ast::TypeEnvironment & ) 230 ) ptrsCastable ); 231 } else { 232 #warning cast on castCost artifact of having two functions, remove when port done 233 ast::Pass< CastCost_new > converter{ 234 dst, symtab, env, 235 ( Cost (*)( 236 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 237 const ast::TypeEnvironment & ) 238 ) castCost }; 239 src->accept( converter ); 240 return converter.pass.cost; 241 } 242 } 243 127 244 } // namespace ResolvExpr 128 245 -
src/ResolvExpr/CommonType.cc
r7951100 rb067d9b 10 10 // Created On : Sun May 17 06:59:27 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 15:18:17 201713 // Update Count : 912 // Last Modified On : Thu Feb 14 17:10:10 2019 13 // Update Count : 24 14 14 // 15 15 … … 18 18 #include <utility> // for pair 19 19 20 #include "AST/Decl.hpp" 21 #include "AST/Type.hpp" 20 22 #include "Common/PassVisitor.h" 21 23 #include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet … … 24 26 #include "SynTree/Type.h" // for BasicType, BasicType::Kind::... 25 27 #include "SynTree/Visitor.h" // for Visitor 26 #include "Unify.h" // for unifyExact, bindVar,WidenMode28 #include "Unify.h" // for unifyExact, WidenMode 27 29 #include "typeops.h" // for isFtype 28 30 … … 35 37 36 38 namespace ResolvExpr { 37 struct CommonType : public WithShortCircuiting {38 CommonType ( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );39 Type * get_result() const { return result; }39 struct CommonType_old : public WithShortCircuiting { 40 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 41 Type * get_result() const { return result; } 40 42 41 43 void previsit( BaseSyntaxNode * ) { visit_children = false; } … … 58 60 59 61 private: 60 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer* otherPointer );61 template< typename RefType > void handleRefType( RefType * inst, Type *other );62 63 Type * result;64 Type * type2; // inherited62 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ); 63 template< typename RefType > void handleRefType( RefType * inst, Type * other ); 64 65 Type * result; 66 Type * type2; // inherited 65 67 bool widenFirst, widenSecond; 66 68 const SymTab::Indexer &indexer; … … 78 80 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 79 81 ) 80 if ( (widenFirst || t2-> get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {82 if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) { 81 83 PRINT( 82 84 std::cerr << "widen okay" << std::endl; 83 85 ) 84 common-> get_qualifiers() |= t1->get_qualifiers();85 common-> get_qualifiers() |= t2->get_qualifiers();86 common->tq |= t1->tq; 87 common->tq |= t2->tq; 86 88 return common; 87 89 } … … 93 95 } 94 96 95 Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {96 PassVisitor<CommonType > visitor( type2, widenFirst, widenSecond, indexer, env, openVars );97 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 98 PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 97 99 98 100 int depth1 = type1->referenceDepth(); … … 125 127 std::cerr << "formal is reference; result should be reference" << std::endl; 126 128 ) 127 result = new ReferenceType( ref1-> get_qualifiers(), result );129 result = new ReferenceType( ref1->tq, result ); 128 130 } 129 131 PRINT( … … 136 138 137 139 type1->accept( visitor ); 138 Type * result = visitor.pass.get_result();140 Type * result = visitor.pass.get_result(); 139 141 if ( ! result ) { 140 142 // this appears to be handling for opaque type declarations 141 143 if ( widenSecond ) { 142 if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {143 if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {144 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );144 if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) { 145 if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) { 146 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 145 147 if ( type->get_base() ) { 146 Type::Qualifiers tq1 = type1-> get_qualifiers(), tq2 = type2->get_qualifiers();148 Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq; 147 149 AssertionSet have, need; 148 150 OpenVarSet newOpen( openVars ); 149 type1-> get_qualifiers()= Type::Qualifiers();150 type->get_base()-> get_qualifiers()= tq1;151 type1->tq = Type::Qualifiers(); 152 type->get_base()->tq = tq1; 151 153 if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) { 152 154 result = type1->clone(); 153 result-> get_qualifiers()= tq1 | tq2;155 result->tq = tq1 | tq2; 154 156 } // if 155 type1-> get_qualifiers()= tq1;156 type->get_base()-> get_qualifiers()= Type::Qualifiers();157 type1->tq = tq1; 158 type->get_base()->tq = Type::Qualifiers(); 157 159 } // if 158 160 } // if … … 176 178 } 177 179 178 static const BasicType::Kind combinedType[][ BasicType::NUMBER_OF_BASIC_TYPES ] = 179 { 180 /* Bool Char SignedChar UnsignedChar ShortSignedInt ShortUnsignedInt SignedInt UnsignedInt LongSignedInt LongUnsignedInt LongLongSignedInt LongLongUnsignedInt Float Double LongDouble FloatComplex DoubleComplex LongDoubleComplex FloatImaginary DoubleImaginary LongDoubleImaginary SignedInt128 UnsignedInt128 Float80 Float128 */ 181 /* Bool */ { BasicType::Bool, BasicType::Char, BasicType::SignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 182 /* Char */ { BasicType::Char, BasicType::Char, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 183 /* SignedChar */ { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::SignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 184 /* UnsignedChar */ { BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::UnsignedChar, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 185 /* ShortSignedInt */ { BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortSignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 186 /* ShortUnsignedInt */ { BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::ShortUnsignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 187 /* SignedInt */ { BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::SignedInt, BasicType::UnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 188 /* UnsignedInt */ { BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 189 /* LongSignedInt */ { BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongSignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 190 /* LongUnsignedInt */ { BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 191 /* LongLongSignedInt */ { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongSignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 192 /* LongLongUnsignedInt */ { BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 }, 193 /* Float */ { BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::Float, BasicType::Float, BasicType::Float80, BasicType::Float128 }, 194 /* Double */ { BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::Double, BasicType::LongDouble, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::Double, BasicType::Double, BasicType::Float80, BasicType::Float128 }, 195 /* LongDouble */ { BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDouble, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDouble, BasicType::LongDouble, BasicType::BasicType::LongDouble, BasicType::Float128 }, 196 /* FloatComplex */ { BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, }, 197 /* DoubleComplex */ { BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex }, 198 /* LongDoubleComplex */ { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, }, 199 /* FloatImaginary */ { BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::FloatImaginary, BasicType::FloatImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, }, 200 /* DoubleImaginary */ { BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::DoubleImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::DoubleImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, }, 201 /* LongDoubleImaginary */ { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, }, 202 /* SignedInt128 */ { BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::SignedInt128, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::SignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, }, 203 /* UnsignedInt128 */ { BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::UnsignedInt128, BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, }, 204 /* Float80 */ { BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::LongDouble, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::Float80, BasicType::Float80, BasicType::Float80, BasicType::Float128 }, 205 /* Float128 */ { BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::Float128, BasicType::Float128, BasicType::Float128, BasicType::Float128 }, 206 }; 180 // GENERATED START, DO NOT EDIT 181 // GENERATED BY BasicTypes-gen.cc 182 #define BT BasicType:: 183 static const BasicType::Kind commonTypes[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor 184 /* B C SC UC SI SUI 185 I UI LI LUI LLI LLUI 186 IB UIB _FH _FH _F _FC 187 F FC _FX _FXC FD _FDC 188 D DC F80X _FDXC F80 _FB 189 _FLDC FB LD LDC _FBX _FLDXC 190 */ 191 { 192 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 193 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 194 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 195 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 196 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 197 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 198 }, 199 { 200 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 201 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 202 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 203 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 204 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 205 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 206 }, 207 { 208 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 209 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 210 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 211 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 212 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 213 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 214 }, 215 { 216 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 217 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 218 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 219 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 220 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 221 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 222 }, 223 { 224 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt, 225 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 226 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 227 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 228 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 229 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 230 }, 231 { 232 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, 233 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 234 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 235 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 236 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 237 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 238 }, 239 { 240 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, 241 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 242 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 243 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 244 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 245 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 246 }, 247 { 248 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, 249 BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 250 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 251 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 252 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 253 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 254 }, 255 { 256 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, 257 BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 258 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 259 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 260 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 261 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 262 }, 263 { 264 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, 265 BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 266 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 267 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 268 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 269 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 270 }, 271 { 272 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, 273 BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 274 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 275 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 276 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 277 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 278 }, 279 { 280 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 281 BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 282 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 283 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 284 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 285 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 286 }, 287 { 288 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 289 BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 290 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 291 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 292 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 293 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 294 }, 295 { 296 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 297 BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 298 BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 299 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 300 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 301 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 302 }, 303 { 304 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 305 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 306 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, 307 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 308 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 309 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 310 }, 311 { 312 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 313 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 314 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex, 315 BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, 316 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, 317 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 318 }, 319 { 320 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 321 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 322 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex, 323 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 324 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 325 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 326 }, 327 { 328 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 329 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 330 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 331 BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, 332 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, 333 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 334 }, 335 { 336 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 337 BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 338 BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex, 339 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 340 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 341 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 342 }, 343 { 344 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 345 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 346 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 347 BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, 348 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, 349 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 350 }, 351 { 352 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 353 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 354 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, 355 BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, 356 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 357 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 358 }, 359 { 360 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 361 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 362 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 363 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, 364 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, 365 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 366 }, 367 { 368 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 369 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 370 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, 371 BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, 372 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 373 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 374 }, 375 { 376 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 377 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 378 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 379 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 380 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, 381 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 382 }, 383 { 384 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 385 BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 386 BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, 387 BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, 388 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 389 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 390 }, 391 { 392 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 393 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 394 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 395 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 396 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, 397 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 398 }, 399 { 400 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 401 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 402 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, 403 BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, 404 BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 405 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 406 }, 407 { 408 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 409 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 410 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 411 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 412 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, 413 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 414 }, 415 { 416 /* F80 */ BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, 417 BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, 418 BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, 419 BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, 420 BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, 421 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 422 }, 423 { 424 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 425 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 426 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, 427 BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, 428 BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128, 429 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 430 }, 431 { 432 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 433 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 434 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 435 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 436 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 437 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 438 }, 439 { 440 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 441 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 442 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, 443 BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, 444 BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uuFloat128, 445 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 446 }, 447 { 448 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 449 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 450 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, 451 BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, 452 BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDouble, 453 BT LongDoubleComplex, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, 454 }, 455 { 456 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 457 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 458 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 459 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 460 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 461 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, 462 }, 463 { 464 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 465 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 466 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, 467 BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, 468 BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128x, 469 BT uFloat128xComplex, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, 470 }, 471 { 472 /* _FLDXC */ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 473 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 474 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 475 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 476 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 477 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 478 }, 479 }; // commonTypes 480 #undef BT 481 // GENERATED END 207 482 static_assert( 208 sizeof(com binedType)/sizeof(combinedType[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,483 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 209 484 "Each basic type kind should have a corresponding row in the combined type matrix" 210 485 ); 211 486 212 CommonType ::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )487 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) 213 488 : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) { 214 489 } 215 490 216 void CommonType ::postvisit( VoidType * ) {}217 218 void CommonType ::postvisit( BasicType *basicType ) {219 if ( BasicType * otherBasic = dynamic_cast< BasicType* >( type2 ) ) {220 BasicType::Kind newType = com binedType[ basicType->get_kind() ][ otherBasic->get_kind() ];221 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers()) || widenSecond ) ) {222 result = new BasicType( basicType-> get_qualifiers() | otherBasic->get_qualifiers(), newType );491 void CommonType_old::postvisit( VoidType * ) {} 492 493 void CommonType_old::postvisit( BasicType * basicType ) { 494 if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) { 495 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ]; 496 if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) { 497 result = new BasicType( basicType->tq | otherBasic->tq, newType ); 223 498 } // if 224 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 225 500 // use signed int in lieu of the enum/zero/one type 226 BasicType::Kind newType = com binedType[ basicType->get_kind() ][ BasicType::SignedInt ];227 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers()) || widenSecond ) ) {228 result = new BasicType( basicType-> get_qualifiers() | type2->get_qualifiers(), newType );501 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ]; 502 if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) { 503 result = new BasicType( basicType->tq | type2->tq, newType ); 229 504 } // if 230 505 } // if … … 232 507 233 508 template< typename Pointer > 234 void CommonType ::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {235 if ( TypeInstType * var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) { 510 if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) { 236 511 OpenVarSet::const_iterator entry = openVars.find( var->get_name() ); 237 512 if ( entry != openVars.end() ) { 238 513 AssertionSet need, have; 239 514 WidenMode widen( widenFirst, widenSecond ); 240 if ( entry != openVars.end() && ! bindVar(var, voidPointer->get_base(), entry->second, env, need, have, openVars, widen, indexer ) ) return;515 if ( entry != openVars.end() && ! env.bindVar(var, voidPointer->get_base(), entry->second, need, have, openVars, widen, indexer ) ) return; 241 516 } 242 517 } 243 518 result = voidPointer->clone(); 244 result-> get_qualifiers() |= otherPointer->get_qualifiers();245 } 246 247 void CommonType ::postvisit( PointerType *pointerType ) {248 if ( PointerType * otherPointer = dynamic_cast< PointerType* >( type2 ) ) {519 result->tq |= otherPointer->tq; 520 } 521 522 void CommonType_old::postvisit( PointerType * pointerType ) { 523 if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) { 249 524 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl; 250 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) { 251 526 getCommonWithVoidPointer( otherPointer, pointerType ); 252 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) { 253 528 getCommonWithVoidPointer( pointerType, otherPointer ); 254 } else if ( ( pointerType->get_base()-> get_qualifiers() >= otherPointer->get_base()->get_qualifiers()|| widenFirst )255 && ( pointerType->get_base()-> get_qualifiers() <= otherPointer->get_base()->get_qualifiers()|| widenSecond ) ) {529 } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst ) 530 && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) { 256 531 // std::cerr << "middle case" << std::endl; 257 Type::Qualifiers tq1 = pointerType->get_base()-> get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();258 pointerType->get_base()-> get_qualifiers()= Type::Qualifiers();259 otherPointer->get_base()-> get_qualifiers()= Type::Qualifiers();532 Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq; 533 pointerType->get_base()->tq = Type::Qualifiers(); 534 otherPointer->get_base()->tq = Type::Qualifiers(); 260 535 AssertionSet have, need; 261 536 OpenVarSet newOpen( openVars ); … … 267 542 result = otherPointer->clone(); 268 543 } // if 269 result->get_qualifiers()= tq1 | tq2;544 strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2; 270 545 } else { 271 546 /// std::cerr << "place for ptr-to-type" << std::endl; 272 547 } // if 273 pointerType->get_base()-> get_qualifiers()= tq1;274 otherPointer->get_base()-> get_qualifiers()= tq2;548 pointerType->get_base()->tq = tq1; 549 otherPointer->get_base()->tq = tq2; 275 550 } // if 276 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 277 552 result = pointerType->clone(); 278 result-> get_qualifiers() |= type2->get_qualifiers();553 result->tq |= type2->tq; 279 554 } // if 280 555 } 281 556 282 void CommonType ::postvisit( ArrayType * ) {}283 284 void CommonType ::postvisit( ReferenceType *refType ) {285 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {557 void CommonType_old::postvisit( ArrayType * ) {} 558 559 void CommonType_old::postvisit( ReferenceType * refType ) { 560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) { 286 561 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl; 287 // std::cerr << ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond) << std::endl;288 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {562 // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl; 563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) { 289 564 getCommonWithVoidPointer( otherRef, refType ); 290 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) { 291 566 getCommonWithVoidPointer( refType, otherRef ); 292 } else if ( ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers()|| widenFirst )293 && ( refType->get_base()-> get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond ) ) {567 } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) 568 && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) { 294 569 // std::cerr << "middle case" << std::endl; 295 Type::Qualifiers tq1 = refType->get_base()-> get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();296 refType->get_base()-> get_qualifiers()= Type::Qualifiers();297 otherRef->get_base()-> get_qualifiers()= Type::Qualifiers();570 Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq; 571 refType->get_base()->tq = Type::Qualifiers(); 572 otherRef->get_base()->tq = Type::Qualifiers(); 298 573 AssertionSet have, need; 299 574 OpenVarSet newOpen( openVars ); … … 304 579 result = otherRef->clone(); 305 580 } // if 306 result->get_qualifiers()= tq1 | tq2;581 strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2; 307 582 } else { 308 583 /// std::cerr << "place for ptr-to-type" << std::endl; 309 584 } // if 310 refType->get_base()-> get_qualifiers()= tq1;311 otherRef->get_base()-> get_qualifiers()= tq2;585 refType->get_base()->tq = tq1; 586 otherRef->get_base()->tq = tq2; 312 587 } // if 313 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 314 589 result = refType->clone(); 315 result-> get_qualifiers() |= type2->get_qualifiers();590 result->tq |= type2->tq; 316 591 } // if 317 592 } 318 593 319 void CommonType ::postvisit( FunctionType * ) {}320 void CommonType ::postvisit( StructInstType * ) {}321 void CommonType ::postvisit( UnionInstType * ) {}322 323 void CommonType ::postvisit( EnumInstType *enumInstType ) {324 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {594 void CommonType_old::postvisit( FunctionType * ) {} 595 void CommonType_old::postvisit( StructInstType * ) {} 596 void CommonType_old::postvisit( UnionInstType * ) {} 597 598 void CommonType_old::postvisit( EnumInstType * enumInstType ) { 599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 325 600 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 326 601 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); … … 328 603 } 329 604 330 void CommonType ::postvisit( TraitInstType * ) {331 } 332 333 void CommonType ::postvisit( TypeInstType *inst ) {605 void CommonType_old::postvisit( TraitInstType * ) { 606 } 607 608 void CommonType_old::postvisit( TypeInstType * inst ) { 334 609 if ( widenFirst ) { 335 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );610 const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ); 336 611 if ( nt ) { 337 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );612 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 338 613 if ( type->get_base() ) { 339 Type::Qualifiers tq1 = inst-> get_qualifiers(), tq2 = type2->get_qualifiers();614 Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq; 340 615 AssertionSet have, need; 341 616 OpenVarSet newOpen( openVars ); 342 type2-> get_qualifiers()= Type::Qualifiers();343 type->get_base()-> get_qualifiers()= tq1;617 type2->tq = Type::Qualifiers(); 618 type->get_base()->tq = tq1; 344 619 if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) { 345 620 result = type2->clone(); 346 result-> get_qualifiers()= tq1 | tq2;621 result->tq = tq1 | tq2; 347 622 } // if 348 type2-> get_qualifiers()= tq2;349 type->get_base()-> get_qualifiers()= Type::Qualifiers();623 type2->tq = tq2; 624 type->get_base()->tq = Type::Qualifiers(); 350 625 } // if 351 626 } // if … … 353 628 } 354 629 355 void CommonType ::postvisit( TupleType * ) {}356 void CommonType ::postvisit( VarArgsType * ) {}357 358 void CommonType ::postvisit( ZeroType *zeroType ) {630 void CommonType_old::postvisit( TupleType * ) {} 631 void CommonType_old::postvisit( VarArgsType * ) {} 632 633 void CommonType_old::postvisit( ZeroType * zeroType ) { 359 634 if ( widenFirst ) { 360 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {361 if ( widenSecond || zeroType-> get_qualifiers() <= type2->get_qualifiers()) {635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 636 if ( widenSecond || zeroType->tq <= type2->tq ) { 362 637 result = type2->clone(); 363 result-> get_qualifiers() |= zeroType->get_qualifiers();364 } 365 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {366 result = new BasicType( zeroType-> get_qualifiers(), BasicType::SignedInt );367 result-> get_qualifiers() |= type2->get_qualifiers();368 } 369 } 370 } 371 372 void CommonType ::postvisit( OneType *oneType ) {638 result->tq |= zeroType->tq; 639 } 640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) { 641 result = new BasicType( zeroType->tq, BasicType::SignedInt ); 642 result->tq |= type2->tq; 643 } 644 } 645 } 646 647 void CommonType_old::postvisit( OneType * oneType ) { 373 648 if ( widenFirst ) { 374 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {375 if ( widenSecond || oneType-> get_qualifiers() <= type2->get_qualifiers()) {649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 650 if ( widenSecond || oneType->tq <= type2->tq ) { 376 651 result = type2->clone(); 377 result->get_qualifiers() |= oneType->get_qualifiers(); 378 } 379 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) { 380 result = new BasicType( oneType->get_qualifiers(), BasicType::SignedInt ); 381 result->get_qualifiers() |= type2->get_qualifiers(); 382 } 383 } 384 } 652 result->tq |= oneType->tq; 653 } 654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 655 result = new BasicType( oneType->tq, BasicType::SignedInt ); 656 result->tq |= type2->tq; 657 } 658 } 659 } 660 661 class CommonType_new final : public ast::WithShortCircuiting { 662 const ast::Type * type2; 663 WidenMode widen; 664 const ast::SymbolTable & symtab; 665 ast::TypeEnvironment & tenv; 666 const ast::OpenVarSet & open; 667 public: 668 ast::ptr< ast::Type > result; 669 670 CommonType_new( 671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 672 ast::TypeEnvironment & env, const ast::OpenVarSet & o ) 673 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {} 674 675 void previsit( const ast::Node * ) { visit_children = false; } 676 677 void postvisit( const ast::VoidType * ) {} 678 679 void postvisit( const ast::BasicType * basic ) { 680 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) { 681 #warning remove casts when `commonTypes` moved to new AST 682 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ]; 683 if ( 684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 685 || widen.first ) 686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 687 || widen.second ) 688 ) { 689 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers }; 690 } 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 693 || dynamic_cast< const ast::ZeroType * >( type2 ) 694 || dynamic_cast< const ast::OneType * >( type2 ) 695 ) { 696 #warning remove casts when `commonTypes` moved to new AST 697 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ]; 698 if ( 699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 700 || widen.first ) 701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 702 || widen.second ) 703 ) { 704 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; 705 } 706 } 707 } 708 709 private: 710 template< typename Pointer > 711 void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) { 712 const ast::Type * base = oPtr->base; 713 if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) { 714 auto entry = open.find( var->name ); 715 if ( entry != open.end() ) { 716 ast::AssertionSet need, have; 717 if ( ! tenv.bindVar( 718 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 719 ) return; 720 } 721 } 722 result = voidPtr; 723 add_qualifiers( result, oPtr->qualifiers ); 724 } 725 726 public: 727 void postvisit( const ast::PointerType * pointer ) { 728 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 729 if ( 730 widen.first 731 && pointer2->base.as< ast::VoidType >() 732 && ! ast::isFtype( pointer->base ) 733 ) { 734 getCommonWithVoidPointer( pointer2, pointer ); 735 } else if ( 736 widen.second 737 && pointer->base.as< ast::VoidType >() 738 && ! ast::isFtype( pointer2->base ) 739 ) { 740 getCommonWithVoidPointer( pointer, pointer2 ); 741 } else if ( 742 ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first ) 743 && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second ) 744 ) { 745 ast::CV::Qualifiers q1 = pointer->base->qualifiers; 746 ast::CV::Qualifiers q2 = pointer2->base->qualifiers; 747 748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 749 // pointer{,2}->base are unchanged 750 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base }; 751 reset_qualifiers( t1 ); 752 reset_qualifiers( t2 ); 753 754 ast::AssertionSet have, need; 755 ast::OpenVarSet newOpen{ open }; 756 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { 757 result = pointer; 758 if ( q1.val != q2.val ) { 759 // reset result->base->qualifiers to be union of two base qualifiers 760 strict_dynamic_cast< ast::PointerType * >( 761 result.get_and_mutate() 762 )->base.get_and_mutate()->qualifiers = q1 | q2; 763 } 764 } 765 } 766 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 767 result = pointer; 768 add_qualifiers( result, type2->qualifiers ); 769 } 770 } 771 772 void postvisit( const ast::ArrayType * ) {} 773 774 void postvisit( const ast::ReferenceType * ref ) { 775 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 776 if ( 777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 778 ) { 779 getCommonWithVoidPointer( ref2, ref ); 780 } else if ( 781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 782 ) { 783 getCommonWithVoidPointer( ref, ref2 ); 784 } else if ( 785 ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first ) 786 && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second ) 787 ) { 788 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers; 789 790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 791 // ref{,2}->base are unchanged 792 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base }; 793 reset_qualifiers( t1 ); 794 reset_qualifiers( t2 ); 795 796 ast::AssertionSet have, need; 797 ast::OpenVarSet newOpen{ open }; 798 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { 799 result = ref; 800 if ( q1.val != q2.val ) { 801 // reset result->base->qualifiers to be union of two base qualifiers 802 strict_dynamic_cast< ast::ReferenceType * >( 803 result.get_and_mutate() 804 )->base.get_and_mutate()->qualifiers = q1 | q2; 805 } 806 } 807 } 808 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 809 result = ref; 810 add_qualifiers( result, type2->qualifiers ); 811 } 812 } 813 814 void postvisit( const ast::FunctionType * ) {} 815 816 void postvisit( const ast::StructInstType * ) {} 817 818 void postvisit( const ast::UnionInstType * ) {} 819 820 void postvisit( const ast::EnumInstType * enumInst ) { 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 823 || dynamic_cast< const ast::ZeroType * >( type2 ) 824 || dynamic_cast< const ast::OneType * >( type2 ) 825 ) { 826 // reuse BasicType/EnumInstType common type by swapping 827 result = commonType( type2, enumInst, widen, symtab, tenv, open ); 828 } 829 } 830 831 void postvisit( const ast::TraitInstType * ) {} 832 833 void postvisit( const ast::TypeInstType * inst ) { 834 if ( ! widen.first ) return; 835 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) { 836 if ( const ast::Type * base = 837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 838 ) { 839 ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers; 840 841 // force t{1,2} to be cloned if their qualifiers must be mutated 842 ast::ptr< ast::Type > t1{ base }, t2{ type2 }; 843 reset_qualifiers( t1, q1 ); 844 reset_qualifiers( t2 ); 845 846 ast::AssertionSet have, need; 847 ast::OpenVarSet newOpen{ open }; 848 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { 849 result = type2; 850 reset_qualifiers( result, q1 | q2 ); 851 } 852 } 853 } 854 } 855 856 void postvisit( const ast::TupleType * ) {} 857 858 void postvisit( const ast::VarArgsType * ) {} 859 860 void postvisit( const ast::ZeroType * zero ) { 861 if ( ! widen.first ) return; 862 if ( 863 dynamic_cast< const ast::BasicType * >( type2 ) 864 || dynamic_cast< const ast::PointerType * >( type2 ) 865 || dynamic_cast< const ast::EnumInstType * >( type2 ) 866 ) { 867 if ( widen.second || zero->qualifiers <= type2->qualifiers ) { 868 result = type2; 869 add_qualifiers( result, zero->qualifiers ); 870 } 871 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) { 872 result = new ast::BasicType{ 873 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers }; 874 } 875 } 876 877 void postvisit( const ast::OneType * one ) { 878 if ( ! widen.first ) return; 879 if ( 880 dynamic_cast< const ast::BasicType * >( type2 ) 881 || dynamic_cast< const ast::EnumInstType * >( type2 ) 882 ) { 883 if ( widen.second || one->qualifiers <= type2->qualifiers ) { 884 result = type2; 885 add_qualifiers( result, one->qualifiers ); 886 } 887 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 888 result = new ast::BasicType{ 889 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers }; 890 } 891 } 892 893 }; 894 895 namespace { 896 ast::ptr< ast::Type > handleReference( 897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 899 const ast::OpenVarSet & open 900 ) { 901 ast::ptr<ast::Type> common; 902 ast::AssertionSet have, need; 903 ast::OpenVarSet newOpen{ open }; 904 905 // need unify to bind type variables 906 if ( unify( t1, t2, env, have, need, newOpen, symtab, common ) ) { 907 ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers; 908 PRINT( 909 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 910 ) 911 if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) { 912 PRINT( 913 std::cerr << "widen okay" << std::endl; 914 ) 915 add_qualifiers( common, q1 | q2 ); 916 return common; 917 } 918 } 919 920 PRINT( 921 std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl; 922 ) 923 return { nullptr }; 924 } 925 } 926 927 ast::ptr< ast::Type > commonType( 928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 930 const ast::OpenVarSet & open 931 ) { 932 unsigned depth1 = type1->referenceDepth(); 933 unsigned depth2 = type2->referenceDepth(); 934 935 if ( depth1 != depth2 ) { // implies depth1 > 0 || depth2 > 0 936 PRINT( 937 std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl; 938 ) 939 ast::ptr< ast::Type > result; 940 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >(); 941 const ast::ReferenceType * ref2 = type1.as< ast::ReferenceType >(); 942 943 if ( depth1 > depth2 ) { 944 assert( ref1 ); 945 result = handleReference( ref1->base, type2, widen, symtab, env, open ); 946 } else { // implies depth1 < depth2 947 assert( ref2 ); 948 result = handleReference( type1, ref2->base, widen, symtab, env, open ); 949 } 950 951 if ( result && ref1 ) { 952 // formal is reference, so result should be reference 953 PRINT( 954 std::cerr << "formal is reference; result should be reference" << std::endl; 955 ) 956 result = new ast::ReferenceType{ result, ref1->qualifiers }; 957 } 958 959 PRINT( 960 std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is " 961 "[" << result << "]" << std::endl; 962 ) 963 return result; 964 } 965 // otherwise both are reference types of the same depth and this is handled by the visitor 966 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open }; 967 type1->accept( visitor ); 968 ast::ptr< ast::Type > result = visitor.pass.result; 969 970 // handling for opaque type declarations (?) 971 if ( ! result && widen.second ) { 972 if ( const ast::TypeInstType * inst = type2.as< ast::TypeInstType >() ) { 973 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) { 974 auto type = strict_dynamic_cast< const ast::TypeDecl * >( nt ); 975 if ( type->base ) { 976 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 977 ast::AssertionSet have, need; 978 ast::OpenVarSet newOpen{ open }; 979 980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 981 // type1 and type->base are left unchanged; calling convention forces 982 // {type1,type->base}->strong_ref >= 1 983 ast::ptr<ast::Type> t1{ type1 }, t2{ type->base }; 984 reset_qualifiers( t1 ); 985 reset_qualifiers( t2, q1 ); 986 987 if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) { 988 result = t1; 989 reset_qualifiers( result, q1 | q2 ); 990 } 991 } 992 } 993 } 994 } 995 996 return result; 997 } 998 385 999 } // namespace ResolvExpr 386 1000 -
src/ResolvExpr/ConversionCost.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 07:06:19 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Sep 25 15:43:34 201713 // Update Count : 1011 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Aug 12 10:21:00 2019 13 // Update Count : 27 14 14 // 15 15 … … 28 28 29 29 namespace ResolvExpr { 30 const Cost Cost::zero = Cost( 0, 0, 0, 0 ); 31 const Cost Cost::infinity = Cost( -1, -1, -1, -1 ); 32 const Cost Cost::unsafe = Cost( 1, 0, 0, 0 ); 33 const Cost Cost::poly = Cost( 0, 1, 0, 0 ); 34 const Cost Cost::safe = Cost( 0, 0, 1, 0 ); 35 const Cost Cost::reference = Cost( 0, 0, 0, 1 ); 30 #if 0 31 const Cost Cost::zero = Cost{ 0, 0, 0, 0, 0, 0, 0 }; 32 const Cost Cost::infinity = Cost{ -1, -1, -1, -1, -1, 1, -1 }; 33 const Cost Cost::unsafe = Cost{ 1, 0, 0, 0, 0, 0, 0 }; 34 const Cost Cost::poly = Cost{ 0, 1, 0, 0, 0, 0, 0 }; 35 const Cost Cost::safe = Cost{ 0, 0, 1, 0, 0, 0, 0 }; 36 const Cost Cost::sign = Cost{ 0, 0, 0, 1, 0, 0, 0 }; 37 const Cost Cost::var = Cost{ 0, 0, 0, 0, 1, 0, 0 }; 38 const Cost Cost::spec = Cost{ 0, 0, 0, 0, 0, -1, 0 }; 39 const Cost Cost::reference = Cost{ 0, 0, 0, 0, 0, 0, 1 }; 40 #endif 36 41 37 42 #if 0 … … 40 45 #define PRINT(x) 41 46 #endif 42 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 43 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 47 48 Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue, 49 const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 50 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 44 51 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 45 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {52 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 46 53 if ( eqvClass->type ) { 47 return conversionCost( src, eqvClass->type, indexer, env );54 return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env ); 48 55 } else { 49 56 return Cost::infinity; 50 57 } 51 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {58 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 52 59 PRINT( std::cerr << " found" << std::endl; ) 53 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );60 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 54 61 // all typedefs should be gone by this point 55 62 assert( type ); 56 63 if ( type->base ) { 57 return conversionCost( src, type->base, indexer, env ) + Cost::safe; 64 return conversionCost( src, type->base, srcIsLvalue, indexer, env ) 65 + Cost::safe; 58 66 } // if 59 67 } // if … … 71 79 PRINT( std::cerr << "compatible!" << std::endl; ) 72 80 return Cost::zero; 73 } else if ( dynamic_cast< VoidType* >( dest ) ) {81 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 74 82 return Cost::safe; 75 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {83 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 76 84 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 77 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1,Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){85 return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 78 86 return ptrsAssignable( t1, t2, env ); 79 87 }); 80 88 } else { 81 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 89 PassVisitor<ConversionCost> converter( 90 dest, srcIsLvalue, indexer, env, 91 (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&)) 92 conversionCost ); 82 93 src->accept( converter ); 83 94 if ( converter.pass.get_cost() == Cost::infinity ) { … … 89 100 } 90 101 91 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 102 static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue, 103 int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 92 104 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 93 105 if ( diff > 0 ) { 94 106 // TODO: document this 95 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 107 Cost cost = convertToReferenceCost( 108 strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue, 109 diff-1, indexer, env, func ); 96 110 cost.incReference(); 97 111 return cost; 98 112 } else if ( diff < -1 ) { 99 113 // TODO: document this 100 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 114 Cost cost = convertToReferenceCost( 115 src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue, 116 diff+1, indexer, env, func ); 101 117 cost.incReference(); 102 118 return cost; 103 119 } else if ( diff == 0 ) { 104 ReferenceType * srcAsRef = dynamic_cast<ReferenceType * >( src );105 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );120 const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src ); 121 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 106 122 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 107 123 PRINT( std::cerr << "converting between references" << std::endl; ) 108 Type::Qualifiers tq1 = srcAsRef->base-> get_qualifiers();109 Type::Qualifiers tq2 = destAsRef->base-> get_qualifiers();124 Type::Qualifiers tq1 = srcAsRef->base->tq; 125 Type::Qualifiers tq2 = destAsRef->base->tq; 110 126 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 111 127 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 128 144 } else { 129 145 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 130 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 146 PassVisitor<ConversionCost> converter( 147 dest, srcIsLvalue, indexer, env, 148 (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&)) 149 conversionCost ); 131 150 src->accept( converter ); 132 151 return converter.pass.get_cost(); 133 152 } // if 134 153 } else { 135 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );154 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 136 155 assert( diff == -1 && destAsRef ); 137 156 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) 138 157 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) { 139 158 PRINT( std::cerr << "converting compatible base type" << std::endl; ) 140 if ( src ->get_lvalue()) {159 if ( srcIsLvalue ) { 141 160 PRINT( 142 161 std::cerr << "lvalue to reference conversion" << std::endl; … … 144 163 ) 145 164 // lvalue-to-reference conversion: cv lvalue T => cv T & 146 if ( src-> get_qualifiers() == destAsRef->base->get_qualifiers()) {165 if ( src->tq == destAsRef->base->tq ) { 147 166 return Cost::reference; // cost needs to be non-zero to add cast 148 } if ( src-> get_qualifiers() < destAsRef->base->get_qualifiers()) {167 } if ( src->tq < destAsRef->base->tq ) { 149 168 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 150 169 } else { … … 166 185 } 167 186 168 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 187 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue, 188 const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 169 189 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 170 Cost cost = convertToReferenceCost( src, dest, s depth-ddepth, indexer, env, func );190 Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func ); 171 191 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; ) 172 192 return cost; 173 193 } 174 194 175 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 176 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 177 } 178 179 /* 180 Old 181 === 182 Double 183 | 184 Float 185 | 186 ULong 187 / \ 188 UInt Long 189 \ / 190 Int 191 | 192 Ushort 193 | 194 Short 195 | 196 Uchar 197 / \ 198 Schar Char 199 200 New 201 === 202 +-----LongDoubleComplex--+ 203 LongDouble--+ | +-LongDoubleImag 204 | +---DoubleComplex---+ | 205 Double------+ | +----DoubleImag 206 | +-FloatComplex-+ | 207 Float---------+ +-------FloatImag 208 | 209 ULongLong 210 | 211 LongLong 212 | 213 ULong 214 / \ 215 UInt Long 216 \ / 217 Int 218 | 219 Ushort 220 | 221 Short 222 | 223 Uchar 224 / \ 225 Schar Char 226 \ / 227 Bool 228 */ 229 230 static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = { 231 /* Src \ Dest: Bool Char SChar UChar Short UShort Int UInt Long ULong LLong ULLong Float Double LDbl FCplex DCplex LDCplex FImag DImag LDImag I128, U128, F80, F128 */ 232 /* Bool */ { 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 12, 13, 14, 12, 13, 14, -1, -1, -1, 10, 11, 14, 15}, 233 /* Char */ { -1, 0, -1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, 13, 14}, 234 /* SChar */ { -1, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, 13, 14}, 235 /* UChar */ { -1, -1, -1, 0, 1, 2, 3, 4, 4, 5, 6, 7, 10, 11, 12, 10, 11, 12, -1, -1, -1, 8, 9, 12, 13}, 236 /* Short */ { -1, -1, -1, -1, 0, 1, 2, 3, 3, 4, 5, 6, 9, 10, 11, 9, 10, 11, -1, -1, -1, 7, 8, 11, 12}, 237 /* UShort */{ -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 4, 5, 8, 9, 10, 8, 9, 10, -1, -1, -1, 6, 7, 10, 11}, 238 /* Int */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 7, 8, 9, 7, 8, 9, -1, -1, -1, 5, 6, 9, 10}, 239 /* UInt */ { -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, 8, 9}, 240 /* Long */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, 8, 9}, 241 /* ULong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 5, 6, 7, 5, 6, 7, -1, -1, -1, 3, 4, 7, 8}, 242 /* LLong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 4, 5, 6, 4, 5, 6, -1, -1, -1, 2, 3, 6, 7}, 243 /* ULLong */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 4, 5, 3, 4, 5, -1, -1, -1, 1, 2, 5, 6}, 244 245 /* Float */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 3, -1, -1, -1, -1, -1, 2, 3}, 246 /* Double */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 2, -1, -1, -1, -1, -1, 1, 2}, 247 /* LDbl */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1}, 248 /* FCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, -1, -1, -1, -1, -1, -1}, 249 /* DCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, -1}, 250 /* LDCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1}, 251 /* FImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 0, 1, 2, -1, -1, -1, -1}, 252 /* DImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, 0, 1, -1, -1, -1, -1}, 253 /* LDImag */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, -1, -1, -1}, 254 255 /* I128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 3, 4, 5, -1, -1, -1, 0, 1, 4, 4}, 256 /* U128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 2, 3, 4, -1, -1, -1, -1, 0, 3, 3}, 257 258 /* F80 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 0, 1}, 259 /* F128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 0}, 260 }; 195 ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 196 : dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 197 } 198 199 // GENERATED START, DO NOT EDIT 200 // GENERATED BY BasicTypes-gen.cc 201 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves) 202 _Bool 203 char signed char unsigned char 204 signed short int unsigned short int 205 signed int unsigned int 206 signed long int unsigned long int 207 signed long long int unsigned long long int 208 __int128 unsigned __int128 209 _Float16 _Float16 _Complex 210 _Float32 _Float32 _Complex 211 float float _Complex 212 _Float32x _Float32x _Complex 213 _Float64 _Float64 _Complex 214 double double _Complex 215 _Float64x _Float64x _Complex 216 __float80 217 _Float128 _Float128 _Complex 218 __float128 219 long double long double _Complex 220 _Float128x _Float128x _Complex 221 */ 222 // GENERATED END 223 224 // GENERATED START, DO NOT EDIT 225 // GENERATED BY BasicTypes-gen.cc 226 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node 227 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 228 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, }, 229 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 230 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 231 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 232 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 233 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 234 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 235 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 236 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 237 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 238 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 239 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 240 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 241 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 242 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, }, 243 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, }, 244 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, }, 245 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, }, 246 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, }, 247 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, }, 248 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, }, 249 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, }, 250 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, }, 251 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, }, 252 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, }, 253 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, }, 254 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 3, 5, 4, }, 255 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, 3, }, 256 /* F80 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, 3, 4, 4, }, 257 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, }, 258 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, }, 259 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, }, 260 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, }, 261 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, }, 262 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, }, 263 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 264 }; // costMatrix 265 static const int maxIntCost = 15; 266 // GENERATED END 261 267 static_assert( 262 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,263 " Each basic type kind should have a corresponding row in the cost matrix"268 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 269 "Missing row in the cost matrix" 264 270 ); 265 271 266 267 void ConversionCost::postvisit( VoidType * ) { 272 // GENERATED START, DO NOT EDIT 273 // GENERATED BY BasicTypes-gen.cc 274 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion 275 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 276 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 277 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 278 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 279 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 280 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 281 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 282 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 283 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 284 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 285 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 286 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 287 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 288 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 289 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 290 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 291 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 292 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 293 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 294 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 295 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 296 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 297 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 298 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 299 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 300 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 301 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 302 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 303 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 304 /* F80 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 305 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, }, 306 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, }, 307 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, }, 308 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, }, 309 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, }, 310 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, }, 311 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 312 }; // signMatrix 313 // GENERATED END 314 static_assert( 315 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 316 "Missing row in the sign matrix" 317 ); 318 319 void ConversionCost::postvisit( const VoidType * ) { 268 320 cost = Cost::infinity; 269 321 } 270 322 271 void ConversionCost::postvisit( BasicType *basicType) {272 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {273 int tableResult = costMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()];323 void ConversionCost::postvisit(const BasicType * basicType) { 324 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 325 int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ]; 274 326 if ( tableResult == -1 ) { 275 327 cost = Cost::unsafe; … … 277 329 cost = Cost::zero; 278 330 cost.incSafe( tableResult ); 279 } // if 280 } else if ( dynamic_cast< EnumInstType *>( dest ) ) { 331 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] ); 332 } // if 333 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) { 281 334 // xxx - not positive this is correct, but appears to allow casting int => enum 282 335 cost = Cost::unsafe; … … 285 338 } 286 339 287 void ConversionCost::postvisit( PointerType * pointerType ) {288 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {340 void ConversionCost::postvisit( const PointerType * pointerType ) { 341 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 289 342 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 290 Type::Qualifiers tq1 = pointerType->base-> get_qualifiers();291 Type::Qualifiers tq2 = destAsPtr->base-> get_qualifiers();343 Type::Qualifiers tq1 = pointerType->base->tq; 344 Type::Qualifiers tq2 = destAsPtr->base->tq; 292 345 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 293 346 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 298 351 // types are the same, except otherPointer has more qualifiers 299 352 cost = Cost::safe; 300 } 353 } // if 301 354 } else { 302 355 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env ); … … 318 371 } 319 372 320 void ConversionCost::postvisit( ArrayType * ) {}321 322 void ConversionCost::postvisit( ReferenceType * refType ) {373 void ConversionCost::postvisit( const ArrayType * ) {} 374 375 void ConversionCost::postvisit( const ReferenceType * refType ) { 323 376 // Note: dest can never be a reference, since it would have been caught in an earlier check 324 assert( ! dynamic_cast< ReferenceType * >( dest ) );377 assert( ! dynamic_cast< const ReferenceType * >( dest ) ); 325 378 // convert reference to rvalue: cv T1 & => T2 326 379 // recursively compute conversion cost from T1 to T2. 327 380 // cv can be safely dropped because of 'implicit dereference' behavior. 328 cost = costFunc( refType->base, dest, indexer, env );329 if ( refType->base-> get_qualifiers() == dest->get_qualifiers()) {381 cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env ); 382 if ( refType->base->tq == dest->tq ) { 330 383 cost.incReference(); // prefer exact qualifiers 331 } else if ( refType->base-> get_qualifiers() < dest->get_qualifiers()) {384 } else if ( refType->base->tq < dest->tq ) { 332 385 cost.incSafe(); // then gaining qualifiers 333 386 } else { … … 337 390 } 338 391 339 void ConversionCost::postvisit( FunctionType * ) {}340 341 void ConversionCost::postvisit( StructInstType * inst ) {342 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {392 void ConversionCost::postvisit( const FunctionType * ) {} 393 394 void ConversionCost::postvisit( const StructInstType * inst ) { 395 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) { 343 396 if ( inst->name == destAsInst->name ) { 344 397 cost = Cost::zero; … … 347 400 } 348 401 349 void ConversionCost::postvisit( UnionInstType * inst ) {350 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {402 void ConversionCost::postvisit( const UnionInstType * inst ) { 403 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) { 351 404 if ( inst->name == destAsInst->name ) { 352 405 cost = Cost::zero; … … 355 408 } 356 409 357 void ConversionCost::postvisit( EnumInstType * ) {410 void ConversionCost::postvisit( const EnumInstType * ) { 358 411 static Type::Qualifiers q; 359 412 static BasicType integer( q, BasicType::SignedInt ); 360 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int413 cost = costFunc( &integer, dest, srcIsLvalue, indexer, env ); // safe if dest >= int 361 414 if ( cost < Cost::unsafe ) { 362 415 cost.incSafe(); … … 364 417 } 365 418 366 void ConversionCost::postvisit( TraitInstType * ) {}367 368 void ConversionCost::postvisit( TypeInstType *inst ) {369 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {370 cost = costFunc( eqvClass->type, dest, indexer, env );371 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {419 void ConversionCost::postvisit( const TraitInstType * ) {} 420 421 void ConversionCost::postvisit( const TypeInstType * inst ) { 422 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 423 cost = costFunc( eqvClass->type, dest, srcIsLvalue, indexer, env ); 424 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) { 372 425 if ( inst->name == destAsInst->name ) { 373 426 cost = Cost::zero; 374 427 } 375 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {376 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );428 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) { 429 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 377 430 // all typedefs should be gone by this point 378 431 assert( type ); 379 432 if ( type->base ) { 380 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;381 } // if 382 } // if 383 } 384 385 void ConversionCost::postvisit( TupleType * tupleType ) {433 cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe; 434 } // if 435 } // if 436 } 437 438 void ConversionCost::postvisit( const TupleType * tupleType ) { 386 439 Cost c = Cost::zero; 387 if ( TupleType * destAsTuple = dynamic_cast<TupleType * >( dest ) ) {440 if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) { 388 441 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 389 442 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 390 443 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) { 391 Cost newCost = costFunc( * srcIt++, *destIt++, indexer, env );444 Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env ); 392 445 if ( newCost == Cost::infinity ) { 393 446 return; … … 403 456 } 404 457 405 void ConversionCost::postvisit( VarArgsType * ) {406 if ( dynamic_cast< VarArgsType* >( dest ) ) {407 cost = Cost::zero; 408 } 409 } 410 411 void ConversionCost::postvisit( ZeroType * ) {412 if ( dynamic_cast< ZeroType * >( dest ) ) {413 cost = Cost::zero; 414 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {415 // copied from visit(BasicType *) for signed int, but +1 for safe conversions416 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];458 void ConversionCost::postvisit( const VarArgsType * ) { 459 if ( dynamic_cast< const VarArgsType * >( dest ) ) { 460 cost = Cost::zero; 461 } 462 } 463 464 void ConversionCost::postvisit( const ZeroType * ) { 465 if ( dynamic_cast< const ZeroType * >( dest ) ) { 466 cost = Cost::zero; 467 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 468 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 469 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 417 470 if ( tableResult == -1 ) { 418 471 cost = Cost::unsafe; … … 420 473 cost = Cost::zero; 421 474 cost.incSafe( tableResult + 1 ); 422 } 423 } else if ( dynamic_cast< PointerType* >( dest ) ) { 424 cost = Cost::safe; 425 } 426 } 427 428 void ConversionCost::postvisit( OneType * ) { 429 if ( dynamic_cast< OneType * >( dest ) ) { 430 cost = Cost::zero; 431 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 432 // copied from visit(BasicType*) for signed int, but +1 for safe conversions 433 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ]; 475 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 476 } // if 477 } else if ( dynamic_cast< const PointerType * >( dest ) ) { 478 cost = Cost::zero; 479 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation 480 } // if 481 } 482 483 void ConversionCost::postvisit( const OneType * ) { 484 if ( dynamic_cast< const OneType * >( dest ) ) { 485 cost = Cost::zero; 486 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 487 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 488 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 434 489 if ( tableResult == -1 ) { 435 490 cost = Cost::unsafe; … … 437 492 cost = Cost::zero; 438 493 cost.incSafe( tableResult + 1 ); 494 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 495 } // if 496 } // if 497 } 498 499 static int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2, 500 const ast::SymbolTable &, const ast::TypeEnvironment & env ) { 501 return ptrsAssignable( t1, t2, env ); 502 } 503 504 // TODO: This is used for overload resolution. It might be able to be dropped once the old system 505 // is removed. 506 static Cost localConversionCost( 507 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 508 const ast::TypeEnvironment & env 509 ) { return conversionCost( src, dst, symtab, env ); } 510 511 Cost conversionCost( 512 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 513 const ast::TypeEnvironment & env 514 ) { 515 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 516 if ( const ast::EqvClass * eqv = env.lookup( inst->name ) ) { 517 if ( eqv->bound ) { 518 return conversionCost(src, eqv->bound, symtab, env ); 519 } else { 520 return Cost::infinity; 439 521 } 440 } 441 } 522 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) { 523 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named ); 524 assertf( type, "Unexpected typedef." ); 525 if ( type->base ) { 526 return conversionCost( src, type->base, symtab, env ) + Cost::safe; 527 } 528 } 529 } 530 if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) { 531 return Cost::zero; 532 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) { 533 return Cost::safe; 534 } else if ( const ast::ReferenceType * refType = 535 dynamic_cast< const ast::ReferenceType * >( dst ) ) { 536 return convertToReferenceCost( src, refType, symtab, env, localPtrsAssignable ); 537 } else { 538 ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost ); 539 src->accept( converter ); 540 return converter.pass.cost; 541 } 542 } 543 544 static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, 545 int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env, 546 NumCostCalculation func ) { 547 if ( 0 < diff ) { 548 Cost cost = convertToReferenceCost( 549 strict_dynamic_cast< const ast::ReferenceType * >( src )->base, 550 dst, (diff - 1), symtab, env, func ); 551 cost.incReference(); 552 return cost; 553 } else if ( diff < -1 ) { 554 Cost cost = convertToReferenceCost( 555 src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base, 556 (diff + 1), symtab, env, func ); 557 cost.incReference(); 558 return cost; 559 } else if ( 0 == diff ) { 560 const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src ); 561 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst ); 562 if ( srcAsRef && dstAsRef ) { 563 ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers; 564 ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers; 565 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( 566 srcAsRef->base, dstAsRef->base, symtab, env ) ) { 567 if ( tq1 == tq2 ) { 568 return Cost::zero; 569 } else { 570 return Cost::safe; 571 } 572 } else { 573 int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env ); 574 if ( 0 < assignResult ) { 575 return Cost::safe; 576 } else if ( assignResult < 0 ) { 577 return Cost::unsafe; 578 } 579 } 580 } else { 581 ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost ); 582 src->accept( converter ); 583 return converter.pass.cost; 584 } 585 } else { 586 assert( -1 == diff ); 587 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst ); 588 assert( dstAsRef ); 589 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, symtab, env ) ) { 590 if ( src->is_lvalue() ) { 591 if ( src->qualifiers == dstAsRef->base->qualifiers ) { 592 return Cost::reference; 593 } else if ( src->qualifiers < dstAsRef->base->qualifiers ) { 594 return Cost::safe; 595 } else { 596 return Cost::unsafe; 597 } 598 } else if ( dstAsRef->base->is_const() ) { 599 return Cost::safe; 600 } else { 601 return Cost::unsafe; 602 } 603 } 604 } 605 return Cost::infinity; 606 } 607 608 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst, 609 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env, 610 NumCostCalculation func ) { 611 int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth(); 612 return convertToReferenceCost( src, dst, sdepth - ddepth, symtab, env, func ); 613 } 614 615 void ConversionCost_new::postvisit( const ast::VoidType * voidType ) { 616 (void)voidType; 617 cost = Cost::infinity; 618 } 619 620 void ConversionCost_new::postvisit( const ast::BasicType * basicType ) { 621 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) { 622 int tableResult = costMatrix[ basicType->kind ][ dstAsBasic->kind ]; 623 if ( tableResult == -1 ) { 624 cost = Cost::unsafe; 625 } else { 626 cost = Cost::zero; 627 cost.incSafe( tableResult ); 628 cost.incSign( signMatrix[ basicType->kind ][ dstAsBasic->kind ] ); 629 } 630 } else if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) { 631 // xxx - not positive this is correct, but appears to allow casting int => enum 632 cost = Cost::unsafe; 633 } 634 } 635 636 void ConversionCost_new::postvisit( const ast::PointerType * pointerType ) { 637 if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) { 638 ast::CV::Qualifiers tq1 = pointerType->base->qualifiers; 639 ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers; 640 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( 641 pointerType->base, dstAsPtr->base, symtab, env ) ) { 642 if ( tq1 == tq2 ) { 643 cost = Cost::zero; 644 } else { 645 cost = Cost::safe; 646 } 647 } else { 648 int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env ); 649 if ( 0 < assignResult && tq1 <= tq2 ) { 650 if ( tq1 == tq2 ) { 651 cost = Cost::safe; 652 } else { 653 cost = Cost::safe + Cost::safe; 654 } 655 } else if ( assignResult < 0 ) { 656 cost = Cost::unsafe; 657 } // else Cost::infinity 658 } 659 } 660 } 661 662 void ConversionCost_new::postvisit( const ast::ArrayType * arrayType ) { 663 (void)arrayType; 664 } 665 666 void ConversionCost_new::postvisit( const ast::ReferenceType * refType ) { 667 assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) ); 668 669 cost = costCalc( refType->base, dst, symtab, env ); 670 if ( refType->base->qualifiers == dst->qualifiers ) { 671 cost.incReference(); 672 } else if ( refType->base->qualifiers < dst->qualifiers ) { 673 cost.incSafe(); 674 } else { 675 cost.incUnsafe(); 676 } 677 } 678 679 void ConversionCost_new::postvisit( const ast::FunctionType * functionType ) { 680 (void)functionType; 681 } 682 683 void ConversionCost_new::postvisit( const ast::StructInstType * structInstType ) { 684 if ( const ast::StructInstType * dstAsInst = 685 dynamic_cast< const ast::StructInstType * >( dst ) ) { 686 if ( structInstType->name == dstAsInst->name ) { 687 cost = Cost::zero; 688 } 689 } 690 } 691 692 void ConversionCost_new::postvisit( const ast::UnionInstType * unionInstType ) { 693 if ( const ast::UnionInstType * dstAsInst = 694 dynamic_cast< const ast::UnionInstType * >( dst ) ) { 695 if ( unionInstType->name == dstAsInst->name ) { 696 cost = Cost::zero; 697 } 698 } 699 } 700 701 void ConversionCost_new::postvisit( const ast::EnumInstType * enumInstType ) { 702 (void)enumInstType; 703 static const ast::BasicType integer( ast::BasicType::SignedInt ); 704 cost = costCalc( &integer, dst, symtab, env ); 705 if ( cost < Cost::unsafe ) { 706 cost.incSafe(); 707 } 708 } 709 710 void ConversionCost_new::postvisit( const ast::TraitInstType * traitInstType ) { 711 (void)traitInstType; 712 } 713 714 void ConversionCost_new::postvisit( const ast::TypeInstType * typeInstType ) { 715 if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) { 716 cost = costCalc( eqv->bound, dst, symtab, env ); 717 } else if ( const ast::TypeInstType * dstAsInst = 718 dynamic_cast< const ast::TypeInstType * >( dst ) ) { 719 if ( typeInstType->name == dstAsInst->name ) { 720 cost = Cost::zero; 721 } 722 } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) { 723 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType ); 724 assertf( type, "Unexpected typedef."); 725 if ( type->base ) { 726 cost = costCalc( type->base, dst, symtab, env ) + Cost::safe; 727 } 728 } 729 } 730 731 void ConversionCost_new::postvisit( const ast::TupleType * tupleType ) { 732 Cost c = Cost::zero; 733 if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) { 734 auto srcIt = tupleType->types.begin(); 735 auto dstIt = dstAsTuple->types.begin(); 736 auto srcEnd = tupleType->types.end(); 737 auto dstEnd = dstAsTuple->types.end(); 738 while ( srcIt != srcEnd && dstIt != dstEnd ) { 739 Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env ); 740 if ( newCost == Cost::infinity ) { 741 return; 742 } 743 c += newCost; 744 } 745 if ( dstIt != dstEnd ) { 746 cost = Cost::infinity; 747 } else { 748 cost = c; 749 } 750 } 751 } 752 753 void ConversionCost_new::postvisit( const ast::VarArgsType * varArgsType ) { 754 (void)varArgsType; 755 if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) { 756 cost = Cost::zero; 757 } 758 } 759 760 void ConversionCost_new::postvisit( const ast::ZeroType * zeroType ) { 761 (void)zeroType; 762 if ( dynamic_cast< const ast::ZeroType * >( dst ) ) { 763 cost = Cost::zero; 764 } else if ( const ast::BasicType * dstAsBasic = 765 dynamic_cast< const ast::BasicType * >( dst ) ) { 766 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ]; 767 if ( -1 == tableResult ) { 768 cost = Cost::unsafe; 769 } else { 770 cost = Cost::zero; 771 cost.incSafe( tableResult + 1 ); 772 cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] ); 773 } 774 } 775 } 776 777 void ConversionCost_new::postvisit( const ast::OneType * oneType ) { 778 (void)oneType; 779 if ( dynamic_cast< const ast::OneType * >( dst ) ) { 780 cost = Cost::zero; 781 } else if ( const ast::BasicType * dstAsBasic = 782 dynamic_cast< const ast::BasicType * >( dst ) ) { 783 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ]; 784 if ( -1 == tableResult ) { 785 cost = Cost::unsafe; 786 } else { 787 cost = Cost::zero; 788 cost.incSafe( tableResult + 1 ); 789 cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] ); 790 } 791 } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) { 792 cost = Cost::zero; 793 cost.incSafe( maxIntCost + 2 ); 794 } 795 } 796 797 442 798 } // namespace ResolvExpr 443 799 -
src/ResolvExpr/ConversionCost.h
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 09:37:28 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:38:24 201713 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:13:00 2019 13 // Update Count : 6 14 14 // 15 15 … … 20 20 #include "Cost.h" // for Cost 21 21 22 #include "AST/Fwd.hpp" 23 #include "AST/Pass.hpp" // for WithShortCircuiting 22 24 #include "Common/PassVisitor.h" 23 25 #include "SynTree/Visitor.h" // for Visitor … … 31 33 class TypeEnvironment; 32 34 33 typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction; 35 typedef std::function<Cost(const Type *, const Type *, bool, 36 const SymTab::Indexer &, const TypeEnvironment &)> CostFunction; 37 34 38 struct ConversionCost : public WithShortCircuiting { 35 39 public: 36 ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction ); 40 ConversionCost( const Type * dest, bool srcIsLvalue, 41 const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction ); 37 42 38 43 Cost get_cost() const { return cost; } 39 44 40 void previsit( BaseSyntaxNode * ) { visit_children = false; }45 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 41 46 42 void postvisit( VoidType * voidType );43 void postvisit( BasicType * basicType );44 void postvisit( PointerType * pointerType );45 void postvisit( ArrayType * arrayType );46 void postvisit( ReferenceType * refType );47 void postvisit( FunctionType * functionType );48 void postvisit( StructInstType * aggregateUseType );49 void postvisit( UnionInstType * aggregateUseType );50 void postvisit( EnumInstType * aggregateUseType );51 void postvisit( TraitInstType * aggregateUseType );52 void postvisit( TypeInstType * aggregateUseType );53 void postvisit( TupleType * tupleType );54 void postvisit( VarArgsType * varArgsType );55 void postvisit( ZeroType * zeroType );56 void postvisit( OneType * oneType );47 void postvisit( const VoidType * voidType ); 48 void postvisit( const BasicType * basicType ); 49 void postvisit( const PointerType * pointerType ); 50 void postvisit( const ArrayType * arrayType ); 51 void postvisit( const ReferenceType * refType ); 52 void postvisit( const FunctionType * functionType ); 53 void postvisit( const StructInstType * aggregateUseType ); 54 void postvisit( const UnionInstType * aggregateUseType ); 55 void postvisit( const EnumInstType * aggregateUseType ); 56 void postvisit( const TraitInstType * aggregateUseType ); 57 void postvisit( const TypeInstType * aggregateUseType ); 58 void postvisit( const TupleType * tupleType ); 59 void postvisit( const VarArgsType * varArgsType ); 60 void postvisit( const ZeroType * zeroType ); 61 void postvisit( const OneType * oneType ); 57 62 protected: 58 Type *dest; 63 const Type * dest; 64 bool srcIsLvalue; 59 65 const SymTab::Indexer &indexer; 60 66 Cost cost; … … 63 69 }; 64 70 65 typedef std::function<int(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction; 66 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ); 71 typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction; 72 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue, 73 const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ); 74 75 // Some function pointer types, differ in return type. 76 using CostCalculation = std::function<Cost(const ast::Type *, const ast::Type *, 77 const ast::SymbolTable &, const ast::TypeEnvironment &)>; 78 using NumCostCalculation = std::function<int(const ast::Type *, const ast::Type *, 79 const ast::SymbolTable &, const ast::TypeEnvironment &)>; 80 81 #warning when the old ConversionCost is removed, get ride of the _new suffix. 82 class ConversionCost_new : public ast::WithShortCircuiting { 83 protected: 84 const ast::Type * dst; 85 const ast::SymbolTable & symtab; 86 const ast::TypeEnvironment & env; 87 CostCalculation costCalc; 88 public: 89 Cost cost; 90 91 ConversionCost_new( const ast::Type * dst, const ast::SymbolTable & symtab, 92 const ast::TypeEnvironment & env, CostCalculation costCalc ) : 93 dst( dst ), symtab( symtab ), env( env ), costCalc( costCalc ), cost( Cost::infinity ) 94 {} 95 96 void previsit( const ast::Node * ) { visit_children = false; } 97 98 void postvisit( const ast::VoidType * voidType ); 99 void postvisit( const ast::BasicType * basicType ); 100 void postvisit( const ast::PointerType * pointerType ); 101 void postvisit( const ast::ArrayType * arrayType ); 102 void postvisit( const ast::ReferenceType * refType ); 103 void postvisit( const ast::FunctionType * functionType ); 104 void postvisit( const ast::StructInstType * structInstType ); 105 void postvisit( const ast::UnionInstType * unionInstType ); 106 void postvisit( const ast::EnumInstType * enumInstType ); 107 void postvisit( const ast::TraitInstType * traitInstType ); 108 void postvisit( const ast::TypeInstType * typeInstType ); 109 void postvisit( const ast::TupleType * tupleType ); 110 void postvisit( const ast::VarArgsType * varArgsType ); 111 void postvisit( const ast::ZeroType * zeroType ); 112 void postvisit( const ast::OneType * oneType ); 113 }; 114 115 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest, 116 const ast::SymbolTable & indexer, const ast::TypeEnvironment & env, NumCostCalculation func ); 117 67 118 } // namespace ResolvExpr 68 119 -
src/ResolvExpr/Cost.h
r7951100 rb067d9b 7 7 // Cost.h -- 8 8 // 9 // Author : Richard C. Bilson9 // Author : Peter Buhr and Aaron Moss 10 10 // Created On : Sun May 17 09:39:50 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:35:55 201713 // Update Count : 512 // Last Modified On : Fri Jun 21 11:39:13 2019 13 // Update Count : 63 14 14 // 15 15 … … 17 17 18 18 #include <iostream> 19 #include <cassert> 20 #include <climits> 19 21 20 22 namespace ResolvExpr { 23 // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the 24 // specialization cost is a negative value so a correction is needed is a few places. 25 21 26 class Cost { 22 private: 23 Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ); 27 union { 28 struct { 29 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 30 // Little-endian => first value is low priority and last is high priority. 31 unsigned char padding; ///< unused 32 unsigned char referenceCost; ///< reference conversions 33 unsigned char specCost; ///< Polymorphic type specializations (type assertions), negative cost 34 unsigned char varCost; ///< Count of polymorphic type variables 35 unsigned char signCost; ///< Count of safe sign conversions 36 unsigned char safeCost; ///< Safe (widening) conversions 37 unsigned char polyCost; ///< Count of parameters and return values bound to some poly type 38 unsigned char unsafeCost; ///< Unsafe (narrowing) conversions 39 #else 40 #error Cost BIG_ENDIAN unsupported 41 #endif 42 } v; 43 uint64_t all; 44 }; 45 static const unsigned char correctb = 0xff; // byte correction for negative spec cost 46 static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost 47 public: 48 // Compiler adjusts constants for correct endian. 49 enum : uint64_t { 50 zero = 0x00'00'00'00'00'ff'00'00, 51 infinity = 0xff'ff'ff'ff'ff'00'ff'ff, 52 unsafe = 0x01'00'00'00'00'ff'00'00, 53 poly = 0x00'01'00'00'00'ff'00'00, 54 safe = 0x00'00'01'00'00'ff'00'00, 55 sign = 0x00'00'00'01'00'ff'00'00, 56 var = 0x00'00'00'00'01'ff'00'00, 57 spec = 0x00'00'00'00'00'fe'00'00, 58 reference = 0x00'00'00'00'00'ff'01'00, 59 }; //' 24 60 25 public: 26 Cost & incUnsafe( int inc = 1 ); 27 Cost & incPoly( int inc = 1 ); 28 Cost & incSafe( int inc = 1 ); 29 Cost & incReference( int inc = 1 ); 61 Cost( uint64_t all ) { Cost::all = all; } 62 Cost( int unsafeCost, int polyCost, int safeCost, int signCost, int varCost, int specCost, int referenceCost ) { 63 // Assume little-endian => first value is low priority and last is high priority. 64 v = { 65 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 66 (unsigned char)0, // padding 67 (unsigned char)referenceCost, // low priority 68 (unsigned char)(specCost + correctb), // correct for signedness 69 (unsigned char)varCost, 70 (unsigned char)signCost, 71 (unsigned char)safeCost, 72 (unsigned char)polyCost, 73 (unsigned char)unsafeCost, // high priority 74 #else 75 #error Cost BIG_ENDIAN unsupported 76 #endif 77 }; 78 } 30 79 31 int get_unsafeCost() const { return unsafeCost; } 32 int get_polyCost() const { return polyCost; } 33 int get_safeCost() const { return safeCost; } 34 int get_referenceCost() const { return referenceCost; } 80 int get_unsafeCost() const { return v.unsafeCost; } 81 int get_polyCost() const { return v.polyCost; } 82 int get_safeCost() const { return v.safeCost; } 83 int get_signCost() const { return v.signCost; } 84 int get_varCost() const { return v.varCost; } 85 int get_specCost() const { return -(correctb - v.specCost); } 86 int get_referenceCost() const { return v.referenceCost; } 35 87 36 Cost operator+( const Cost &other ) const; 37 Cost operator-( const Cost &other ) const; 38 Cost &operator+=( const Cost &other ); 39 bool operator<( const Cost &other ) const; 40 bool operator==( const Cost &other ) const; 41 bool operator!=( const Cost &other ) const; 42 friend std::ostream &operator<<( std::ostream &os, const Cost &cost ); 88 friend bool operator==( const Cost, const Cost ); 89 friend bool operator!=( const Cost lhs, const Cost rhs ); 90 // returns negative for *this < rhs, 0 for *this == rhs, positive for *this > rhs 91 int compare( const Cost rhs ) const { 92 if ( all == infinity ) return 1; 93 if ( rhs.all == infinity ) return -1; 94 return all > rhs.all ? 1 : all == rhs.all ? 0 : -1; 95 } 96 friend bool operator<( const Cost lhs, const Cost rhs ); 43 97 44 static const Cost zero; 45 static const Cost infinity; 98 friend Cost operator+( const Cost lhs, const Cost rhs ); 99 100 Cost operator+=( const Cost rhs ) { 101 if ( all == infinity ) return *this; 102 if ( rhs.all == infinity ) { 103 all = infinity; 104 return *this; 105 } 106 all += rhs.all - correctw; // correct for negative spec cost 107 return *this; 108 } 46 109 47 static const Cost unsafe; 48 static const Cost poly; 49 static const Cost safe; 50 static const Cost reference; 51 private: 52 int compare( const Cost &other ) const; 110 Cost incUnsafe( int inc = 1 ) { 111 if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; } 112 return *this; 113 } 53 114 54 int unsafeCost; 55 int polyCost; 56 int safeCost; 57 int referenceCost; 115 Cost incPoly( int inc = 1 ) { 116 if ( all != infinity ) { assert( v.polyCost + inc <= UCHAR_MAX ); v.polyCost += inc; } 117 return *this; 118 } 119 120 Cost incSafe( int inc = 1 ) { 121 if ( all != infinity ) { assert( v.safeCost + inc <= UCHAR_MAX ); v.safeCost += inc; } 122 return *this; 123 } 124 125 Cost incSign( int inc = 1 ) { 126 if ( all != infinity ) { assert( v.signCost + inc <= UCHAR_MAX ); v.signCost += inc; } 127 return *this; 128 } 129 130 Cost incVar( int inc = 1 ) { 131 if ( all != infinity ) { assert( v.varCost + inc <= UCHAR_MAX ); v.varCost += inc; } 132 return *this; 133 } 134 135 Cost decSpec( int dec = 1 ) { 136 if ( all != infinity ) { assert( v.specCost - dec >= 0 ); v.specCost -= dec; } 137 return *this; 138 } 139 140 Cost incReference( int inc = 1 ) { 141 if ( all != infinity ) { assert( v.referenceCost + inc <= UCHAR_MAX ); v.referenceCost += inc; } 142 return *this; 143 } 144 145 friend std::ostream & operator<<( std::ostream & os, const Cost cost ); 58 146 }; 59 147 60 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ) : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), referenceCost( referenceCost ) {} 61 62 inline Cost & Cost::incUnsafe( int inc ) { 63 if ( *this == infinity ) return *this; 64 unsafeCost += inc; 65 return *this; 148 inline bool operator==( const Cost lhs, const Cost rhs ) { 149 return lhs.all == rhs.all; 66 150 } 67 151 68 inline Cost & Cost::incPoly( int inc ) { 69 if ( *this == infinity ) return *this; 70 polyCost += inc; 71 return *this; 152 inline bool operator!=( const Cost lhs, const Cost rhs ) { 153 return !( lhs.all == rhs.all ); 72 154 } 73 155 74 inline Cost & Cost::incSafe( int inc) {75 if ( *this == infinity ) return *this;76 safeCost += inc;77 return *this;156 inline bool operator<( const Cost lhs, const Cost rhs ) { 157 if ( lhs.all == Cost::infinity ) return false; 158 if ( rhs.all == Cost::infinity ) return true; 159 return lhs.all < rhs.all; 78 160 } 79 161 80 inline Cost & Cost::incReference( int inc ) { 81 if ( *this == infinity ) return *this; 82 referenceCost += inc; 83 return *this; 162 inline Cost operator+( const Cost lhs, const Cost rhs ) { 163 if ( lhs.all == Cost::infinity || rhs.all == Cost::infinity ) return Cost{ Cost::infinity }; 164 return Cost{ lhs.all + rhs.all - Cost::correctw }; // correct for negative spec cost 84 165 } 85 166 86 inline Cost Cost::operator+( const Cost &other ) const { 87 if ( *this == infinity || other == infinity ) return infinity; 88 return Cost( unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, referenceCost + other.referenceCost ); 89 } 90 91 inline Cost Cost::operator-( const Cost &other ) const { 92 if ( *this == infinity || other == infinity ) return infinity; 93 return Cost( unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost, referenceCost - other.referenceCost ); 94 } 95 96 inline Cost &Cost::operator+=( const Cost &other ) { 97 if ( *this == infinity ) return *this; 98 if ( other == infinity ) { 99 *this = infinity; 100 return *this; 101 } 102 unsafeCost += other.unsafeCost; 103 polyCost += other.polyCost; 104 safeCost += other.safeCost; 105 referenceCost += other.referenceCost; 106 return *this; 107 } 108 109 inline bool Cost::operator<( const Cost &other ) const { 110 if ( *this == infinity ) return false; 111 if ( other == infinity ) return true; 112 113 if ( unsafeCost > other.unsafeCost ) { 114 return false; 115 } else if ( unsafeCost < other.unsafeCost ) { 116 return true; 117 } else if ( polyCost > other.polyCost ) { 118 return false; 119 } else if ( polyCost < other.polyCost ) { 120 return true; 121 } else if ( safeCost > other.safeCost ) { 122 return false; 123 } else if ( safeCost < other.safeCost ) { 124 return true; 125 } else if ( referenceCost > other.referenceCost ) { 126 return false; 127 } else if ( referenceCost < other.referenceCost ) { 128 return true; 129 } else { 130 return false; 131 } // if 132 } 133 134 inline bool Cost::operator==( const Cost &other ) const { 135 return unsafeCost == other.unsafeCost 136 && polyCost == other.polyCost 137 && safeCost == other.safeCost 138 && referenceCost == other.referenceCost; 139 } 140 141 inline bool Cost::operator!=( const Cost &other ) const { 142 return !( *this == other ); 143 } 144 145 inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) { 146 os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " << cost.safeCost << ", " << cost.referenceCost << " )"; 147 return os; 167 inline std::ostream & operator<<( std::ostream & os, const Cost cost ) { 168 return os << "( " << cost.get_unsafeCost() << ", " << cost.get_polyCost() << ", " << cost.get_safeCost() 169 << ", " << cost.get_signCost() << ", " << cost.get_varCost() << ", " << cost.get_specCost() 170 << ", " << cost.get_referenceCost() << " )"; 148 171 } 149 172 } // namespace ResolvExpr -
src/ResolvExpr/CurrentObject.cc
r7951100 rb067d9b 16 16 #include <stddef.h> // for size_t 17 17 #include <cassert> // for assertf, assert, safe_dynamic_... 18 #include <deque> 18 19 #include <iostream> // for ostream, operator<<, basic_ost... 19 20 #include <stack> // for stack 20 21 #include <string> // for string, operator<<, allocator 21 22 23 #include "AST/Expr.hpp" // for InitAlternative 24 #include "AST/GenericSubstitution.hpp" // for genericSubstitution 25 #include "AST/Init.hpp" // for Designation 26 #include "AST/Node.hpp" // for readonly 27 #include "AST/Type.hpp" 22 28 #include "Common/Indenter.h" // for Indenter, operator<< 23 29 #include "Common/SemanticError.h" // for SemanticError … … 139 145 ArrayIterator( ArrayType * at ) : array( at ) { 140 146 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; ) 141 base = at-> get_base();147 base = at->base; 142 148 memberIter = createMemberIterator( base ); 143 if ( at->isVarLen ) SemanticError( at, "VLA initialization does not support @= " );144 setSize( at-> get_dimension());149 if ( at->isVarLen ) SemanticError( at, "VLA initialization does not support @=: " ); 150 setSize( at->dimension ); 145 151 } 146 152 … … 150 156 151 157 private: 152 void setSize( Expression * expr ) { 153 if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) { 154 try { 155 size = constExpr->intValue(); 156 PRINT( std::cerr << "array type with size: " << size << std::endl; ) 157 } catch ( SemanticErrorException & ) { 158 SemanticError( expr, "Constant expression of non-integral type in array dimension: " ); 159 } 160 } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 161 setSize( castExpr->get_arg() ); // xxx - need to perform the conversion specified by the cast 162 } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) { 163 if ( EnumInstType * inst = dynamic_cast< EnumInstType * > ( varExpr->result ) ) { 164 long long int value; 165 if ( inst->baseEnum->valueOf( varExpr->var, value ) ) { 166 size = value; 167 } 168 } 158 void setSize( Expression * expr ) { // replace this logic with an eval call 159 auto res = eval(expr); 160 if (res.second) { 161 size = res.first; 169 162 } else { 170 assertf( false, "unhandled expression in setSize: %s", toString( expr ).c_str() ); // xxx - if not a constant expression, it's not simple to determine how long the array actually is, which is necessary for initialization to be done correctly -- fix this163 SemanticError( expr->location, toString("Array designator must be a constant expression: ", expr) ); 171 164 } 172 165 } … … 592 585 } // namespace ResolvExpr 593 586 587 namespace ast { 588 /// create a new MemberIterator that traverses a type correctly 589 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); 590 591 /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry 592 class SimpleIterator final : public MemberIterator { 593 CodeLocation location; 594 readonly< Type > type = nullptr; 595 public: 596 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} 597 598 void setPosition( 599 std::deque< ptr< Expr > >::const_iterator begin, 600 std::deque< ptr< Expr > >::const_iterator end 601 ) override { 602 if ( begin != end ) { 603 SemanticError( location, "Un-designated initializer given non-empty designator" ); 604 } 605 } 606 607 std::deque< InitAlternative > operator* () const override { return first(); } 608 609 operator bool() const override { return type; } 610 611 SimpleIterator & bigStep() override { return smallStep(); } 612 SimpleIterator & smallStep() override { 613 type = nullptr; // empty on increment because no members 614 return *this; 615 } 616 617 const Type * getType() override { return type; } 618 619 const Type * getNext() override { return type; } 620 621 std::deque< InitAlternative > first() const override { 622 if ( type ) return { InitAlternative{ type, new Designation{ location } } }; 623 return {}; 624 } 625 }; 626 627 /// Iterates array types 628 class ArrayIterator final : public MemberIterator { 629 CodeLocation location; 630 readonly< ArrayType > array = nullptr; 631 readonly< Type > base = nullptr; 632 size_t index = 0; 633 size_t size = 0; 634 std::unique_ptr< MemberIterator > memberIter; 635 636 void setSize( const Expr * expr ) { 637 auto res = eval(expr); 638 if ( ! res.second ) { 639 SemanticError( location, 640 toString("Array designator must be a constant expression: ", expr ) ); 641 } 642 size = res.first; 643 } 644 645 public: 646 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) 647 : location( loc ), array( at ), base( at->base ) { 648 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; ) 649 memberIter.reset( createMemberIterator( loc, base ) ); 650 if ( at->isVarLen ) { 651 SemanticError( location, at, "VLA initialization does not support @=: " ); 652 } 653 setSize( at->dimension ); 654 } 655 656 void setPosition( const Expr * expr ) { 657 // need to permit integer-constant-expressions, including: integer constants, 658 // enumeration constants, character constants, sizeof expressions, alignof expressions, 659 // cast expressions 660 if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) { 661 try { 662 index = constExpr->intValue(); 663 } catch ( SemanticErrorException & ) { 664 SemanticError( expr, 665 "Constant expression of non-integral type in array designator: " ); 666 } 667 } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) { 668 setPosition( castExpr->arg ); 669 } else if ( 670 dynamic_cast< const SizeofExpr * >( expr ) 671 || dynamic_cast< const AlignofExpr * >( expr ) 672 ) { 673 index = 0; 674 } else { 675 assertf( false, 676 "bad designator given to ArrayIterator: %s", toString( expr ).c_str() ); 677 } 678 } 679 680 void setPosition( 681 std::deque< ptr< Expr > >::const_iterator begin, 682 std::deque< ptr< Expr > >::const_iterator end 683 ) override { 684 if ( begin == end ) return; 685 686 setPosition( *begin ); 687 memberIter->setPosition( ++begin, end ); 688 } 689 690 std::deque< InitAlternative > operator* () const override { return first(); } 691 692 operator bool() const override { return index < size; } 693 694 ArrayIterator & bigStep() override { 695 PRINT( std::cerr << "bigStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 696 ++index; 697 memberIter.reset( index < size ? createMemberIterator( location, base ) : nullptr ); 698 return *this; 699 } 700 701 ArrayIterator & smallStep() override { 702 PRINT( std::cerr << "smallStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 703 if ( memberIter ) { 704 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; ) 705 memberIter->smallStep(); 706 if ( *memberIter ) { 707 PRINT( std::cerr << "has valid member iter" << std::endl; ) 708 return *this; 709 } 710 } 711 return bigStep(); 712 } 713 714 const Type * getType() override { return array; } 715 716 const Type * getNext() override { return base; } 717 718 std::deque< InitAlternative > first() const override { 719 PRINT( std::cerr << "first in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 720 if ( memberIter && *memberIter ) { 721 std::deque< InitAlternative > ret = memberIter->first(); 722 for ( InitAlternative & alt : ret ) { 723 alt.designation.get_and_mutate()->designators.emplace_front( 724 ConstantExpr::from_ulong( location, index ) ); 725 } 726 return ret; 727 } 728 return {}; 729 } 730 }; 731 732 class AggregateIterator : public MemberIterator { 733 protected: 734 using MemberList = std::vector< ptr< Decl > >; 735 736 CodeLocation location; 737 std::string kind; // for debug 738 std::string name; 739 const Type * inst; 740 const MemberList & members; 741 MemberList::const_iterator curMember; 742 bool atbegin = true; // false at first {small,big}Step 743 const Type * curType = nullptr; 744 std::unique_ptr< MemberIterator > memberIter = nullptr; 745 TypeSubstitution sub; 746 747 bool init() { 748 PRINT( std::cerr << "--init()--" << members.size() << std::endl; ) 749 if ( curMember != members.end() ) { 750 if ( auto field = curMember->as< ObjectDecl >() ) { 751 PRINT( std::cerr << "incremented to field: " << field << std::endl; ) 752 curType = field->get_type(); 753 memberIter.reset( createMemberIterator( location, curType ) ); 754 return true; 755 } 756 } 757 return false; 758 } 759 760 AggregateIterator( 761 const CodeLocation & loc, const std::string k, const std::string & n, const Type * i, 762 const MemberList & ms ) 763 : location( loc ), kind( k ), name( n ), inst( i ), members( ms ), curMember( ms.begin() ), 764 sub( genericSubstitution( i ) ) { 765 PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; ) 766 init(); 767 } 768 769 public: 770 void setPosition( 771 std::deque< ptr< Expr > >::const_iterator begin, 772 std::deque< ptr< Expr > >::const_iterator end 773 ) final { 774 if ( begin == end ) return; 775 776 if ( auto varExpr = begin->as< VariableExpr >() ) { 777 for ( curMember = members.begin(); curMember != members.end(); ++curMember ) { 778 if ( *curMember != varExpr->var ) continue; 779 780 ++begin; 781 782 memberIter.reset( createMemberIterator( location, varExpr->result ) ); 783 curType = varExpr->result; 784 atbegin = curMember == members.begin() && begin == end; 785 memberIter->setPosition( begin, end ); 786 return; 787 } 788 assertf( false, 789 "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() ); 790 } else { 791 assertf( false, 792 "bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() ); 793 } 794 } 795 796 std::deque< InitAlternative > operator* () const final { 797 if ( memberIter && *memberIter ) { 798 std::deque< InitAlternative > ret = memberIter->first(); 799 PRINT( std::cerr << "sub: " << sub << std::endl; ) 800 for ( InitAlternative & alt : ret ) { 801 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 802 alt.designation.get_and_mutate()->designators.emplace_front( 803 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 804 // need to substitute for generic types so that casts are to concrete types 805 PRINT( std::cerr << " type is: " << alt.type; ) 806 sub.apply( alt.type ); // also apply to designation?? 807 PRINT( std::cerr << " ==> " << alt.type << std::endl; ) 808 } 809 return ret; 810 } 811 return {}; 812 } 813 814 AggregateIterator & smallStep() final { 815 PRINT( std::cerr << "smallStep in " << kind << std::endl; ) 816 atbegin = false; 817 if ( memberIter ) { 818 PRINT( std::cerr << "has member iter, incrementing..." << std::endl; ) 819 memberIter->smallStep(); 820 if ( *memberIter ) { 821 PRINT( std::cerr << "success!" << std::endl; ) 822 return *this; 823 } 824 } 825 return bigStep(); 826 } 827 828 AggregateIterator & bigStep() override = 0; 829 830 const Type * getType() final { return inst; } 831 832 const Type * getNext() final { 833 return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr; 834 } 835 836 std::deque< InitAlternative > first() const final { 837 std::deque< InitAlternative > ret; 838 PRINT( std::cerr << "first " << kind << std::endl; ) 839 if ( memberIter && *memberIter ) { 840 PRINT( std::cerr << "adding children" << std::endl; ) 841 ret = memberIter->first(); 842 for ( InitAlternative & alt : ret ) { 843 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 844 alt.designation.get_and_mutate()->designators.emplace_front( 845 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 846 } 847 } 848 if ( atbegin ) { 849 // only add self if at the very beginning of the structure 850 PRINT( std::cerr << "adding self" << std::endl; ) 851 ret.emplace_front( inst, new Designation{ location } ); 852 } 853 return ret; 854 } 855 }; 856 857 class StructIterator final : public AggregateIterator { 858 public: 859 StructIterator( const CodeLocation & loc, const StructInstType * inst ) 860 : AggregateIterator( loc, "StructIterator", inst->name, inst, inst->base->members ) {} 861 862 operator bool() const override { 863 return curMember != members.end() || (memberIter && *memberIter); 864 } 865 866 StructIterator & bigStep() override { 867 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 868 atbegin = false; 869 memberIter = nullptr; 870 curType = nullptr; 871 while ( curMember != members.end() ) { 872 ++curMember; 873 if ( init() ) return *this; 874 } 875 return *this; 876 } 877 }; 878 879 class UnionIterator final : public AggregateIterator { 880 public: 881 UnionIterator( const CodeLocation & loc, const UnionInstType * inst ) 882 : AggregateIterator( loc, "UnionIterator", inst->name, inst, inst->base->members ) {} 883 884 operator bool() const override { return memberIter && *memberIter; } 885 886 UnionIterator & bigStep() override { 887 // unions only initialize one member 888 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 889 atbegin = false; 890 memberIter = nullptr; 891 curType = nullptr; 892 curMember = members.end(); 893 return *this; 894 } 895 }; 896 897 class TupleIterator final : public AggregateIterator { 898 public: 899 TupleIterator( const CodeLocation & loc, const TupleType * inst ) 900 : AggregateIterator( 901 loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members 902 ) {} 903 904 operator bool() const override { 905 return curMember != members.end() || (memberIter && *memberIter); 906 } 907 908 TupleIterator & bigStep() override { 909 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 910 atbegin = false; 911 memberIter = nullptr; 912 curType = nullptr; 913 while ( curMember != members.end() ) { 914 ++curMember; 915 if ( init() ) return *this; 916 } 917 return *this; 918 } 919 }; 920 921 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) { 922 if ( auto aggr = dynamic_cast< const ReferenceToType * >( type ) ) { 923 if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) { 924 return new StructIterator{ loc, sit }; 925 } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) { 926 return new UnionIterator{ loc, uit }; 927 } else { 928 assertf( 929 dynamic_cast< const EnumInstType * >( aggr ) 930 || dynamic_cast< const TypeInstType * >( aggr ), 931 "Encountered unhandled ReferenceToType in createMemberIterator: %s", 932 toString( type ).c_str() ); 933 return new SimpleIterator{ loc, type }; 934 } 935 } else if ( auto at = dynamic_cast< const ArrayType * >( type ) ) { 936 return new ArrayIterator{ loc, at }; 937 } else if ( auto tt = dynamic_cast< const TupleType * >( type ) ) { 938 return new TupleIterator{ loc, tt }; 939 } else { 940 return new SimpleIterator{ loc, type }; 941 } 942 } 943 944 CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() { 945 objStack.emplace_back( new SimpleIterator{ loc, type } ); 946 } 947 948 const Designation * CurrentObject::findNext( const Designation * designation ) { 949 using DesignatorChain = std::deque< ptr< Expr > >; 950 PRINT( std::cerr << "___findNext" << std::endl; ) 951 952 // find all the d's 953 std::vector< DesignatorChain > desigAlts{ {} }, newDesigAlts; 954 std::deque< const Type * > curTypes{ objStack.back()->getType() }, newTypes; 955 for ( const Expr * expr : designation->designators ) { 956 PRINT( std::cerr << "____untyped: " << expr << std::endl; ) 957 auto dit = desigAlts.begin(); 958 if ( auto nexpr = dynamic_cast< const NameExpr * >( expr ) ) { 959 for ( const Type * t : curTypes ) { 960 assert( dit != desigAlts.end() ); 961 962 DesignatorChain & d = *dit; 963 PRINT( std::cerr << "____actual: " << t << std::endl; ) 964 if ( auto refType = dynamic_cast< const ReferenceToType * >( t ) ) { 965 // concatenate identical field names 966 for ( const Decl * mem : refType->lookup( nexpr->name ) ) { 967 if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) { 968 PRINT( std::cerr << "____alt: " << field->type << std::endl; ) 969 DesignatorChain d2 = d; 970 d2.emplace_back( new VariableExpr{ expr->location, field } ); 971 newDesigAlts.emplace_back( std::move( d2 ) ); 972 newTypes.emplace_back( field->type ); 973 } 974 } 975 } 976 977 ++dit; 978 } 979 } else { 980 for ( const Type * t : curTypes ) { 981 assert( dit != desigAlts.end() ); 982 983 DesignatorChain & d = *dit; 984 if ( auto at = dynamic_cast< const ArrayType * >( t ) ) { 985 PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; ) 986 d.emplace_back( expr ); 987 newDesigAlts.emplace_back( d ); 988 newTypes.emplace_back( at->base ); 989 } 990 } 991 } 992 993 // reset queue 994 desigAlts = std::move( newDesigAlts ); 995 newDesigAlts.clear(); 996 curTypes = std::move( newTypes ); 997 newTypes.clear(); 998 assertf( desigAlts.size() == curTypes.size(), "Designator alternatives (%zu) and current types (%zu) out of sync", desigAlts.size(), curTypes.size() ); 999 } 1000 1001 if ( desigAlts.size() > 1 ) { 1002 SemanticError( designation, toString("Too many alternatives (", desigAlts.size(), ") for designation: ") ); 1003 } else if ( desigAlts.empty() ) { 1004 SemanticError( designation, "No reasonable alternatives for designation: " ); 1005 } 1006 1007 DesignatorChain & d = desigAlts.back(); 1008 PRINT( for ( Expression * expr : d ) { 1009 std::cerr << "____desig: " << expr << std::endl; 1010 } ) // for 1011 assertf( ! curTypes.empty(), "empty designator chosen"); 1012 1013 // set new designators 1014 assertf( ! objStack.empty(), "empty object stack when setting designation" ); 1015 Designation * actualDesignation = 1016 new Designation{ designation->location, DesignatorChain{d} }; 1017 objStack.back()->setPosition( d ); // destroys d 1018 return actualDesignation; 1019 } 1020 1021 void CurrentObject::setNext( const Designation * designation ) { 1022 PRINT( std::cerr << "____setNext" << designation << std::endl; ) 1023 assertf( ! objStack.empty(), "obj stack empty in setNext" ); 1024 objStack.back()->setPosition( designation->designators ); 1025 } 1026 1027 void CurrentObject::increment() { 1028 PRINT( std::cerr << "____increment" << std::endl; ) 1029 if ( objStack.empty() ) return; 1030 PRINT( std::cerr << *objStack.back() << std::endl; ) 1031 objStack.back()->smallStep(); 1032 } 1033 1034 void CurrentObject::enterListInit( const CodeLocation & loc ) { 1035 PRINT( std::cerr << "____entering list init" << std::endl; ) 1036 assertf( ! objStack.empty(), "empty obj stack entering list init" ); 1037 const ast::Type * type = objStack.back()->getNext(); 1038 assert( type ); 1039 objStack.emplace_back( createMemberIterator( loc, type ) ); 1040 } 1041 1042 void CurrentObject::exitListInit() { 1043 PRINT( std::cerr << "____exiting list init" << std::endl; ) 1044 assertf( ! objStack.empty(), "objstack empty" ); 1045 objStack.pop_back(); 1046 if ( ! objStack.empty() ) { 1047 PRINT( std::cerr << *objStack.back() << std::endl; ) 1048 objStack.back()->bigStep(); 1049 } 1050 } 1051 1052 std::deque< InitAlternative > CurrentObject::getOptions() { 1053 PRINT( std::cerr << "____getting current options" << std::endl; ) 1054 assertf( ! objStack.empty(), "objstack empty in getOptions" ); 1055 return **objStack.back(); 1056 } 1057 1058 const Type * CurrentObject::getCurrentType() { 1059 PRINT( std::cerr << "____getting current type" << std::endl; ) 1060 assertf( ! objStack.empty(), "objstack empty in getCurrentType" ); 1061 return objStack.back()->getNext(); 1062 } 1063 } 1064 594 1065 // Local Variables: // 595 1066 // tab-width: 4 // -
src/ResolvExpr/CurrentObject.h
r7951100 rb067d9b 16 16 #pragma once 17 17 18 #include <deque> 18 19 #include <list> // for list 20 #include <memory> // for unique_ptr 19 21 #include <stack> // for stack 22 #include <vector> 23 24 #include "AST/Node.hpp" // for ptr 25 #include "Common/CodeLocation.h" 20 26 21 27 class Designation; … … 52 58 } // namespace ResolvExpr 53 59 60 namespace ast { 61 // AST class types 62 class Designation; 63 struct InitAlternative; 64 class Type; 65 66 /// Iterates members of a type by initializer 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 }; 104 105 /// Builds initializer lists in resolution 106 class CurrentObject final { 107 std::vector< std::shared_ptr<MemberIterator> > objStack; 108 109 public: 110 CurrentObject() = default; 111 CurrentObject( const CodeLocation & loc, const Type * type ); 112 113 /// resolves unresolved designation 114 const Designation * findNext( const Designation * designation ); 115 /// sets current position using the resolved designation 116 void setNext( const ast::Designation * designation ); 117 /// steps to next sub-object of current object 118 void increment(); 119 /// sets new current object for the duration of this brace-enclosed intializer-list 120 void enterListInit( const CodeLocation & loc ); 121 /// restores previous current object 122 void exitListInit(); 123 /// produces a list of alternatives (Type *, Designation *) for the current sub-object's 124 /// initializer. 125 std::deque< InitAlternative > getOptions(); 126 /// produces the type of the current object but no subobjects 127 const Type * getCurrentType(); 128 }; 129 } // namespace ast 130 54 131 // Local Variables: // 55 132 // tab-width: 4 // -
src/ResolvExpr/ExplodedActual.cc
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Alternative.h--7 // ExplodedActual.cc -- 8 8 // 9 9 // Author : Aaron B. Moss … … 24 24 } 25 25 } 26 27 // Local Variables: // 28 // tab-width: 4 // 29 // mode: c++ // 30 // compile-command: "make install" // 31 // End: // -
src/ResolvExpr/ExplodedActual.h
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Alternative.h --7 // ExplodedActual.h -- 8 8 // 9 9 // Author : Aaron B. Moss … … 32 32 33 33 ExplodedActual() : env(), cost(Cost::zero), exprs() {} 34 35 34 ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer ); 35 ExplodedActual(ExplodedActual&&) = default; 36 ExplodedActual& operator= (ExplodedActual&&) = default; 36 37 }; 37 38 } 39 40 // Local Variables: // 41 // tab-width: 4 // 42 // mode: c++ // 43 // compile-command: "make install" // 44 // End: // -
src/ResolvExpr/FindOpenVars.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 09:42:48 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun May 17 09:45:25 201513 // Update Count : 311 // Last Modified By : Andrew 12 // Last Modified On : Fri Jul 12 14:18:00 2019 13 // Update Count : 4 14 14 // 15 15 … … 19 19 #include <map> // for map<>::mapped_type 20 20 21 #include "AST/Pass.hpp" 22 #include "AST/Type.hpp" 21 23 #include "Common/PassVisitor.h" 22 24 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType (ptr ... … … 24 26 25 27 namespace ResolvExpr { 26 struct FindOpenVars : public WithGuards {27 FindOpenVars ( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );28 struct FindOpenVars_old : public WithGuards { 29 FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ); 28 30 29 void previsit( PointerType * pointerType );30 void previsit( ArrayType * arrayType );31 void previsit( FunctionType * functionType );32 void previsit( TupleType * tupleType );31 void previsit( const PointerType * pointerType ); 32 void previsit( const ArrayType * arrayType ); 33 void previsit( const FunctionType * functionType ); 34 void previsit( const TupleType * tupleType ); 33 35 34 void common_action( Type *type );36 void common_action( const Type *type ); 35 37 36 38 OpenVarSet &openVars, &closedVars; … … 39 41 }; 40 42 41 void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {42 PassVisitor<FindOpenVars > finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );43 void findOpenVars( const Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) { 44 PassVisitor<FindOpenVars_old> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen ); 43 45 type->accept( finder ); 44 46 } 45 47 46 FindOpenVars ::FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )48 FindOpenVars_old::FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) 47 49 : openVars( openVars ), closedVars( closedVars ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), nextIsOpen( firstIsOpen ) { 48 50 } 49 51 50 void FindOpenVars ::common_action( Type *type ) {52 void FindOpenVars_old::common_action( const Type * type ) { 51 53 if ( nextIsOpen ) { 52 for ( Type::ForallList::const_iterator i = type-> get_forall().begin(); i != type->get_forall().end(); ++i ) {54 for ( Type::ForallList::const_iterator i = type->forall.begin(); i != type->forall.end(); ++i ) { 53 55 openVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) }; 54 56 for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { … … 59 61 } 60 62 } else { 61 for ( Type::ForallList::const_iterator i = type-> get_forall().begin(); i != type->get_forall().end(); ++i ) {63 for ( Type::ForallList::const_iterator i = type->forall.begin(); i != type->forall.end(); ++i ) { 62 64 closedVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) }; 63 65 for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { … … 76 78 } 77 79 78 void FindOpenVars ::previsit(PointerType *pointerType) {80 void FindOpenVars_old::previsit(const PointerType * pointerType) { 79 81 common_action( pointerType ); 80 82 } 81 83 82 void FindOpenVars ::previsit(ArrayType *arrayType) {84 void FindOpenVars_old::previsit(const ArrayType * arrayType) { 83 85 common_action( arrayType ); 84 86 } 85 87 86 void FindOpenVars ::previsit(FunctionType *functionType) {88 void FindOpenVars_old::previsit(const FunctionType * functionType) { 87 89 common_action( functionType ); 88 90 nextIsOpen = ! nextIsOpen; … … 90 92 } 91 93 92 void FindOpenVars ::previsit(TupleType *tupleType) {94 void FindOpenVars_old::previsit(const TupleType * tupleType) { 93 95 common_action( tupleType ); 96 } 97 98 namespace { 99 struct FindOpenVars_new final : public ast::WithGuards { 100 ast::OpenVarSet & open; 101 ast::OpenVarSet & closed; 102 ast::AssertionSet & need; 103 ast::AssertionSet & have; 104 bool nextIsOpen; 105 106 FindOpenVars_new( 107 ast::OpenVarSet & o, ast::OpenVarSet & c, ast::AssertionSet & n, 108 ast::AssertionSet & h, FirstMode firstIsOpen ) 109 : open( o ), closed( c ), need( n ), have( h ), nextIsOpen( firstIsOpen ) {} 110 111 void previsit( const ast::FunctionType * type ) { 112 // mark open/closed variables 113 if ( nextIsOpen ) { 114 for ( const ast::TypeDecl * decl : type->forall ) { 115 open[ decl->name ] = ast::TypeDecl::Data{ decl }; 116 for ( const ast::DeclWithType * assert : decl->assertions ) { 117 need[ assert ].isUsed = false; 118 } 119 } 120 } else { 121 for ( const ast::TypeDecl * decl : type->forall ) { 122 closed[ decl->name ] = ast::TypeDecl::Data{ decl }; 123 for ( const ast::DeclWithType * assert : decl->assertions ) { 124 have[ assert ].isUsed = false; 125 } 126 } 127 } 128 129 // flip open variables for contained function types 130 nextIsOpen = ! nextIsOpen; 131 GuardAction( [this](){ nextIsOpen = ! nextIsOpen; } ); 132 } 133 134 }; 135 } 136 137 void findOpenVars( 138 const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed, 139 ast::AssertionSet & need, ast::AssertionSet & have, FirstMode firstIsOpen ) { 140 ast::Pass< FindOpenVars_new > finder{ open, closed, need, have, firstIsOpen }; 141 type->accept( finder ); 94 142 } 95 143 } // namespace ResolvExpr -
src/ResolvExpr/FindOpenVars.h
r7951100 rb067d9b 16 16 #pragma once 17 17 18 #include "AST/TypeEnvironment.hpp" // for AssertionSet, OpenVarSet 18 19 #include "ResolvExpr/TypeEnvironment.h" // for AssertionSet, OpenVarSet 19 20 20 21 class Type; 22 namespace ast { 23 class Type; 24 } 21 25 22 26 namespace ResolvExpr { 23 27 // Updates open and closed variables and their associated assertions 24 void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ); 28 void findOpenVars( const Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ); 29 30 enum FirstMode { FirstClosed, FirstOpen }; 31 32 // Updates open and closed variables and their associated assertions 33 void findOpenVars( 34 const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed, 35 ast::AssertionSet & need, ast::AssertionSet & have, FirstMode firstIsOpen ); 25 36 } // namespace ResolvExpr 26 37 -
src/ResolvExpr/Occurs.cc
r7951100 rb067d9b 24 24 struct Occurs : public WithVisitorRef<Occurs> { 25 25 Occurs( std::string varName, const TypeEnvironment &env ); 26 void previsit( TypeInstType * typeInst );26 void previsit( const TypeInstType * typeInst ); 27 27 28 28 bool result; … … 31 31 }; 32 32 33 bool occurs( Type *type, std::stringvarName, const TypeEnvironment &env ) {33 bool occurs( const Type *type, const std::string & varName, const TypeEnvironment &env ) { 34 34 PassVisitor<Occurs> occur( varName, env ); 35 35 type->accept( occur ); … … 45 45 } 46 46 47 void Occurs::previsit( TypeInstType * typeInst ) {47 void Occurs::previsit( const TypeInstType * typeInst ) { 48 48 /// std::cerr << "searching for vars: "; 49 49 /// std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cerr, " " ) ); -
src/ResolvExpr/PolyCost.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 09:50:12 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun May 17 09:52:02 201513 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 19 10:45:00 2019 13 // Update Count : 4 14 14 // 15 15 16 #include "AST/SymbolTable.hpp" 17 #include "AST/Type.hpp" 18 #include "AST/TypeEnvironment.hpp" 16 19 #include "Common/PassVisitor.h" 17 20 #include "SymTab/Indexer.h" // for Indexer … … 54 57 } 55 58 59 // TODO: When the old PolyCost is torn out get rid of the _new suffix. 60 struct PolyCost_new { 61 int result; 62 const ast::SymbolTable &symtab; 63 const ast::TypeEnvironment &env_; 64 65 PolyCost_new( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ) : 66 result( 0 ), symtab( symtab ), env_( env ) {} 67 68 void previsit( const ast::TypeInstType * type ) { 69 if ( const ast::EqvClass * eqv = env_.lookup( type->name ) ) /* && */ if ( eqv->bound ) { 70 if ( const ast::TypeInstType * otherType = eqv->bound.as< ast::TypeInstType >() ) { 71 if ( symtab.lookupType( otherType->name ) ) { 72 // Bound to opaque type. 73 result += 1; 74 } 75 } else { 76 // Bound to concrete type. 77 result += 1; 78 } 79 } 80 } 81 }; 82 83 int polyCost( 84 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env 85 ) { 86 ast::Pass<PolyCost_new> costing( symtab, env ); 87 type->accept( costing ); 88 return costing.pass.result; 89 } 90 56 91 } // namespace ResolvExpr 57 92 -
src/ResolvExpr/PtrsAssignable.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 11:44:11 2015 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:36:05 2016 13 // Update Count : 8 14 // 15 11 // Last Modified By : Andrew 12 // Last Modified On : Mon Jun 24 15:29:00 2019 13 // Update Count : 9 14 // 15 16 #include "typeops.h" 17 18 #include "AST/Pass.hpp" 19 #include "AST/Type.hpp" 20 #include "AST/TypeEnvironment.hpp" 16 21 #include "Common/PassVisitor.h" 17 22 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment … … 22 27 namespace ResolvExpr { 23 28 struct PtrsAssignable : public WithShortCircuiting { 24 PtrsAssignable( Type *dest, const TypeEnvironment &env );29 PtrsAssignable( const Type * dest, const TypeEnvironment &env ); 25 30 26 31 int get_result() const { return result; } 27 32 28 void previsit( Type * ) { visit_children = false; }29 30 void postvisit( VoidType * voidType );31 void postvisit( BasicType * basicType );32 void postvisit( PointerType * pointerType );33 void postvisit( ArrayType * arrayType );34 void postvisit( FunctionType * functionType );35 void postvisit( StructInstType * inst );36 void postvisit( UnionInstType * inst );37 void postvisit( EnumInstType * inst );38 void postvisit( TraitInstType * inst );39 void postvisit( TypeInstType * inst );40 void postvisit( TupleType * tupleType );41 void postvisit( VarArgsType * varArgsType );42 void postvisit( ZeroType * zeroType );43 void postvisit( OneType * oneType );33 void previsit( const Type * ) { visit_children = false; } 34 35 void postvisit( const VoidType * voidType ); 36 void postvisit( const BasicType * basicType ); 37 void postvisit( const PointerType * pointerType ); 38 void postvisit( const ArrayType * arrayType ); 39 void postvisit( const FunctionType * functionType ); 40 void postvisit( const StructInstType * inst ); 41 void postvisit( const UnionInstType * inst ); 42 void postvisit( const EnumInstType * inst ); 43 void postvisit( const TraitInstType * inst ); 44 void postvisit( const TypeInstType * inst ); 45 void postvisit( const TupleType * tupleType ); 46 void postvisit( const VarArgsType * varArgsType ); 47 void postvisit( const ZeroType * zeroType ); 48 void postvisit( const OneType * oneType ); 44 49 private: 45 Type *dest;50 const Type * dest; 46 51 int result; 47 52 const TypeEnvironment &env; 48 53 }; 49 54 50 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {55 int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) { 51 56 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 52 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {53 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {57 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 54 59 return ptrsAssignable( src, eqvClass->type, env ); 55 60 } // if 56 61 } // if 57 if ( dynamic_cast< VoidType* >( dest ) ) {62 if ( dynamic_cast< const VoidType* >( dest ) ) { 58 63 // void * = T * for any T is unsafe 59 64 // xxx - this should be safe, but that currently breaks the build … … 66 71 } 67 72 68 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}69 70 void PtrsAssignable::postvisit( VoidType * ) {73 PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 74 75 void PtrsAssignable::postvisit( const VoidType * ) { 71 76 // T * = void * is disallowed - this is a change from C, where any 72 77 // void * can be assigned or passed to a non-void pointer without a cast. 73 78 } 74 79 75 void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType) {}76 void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType) {}77 void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType) {}78 void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType) {}79 80 void PtrsAssignable::postvisit( __attribute__((unused)) StructInstType *inst) {}81 void PtrsAssignable::postvisit( __attribute__((unused)) UnionInstType *inst) {}82 83 void PtrsAssignable::postvisit( EnumInstType * ) {84 if ( dynamic_cast< BasicType* >( dest ) ) {80 void PtrsAssignable::postvisit( const BasicType * ) {} 81 void PtrsAssignable::postvisit( const PointerType * ) {} 82 void PtrsAssignable::postvisit( const ArrayType * ) {} 83 void PtrsAssignable::postvisit( const FunctionType * ) {} 84 85 void PtrsAssignable::postvisit( const StructInstType * ) {} 86 void PtrsAssignable::postvisit( const UnionInstType * ) {} 87 88 void PtrsAssignable::postvisit( const EnumInstType * ) { 89 if ( dynamic_cast< const BasicType* >( dest ) ) { 85 90 // int * = E *, etc. is safe. This isn't technically correct, as each 86 91 // enum has one basic type that it is compatible with, an that type can … … 92 97 } 93 98 94 void PtrsAssignable::postvisit( __attribute__((unused)) TraitInstType *inst) {}95 void PtrsAssignable::postvisit( TypeInstType *inst ) {96 if ( const EqvClass * eqvClass = env.lookup( inst->get_name()) ) {99 void PtrsAssignable::postvisit( const TraitInstType * ) {} 100 void PtrsAssignable::postvisit( const TypeInstType * inst ) { 101 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 97 102 if ( eqvClass->type ) { 98 103 // T * = S * for any S depends on the type bound to T … … 102 107 } 103 108 104 void PtrsAssignable::postvisit( __attribute__((unused)) TupleType *tupleType ) {} 105 void PtrsAssignable::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {} 106 void PtrsAssignable::postvisit( __attribute__((unused)) ZeroType *zeroType ) {} 107 void PtrsAssignable::postvisit( __attribute__((unused)) OneType *oneType ) {} 109 void PtrsAssignable::postvisit( const TupleType * ) {} 110 void PtrsAssignable::postvisit( const VarArgsType * ) {} 111 void PtrsAssignable::postvisit( const ZeroType * ) {} 112 void PtrsAssignable::postvisit( const OneType * ) {} 113 114 // TODO: Get rid of the `_new` suffix when the old version is removed. 115 struct PtrsAssignable_new : public ast::WithShortCircuiting { 116 const ast::Type * dst; 117 const ast::TypeEnvironment & typeEnv; 118 int result; 119 120 PtrsAssignable_new( const ast::Type * dst, const ast::TypeEnvironment & env ) : 121 dst( dst ), typeEnv( env ), result( 0 ) {} 122 123 void previsit( Type * ) { visit_children = false; } 124 125 void postvisit( const ast::EnumInstType * ) { 126 if ( dynamic_cast< const ast::BasicType * >( dst ) ) { 127 // int * = E *, etc. is safe. This isn't technically correct, as each 128 // enum has one basic type that it is compatible with, an that type can 129 // differ from enum to enum. Without replicating GCC's internal logic, 130 // there is no way to know which type this particular enum is compatible 131 // with, so punt on this for now. 132 result = 1; 133 } 134 } 135 void postvisit( const ast::TypeInstType * inst ) { 136 if ( const ast::EqvClass * eqv = typeEnv.lookup( inst->name ) ) { 137 if ( eqv->bound ) { 138 // T * = S * for any S depends on the type bound to T 139 result = ptrsAssignable( eqv->bound, dst, typeEnv ); 140 } 141 } 142 } 143 }; 144 145 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 146 const ast::TypeEnvironment & env ) { 147 if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 148 if ( const ast::EqvClass * eqv = env.lookup( dstAsInst->name ) ) { 149 return ptrsAssignable( src, eqv->bound, env ); 150 } 151 } 152 if ( dynamic_cast< const ast::VoidType * >( dst ) ) { 153 return -1; 154 } else { 155 ast::Pass<PtrsAssignable_new> visitor( dst, env ); 156 src->accept( visitor ); 157 return visitor.pass.result; 158 } 159 160 // see ticket #136 (this should be able to replace the visitor). 161 #if 0 162 if ( const ast::TypeInstType * dstAsTypeInst = 163 dynamic_cast< const ast::TypeInstType* >( dst ) ) { 164 if ( const ast::EqvClass * eqv = env.lookup( dstAsTypeInst->get_name() ) ) { 165 return ptrsAssignable( src, eqv->type, env ); 166 } // if 167 } // if 168 if ( dynamic_cast< VoidType* >( dst ) ) { 169 // void * = T * for any T is unsafe 170 // xxx - this should be safe, but that currently breaks the build 171 return -1; 172 } else if ( dynamic_cast< EnumInstType * >( src ) ) { 173 if ( dynamic_cast< BasicType * >( dst ) ) { 174 // int * = E *, etc. is safe. This isn't technically correct, as each 175 // enum has one basic type that it is compatible with, an that type can 176 // differ from enum to enum. Without replicating GCC's internal logic, 177 // there is no way to know which type this particular enum is compatible 178 // with, so punt on this for now. 179 return 1; 180 } 181 } else if ( const ast::TypeInstType * typeInstType = 182 dynamic_cast< const ast::TypeInstType * >( src ) ) { 183 if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) { 184 if ( eqv->bound ) { 185 // T * = S * for any S depends on the type bound to T 186 return ptrsAssignable( eqv->bound, dst, env ); 187 } 188 } 189 } 190 return 0; 191 #endif 192 } 108 193 109 194 } // namespace ResolvExpr -
src/ResolvExpr/PtrsCastable.cc
r7951100 rb067d9b 14 14 // 15 15 16 #include "AST/Decl.hpp" 17 #include "AST/Pass.hpp" 18 #include "AST/Type.hpp" 19 #include "AST/TypeEnvironment.hpp" 16 20 #include "Common/PassVisitor.h" 17 21 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment … … 23 27 24 28 namespace ResolvExpr { 25 struct PtrsCastable : public WithShortCircuiting {29 struct PtrsCastable_old : public WithShortCircuiting { 26 30 public: 27 PtrsCastable ( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );31 PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 28 32 29 33 int get_result() const { return result; } 30 34 31 void previsit( Type * ) { visit_children = false; }32 33 void postvisit( VoidType * voidType );34 void postvisit( BasicType * basicType );35 void postvisit( PointerType * pointerType );36 void postvisit( ArrayType * arrayType );37 void postvisit( FunctionType * functionType );38 void postvisit( StructInstType * inst );39 void postvisit( UnionInstType * inst );40 void postvisit( EnumInstType * inst );41 void postvisit( TraitInstType * inst );42 void postvisit( TypeInstType * inst );43 void postvisit( TupleType * tupleType );44 void postvisit( VarArgsType * varArgsType );45 void postvisit( ZeroType * zeroType );46 void postvisit( OneType * oneType );35 void previsit( const Type * ) { visit_children = false; } 36 37 void postvisit( const VoidType * voidType ); 38 void postvisit( const BasicType * basicType ); 39 void postvisit( const PointerType * pointerType ); 40 void postvisit( const ArrayType * arrayType ); 41 void postvisit( const FunctionType * functionType ); 42 void postvisit( const StructInstType * inst ); 43 void postvisit( const UnionInstType * inst ); 44 void postvisit( const EnumInstType * inst ); 45 void postvisit( const TraitInstType * inst ); 46 void postvisit( const TypeInstType * inst ); 47 void postvisit( const TupleType * tupleType ); 48 void postvisit( const VarArgsType * varArgsType ); 49 void postvisit( const ZeroType * zeroType ); 50 void postvisit( const OneType * oneType ); 47 51 private: 48 Type *dest;52 const Type * dest; 49 53 int result; 50 54 const TypeEnvironment &env; … … 53 57 54 58 namespace { 55 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {56 if ( dynamic_cast< FunctionType* >( src ) ) {59 int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 60 if ( dynamic_cast< const FunctionType* >( src ) ) { 57 61 return -1; 58 } else if ( TypeInstType *typeInst = dynamic_cast<TypeInstType* >( src ) ) {59 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name()) ) {60 if ( TypeDecl *tyDecl = dynamic_cast<TypeDecl* >( ntDecl ) ) {61 if ( tyDecl-> get_kind()== TypeDecl::Ftype ) {62 } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) { 63 if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) { 64 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) { 65 if ( tyDecl->kind == TypeDecl::Ftype ) { 62 66 return -1; 63 67 } // if 64 68 } //if 65 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 66 70 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 67 71 return -1; … … 71 75 return 1; 72 76 } 73 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {77 int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 74 78 return -1 * objectCast( src, env, indexer ); // reverse the sense of objectCast 75 79 } 76 80 } 77 81 78 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {79 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {80 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {82 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 83 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 81 85 // xxx - should this be ptrsCastable? 82 86 return ptrsAssignable( src, eqvClass->type, env ); 83 87 } // if 84 88 } // if 85 if ( dynamic_cast< VoidType* >( dest ) ) {89 if ( dynamic_cast< const VoidType* >( dest ) ) { 86 90 return objectCast( src, env, indexer ); 87 91 } else { 88 PassVisitor<PtrsCastable > ptrs( dest, env, indexer );92 PassVisitor<PtrsCastable_old> ptrs( dest, env, indexer ); 89 93 src->accept( ptrs ); 90 94 return ptrs.pass.get_result(); … … 92 96 } 93 97 94 PtrsCastable ::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )98 PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) 95 99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) { 96 100 } 97 101 98 void PtrsCastable ::postvisit(VoidType * ) {99 result = objectCast( dest, env, indexer ); 100 } 101 102 void PtrsCastable ::postvisit(BasicType * ) {103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable ::postvisit(PointerType * ) {107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable ::postvisit(ArrayType * ) {111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable ::postvisit(FunctionType * ) {102 void PtrsCastable_old::postvisit( const VoidType * ) { 103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( const BasicType * ) { 107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( const PointerType * ) { 111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( const ArrayType * ) { 115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( const FunctionType * ) { 115 119 // result = -1; 116 120 result = functionCast( dest, env, indexer ); 117 121 } 118 122 119 void PtrsCastable ::postvisit(StructInstType * ) {120 result = objectCast( dest, env, indexer ); 121 } 122 123 void PtrsCastable ::postvisit(UnionInstType * ) {124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable ::postvisit(EnumInstType * ) {128 if ( dynamic_cast< EnumInstType* >( dest ) ) {123 void PtrsCastable_old::postvisit( const StructInstType * ) { 124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( const UnionInstType * ) { 128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( const EnumInstType * ) { 132 if ( dynamic_cast< const EnumInstType * >( dest ) ) { 129 133 result = 1; 130 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {131 if ( bt-> get_kind()== BasicType::SignedInt ) {134 } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) { 135 if ( bt->kind == BasicType::SignedInt ) { 132 136 result = 0; 133 137 } else { … … 139 143 } 140 144 141 void PtrsCastable ::postvisit(TraitInstType * ) {}142 143 void PtrsCastable ::postvisit(TypeInstType *inst) {145 void PtrsCastable_old::postvisit( const TraitInstType * ) {} 146 147 void PtrsCastable_old::postvisit( const TypeInstType *inst ) { 144 148 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 145 149 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 146 150 } 147 151 148 void PtrsCastable::postvisit( TupleType * ) { 149 result = objectCast( dest, env, indexer ); 150 } 151 152 void PtrsCastable::postvisit( VarArgsType * ) { 153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable::postvisit( ZeroType * ) { 157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable::postvisit( OneType * ) { 161 result = objectCast( dest, env, indexer ); 162 } 152 void PtrsCastable_old::postvisit( const TupleType * ) { 153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( const VarArgsType * ) { 157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( const ZeroType * ) { 161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( const OneType * ) { 165 result = objectCast( dest, env, indexer ); 166 } 167 168 namespace { 169 // can this type be cast to an object (1 for yes, -1 for no) 170 int objectCast( 171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 172 ) { 173 if ( dynamic_cast< const ast::FunctionType * >( src ) ) { 174 return -1; 175 } else if ( auto inst = dynamic_cast< const ast::TypeInstType * >( src ) ) { 176 if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) { 177 if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) { 178 if ( tyDecl->kind == ast::TypeVar::Ftype ) { 179 return -1; 180 } 181 } 182 } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) { 183 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) { 184 return -1; 185 } 186 } 187 } 188 189 return 1; 190 } 191 192 // can this type be cast to a function (inverse of objectCast) 193 int functionCast( 194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 195 ) { 196 return -1 * objectCast( src, env, symtab ); 197 } 198 199 class PtrsCastable_new : public ast::WithShortCircuiting { 200 const ast::Type * dst; 201 const ast::TypeEnvironment & env; 202 const ast::SymbolTable & symtab; 203 public: 204 int result; 205 206 PtrsCastable_new( 207 const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 208 : dst( d ), env( e ), symtab( syms ), result( 0 ) {} 209 210 void previsit( const ast::Type * ) { visit_children = false; } 211 212 void postvisit( const ast::VoidType * ) { 213 result = objectCast( dst, env, symtab ); 214 } 215 216 void postvisit( const ast::BasicType * ) { 217 result = objectCast( dst, env, symtab ); 218 } 219 220 void postvisit( const ast::PointerType * ) { 221 result = objectCast( dst, env, symtab ); 222 } 223 224 void postvisit( const ast::ArrayType * ) { 225 result = objectCast( dst, env, symtab ); 226 } 227 228 void postvisit( const ast::FunctionType * ) { 229 result = functionCast( dst, env, symtab ); 230 } 231 232 void postvisit( const ast::StructInstType * ) { 233 result = objectCast( dst, env, symtab ); 234 } 235 236 void postvisit( const ast::UnionInstType * ) { 237 result = objectCast( dst, env, symtab ); 238 } 239 240 void postvisit( const ast::EnumInstType * ) { 241 if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) { 242 result = 1; 243 } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) { 244 if ( bt->kind == ast::BasicType::SignedInt ) { 245 result = 0; 246 } else { 247 result = 1; 248 } 249 } else { 250 result = objectCast( dst, env, symtab ); 251 } 252 } 253 254 void postvisit( const ast::TraitInstType * ) {} 255 256 void postvisit( const ast::TypeInstType * inst ) { 257 // check trait and destination type are both object or both function 258 result = objectCast( inst, env, symtab ) == objectCast( dst, env, symtab ) ? 1 : -1; 259 } 260 261 void postvisit( const ast::TupleType * ) { 262 result = objectCast( dst, env, symtab ); 263 } 264 265 void postvisit( const ast::VarArgsType * ) { 266 result = objectCast( dst, env, symtab ); 267 } 268 269 void postvisit( const ast::ZeroType * ) { 270 result = objectCast( dst, env, symtab ); 271 } 272 273 void postvisit( const ast::OneType * ) { 274 result = objectCast( dst, env, symtab ); 275 } 276 277 }; 278 } // anonymous namespace 279 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 283 ) { 284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { 285 if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) { 286 return ptrsAssignable( src, eqvClass->bound, env ); 287 } 288 } 289 290 if ( dynamic_cast< const ast::VoidType * >( dst ) ) { 291 return objectCast( src, env, symtab ); 292 } else { 293 ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab }; 294 src->accept( ptrs ); 295 return ptrs.pass.result; 296 } 297 } 298 163 299 } // namespace ResolvExpr 164 300 -
src/ResolvExpr/RenameVars.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:05:18 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 17:36:32 201613 // Update Count : 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 20 17:39:00 2019 13 // Update Count : 8 14 14 // 15 15 … … 19 19 #include <utility> // for pair 20 20 21 #include "AST/Pass.hpp" 22 #include "AST/Type.hpp" 21 23 #include "Common/PassVisitor.h" 24 #include "Common/ScopedMap.h" 22 25 #include "Common/SemanticError.h" // for SemanticError 23 26 #include "RenameVars.h" … … 28 31 29 32 namespace ResolvExpr { 30 namespace {31 struct RenameVars {32 RenameVars();33 void reset();34 33 35 void previsit( TypeInstType * instType ); 36 void previsit( Type * ); 37 void postvisit( Type * ); 34 namespace { 35 class RenamingData { 36 int level = 0; 37 int resetCount = 0; 38 ScopedMap< std::string, std::string > nameMap; 38 39 39 private: 40 int level, resetCount; 41 std::list< std::map< std::string, std::string > > mapStack; 42 }; 43 44 PassVisitor<RenameVars> global_renamer; 45 } // namespace 46 47 void renameTyVars( Type * t ) { 48 t->accept( global_renamer ); 49 } 50 51 void resetTyVarRenaming() { 52 global_renamer.pass.reset(); 53 } 54 55 namespace { 56 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 57 mapStack.push_front( std::map< std::string, std::string >() ); 40 public: 41 void reset() { 42 level = 0; 43 ++resetCount; 58 44 } 59 45 60 void RenameVars::reset() { 61 level = 0; 62 resetCount++; 46 using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator; 47 48 void rename( TypeInstType * type ) { 49 mapConstIterator it = nameMap.find( type->name ); 50 if ( it != nameMap.end() ) { 51 type->name = it->second; 52 } 63 53 } 64 54 65 void RenameVars::previsit( TypeInstType * instType ) { 66 previsit( (Type *)instType ); 67 std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name ); 68 if ( i != mapStack.front().end() ) { 69 instType->name = i->second; 70 } // if 71 } 72 73 void RenameVars::previsit( Type * type ) { 55 void openLevel( Type * type ) { 74 56 if ( ! type->forall.empty() ) { 75 // copies current name mapping into new mapping 76 mapStack.push_front( mapStack.front() ); 57 nameMap.beginScope(); 77 58 // renames all "forall" type names to `_${level}_${name}' 78 59 for ( auto td : type->forall ) { … … 80 61 output << "_" << resetCount << "_" << level << "_" << td->name; 81 62 std::string newname( output.str() ); 82 mapStack.front()[ td->get_name() ] = newname;63 nameMap[ td->get_name() ] = newname; 83 64 td->name = newname; 84 65 // ditto for assertion names, the next level in … … 89 70 } 90 71 91 void RenameVars::postvisit( Type * type ) { 92 // clears name mapping added by typeBefore() 93 if ( ! type->forall.empty() ) { 94 mapStack.pop_front(); 95 } // if 72 void closeLevel( Type * type ) { 73 if ( !type->forall.empty() ) { 74 nameMap.endScope(); 75 } 96 76 } 97 } // namespace 77 78 const ast::TypeInstType * rename( const ast::TypeInstType * type ) { 79 mapConstIterator it = nameMap.find( type->name ); 80 if ( it != nameMap.end() ) { 81 ast::TypeInstType * mutType = ast::mutate( type ); 82 mutType->name = it->second; 83 type = mutType; 84 } 85 return type; 86 } 87 88 template<typename NodeT> 89 const NodeT * openLevel( const NodeT * type ) { 90 if ( !type->forall.empty() ) { 91 nameMap.beginScope(); 92 // Load new names from this forall clause and perform renaming. 93 NodeT * mutType = ast::mutate( type ); 94 for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) { 95 std::ostringstream output; 96 output << "_" << resetCount << "_" << level << "_" << td->name; 97 std::string newname( output.str() ); 98 nameMap[ td->name ] = newname; 99 ++level; 100 101 ast::TypeDecl * decl = ast::mutate( td.get() ); 102 decl->name = newname; 103 td = decl; 104 } 105 } 106 return type; 107 } 108 109 template<typename NodeT> 110 const NodeT * closeLevel( const NodeT * type ) { 111 if ( !type->forall.empty() ) { 112 nameMap.endScope(); 113 } 114 return type; 115 } 116 }; 117 118 // Global State: 119 RenamingData renaming; 120 121 struct RenameVars { 122 void previsit( TypeInstType * instType ) { 123 renaming.openLevel( (Type*)instType ); 124 renaming.rename( instType ); 125 } 126 void previsit( Type * type ) { 127 renaming.openLevel( type ); 128 } 129 void postvisit( Type * type ) { 130 renaming.closeLevel( type ); 131 } 132 133 const ast::FunctionType * previsit( const ast::FunctionType * type ) { 134 return renaming.openLevel( type ); 135 } 136 const ast::StructInstType * previsit( const ast::StructInstType * type ) { 137 return renaming.openLevel( type ); 138 } 139 const ast::UnionInstType * previsit( const ast::UnionInstType * type ) { 140 return renaming.openLevel( type ); 141 } 142 const ast::TraitInstType * previsit( const ast::TraitInstType * type ) { 143 return renaming.openLevel( type ); 144 } 145 const ast::TypeInstType * previsit( const ast::TypeInstType * type ) { 146 return renaming.rename( renaming.openLevel( type ) ); 147 } 148 const ast::ParameterizedType * postvisit( const ast::ParameterizedType * type ) { 149 return renaming.closeLevel( type ); 150 } 151 }; 152 153 } // namespace 154 155 void renameTyVars( Type * t ) { 156 PassVisitor<RenameVars> renamer; 157 t->accept( renamer ); 158 } 159 160 const ast::Type * renameTyVars( const ast::Type * t ) { 161 ast::Pass<RenameVars> renamer; 162 return t->accept( renamer ); 163 } 164 165 void resetTyVarRenaming() { 166 renaming.reset(); 167 } 168 98 169 } // namespace ResolvExpr 99 170 -
src/ResolvExpr/RenameVars.h
r7951100 rb067d9b 23 23 #include "SynTree/Visitor.h" // for Visitor 24 24 25 namespace ast { 26 class Type; 27 } 28 25 29 namespace ResolvExpr { 26 30 /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID 27 31 void renameTyVars( Type * ); 32 const ast::Type * renameTyVars( const ast::Type * ); 28 33 29 34 /// resets internal state of renamer to avoid overflow -
src/ResolvExpr/ResolveTypeof.cc
r7951100 rb067d9b 18 18 #include <cassert> // for assert 19 19 20 #include "AST/CVQualifiers.hpp" 21 #include "AST/Node.hpp" 22 #include "AST/Pass.hpp" 23 #include "AST/Type.hpp" 24 #include "AST/TypeEnvironment.hpp" 20 25 #include "Common/PassVisitor.h" // for PassVisitor 26 #include "Common/utility.h" // for copy 21 27 #include "Resolver.h" // for resolveInVoidContext 22 28 #include "SynTree/Expression.h" // for Expression … … 42 48 } 43 49 44 class ResolveTypeof : public WithShortCircuiting {50 class ResolveTypeof_old : public WithShortCircuiting { 45 51 public: 46 ResolveTypeof ( const SymTab::Indexer &indexer ) : indexer( indexer ) {}52 ResolveTypeof_old( const SymTab::Indexer &indexer ) : indexer( indexer ) {} 47 53 void premutate( TypeofType *typeofType ); 48 54 Type * postmutate( TypeofType *typeofType ); … … 53 59 54 60 Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) { 55 PassVisitor<ResolveTypeof > mutator( indexer );61 PassVisitor<ResolveTypeof_old> mutator( indexer ); 56 62 return type->acceptMutator( mutator ); 57 63 } 58 64 59 void ResolveTypeof ::premutate( TypeofType * ) {65 void ResolveTypeof_old::premutate( TypeofType * ) { 60 66 visit_children = false; 61 67 } 62 68 63 Type * ResolveTypeof ::postmutate( TypeofType *typeofType ) {69 Type * ResolveTypeof_old::postmutate( TypeofType *typeofType ) { 64 70 #if 0 65 71 std::cerr << "resolving typeof: "; … … 67 73 std::cerr << std::endl; 68 74 #endif 69 if ( typeofType->expr ) { 75 // pass on null expression 76 if ( ! typeofType->expr ) return typeofType; 77 78 bool isBasetypeof = typeofType->is_basetypeof; 79 auto oldQuals = typeofType->get_qualifiers().val; 80 81 Type* newType; 82 if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) { 83 // typeof wrapping type 84 newType = tyExpr->type; 85 tyExpr->type = nullptr; 86 delete tyExpr; 87 } else { 88 // typeof wrapping expression 70 89 Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer ); 71 90 assert( newExpr->result && ! newExpr->result->isVoid() ); 72 Type *newType = newExpr->result;91 newType = newExpr->result; 73 92 newExpr->result = nullptr; 74 93 delete typeofType; 75 94 delete newExpr; 95 } 96 97 // clear qualifiers for base, combine with typeoftype quals in any case 98 if ( isBasetypeof ) { 99 // replace basetypeof(<enum>) by int 100 if ( dynamic_cast<EnumInstType*>(newType) ) { 101 Type* newerType = 102 new BasicType{ newType->get_qualifiers(), BasicType::SignedInt, 103 newType->attributes }; 104 delete newType; 105 newType = newerType; 106 } 107 newType->get_qualifiers().val 108 = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals; 109 } else { 110 newType->get_qualifiers().val |= oldQuals; 111 } 112 113 return newType; 114 } 115 116 namespace { 117 struct ResolveTypeof_new : public ast::WithShortCircuiting { 118 const ast::SymbolTable & localSymtab; 119 120 ResolveTypeof_new( const ast::SymbolTable & syms ) : localSymtab( syms ) {} 121 122 void premutate( const ast::TypeofType * ) { visit_children = false; } 123 124 const ast::Type * postmutate( const ast::TypeofType * typeofType ) { 125 // pass on null expression 126 if ( ! typeofType->expr ) return typeofType; 127 128 ast::ptr< ast::Type > newType; 129 if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) { 130 // typeof wrapping type 131 newType = tyExpr->type; 132 } else { 133 // typeof wrapping expression 134 ast::TypeEnvironment dummy; 135 ast::ptr< ast::Expr > newExpr = 136 resolveInVoidContext( typeofType->expr, localSymtab, dummy ); 137 assert( newExpr->result && ! newExpr->result->isVoid() ); 138 newType = newExpr->result; 139 } 140 141 // clear qualifiers for base, combine with typeoftype quals regardless 142 if ( typeofType->kind == ast::TypeofType::Basetypeof ) { 143 // replace basetypeof(<enum>) by int 144 if ( newType.as< ast::EnumInstType >() ) { 145 newType = new ast::BasicType{ 146 ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) }; 147 } 148 reset_qualifiers( 149 newType, 150 ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers ); 151 } else { 152 add_qualifiers( newType, typeofType->qualifiers ); 153 } 154 76 155 return newType; 77 } // if 78 return typeofType; 79 } 156 } 157 }; 158 } // anonymous namespace 159 160 const ast::Type * resolveTypeof( const ast::Type * type , const ast::SymbolTable & symtab ) { 161 ast::Pass< ResolveTypeof_new > mutator{ symtab }; 162 return type->accept( mutator ); 163 } 164 80 165 } // namespace ResolvExpr 81 166 -
src/ResolvExpr/ResolveTypeof.h
r7951100 rb067d9b 20 20 class Indexer; 21 21 } // namespace SymTab 22 namespace ast { 23 class Type; 24 class SymbolTable; 25 } 22 26 23 27 namespace ResolvExpr { 24 28 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer ); 29 const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & ); 25 30 } // namespace ResolvExpr 26 31 -
src/ResolvExpr/Resolver.cc
r7951100 rb067d9b 7 7 // Resolver.cc -- 8 8 // 9 // Author : Richard C. Bilson9 // Author : Aaron B. Moss 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Feb 17 11:19:40 201813 // Update Count : 2 1311 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Wed May 29 11:00:00 2019 13 // Update Count : 241 14 14 // 15 15 16 #include <stddef.h> // for NULL17 16 #include <cassert> // for strict_dynamic_cast, assert 18 17 #include <memory> // for allocator, allocator_traits<... 19 18 #include <tuple> // for get 20 #include <vector> 19 #include <vector> // for vector 21 20 22 21 #include "Alternative.h" // for Alternative, AltList 23 22 #include "AlternativeFinder.h" // for AlternativeFinder, resolveIn... 23 #include "Candidate.hpp" 24 #include "CandidateFinder.hpp" 25 #include "CurrentObject.h" // for CurrentObject 26 #include "RenameVars.h" // for RenameVars, global_renamer 27 #include "Resolver.h" 28 #include "ResolvMode.h" // for ResolvMode 29 #include "typeops.h" // for extractResultType 30 #include "Unify.h" // for unify 31 #include "AST/Chain.hpp" 32 #include "AST/Decl.hpp" 33 #include "AST/Init.hpp" 34 #include "AST/Pass.hpp" 35 #include "AST/Print.hpp" 36 #include "AST/SymbolTable.hpp" 37 #include "AST/Type.hpp" 24 38 #include "Common/PassVisitor.h" // for PassVisitor 25 39 #include "Common/SemanticError.h" // for SemanticError 26 40 #include "Common/utility.h" // for ValueGuard, group_iterate 27 #include "CurrentObject.h" // for CurrentObject28 41 #include "InitTweak/GenInit.h" 29 42 #include "InitTweak/InitTweak.h" // for isIntrinsicSingleArgCallStmt 30 #include "RenameVars.h" // for RenameVars, global_renamer31 43 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 32 #include "ResolveTypeof.h" // for resolveTypeof33 #include "Resolver.h"34 44 #include "SymTab/Autogen.h" // for SizeType 35 45 #include "SymTab/Indexer.h" // for Indexer … … 42 52 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 43 53 #include "Tuples/Tuples.h" 44 #include "typeops.h" // for extractResultType 45 #include "Unify.h" // for unify 54 #include "Validate/FindSpecialDecls.h" // for SizeType 46 55 47 56 using namespace std; 48 57 49 58 namespace ResolvExpr { 50 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd {51 Resolver () {}52 Resolver ( const SymTab::Indexer & other ) {59 struct Resolver_old final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver_old>, public WithShortCircuiting, public WithStmtsToAdd { 60 Resolver_old() {} 61 Resolver_old( const SymTab::Indexer & other ) { 53 62 indexer = other; 54 63 } 55 64 56 void previsit( FunctionDecl *functionDecl ); 57 void postvisit( FunctionDecl *functionDecl ); 58 void previsit( ObjectDecl *objectDecll ); 59 void previsit( TypeDecl *typeDecl ); 65 void previsit( FunctionDecl * functionDecl ); 66 void postvisit( FunctionDecl * functionDecl ); 67 void previsit( ObjectDecl * objectDecll ); 60 68 void previsit( EnumDecl * enumDecl ); 61 69 void previsit( StaticAssertDecl * assertDecl ); … … 64 72 void previsit( PointerType * at ); 65 73 66 void previsit( ExprStmt * exprStmt );67 void previsit( AsmExpr * asmExpr );68 void previsit( AsmStmt * asmStmt );69 void previsit( IfStmt * ifStmt );70 void previsit( WhileStmt * whileStmt );71 void previsit( ForStmt * forStmt );72 void previsit( SwitchStmt * switchStmt );73 void previsit( CaseStmt * caseStmt );74 void previsit( BranchStmt * branchStmt );75 void previsit( ReturnStmt * returnStmt );76 void previsit( ThrowStmt * throwStmt );77 void previsit( CatchStmt * catchStmt );74 void previsit( ExprStmt * exprStmt ); 75 void previsit( AsmExpr * asmExpr ); 76 void previsit( AsmStmt * asmStmt ); 77 void previsit( IfStmt * ifStmt ); 78 void previsit( WhileStmt * whileStmt ); 79 void previsit( ForStmt * forStmt ); 80 void previsit( SwitchStmt * switchStmt ); 81 void previsit( CaseStmt * caseStmt ); 82 void previsit( BranchStmt * branchStmt ); 83 void previsit( ReturnStmt * returnStmt ); 84 void previsit( ThrowStmt * throwStmt ); 85 void previsit( CatchStmt * catchStmt ); 78 86 void previsit( WaitForStmt * stmt ); 79 void previsit( WithStmt * withStmt ); 80 81 void previsit( SingleInit *singleInit ); 82 void previsit( ListInit *listInit ); 83 void previsit( ConstructorInit *ctorInit ); 87 88 void previsit( SingleInit * singleInit ); 89 void previsit( ListInit * listInit ); 90 void previsit( ConstructorInit * ctorInit ); 84 91 private: 85 92 typedef std::list< Initializer * >::iterator InitIterator; … … 88 95 void handlePtrType( PtrType * type ); 89 96 90 void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );91 97 void fallbackInit( ConstructorInit * ctorInit ); 92 98 … … 96 102 }; 97 103 104 struct ResolveWithExprs : public WithIndexer, public WithGuards, public WithVisitorRef<ResolveWithExprs>, public WithShortCircuiting, public WithStmtsToAdd { 105 void previsit( FunctionDecl * ); 106 void previsit( WithStmt * ); 107 108 void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ); 109 }; 110 98 111 void resolve( std::list< Declaration * > translationUnit ) { 99 PassVisitor<Resolver > resolver;112 PassVisitor<Resolver_old> resolver; 100 113 acceptAll( translationUnit, resolver ); 101 114 } 102 115 103 void resolveDecl( Declaration * decl, const SymTab::Indexer & indexer ) {104 PassVisitor<Resolver > resolver( indexer );116 void resolveDecl( Declaration * decl, const SymTab::Indexer & indexer ) { 117 PassVisitor<Resolver_old> resolver( indexer ); 105 118 maybeAccept( decl, resolver ); 106 119 } 107 120 108 121 namespace { 109 struct DeleteFinder : public WithShortCircuiting {122 struct DeleteFinder_old : public WithShortCircuiting { 110 123 DeletedExpr * delExpr = nullptr; 111 124 void previsit( DeletedExpr * expr ) { … … 121 134 122 135 DeletedExpr * findDeletedExpr( Expression * expr ) { 123 PassVisitor<DeleteFinder > finder;136 PassVisitor<DeleteFinder_old> finder; 124 137 expr->accept( finder ); 125 138 return finder.pass.delExpr; … … 127 140 128 141 namespace { 129 struct StripCasts {142 struct StripCasts_old { 130 143 Expression * postmutate( CastExpr * castExpr ) { 131 144 if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) { … … 140 153 141 154 static void strip( Expression *& expr ) { 142 PassVisitor<StripCasts > stripper;155 PassVisitor<StripCasts_old> stripper; 143 156 expr = expr->acceptMutator( stripper ); 144 157 } 145 158 }; 146 159 147 void finishExpr( Expression *& expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {160 void finishExpr( Expression *& expr, const TypeEnvironment & env, TypeSubstitution * oldenv = nullptr ) { 148 161 expr->env = oldenv ? oldenv->clone() : new TypeSubstitution; 149 162 env.makeSubstitution( *expr->env ); 150 StripCasts ::strip( expr ); // remove unnecessary casts that may be buried in an expression163 StripCasts_old::strip( expr ); // remove unnecessary casts that may be buried in an expression 151 164 } 152 165 153 166 void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) { 154 167 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 155 if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {168 if ( typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) { 156 169 // cast is to the same type as its argument, so it's unnecessary -- remove it 157 170 expr = castExpr->arg; … … 165 178 166 179 namespace { 167 void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, bool adjust = false, bool prune = true, bool failFast = true) {180 void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{} ) { 168 181 assertf( untyped, "expected a non-null expression." ); 182 183 // xxx - this isn't thread-safe, but should work until we parallelize the resolver 184 static unsigned recursion_level = 0; 185 186 ++recursion_level; 169 187 TypeEnvironment env; 170 188 AlternativeFinder finder( indexer, env ); 171 finder.find( untyped, adjust, prune, failFast ); 189 finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode ); 190 --recursion_level; 172 191 173 192 #if 0 … … 182 201 #endif 183 202 203 // produce filtered list of alternatives 184 204 AltList candidates; 185 205 for ( Alternative & alt : finder.get_alternatives() ) { … … 189 209 } 190 210 191 // xxx - if > 1 alternative with same cost, ignore deleted and pick from remaining 192 // choose the lowest cost expression among the candidates 211 // produce invalid error if no candidates 212 if ( candidates.empty() ) { 213 SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") ); 214 } 215 216 // search for cheapest candidate 193 217 AltList winners; 194 findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) ); 195 if ( winners.size() == 0 ) { 196 SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") ); 197 } else if ( winners.size() != 1 ) { 218 bool seen_undeleted = false; 219 for ( unsigned i = 0; i < candidates.size(); ++i ) { 220 int c = winners.empty() ? -1 : candidates[i].cost.compare( winners.front().cost ); 221 222 if ( c > 0 ) continue; // skip more expensive than winner 223 224 if ( c < 0 ) { 225 // reset on new cheapest 226 seen_undeleted = ! findDeletedExpr( candidates[i].expr ); 227 winners.clear(); 228 } else /* if ( c == 0 ) */ { 229 if ( findDeletedExpr( candidates[i].expr ) ) { 230 // skip deleted expression if already seen one equivalent-cost not 231 if ( seen_undeleted ) continue; 232 } else if ( ! seen_undeleted ) { 233 // replace list of equivalent-cost deleted expressions with one non-deleted 234 winners.clear(); 235 seen_undeleted = true; 236 } 237 } 238 239 winners.emplace_back( std::move( candidates[i] ) ); 240 } 241 242 // promote alternative.cvtCost to .cost 243 // xxx - I don't know why this is done, but I'm keeping the behaviour from findMinCost 244 for ( Alternative& winner : winners ) { 245 winner.cost = winner.cvtCost; 246 } 247 248 // produce ambiguous errors, if applicable 249 if ( winners.size() != 1 ) { 198 250 std::ostringstream stream; 199 251 stream << "Cannot choose between " << winners.size() << " alternatives for " << kindStr << (kindStr != "" ? " " : "") << "expression\n"; … … 204 256 } 205 257 206 // there is one unambiguous interpretation - move the expression into the with statement 207 Alternative & choice = winners.front(); 208 if ( findDeletedExpr( choice.expr ) ) { 258 // single selected choice 259 Alternative& choice = winners.front(); 260 261 // fail on only expression deleted 262 if ( ! seen_undeleted ) { 209 263 SemanticError( untyped->location, choice.expr, "Unique best alternative includes deleted identifier in " ); 210 264 } 265 266 // xxx - check for ambiguous expressions 267 268 // output selected choice 211 269 alt = std::move( choice ); 212 270 } 213 271 214 272 /// resolve `untyped` to the expression whose alternative satisfies `pred` with the lowest cost; kindStr is used for providing better error messages 215 void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, bool adjust = false, bool prune = true, bool failFast = true) {273 void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{}) { 216 274 if ( ! untyped ) return; 217 275 Alternative choice; 218 findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, adjust, prune, failFast);276 findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, mode ); 219 277 finishExpr( choice.expr, choice.env, untyped->env ); 220 278 delete untyped; … … 231 289 232 290 // used in resolveTypeof 233 Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer &indexer ) {291 Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer ) { 234 292 TypeEnvironment env; 235 293 return resolveInVoidContext( expr, indexer, env ); 236 294 } 237 295 238 Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) {296 Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer, TypeEnvironment & env ) { 239 297 // it's a property of the language that a cast expression has either 1 or 0 interpretations; if it has 0 240 298 // interpretations, an exception has already been thrown. 241 299 assertf( expr, "expected a non-null expression." ); 242 300 243 static CastExpr untyped( nullptr ); // cast to void244 untyped .location = expr->location;301 CastExpr * untyped = new CastExpr( expr ); // cast to void 302 untyped->location = expr->location; 245 303 246 304 // set up and resolve expression cast to void 247 untyped.arg = expr;248 305 Alternative choice; 249 findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, true);306 findUnfinishedKindExpression( untyped, choice, indexer, "", standardAlternativeFilter, ResolvMode::withAdjustment() ); 250 307 CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( choice.expr ); 308 assert( castExpr ); 251 309 env = std::move( choice.env ); 252 310 … … 256 314 257 315 // unlink the arg so that it isn't deleted twice at the end of the program 258 untyped .arg = nullptr;316 untyped->arg = nullptr; 259 317 return ret; 260 318 } 261 319 262 void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {320 void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer ) { 263 321 resetTyVarRenaming(); 264 322 TypeEnvironment env; … … 269 327 } 270 328 271 void findSingleExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {329 void findSingleExpression( Expression *& untyped, const SymTab::Indexer & indexer ) { 272 330 findKindExpression( untyped, indexer, "", standardAlternativeFilter ); 273 331 } … … 288 346 if ( dynamic_cast< EnumInstType * >( type ) ) { 289 347 return true; 290 } else if ( BasicType * bt = dynamic_cast< BasicType * >( type ) ) {348 } else if ( BasicType * bt = dynamic_cast< BasicType * >( type ) ) { 291 349 return bt->isInteger(); 292 350 } else if ( dynamic_cast< ZeroType* >( type ) != nullptr || dynamic_cast< OneType* >( type ) != nullptr ) { … … 297 355 } 298 356 299 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {357 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer & indexer ) { 300 358 findKindExpression( untyped, indexer, "condition", isIntegralType ); 301 359 } 302 360 } 303 361 304 void Resolver::previsit( ObjectDecl *objectDecl ) { 305 Type *new_type = resolveTypeof( objectDecl->get_type(), indexer ); 306 objectDecl->set_type( new_type ); 307 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable 308 // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes 309 // initContext because of a function type can contain object declarations in the return and parameter types. So 310 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 311 // the RHS. 312 GuardValue( currentObject ); 313 currentObject = CurrentObject( objectDecl->get_type() ); 314 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 315 // enumerator initializers should not use the enum type to initialize, since 316 // the enum type is still incomplete at this point. Use signed int instead. 317 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 318 } 319 } 320 321 template< typename PtrType > 322 void Resolver::handlePtrType( PtrType * type ) { 323 if ( type->get_dimension() ) { 324 findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer ); 325 } 326 } 327 328 void Resolver::previsit( ArrayType * at ) { 329 handlePtrType( at ); 330 } 331 332 void Resolver::previsit( PointerType * pt ) { 333 handlePtrType( pt ); 334 } 335 336 void Resolver::previsit( TypeDecl *typeDecl ) { 337 if ( typeDecl->get_base() ) { 338 Type *new_type = resolveTypeof( typeDecl->get_base(), indexer ); 339 typeDecl->set_base( new_type ); 340 } // if 341 } 342 343 void Resolver::previsit( FunctionDecl *functionDecl ) { 344 #if 0 345 std::cerr << "resolver visiting functiondecl "; 346 functionDecl->print( std::cerr ); 347 std::cerr << std::endl; 348 #endif 349 Type *new_type = resolveTypeof( functionDecl->type, indexer ); 350 functionDecl->set_type( new_type ); 351 GuardValue( functionReturn ); 352 functionReturn = ResolvExpr::extractResultType( functionDecl->type ); 353 362 363 bool isStructOrUnion( const Alternative & alt ) { 364 Type * t = alt.expr->result->stripReferences(); 365 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ); 366 } 367 368 void resolveWithExprs( std::list< Declaration * > & translationUnit ) { 369 PassVisitor<ResolveWithExprs> resolver; 370 acceptAll( translationUnit, resolver ); 371 } 372 373 void ResolveWithExprs::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) { 374 for ( Expression *& expr : withExprs ) { 375 // only struct- and union-typed expressions are viable candidates 376 findKindExpression( expr, indexer, "with statement", isStructOrUnion ); 377 378 // if with expression might be impure, create a temporary so that it is evaluated once 379 if ( Tuples::maybeImpure( expr ) ) { 380 static UniqueName tmpNamer( "_with_tmp_" ); 381 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) ); 382 expr = new VariableExpr( tmp ); 383 newStmts.push_back( new DeclStmt( tmp ) ); 384 if ( InitTweak::isConstructable( tmp->type ) ) { 385 // generate ctor/dtor and resolve them 386 tmp->init = InitTweak::genCtorInit( tmp ); 387 tmp->accept( *visitor ); 388 } 389 } 390 } 391 } 392 393 void ResolveWithExprs::previsit( WithStmt * withStmt ) { 394 resolveWithExprs( withStmt->exprs, stmtsToAddBefore ); 395 } 396 397 void ResolveWithExprs::previsit( FunctionDecl * functionDecl ) { 354 398 { 355 399 // resolve with-exprs with parameters in scope and add any newly generated declarations to the … … 367 411 } 368 412 369 void Resolver::postvisit( FunctionDecl *functionDecl ) { 370 // default value expressions have an environment which shouldn't be there and trips up later passes. 371 // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently 372 // see how it's useful. 413 void Resolver_old::previsit( ObjectDecl * objectDecl ) { 414 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 415 // class-variable initContext is changed multiple time because the LHS is analysed twice. 416 // The second analysis changes initContext because of a function type can contain object 417 // declarations in the return and parameter types. So each value of initContext is 418 // retained, so the type on the first analysis is preserved and used for selecting the RHS. 419 GuardValue( currentObject ); 420 currentObject = CurrentObject( objectDecl->get_type() ); 421 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 422 // enumerator initializers should not use the enum type to initialize, since 423 // the enum type is still incomplete at this point. Use signed int instead. 424 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 425 } 426 } 427 428 template< typename PtrType > 429 void Resolver_old::handlePtrType( PtrType * type ) { 430 if ( type->get_dimension() ) { 431 findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer ); 432 } 433 } 434 435 void Resolver_old::previsit( ArrayType * at ) { 436 handlePtrType( at ); 437 } 438 439 void Resolver_old::previsit( PointerType * pt ) { 440 handlePtrType( pt ); 441 } 442 443 void Resolver_old::previsit( FunctionDecl * functionDecl ) { 444 #if 0 445 std::cerr << "resolver visiting functiondecl "; 446 functionDecl->print( std::cerr ); 447 std::cerr << std::endl; 448 #endif 449 GuardValue( functionReturn ); 450 functionReturn = ResolvExpr::extractResultType( functionDecl->type ); 451 } 452 453 void Resolver_old::postvisit( FunctionDecl * functionDecl ) { 454 // default value expressions have an environment which shouldn't be there and trips up 455 // later passes. 456 // xxx - it might be necessary to somehow keep the information from this environment, but I 457 // can't currently see how it's useful. 373 458 for ( Declaration * d : functionDecl->type->parameters ) { 374 459 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( d ) ) { … … 381 466 } 382 467 383 void Resolver ::previsit( EnumDecl * ) {468 void Resolver_old::previsit( EnumDecl * ) { 384 469 // in case we decide to allow nested enums 385 470 GuardValue( inEnumDecl ); … … 387 472 } 388 473 389 void Resolver ::previsit( StaticAssertDecl * assertDecl ) {474 void Resolver_old::previsit( StaticAssertDecl * assertDecl ) { 390 475 findIntegralExpression( assertDecl->condition, indexer ); 391 476 } 392 477 393 void Resolver ::previsit( ExprStmt *exprStmt ) {478 void Resolver_old::previsit( ExprStmt * exprStmt ) { 394 479 visit_children = false; 395 480 assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" ); … … 397 482 } 398 483 399 void Resolver ::previsit( AsmExpr *asmExpr ) {484 void Resolver_old::previsit( AsmExpr * asmExpr ) { 400 485 visit_children = false; 401 486 findVoidExpression( asmExpr->operand, indexer ); … … 405 490 } 406 491 407 void Resolver ::previsit( AsmStmt *asmStmt ) {492 void Resolver_old::previsit( AsmStmt * asmStmt ) { 408 493 visit_children = false; 409 494 acceptAll( asmStmt->get_input(), *visitor ); … … 411 496 } 412 497 413 void Resolver ::previsit( IfStmt *ifStmt ) {498 void Resolver_old::previsit( IfStmt * ifStmt ) { 414 499 findIntegralExpression( ifStmt->condition, indexer ); 415 500 } 416 501 417 void Resolver ::previsit( WhileStmt *whileStmt ) {502 void Resolver_old::previsit( WhileStmt * whileStmt ) { 418 503 findIntegralExpression( whileStmt->condition, indexer ); 419 504 } 420 505 421 void Resolver ::previsit( ForStmt *forStmt ) {506 void Resolver_old::previsit( ForStmt * forStmt ) { 422 507 if ( forStmt->condition ) { 423 508 findIntegralExpression( forStmt->condition, indexer ); … … 429 514 } 430 515 431 void Resolver ::previsit( SwitchStmt *switchStmt ) {516 void Resolver_old::previsit( SwitchStmt * switchStmt ) { 432 517 GuardValue( currentObject ); 433 518 findIntegralExpression( switchStmt->condition, indexer ); … … 436 521 } 437 522 438 void Resolver ::previsit( CaseStmt *caseStmt ) {523 void Resolver_old::previsit( CaseStmt * caseStmt ) { 439 524 if ( caseStmt->condition ) { 440 525 std::list< InitAlternative > initAlts = currentObject.getOptions(); … … 455 540 } 456 541 457 void Resolver ::previsit( BranchStmt *branchStmt ) {542 void Resolver_old::previsit( BranchStmt * branchStmt ) { 458 543 visit_children = false; 459 544 // must resolve the argument for a computed goto … … 466 551 } 467 552 468 void Resolver ::previsit( ReturnStmt *returnStmt ) {553 void Resolver_old::previsit( ReturnStmt * returnStmt ) { 469 554 visit_children = false; 470 555 if ( returnStmt->expr ) { … … 473 558 } 474 559 475 void Resolver ::previsit( ThrowStmt *throwStmt ) {560 void Resolver_old::previsit( ThrowStmt * throwStmt ) { 476 561 visit_children = false; 477 562 // TODO: Replace *exception type with &exception type. 478 563 if ( throwStmt->get_expr() ) { 479 StructDecl * exception_decl = 480 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 564 const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 481 565 assert( exception_decl ); 482 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl) );566 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) ); 483 567 findSingleExpression( throwStmt->expr, exceptType, indexer ); 484 568 } 485 569 } 486 570 487 void Resolver ::previsit( CatchStmt *catchStmt ) {571 void Resolver_old::previsit( CatchStmt * catchStmt ) { 488 572 if ( catchStmt->cond ) { 489 573 findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer ); … … 500 584 } 501 585 502 void Resolver ::previsit( WaitForStmt * stmt ) {586 void Resolver_old::previsit( WaitForStmt * stmt ) { 503 587 visit_children = false; 504 588 … … 582 666 583 667 // Make sure we don't widen any existing bindings 584 for ( auto & i : resultEnv ) { 585 i.allowWidening = false; 586 } 668 resultEnv.forbidWidening(); 587 669 588 670 // Find any unbound type variables … … 592 674 auto param_end = function->parameters.end(); 593 675 594 int n_mutex_ arg= 0;676 int n_mutex_param = 0; 595 677 596 678 // For every arguments of its set, check if it matches one of the parameter … … 602 684 // We ran out of parameters but still have arguments 603 685 // this function doesn't match 604 SemanticError( function, toString("candidate function not viable: too many mutex arguments, expected ", n_mutex_ arg, "\n" ));686 SemanticError( function, toString("candidate function not viable: too many mutex arguments, expected ", n_mutex_param, "\n" )); 605 687 } 606 688 607 n_mutex_ arg++;689 n_mutex_param++; 608 690 609 691 // Check if the argument matches the parameter type in the current scope … … 628 710 // Check if parameters are missing 629 711 if( advance_to_mutex( param, param_end ) ) { 712 do { 713 n_mutex_param++; 714 param++; 715 } while( advance_to_mutex( param, param_end ) ); 716 630 717 // We ran out of arguments but still have parameters left 631 718 // this function doesn't match 632 SemanticError( function, toString("candidate function not viable: too few mutex arguments, expected ", n_mutex_ arg, "\n" ));719 SemanticError( function, toString("candidate function not viable: too few mutex arguments, expected ", n_mutex_param, "\n" )); 633 720 } 634 721 … … 646 733 647 734 } 648 catch( SemanticErrorException & e ) {735 catch( SemanticErrorException & e ) { 649 736 errors.append( e ); 650 737 } 651 738 } 652 739 } 653 catch( SemanticErrorException & e ) {740 catch( SemanticErrorException & e ) { 654 741 errors.append( e ); 655 742 } … … 694 781 } 695 782 696 bool isStructOrUnion( const Alternative & alt ) { 697 Type * t = alt.expr->result->stripReferences(); 698 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ); 699 } 700 701 void Resolver::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) { 702 for ( Expression *& expr : withExprs ) { 703 // only struct- and union-typed expressions are viable candidates 704 findKindExpression( expr, indexer, "with statement", isStructOrUnion ); 705 706 // if with expression might be impure, create a temporary so that it is evaluated once 707 if ( Tuples::maybeImpure( expr ) ) { 708 static UniqueName tmpNamer( "_with_tmp_" ); 709 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) ); 710 expr = new VariableExpr( tmp ); 711 newStmts.push_back( new DeclStmt( tmp ) ); 712 if ( InitTweak::isConstructable( tmp->type ) ) { 713 // generate ctor/dtor and resolve them 714 tmp->init = InitTweak::genCtorInit( tmp ); 715 tmp->accept( *visitor ); 716 } 717 } 718 } 719 } 720 721 void Resolver::previsit( WithStmt * withStmt ) { 722 resolveWithExprs( withStmt->exprs, stmtsToAddBefore ); 723 } 724 725 template< typename T > 726 bool isCharType( T t ) { 783 bool isCharType( Type * t ) { 727 784 if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) { 728 785 return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || … … 732 789 } 733 790 734 void Resolver ::previsit( SingleInit *singleInit ) {791 void Resolver_old::previsit( SingleInit * singleInit ) { 735 792 visit_children = false; 736 793 // resolve initialization using the possibilities as determined by the currentObject cursor … … 746 803 initExpr->expr = nullptr; 747 804 std::swap( initExpr->env, newExpr->env ); 748 // InitExpr may have inferParams in the case where the expression specializes a function pointer, 749 // and newExpr may already have inferParams of its own, so a simple swap is not sufficient. 805 // InitExpr may have inferParams in the case where the expression specializes a function 806 // pointer, and newExpr may already have inferParams of its own, so a simple swap is not 807 // sufficient. 750 808 newExpr->spliceInferParams( initExpr ); 751 809 delete initExpr; 752 810 753 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 811 // get the actual object's type (may not exactly match what comes back from the resolver 812 // due to conversions) 754 813 Type * initContext = currentObject.getCurrentType(); 755 814 … … 762 821 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 763 822 if ( isCharType( pt->get_base() ) ) { 764 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) { 765 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 823 if ( CastExpr * ce = dynamic_cast< CastExpr * >( newExpr ) ) { 824 // strip cast if we're initializing a char[] with a char *, 825 // e.g. char x[] = "hello"; 766 826 newExpr = ce->get_arg(); 767 827 ce->set_arg( nullptr ); … … 781 841 } 782 842 783 void Resolver ::previsit( ListInit * listInit ) {843 void Resolver_old::previsit( ListInit * listInit ) { 784 844 visit_children = false; 785 845 // move cursor into brace-enclosed initializer-list 786 846 currentObject.enterListInit(); 787 // xxx - fix this so that the list isn't copied, iterator should be used to change current element 847 // xxx - fix this so that the list isn't copied, iterator should be used to change current 848 // element 788 849 std::list<Designation *> newDesignations; 789 850 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) { 790 // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving791 // the initializer against that object.851 // iterate designations and initializers in pairs, moving the cursor to the current 852 // designated object and resolving the initializer against that object. 792 853 Designation * des = std::get<0>(p); 793 854 Initializer * init = std::get<1>(p); … … 815 876 816 877 // ConstructorInit - fall back on C-style initializer 817 void Resolver ::fallbackInit( ConstructorInit * ctorInit ) {878 void Resolver_old::fallbackInit( ConstructorInit * ctorInit ) { 818 879 // could not find valid constructor, or found an intrinsic constructor 819 880 // fall back on C-style initializer 820 881 delete ctorInit->get_ctor(); 821 ctorInit->set_ctor( NULL);882 ctorInit->set_ctor( nullptr ); 822 883 delete ctorInit->get_dtor(); 823 ctorInit->set_dtor( NULL);884 ctorInit->set_dtor( nullptr ); 824 885 maybeAccept( ctorInit->get_init(), *visitor ); 825 886 } … … 828 889 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) { 829 890 assert( ctorInit ); 830 PassVisitor<Resolver > resolver( indexer );891 PassVisitor<Resolver_old> resolver( indexer ); 831 892 ctorInit->accept( resolver ); 832 893 } … … 834 895 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) { 835 896 assert( stmtExpr ); 836 PassVisitor<Resolver > resolver( indexer );897 PassVisitor<Resolver_old> resolver( indexer ); 837 898 stmtExpr->accept( resolver ); 838 899 stmtExpr->computeResult(); … … 840 901 } 841 902 842 void Resolver ::previsit( ConstructorInit *ctorInit ) {903 void Resolver_old::previsit( ConstructorInit * ctorInit ) { 843 904 visit_children = false; 844 905 // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit … … 864 925 865 926 // xxx - todo -- what about arrays? 866 // if ( dtor == NULL&& InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {927 // if ( dtor == nullptr && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) { 867 928 // // can reduce the constructor down to a SingleInit using the 868 929 // // second argument from the ctor call, since 869 930 // delete ctorInit->get_ctor(); 870 // ctorInit->set_ctor( NULL);931 // ctorInit->set_ctor( nullptr ); 871 932 872 933 // Expression * arg = … … 874 935 // } 875 936 } 937 938 /////////////////////////////////////////////////////////////////////////// 939 // 940 // *** NEW RESOLVER *** 941 // 942 /////////////////////////////////////////////////////////////////////////// 943 944 namespace { 945 /// Finds deleted expressions in an expression tree 946 struct DeleteFinder_new final : public ast::WithShortCircuiting { 947 const ast::DeletedExpr * delExpr = nullptr; 948 949 void previsit( const ast::DeletedExpr * expr ) { 950 if ( delExpr ) { visit_children = false; } 951 else { delExpr = expr; } 952 } 953 954 void previsit( const ast::Expr * ) { 955 if ( delExpr ) { visit_children = false; } 956 } 957 }; 958 } // anonymous namespace 959 960 /// Check if this expression is or includes a deleted expression 961 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) { 962 ast::Pass<DeleteFinder_new> finder; 963 expr->accept( finder ); 964 return finder.pass.delExpr; 965 } 966 967 namespace { 968 /// always-accept candidate filter 969 bool anyCandidate( const Candidate & ) { return true; } 970 971 /// Calls the CandidateFinder and finds the single best candidate 972 CandidateRef findUnfinishedKindExpression( 973 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 974 std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {} 975 ) { 976 if ( ! untyped ) return nullptr; 977 978 // xxx - this isn't thread-safe, but should work until we parallelize the resolver 979 static unsigned recursion_level = 0; 980 981 ++recursion_level; 982 ast::TypeEnvironment env; 983 CandidateFinder finder{ symtab, env }; 984 finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode ); 985 --recursion_level; 986 987 // produce a filtered list of candidates 988 CandidateList candidates; 989 for ( auto & cand : finder.candidates ) { 990 if ( pred( *cand ) ) { candidates.emplace_back( cand ); } 991 } 992 993 // produce invalid error if no candidates 994 if ( candidates.empty() ) { 995 SemanticError( untyped, 996 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 997 "expression: ") ); 998 } 999 1000 // search for cheapest candidate 1001 CandidateList winners; 1002 bool seen_undeleted = false; 1003 for ( CandidateRef & cand : candidates ) { 1004 int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost ); 1005 1006 if ( c > 0 ) continue; // skip more expensive than winner 1007 1008 if ( c < 0 ) { 1009 // reset on new cheapest 1010 seen_undeleted = ! findDeletedExpr( cand->expr ); 1011 winners.clear(); 1012 } else /* if ( c == 0 ) */ { 1013 if ( findDeletedExpr( cand->expr ) ) { 1014 // skip deleted expression if already seen one equivalent-cost not 1015 if ( seen_undeleted ) continue; 1016 } else if ( ! seen_undeleted ) { 1017 // replace list of equivalent-cost deleted expressions with one non-deleted 1018 winners.clear(); 1019 seen_undeleted = true; 1020 } 1021 } 1022 1023 winners.emplace_back( std::move( cand ) ); 1024 } 1025 1026 // promote candidate.cvtCost to .cost 1027 promoteCvtCost( winners ); 1028 1029 // produce ambiguous errors, if applicable 1030 if ( winners.size() != 1 ) { 1031 std::ostringstream stream; 1032 stream << "Cannot choose between " << winners.size() << " alternatives for " 1033 << kind << (kind != "" ? " " : "") << "expression\n"; 1034 ast::print( stream, untyped ); 1035 stream << " Alternatives are:\n"; 1036 print( stream, winners, 1 ); 1037 SemanticError( untyped->location, stream.str() ); 1038 } 1039 1040 // single selected choice 1041 CandidateRef & choice = winners.front(); 1042 1043 // fail on only expression deleted 1044 if ( ! seen_undeleted ) { 1045 SemanticError( untyped->location, choice->expr.get(), "Unique best alternative " 1046 "includes deleted identifier in " ); 1047 } 1048 1049 return std::move( choice ); 1050 } 1051 1052 /// Strips extraneous casts out of an expression 1053 struct StripCasts_new final { 1054 const ast::Expr * postmutate( const ast::CastExpr * castExpr ) { 1055 if ( 1056 castExpr->isGenerated 1057 && typesCompatible( castExpr->arg->result, castExpr->result ) 1058 ) { 1059 // generated cast is the same type as its argument, remove it after keeping env 1060 return ast::mutate_field( 1061 castExpr->arg.get(), &ast::Expr::env, castExpr->env ); 1062 } 1063 return castExpr; 1064 } 1065 1066 static void strip( ast::ptr< ast::Expr > & expr ) { 1067 ast::Pass< StripCasts_new > stripper; 1068 expr = expr->accept( stripper ); 1069 } 1070 }; 1071 1072 /// Swaps argument into expression pointer, saving original environment 1073 void swap_and_save_env( ast::ptr< ast::Expr > & expr, const ast::Expr * newExpr ) { 1074 ast::ptr< ast::TypeSubstitution > env = expr->env; 1075 expr.set_and_mutate( newExpr )->env = env; 1076 } 1077 1078 /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts) 1079 void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) { 1080 if ( const ast::CastExpr * castExpr = expr.as< ast::CastExpr >() ) { 1081 if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) { 1082 // cast is to the same type as its argument, remove it 1083 swap_and_save_env( expr, castExpr->arg ); 1084 } 1085 } 1086 } 1087 1088 /// Establish post-resolver invariants for expressions 1089 void finishExpr( 1090 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1091 const ast::TypeSubstitution * oldenv = nullptr 1092 ) { 1093 // set up new type substitution for expression 1094 ast::ptr< ast::TypeSubstitution > newenv = 1095 oldenv ? oldenv : new ast::TypeSubstitution{}; 1096 env.writeToSubstitution( *newenv.get_and_mutate() ); 1097 expr.get_and_mutate()->env = std::move( newenv ); 1098 // remove unncecessary casts 1099 StripCasts_new::strip( expr ); 1100 } 1101 } // anonymous namespace 1102 1103 1104 ast::ptr< ast::Expr > resolveInVoidContext( 1105 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1106 ) { 1107 assertf( expr, "expected a non-null expression" ); 1108 1109 // set up and resolve expression cast to void 1110 ast::CastExpr * untyped = new ast::CastExpr{ expr }; 1111 CandidateRef choice = findUnfinishedKindExpression( 1112 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1113 1114 // a cast expression has either 0 or 1 interpretations (by language rules); 1115 // if 0, an exception has already been thrown, and this code will not run 1116 const ast::CastExpr * castExpr = choice->expr.strict_as< ast::CastExpr >(); 1117 env = std::move( choice->env ); 1118 1119 return castExpr->arg; 1120 } 1121 1122 namespace { 1123 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1124 /// context. 1125 ast::ptr< ast::Expr > findVoidExpression( 1126 const ast::Expr * untyped, const ast::SymbolTable & symtab 1127 ) { 1128 resetTyVarRenaming(); 1129 ast::TypeEnvironment env; 1130 ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env ); 1131 finishExpr( newExpr, env, untyped->env ); 1132 return newExpr; 1133 } 1134 1135 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1136 /// lowest cost, returning the resolved version 1137 ast::ptr< ast::Expr > findKindExpression( 1138 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1139 std::function<bool(const Candidate &)> pred = anyCandidate, 1140 const std::string & kind = "", ResolvMode mode = {} 1141 ) { 1142 if ( ! untyped ) return {}; 1143 CandidateRef choice = 1144 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1145 finishExpr( choice->expr, choice->env, untyped->env ); 1146 return std::move( choice->expr ); 1147 } 1148 1149 /// Resolve `untyped` to the single expression whose candidate is the best match 1150 ast::ptr< ast::Expr > findSingleExpression( 1151 const ast::Expr * untyped, const ast::SymbolTable & symtab 1152 ) { 1153 return findKindExpression( untyped, symtab ); 1154 } 1155 } // anonymous namespace 1156 1157 ast::ptr< ast::Expr > findSingleExpression( 1158 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab 1159 ) { 1160 assert( untyped && type ); 1161 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type }; 1162 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab ); 1163 removeExtraneousCast( newExpr, symtab ); 1164 return newExpr; 1165 } 1166 1167 namespace { 1168 /// Predicate for "Candidate has integral type" 1169 bool hasIntegralType( const Candidate & i ) { 1170 const ast::Type * type = i.expr->result; 1171 1172 if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) { 1173 return bt->isInteger(); 1174 } else if ( 1175 dynamic_cast< const ast::EnumInstType * >( type ) 1176 || dynamic_cast< const ast::ZeroType * >( type ) 1177 || dynamic_cast< const ast::OneType * >( type ) 1178 ) { 1179 return true; 1180 } else return false; 1181 } 1182 1183 /// Resolve `untyped` as an integral expression, returning the resolved version 1184 ast::ptr< ast::Expr > findIntegralExpression( 1185 const ast::Expr * untyped, const ast::SymbolTable & symtab 1186 ) { 1187 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); 1188 } 1189 1190 /// check if a type is a character type 1191 bool isCharType( const ast::Type * t ) { 1192 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) { 1193 return bt->kind == ast::BasicType::Char 1194 || bt->kind == ast::BasicType::SignedChar 1195 || bt->kind == ast::BasicType::UnsignedChar; 1196 } 1197 return false; 1198 } 1199 1200 /// Advance a type itertor to the next mutex parameter 1201 template<typename Iter> 1202 inline bool nextMutex( Iter & it, const Iter & end ) { 1203 while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; } 1204 return it != end; 1205 } 1206 } 1207 1208 class Resolver_new final 1209 : public ast::WithSymbolTable, public ast::WithGuards, 1210 public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting, 1211 public ast::WithStmtsToAdd<> { 1212 1213 ast::ptr< ast::Type > functionReturn = nullptr; 1214 ast::CurrentObject currentObject; 1215 bool inEnumDecl = false; 1216 1217 public: 1218 Resolver_new() = default; 1219 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1220 1221 void previsit( const ast::FunctionDecl * ); 1222 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * ); 1223 void previsit( const ast::ObjectDecl * ); 1224 void previsit( const ast::EnumDecl * ); 1225 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * ); 1226 1227 const ast::ArrayType * previsit( const ast::ArrayType * ); 1228 const ast::PointerType * previsit( const ast::PointerType * ); 1229 1230 const ast::ExprStmt * previsit( const ast::ExprStmt * ); 1231 const ast::AsmExpr * previsit( const ast::AsmExpr * ); 1232 const ast::AsmStmt * previsit( const ast::AsmStmt * ); 1233 const ast::IfStmt * previsit( const ast::IfStmt * ); 1234 const ast::WhileStmt * previsit( const ast::WhileStmt * ); 1235 const ast::ForStmt * previsit( const ast::ForStmt * ); 1236 const ast::SwitchStmt * previsit( const ast::SwitchStmt * ); 1237 const ast::CaseStmt * previsit( const ast::CaseStmt * ); 1238 const ast::BranchStmt * previsit( const ast::BranchStmt * ); 1239 const ast::ReturnStmt * previsit( const ast::ReturnStmt * ); 1240 const ast::ThrowStmt * previsit( const ast::ThrowStmt * ); 1241 const ast::CatchStmt * previsit( const ast::CatchStmt * ); 1242 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1243 1244 const ast::SingleInit * previsit( const ast::SingleInit * ); 1245 const ast::ListInit * previsit( const ast::ListInit * ); 1246 const ast::ConstructorInit * previsit( const ast::ConstructorInit * ); 1247 }; 1248 1249 void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ) { 1250 ast::Pass< Resolver_new > resolver; 1251 accept_all( translationUnit, resolver ); 1252 } 1253 1254 ast::ptr< ast::Init > resolveCtorInit( 1255 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1256 ) { 1257 assert( ctorInit ); 1258 ast::Pass< Resolver_new > resolver{ symtab }; 1259 return ctorInit->accept( resolver ); 1260 } 1261 1262 ast::ptr< ast::Expr > resolveStmtExpr( 1263 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1264 ) { 1265 assert( stmtExpr ); 1266 ast::Pass< Resolver_new > resolver{ symtab }; 1267 ast::ptr< ast::Expr > ret = stmtExpr; 1268 ret = ret->accept( resolver ); 1269 strict_dynamic_cast< ast::StmtExpr * >( ret.get_and_mutate() )->computeResult(); 1270 return ret; 1271 } 1272 1273 void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 1274 GuardValue( functionReturn ); 1275 functionReturn = extractResultType( functionDecl->type ); 1276 } 1277 1278 const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) { 1279 // default value expressions have an environment which shouldn't be there and trips up 1280 // later passes. 1281 ast::ptr< ast::FunctionDecl > ret = functionDecl; 1282 for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) { 1283 const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i]; 1284 1285 if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) { 1286 if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) { 1287 if ( init->value->env == nullptr ) continue; 1288 // clone initializer minus the initializer environment 1289 ast::chain_mutate( ret ) 1290 ( &ast::FunctionDecl::type ) 1291 ( &ast::FunctionType::params )[i] 1292 ( &ast::ObjectDecl::init ) 1293 ( &ast::SingleInit::value )->env = nullptr; 1294 1295 assert( functionDecl != ret.get() || functionDecl->unique() ); 1296 assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env ); 1297 } 1298 } 1299 } 1300 return ret.get(); 1301 } 1302 1303 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1304 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1305 // class-variable `initContext` is changed multiple times because the LHS is analyzed 1306 // twice. The second analysis changes `initContext` because a function type can contain 1307 // object declarations in the return and parameter types. Therefore each value of 1308 // `initContext` is retained so the type on the first analysis is preserved and used for 1309 // selecting the RHS. 1310 GuardValue( currentObject ); 1311 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1312 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1313 // enumerator initializers should not use the enum type to initialize, since the 1314 // enum type is still incomplete at this point. Use `int` instead. 1315 currentObject = ast::CurrentObject{ 1316 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1317 } 1318 } 1319 1320 void Resolver_new::previsit( const ast::EnumDecl * ) { 1321 // in case we decide to allow nested enums 1322 GuardValue( inEnumDecl ); 1323 inEnumDecl = false; 1324 } 1325 1326 const ast::StaticAssertDecl * Resolver_new::previsit( 1327 const ast::StaticAssertDecl * assertDecl 1328 ) { 1329 return ast::mutate_field( 1330 assertDecl, &ast::StaticAssertDecl::cond, 1331 findIntegralExpression( assertDecl->cond, symtab ) ); 1332 } 1333 1334 template< typename PtrType > 1335 const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) { 1336 if ( type->dimension ) { 1337 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1338 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1339 ast::mutate_field( 1340 type, &PtrType::dimension, 1341 findSingleExpression( type->dimension, sizeType, symtab ) ); 1342 } 1343 return type; 1344 } 1345 1346 const ast::ArrayType * Resolver_new::previsit( const ast::ArrayType * at ) { 1347 return handlePtrType( at, symtab ); 1348 } 1349 1350 const ast::PointerType * Resolver_new::previsit( const ast::PointerType * pt ) { 1351 return handlePtrType( pt, symtab ); 1352 } 1353 1354 const ast::ExprStmt * Resolver_new::previsit( const ast::ExprStmt * exprStmt ) { 1355 visit_children = false; 1356 assertf( exprStmt->expr, "ExprStmt has null expression in resolver" ); 1357 1358 return ast::mutate_field( 1359 exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) ); 1360 } 1361 1362 const ast::AsmExpr * Resolver_new::previsit( const ast::AsmExpr * asmExpr ) { 1363 visit_children = false; 1364 1365 asmExpr = ast::mutate_field( 1366 asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) ); 1367 1368 if ( asmExpr->inout ) { 1369 asmExpr = ast::mutate_field( 1370 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) ); 1371 } 1372 1373 return asmExpr; 1374 } 1375 1376 const ast::AsmStmt * Resolver_new::previsit( const ast::AsmStmt * asmStmt ) { 1377 visitor->maybe_accept( asmStmt, &ast::AsmStmt::input ); 1378 visitor->maybe_accept( asmStmt, &ast::AsmStmt::output ); 1379 visit_children = false; 1380 return asmStmt; 1381 } 1382 1383 const ast::IfStmt * Resolver_new::previsit( const ast::IfStmt * ifStmt ) { 1384 return ast::mutate_field( 1385 ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, symtab ) ); 1386 } 1387 1388 const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) { 1389 return ast::mutate_field( 1390 whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) ); 1391 } 1392 1393 const ast::ForStmt * Resolver_new::previsit( const ast::ForStmt * forStmt ) { 1394 if ( forStmt->cond ) { 1395 forStmt = ast::mutate_field( 1396 forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, symtab ) ); 1397 } 1398 1399 if ( forStmt->inc ) { 1400 forStmt = ast::mutate_field( 1401 forStmt, &ast::ForStmt::inc, findVoidExpression( forStmt->inc, symtab ) ); 1402 } 1403 1404 return forStmt; 1405 } 1406 1407 const ast::SwitchStmt * Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) { 1408 GuardValue( currentObject ); 1409 switchStmt = ast::mutate_field( 1410 switchStmt, &ast::SwitchStmt::cond, 1411 findIntegralExpression( switchStmt->cond, symtab ) ); 1412 currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result }; 1413 return switchStmt; 1414 } 1415 1416 const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) { 1417 if ( caseStmt->cond ) { 1418 std::deque< ast::InitAlternative > initAlts = currentObject.getOptions(); 1419 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1420 "expression." ); 1421 1422 ast::ptr< ast::Expr > untyped = 1423 new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type }; 1424 ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab ); 1425 1426 // case condition cannot have a cast in C, so it must be removed here, regardless of 1427 // whether it would perform a conversion. 1428 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1429 swap_and_save_env( newExpr, castExpr->arg ); 1430 } 1431 1432 caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr ); 1433 } 1434 return caseStmt; 1435 } 1436 1437 const ast::BranchStmt * Resolver_new::previsit( const ast::BranchStmt * branchStmt ) { 1438 visit_children = false; 1439 // must resolve the argument of a computed goto 1440 if ( branchStmt->kind == ast::BranchStmt::Goto && branchStmt->computedTarget ) { 1441 // computed goto argument is void* 1442 ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} }; 1443 branchStmt = ast::mutate_field( 1444 branchStmt, &ast::BranchStmt::computedTarget, 1445 findSingleExpression( branchStmt->computedTarget, target, symtab ) ); 1446 } 1447 return branchStmt; 1448 } 1449 1450 const ast::ReturnStmt * Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) { 1451 visit_children = false; 1452 if ( returnStmt->expr ) { 1453 returnStmt = ast::mutate_field( 1454 returnStmt, &ast::ReturnStmt::expr, 1455 findSingleExpression( returnStmt->expr, functionReturn, symtab ) ); 1456 } 1457 return returnStmt; 1458 } 1459 1460 const ast::ThrowStmt * Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) { 1461 visit_children = false; 1462 if ( throwStmt->expr ) { 1463 const ast::StructDecl * exceptionDecl = 1464 symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 1465 assert( exceptionDecl ); 1466 ast::ptr< ast::Type > exceptType = 1467 new ast::PointerType{ new ast::StructInstType{ exceptionDecl } }; 1468 throwStmt = ast::mutate_field( 1469 throwStmt, &ast::ThrowStmt::expr, 1470 findSingleExpression( throwStmt->expr, exceptType, symtab ) ); 1471 } 1472 return throwStmt; 1473 } 1474 1475 const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) { 1476 if ( catchStmt->cond ) { 1477 ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool }; 1478 catchStmt = ast::mutate_field( 1479 catchStmt, &ast::CatchStmt::cond, 1480 findSingleExpression( catchStmt->cond, boolType, symtab ) ); 1481 } 1482 return catchStmt; 1483 } 1484 1485 const ast::WaitForStmt * Resolver_new::previsit( const ast::WaitForStmt * stmt ) { 1486 visit_children = false; 1487 1488 // Resolve all clauses first 1489 for ( unsigned i = 0; i < stmt->clauses.size(); ++i ) { 1490 const ast::WaitForStmt::Clause & clause = stmt->clauses[i]; 1491 1492 ast::TypeEnvironment env; 1493 CandidateFinder funcFinder{ symtab, env }; 1494 1495 // Find all candidates for a function in canonical form 1496 funcFinder.find( clause.target.func, ResolvMode::withAdjustment() ); 1497 1498 if ( funcFinder.candidates.empty() ) { 1499 stringstream ss; 1500 ss << "Use of undeclared indentifier '"; 1501 ss << clause.target.func.strict_as< ast::NameExpr >()->name; 1502 ss << "' in call to waitfor"; 1503 SemanticError( stmt->location, ss.str() ); 1504 } 1505 1506 if ( clause.target.args.empty() ) { 1507 SemanticError( stmt->location, 1508 "Waitfor clause must have at least one mutex parameter"); 1509 } 1510 1511 // Find all alternatives for all arguments in canonical form 1512 std::vector< CandidateFinder > argFinders = 1513 funcFinder.findSubExprs( clause.target.args ); 1514 1515 // List all combinations of arguments 1516 std::vector< CandidateList > possibilities; 1517 combos( argFinders.begin(), argFinders.end(), back_inserter( possibilities ) ); 1518 1519 // For every possible function: 1520 // * try matching the arguments to the parameters, not the other way around because 1521 // more arguments than parameters 1522 CandidateList funcCandidates; 1523 std::vector< CandidateList > argsCandidates; 1524 SemanticErrorException errors; 1525 for ( CandidateRef & func : funcFinder.candidates ) { 1526 try { 1527 auto pointerType = dynamic_cast< const ast::PointerType * >( 1528 func->expr->result->stripReferences() ); 1529 if ( ! pointerType ) { 1530 SemanticError( stmt->location, func->expr->result.get(), 1531 "candidate not viable: not a pointer type\n" ); 1532 } 1533 1534 auto funcType = pointerType->base.as< ast::FunctionType >(); 1535 if ( ! funcType ) { 1536 SemanticError( stmt->location, func->expr->result.get(), 1537 "candidate not viable: not a function type\n" ); 1538 } 1539 1540 { 1541 auto param = funcType->params.begin(); 1542 auto paramEnd = funcType->params.end(); 1543 1544 if( ! nextMutex( param, paramEnd ) ) { 1545 SemanticError( stmt->location, funcType, 1546 "candidate function not viable: no mutex parameters\n"); 1547 } 1548 } 1549 1550 CandidateRef func2{ new Candidate{ *func } }; 1551 // strip reference from function 1552 func2->expr = referenceToRvalueConversion( func->expr, func2->cost ); 1553 1554 // Each argument must be matched with a parameter of the current candidate 1555 for ( auto & argsList : possibilities ) { 1556 try { 1557 // Declare data structures needed for resolution 1558 ast::OpenVarSet open; 1559 ast::AssertionSet need, have; 1560 ast::TypeEnvironment resultEnv{ func->env }; 1561 // Add all type variables as open so that those not used in the 1562 // parameter list are still considered open 1563 resultEnv.add( funcType->forall ); 1564 1565 // load type variables from arguments into one shared space 1566 for ( auto & arg : argsList ) { 1567 resultEnv.simpleCombine( arg->env ); 1568 } 1569 1570 // Make sure we don't widen any existing bindings 1571 resultEnv.forbidWidening(); 1572 1573 // Find any unbound type variables 1574 resultEnv.extractOpenVars( open ); 1575 1576 auto param = funcType->params.begin(); 1577 auto paramEnd = funcType->params.end(); 1578 1579 unsigned n_mutex_param = 0; 1580 1581 // For every argument of its set, check if it matches one of the 1582 // parameters. The order is important 1583 for ( auto & arg : argsList ) { 1584 // Ignore non-mutex arguments 1585 if ( ! nextMutex( param, paramEnd ) ) { 1586 // We ran out of parameters but still have arguments. 1587 // This function doesn't match 1588 SemanticError( stmt->location, funcType, 1589 toString("candidate function not viable: too many mutex " 1590 "arguments, expected ", n_mutex_param, "\n" ) ); 1591 } 1592 1593 ++n_mutex_param; 1594 1595 // Check if the argument matches the parameter type in the current 1596 // scope 1597 ast::ptr< ast::Type > paramType = (*param)->get_type(); 1598 if ( 1599 ! unify( 1600 arg->expr->result, paramType, resultEnv, need, have, open, 1601 symtab ) 1602 ) { 1603 // Type doesn't match 1604 stringstream ss; 1605 ss << "candidate function not viable: no known conversion " 1606 "from '"; 1607 ast::print( ss, (*param)->get_type() ); 1608 ss << "' to '"; 1609 ast::print( ss, arg->expr->result ); 1610 ss << "' with env '"; 1611 ast::print( ss, resultEnv ); 1612 ss << "'\n"; 1613 SemanticError( stmt->location, funcType, ss.str() ); 1614 } 1615 1616 ++param; 1617 } 1618 1619 // All arguments match! 1620 1621 // Check if parameters are missing 1622 if ( nextMutex( param, paramEnd ) ) { 1623 do { 1624 ++n_mutex_param; 1625 ++param; 1626 } while ( nextMutex( param, paramEnd ) ); 1627 1628 // We ran out of arguments but still have parameters left; this 1629 // function doesn't match 1630 SemanticError( stmt->location, funcType, 1631 toString( "candidate function not viable: too few mutex " 1632 "arguments, expected ", n_mutex_param, "\n" ) ); 1633 } 1634 1635 // All parameters match! 1636 1637 // Finish the expressions to tie in proper environments 1638 finishExpr( func2->expr, resultEnv ); 1639 for ( CandidateRef & arg : argsList ) { 1640 finishExpr( arg->expr, resultEnv ); 1641 } 1642 1643 // This is a match, store it and save it for later 1644 funcCandidates.emplace_back( std::move( func2 ) ); 1645 argsCandidates.emplace_back( std::move( argsList ) ); 1646 1647 } catch ( SemanticErrorException & e ) { 1648 errors.append( e ); 1649 } 1650 } 1651 } catch ( SemanticErrorException & e ) { 1652 errors.append( e ); 1653 } 1654 } 1655 1656 // Make sure correct number of arguments 1657 if( funcCandidates.empty() ) { 1658 SemanticErrorException top( stmt->location, 1659 "No alternatives for function in call to waitfor" ); 1660 top.append( errors ); 1661 throw top; 1662 } 1663 1664 if( argsCandidates.empty() ) { 1665 SemanticErrorException top( stmt->location, 1666 "No alternatives for arguments in call to waitfor" ); 1667 top.append( errors ); 1668 throw top; 1669 } 1670 1671 if( funcCandidates.size() > 1 ) { 1672 SemanticErrorException top( stmt->location, 1673 "Ambiguous function in call to waitfor" ); 1674 top.append( errors ); 1675 throw top; 1676 } 1677 if( argsCandidates.size() > 1 ) { 1678 SemanticErrorException top( stmt->location, 1679 "Ambiguous arguments in call to waitfor" ); 1680 top.append( errors ); 1681 throw top; 1682 } 1683 // TODO: need to use findDeletedExpr to ensure no deleted identifiers are used. 1684 1685 // build new clause 1686 ast::WaitForStmt::Clause clause2; 1687 1688 clause2.target.func = funcCandidates.front()->expr; 1689 1690 clause2.target.args.reserve( clause.target.args.size() ); 1691 for ( auto arg : argsCandidates.front() ) { 1692 clause2.target.args.emplace_back( std::move( arg->expr ) ); 1693 } 1694 1695 // Resolve the conditions as if it were an IfStmt, statements normally 1696 clause2.cond = findSingleExpression( clause.cond, symtab ); 1697 clause2.stmt = clause.stmt->accept( *visitor ); 1698 1699 // set results into stmt 1700 auto n = mutate( stmt ); 1701 n->clauses[i] = std::move( clause2 ); 1702 stmt = n; 1703 } 1704 1705 if ( stmt->timeout.stmt ) { 1706 // resolve the timeout as a size_t, the conditions like IfStmt, and stmts normally 1707 ast::WaitForStmt::Timeout timeout2; 1708 1709 ast::ptr< ast::Type > target = 1710 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1711 timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab ); 1712 timeout2.cond = findSingleExpression( stmt->timeout.cond, symtab ); 1713 timeout2.stmt = stmt->timeout.stmt->accept( *visitor ); 1714 1715 // set results into stmt 1716 auto n = mutate( stmt ); 1717 n->timeout = std::move( timeout2 ); 1718 stmt = n; 1719 } 1720 1721 if ( stmt->orElse.stmt ) { 1722 // resolve the condition like IfStmt, stmts normally 1723 ast::WaitForStmt::OrElse orElse2; 1724 1725 orElse2.cond = findSingleExpression( stmt->orElse.cond, symtab ); 1726 orElse2.stmt = stmt->orElse.stmt->accept( *visitor ); 1727 1728 // set results into stmt 1729 auto n = mutate( stmt ); 1730 n->orElse = std::move( orElse2 ); 1731 stmt = n; 1732 } 1733 1734 return stmt; 1735 } 1736 1737 1738 1739 const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1740 visit_children = false; 1741 // resolve initialization using the possibilities as determined by the `currentObject` 1742 // cursor. 1743 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1744 singleInit->location, singleInit->value, currentObject.getOptions() }; 1745 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab ); 1746 const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >(); 1747 1748 // move cursor to the object that is actually initialized 1749 currentObject.setNext( initExpr->designation ); 1750 1751 // discard InitExpr wrapper and retain relevant pieces. 1752 // `initExpr` may have inferred params in the case where the expression specialized a 1753 // function pointer, and newExpr may already have inferParams of its own, so a simple 1754 // swap is not sufficient 1755 ast::Expr::InferUnion inferred = initExpr->inferred; 1756 swap_and_save_env( newExpr, initExpr->expr ); 1757 newExpr.get_and_mutate()->inferred.splice( std::move(inferred) ); 1758 1759 // get the actual object's type (may not exactly match what comes back from the resolver 1760 // due to conversions) 1761 const ast::Type * initContext = currentObject.getCurrentType(); 1762 1763 removeExtraneousCast( newExpr, symtab ); 1764 1765 // check if actual object's type is char[] 1766 if ( auto at = dynamic_cast< const ast::ArrayType * >( initContext ) ) { 1767 if ( isCharType( at->base ) ) { 1768 // check if the resolved type is char* 1769 if ( auto pt = newExpr->result.as< ast::PointerType >() ) { 1770 if ( isCharType( pt->base ) ) { 1771 // strip cast if we're initializing a char[] with a char* 1772 // e.g. char x[] = "hello" 1773 if ( auto ce = newExpr.as< ast::CastExpr >() ) { 1774 swap_and_save_env( newExpr, ce->arg ); 1775 } 1776 } 1777 } 1778 } 1779 } 1780 1781 // move cursor to next object in preparation for next initializer 1782 currentObject.increment(); 1783 1784 // set initializer expression to resolved expression 1785 return ast::mutate_field( singleInit, &ast::SingleInit::value, std::move(newExpr) ); 1786 } 1787 1788 const ast::ListInit * Resolver_new::previsit( const ast::ListInit * listInit ) { 1789 // move cursor into brace-enclosed initializer-list 1790 currentObject.enterListInit( listInit->location ); 1791 1792 assert( listInit->designations.size() == listInit->initializers.size() ); 1793 for ( unsigned i = 0; i < listInit->designations.size(); ++i ) { 1794 // iterate designations and initializers in pairs, moving the cursor to the current 1795 // designated object and resolving the initializer against that object 1796 listInit = ast::mutate_field_index( 1797 listInit, &ast::ListInit::designations, i, 1798 currentObject.findNext( listInit->designations[i] ) ); 1799 listInit = ast::mutate_field_index( 1800 listInit, &ast::ListInit::initializers, i, 1801 listInit->initializers[i]->accept( *visitor ) ); 1802 } 1803 1804 // move cursor out of brace-enclosed initializer-list 1805 currentObject.exitListInit(); 1806 1807 visit_children = false; 1808 return listInit; 1809 } 1810 1811 const ast::ConstructorInit * Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) { 1812 visitor->maybe_accept( ctorInit, &ast::ConstructorInit::ctor ); 1813 visitor->maybe_accept( ctorInit, &ast::ConstructorInit::dtor ); 1814 1815 // found a constructor - can get rid of C-style initializer 1816 // xxx - Rob suggests this field is dead code 1817 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr ); 1818 1819 // intrinsic single-parameter constructors and destructors do nothing. Since this was 1820 // implicitly generated, there's no way for it to have side effects, so get rid of it to 1821 // clean up generated code 1822 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) { 1823 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::ctor, nullptr ); 1824 } 1825 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) { 1826 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::dtor, nullptr ); 1827 } 1828 1829 return ctorInit; 1830 } 1831 876 1832 } // namespace ResolvExpr 877 1833 -
src/ResolvExpr/Resolver.h
r7951100 rb067d9b 10 10 // Created On : Sun May 17 12:18:34 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:36:57 201713 // Update Count : 312 // Last Modified On : Mon Feb 18 20:40:38 2019 13 // Update Count : 4 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <list> // for list 18 #include <list> // for list 19 20 #include "AST/Node.hpp" // for ptr 19 21 20 22 class ConstructorInit; … … 23 25 class StmtExpr; 24 26 namespace SymTab { 25 class Indexer; 26 } // namespace SymTab 27 class Indexer; 28 } // namespace SymTab 29 30 namespace ast { 31 class ConstructorInit; 32 class Decl; 33 class DeletedExpr; 34 class Init; 35 class StmtExpr; 36 class SymbolTable; 37 class Type; 38 class TypeEnvironment; 39 } // namespace ast 27 40 28 41 namespace ResolvExpr { 29 42 /// Checks types and binds syntactic constructs to typed representations 30 43 void resolve( std::list< Declaration * > translationUnit ); 31 void resolveDecl( Declaration *, const SymTab::Indexer & indexer );32 Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer );33 void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer );34 void findSingleExpression( Expression *& untyped, const SymTab::Indexer & indexer );35 void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer );44 void resolveDecl( Declaration *, const SymTab::Indexer & indexer ); 45 Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer ); 46 void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer ); 47 void findSingleExpression( Expression *& untyped, const SymTab::Indexer & indexer ); 48 void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ); 36 49 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); 37 50 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ); 51 /// Searches expr and returns the first DeletedExpr found, otherwise nullptr 52 DeletedExpr * findDeletedExpr( Expression * expr ); 53 /// Resolves with-stmts and with-clauses on functions 54 void resolveWithExprs( std::list< Declaration * > & translationUnit ); 55 56 /// Checks types and binds syntactic constructs to typed representations 57 void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ); 58 /// Searches expr and returns the first DeletedExpr found, otherwise nullptr 59 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ); 60 /// Find the expression candidate that is the unique best match for `untyped` in a `void` 61 /// context. 62 ast::ptr< ast::Expr > resolveInVoidContext( 63 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env ); 64 /// Resolve `untyped` to the single expression whose candidate is the best match for the 65 /// given type. 66 ast::ptr< ast::Expr > findSingleExpression( 67 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab ); 68 /// Resolves a constructor init expression 69 ast::ptr< ast::Init > resolveCtorInit( 70 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab ); 71 /// Resolves a statement expression 72 ast::ptr< ast::Expr > resolveStmtExpr( 73 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab ); 38 74 } // namespace ResolvExpr 39 75 -
src/ResolvExpr/TypeEnvironment.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:19:47 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun May 17 12:23:36 201513 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jun 18 14:27:00 2019 13 // Update Count : 5 14 14 // 15 15 … … 17 17 #include <algorithm> // for copy, set_intersection 18 18 #include <iterator> // for ostream_iterator, insert_iterator 19 #include <memory> // for unique_ptr 19 20 #include <utility> // for pair, move 20 21 … … 22 23 #include "SynTree/Type.h" // for Type, FunctionType, Type::Fora... 23 24 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 25 #include "Tuples/Tuples.h" // for isTtype 24 26 #include "TypeEnvironment.h" 27 #include "typeops.h" // for occurs 28 #include "Unify.h" // for unifyInexact 25 29 26 30 namespace ResolvExpr { … … 65 69 } 66 70 71 EqvClass::EqvClass( EqvClass &&other ) 72 : vars{std::move(other.vars)}, type{other.type}, 73 allowWidening{std::move(other.allowWidening)}, data{std::move(other.data)} { 74 other.type = nullptr; 75 } 76 67 77 EqvClass &EqvClass::operator=( const EqvClass &other ) { 68 78 if ( this == &other ) return *this; … … 72 82 } 73 83 84 EqvClass &EqvClass::operator=( EqvClass &&other ) { 85 if ( this == &other ) return *this; 86 delete type; 87 88 vars = std::move(other.vars); 89 type = other.type; 90 other.type = nullptr; 91 allowWidening = std::move(other.allowWidening); 92 data = std::move(other.data); 93 94 return *this; 95 } 96 74 97 EqvClass::~EqvClass() { 75 98 delete type; 99 } 100 101 void EqvClass::set_type( Type* ty ) { 102 if ( ty == type ) return; 103 delete type; 104 type = ty; 76 105 } 77 106 … … 91 120 92 121 const EqvClass* TypeEnvironment::lookup( const std::string &var ) const { 93 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) { 94 if ( i->vars.find( var ) != i->vars.end() ) { 95 /// std::cout << var << " is in class "; 96 /// i->print( std::cout ); 97 return &*i; 98 } 99 /// std::cout << var << " is not in class "; 100 /// i->print( std::cout ); 122 for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) { 123 if ( i->vars.find( var ) != i->vars.end() ) return &*i; 101 124 } // for 102 125 return nullptr; … … 109 132 ++next; 110 133 std::set<std::string> intersection; 111 std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), 134 std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), 112 135 std::inserter( intersection, intersection.begin() ) ); 113 136 if ( ! intersection.empty() ) { env.erase( i ); } 114 137 i = next; 115 138 } 116 }117 118 void TypeEnvironment::add( const EqvClass &eqvClass ) {119 filterOverlappingClasses( env, eqvClass );120 env.push_back( eqvClass );121 139 } 122 140 … … 131 149 newClass.vars.insert( (*i)->get_name() ); 132 150 newClass.data = TypeDecl::Data{ (*i) }; 133 env.push_back( newClass);151 env.push_back( std::move(newClass) ); 134 152 } // for 135 153 } … … 145 163 // transition to TypeSubstitution 146 164 newClass.data = TypeDecl::Data{ TypeDecl::Dtype, false }; 147 add( newClass);165 add( std::move(newClass) ); 148 166 } 149 167 } 150 168 151 169 void TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const { 152 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {170 for ( ClassList::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) { 153 171 for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) { 154 /// std::cerr << "adding " << *theVar;155 172 if ( theClass->type ) { 156 /// std::cerr << " bound to ";157 /// theClass->type->print( std::cerr );158 /// std::cerr << std::endl;159 173 sub.add( *theVar, theClass->type ); 160 174 } else if ( theVar != theClass->vars.begin() ) { 161 175 TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype ); 162 /// std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;163 176 sub.add( *theVar, newTypeInst ); 164 177 delete newTypeInst; … … 166 179 } // for 167 180 } // for 168 /// std::cerr << "input env is:" << std::endl;169 /// print( std::cerr, 8 );170 /// std::cerr << "sub is:" << std::endl;171 /// sub.print( std::cerr, 8 );172 181 sub.normalize(); 173 182 } … … 179 188 } 180 189 181 std::list< EqvClass >::iterator TypeEnvironment::internal_lookup( const std::string &var ) { 182 for ( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) { 183 if ( i->vars.find( var ) == i->vars.end() ) { 184 return i; 185 } // if 190 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const std::string &var ) { 191 for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) { 192 if ( i->vars.count( var ) ) return i; 186 193 } // for 187 194 return env.end(); … … 192 199 } 193 200 194 void TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ) { 195 TypeEnvironment secondCopy( second ); 196 for ( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) { 197 EqvClass &newClass = *firstClass; 198 std::set< std::string > newVars; 199 for ( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) { 200 std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var ); 201 if ( secondClass != secondCopy.env.end() ) { 202 newVars.insert( secondClass->vars.begin(), secondClass->vars.end() ); 203 if ( secondClass->type ) { 204 if ( newClass.type ) { 205 Type *newType = combineFunc( newClass.type, secondClass->type ); 206 delete newClass.type; 207 newClass.type = newType; 208 newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening; 209 } else { 210 newClass.type = secondClass->type->clone(); 211 newClass.allowWidening = secondClass->allowWidening; 212 } // if 213 } // if 214 secondCopy.env.erase( secondClass ); 215 } // if 216 } // for 217 newClass.vars.insert( newVars.begin(), newVars.end() ); 218 } // for 219 for ( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) { 220 env.push_back( *secondClass ); 221 } // for 201 // xxx -- this should maybe be worrying about iterator invalidation (see resolv-proto) 202 bool TypeEnvironment::mergeBound( EqvClass& to, const EqvClass& from, OpenVarSet& openVars, const SymTab::Indexer& indexer ) { 203 if ( from.type ) { 204 if ( to.type ) { 205 // attempt to unify bound types 206 std::unique_ptr<Type> toType{ to.type->clone() }, fromType{ from.type->clone() }; 207 WidenMode widen{ to.allowWidening, from.allowWidening }; 208 Type* common = nullptr; 209 AssertionSet need, have; 210 if ( unifyInexact( toType.get(), fromType.get(), *this, need, have, openVars, widen, indexer, common ) ) { 211 // unifies, set common type if necessary 212 if ( common ) { 213 common->get_qualifiers() = Type::Qualifiers{}; 214 to.set_type( common ); 215 } 216 } else return false; // cannot unify 217 } else { 218 to.type = from.type->clone(); 219 } 220 } 221 222 // unify widening if matches 223 to.allowWidening &= from.allowWidening; 224 return true; 225 } 226 227 // xxx -- this should maybe be worrying about iterator invalidation (see resolv-proto) 228 bool TypeEnvironment::mergeClasses( TypeEnvironment::ClassList::iterator to, TypeEnvironment::ClassList::iterator from, OpenVarSet& openVars, const SymTab::Indexer& indexer ) { 229 EqvClass& r = *to; 230 EqvClass& s = *from; 231 232 // ensure bounds match 233 if ( ! mergeBound( r, s, openVars, indexer ) ) return false; 234 235 // check safely bindable 236 if ( r.type && occursIn( r.type, s.vars.begin(), s.vars.end(), *this ) ) return false; 237 238 // merge classes in 239 r.vars.insert( s.vars.begin(), s.vars.end() ); 240 r.allowWidening &= s.allowWidening; 241 env.erase( from ); 242 243 return true; 244 } 245 246 bool TypeEnvironment::combine( const TypeEnvironment& o, OpenVarSet& openVars, const SymTab::Indexer& indexer ) { 247 // short-circuit easy cases 248 if ( o.isEmpty() ) return true; 249 if ( isEmpty() ) { 250 simpleCombine( o ); 251 return true; 252 } 253 254 // merge classes 255 for ( auto ct = o.env.begin(); ct != o.env.end(); ++ct ) { 256 const EqvClass& c = *ct; 257 258 // typeclass in local environment bound to c 259 auto rt = env.end(); 260 261 // look for first existing bound variable 262 auto vt = c.vars.begin(); 263 for ( ; vt != c.vars.end(); ++vt ) { 264 rt = internal_lookup( *vt ); 265 if ( rt != env.end() ) break; 266 } 267 268 if ( rt != env.end() ) { // c needs to be merged into *rt 269 EqvClass& r = *rt; 270 // merge bindings 271 if ( ! mergeBound( r, c, openVars, indexer ) ) return false; 272 // merge previous unbound variables into this class, checking occurs if needed 273 if ( r.type ) for ( auto ut = c.vars.begin(); ut != vt; ++ut ) { 274 if ( occurs( r.type, *ut, *this ) ) return false; 275 r.vars.insert( *ut ); 276 } else { r.vars.insert( c.vars.begin(), vt ); } 277 // merge subsequent variables into this class (skipping *vt, already there) 278 while ( ++vt != c.vars.end() ) { 279 auto st = internal_lookup( *vt ); 280 if ( st == env.end() ) { 281 // unbound, safe to add if passes occurs 282 if ( r.type && occurs( r.type, *vt, *this ) ) return false; 283 r.vars.insert( *vt ); 284 } else if ( st != rt ) { 285 // bound, but not to the same class 286 if ( ! mergeClasses( rt, st, openVars, indexer ) ) return false; 287 } // ignore bound into the same class 288 } 289 } else { // no variables in c bound; just copy up 290 env.push_back( c ); 291 } 292 } 293 294 // merged all classes 295 return true; 222 296 } 223 297 224 298 void TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const { 225 for ( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {299 for ( ClassList::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) { 226 300 for ( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) { 227 301 openVars[ *var ] = eqvClass->data; … … 241 315 } 242 316 317 bool isFtype( const Type * type ) { 318 if ( dynamic_cast< const FunctionType * >( type ) ) { 319 return true; 320 } else if ( const TypeInstType *typeInst = dynamic_cast< const TypeInstType * >( type ) ) { 321 return typeInst->get_isFtype(); 322 } // if 323 return false; 324 } 325 326 bool tyVarCompatible( const TypeDecl::Data & data, const Type * type ) { 327 switch ( data.kind ) { 328 case TypeDecl::Dtype: 329 // to bind to an object type variable, the type must not be a function type. 330 // if the type variable is specified to be a complete type then the incoming 331 // type must also be complete 332 // xxx - should this also check that type is not a tuple type and that it's not a ttype? 333 return ! isFtype( type ) && (! data.isComplete || type->isComplete() ); 334 case TypeDecl::Ftype: 335 return isFtype( type ); 336 case TypeDecl::Ttype: 337 // ttype unifies with any tuple type 338 return dynamic_cast< const TupleType * >( type ) || Tuples::isTtype( type ); 339 default: 340 assertf(false, "Unhandled tyvar kind: %d", data.kind); 341 } // switch 342 return false; 343 } 344 345 bool TypeEnvironment::bindVar( const TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ) { 346 347 // remove references from other, so that type variables can only bind to value types 348 bindTo = bindTo->stripReferences(); 349 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() ); 350 assert( tyvar != openVars.end() ); 351 if ( ! tyVarCompatible( tyvar->second, bindTo ) ) { 352 return false; 353 } // if 354 if ( occurs( bindTo, typeInst->get_name(), *this ) ) { 355 return false; 356 } // if 357 auto curClass = internal_lookup( typeInst->get_name() ); 358 if ( curClass != env.end() ) { 359 if ( curClass->type ) { 360 Type *common = 0; 361 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to 362 std::unique_ptr< Type > newType( curClass->type->clone() ); 363 newType->tq = typeInst->tq; 364 if ( unifyInexact( newType.get(), bindTo, *this, need, have, openVars, widen & WidenMode( curClass->allowWidening, true ), indexer, common ) ) { 365 if ( common ) { 366 common->get_qualifiers() = Type::Qualifiers{}; 367 curClass->set_type( common ); 368 } // if 369 } else return false; 370 } else { 371 Type* newType = bindTo->clone(); 372 newType->get_qualifiers() = Type::Qualifiers{}; 373 curClass->set_type( newType ); 374 curClass->allowWidening = widen.first && widen.second; 375 } // if 376 } else { 377 EqvClass newClass; 378 newClass.vars.insert( typeInst->get_name() ); 379 newClass.type = bindTo->clone(); 380 newClass.type->get_qualifiers() = Type::Qualifiers(); 381 newClass.allowWidening = widen.first && widen.second; 382 newClass.data = data; 383 env.push_back( std::move(newClass) ); 384 } // if 385 return true; 386 } 387 388 bool TypeEnvironment::bindVarToVar( const TypeInstType * var1, const TypeInstType * var2, 389 TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, 390 const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ) { 391 392 auto class1 = internal_lookup( var1->get_name() ); 393 auto class2 = internal_lookup( var2->get_name() ); 394 395 // exit early if variables already bound together 396 if ( class1 != env.end() && class1 == class2 ) { 397 class1->allowWidening &= widen; 398 return true; 399 } 400 401 bool widen1 = false, widen2 = false; 402 const Type *type1 = nullptr, *type2 = nullptr; 403 404 // check for existing bindings, perform occurs check 405 if ( class1 != env.end() ) { 406 if ( class1->type ) { 407 if ( occurs( class1->type, var2->get_name(), *this ) ) return false; 408 type1 = class1->type; 409 } // if 410 widen1 = widen.first && class1->allowWidening; 411 } // if 412 if ( class2 != env.end() ) { 413 if ( class2->type ) { 414 if ( occurs( class2->type, var1->get_name(), *this ) ) return false; 415 type2 = class2->type; 416 } // if 417 widen2 = widen.second && class2->allowWidening; 418 } // if 419 420 if ( type1 && type2 ) { 421 // both classes bound, merge if bound types can be unified 422 std::unique_ptr<Type> newType1{ type1->clone() }, newType2{ type2->clone() }; 423 WidenMode newWidenMode{ widen1, widen2 }; 424 Type *common = 0; 425 if ( unifyInexact( newType1.get(), newType2.get(), *this, need, have, openVars, newWidenMode, indexer, common ) ) { 426 class1->vars.insert( class2->vars.begin(), class2->vars.end() ); 427 class1->allowWidening = widen1 && widen2; 428 if ( common ) { 429 common->get_qualifiers() = Type::Qualifiers{}; 430 class1->set_type( common ); 431 } 432 class1->data.isComplete |= data.isComplete; 433 env.erase( class2 ); 434 } else return false; 435 } else if ( class1 != env.end() && class2 != env.end() ) { 436 // both classes exist, at least one unbound, merge unconditionally 437 if ( type1 ) { 438 class1->vars.insert( class2->vars.begin(), class2->vars.end() ); 439 class1->allowWidening = widen1; 440 class1->data.isComplete |= data.isComplete; 441 env.erase( class2 ); 442 } else { 443 class2->vars.insert( class1->vars.begin(), class1->vars.end() ); 444 class2->allowWidening = widen2; 445 class2->data.isComplete |= data.isComplete; 446 env.erase( class1 ); 447 } // if 448 } else if ( class1 != env.end() ) { 449 // var2 unbound, add to class1 450 class1->vars.insert( var2->get_name() ); 451 class1->allowWidening = widen1; 452 class1->data.isComplete |= data.isComplete; 453 } else if ( class2 != env.end() ) { 454 // var1 unbound, add to class2 455 class2->vars.insert( var1->get_name() ); 456 class2->allowWidening = widen2; 457 class2->data.isComplete |= data.isComplete; 458 } else { 459 // neither var bound, create new class 460 EqvClass newClass; 461 newClass.vars.insert( var1->get_name() ); 462 newClass.vars.insert( var2->get_name() ); 463 newClass.allowWidening = widen1 && widen2; 464 newClass.data = data; 465 env.push_back( std::move(newClass) ); 466 } // if 467 return true; 468 } 469 470 void TypeEnvironment::forbidWidening() { 471 for ( EqvClass& c : env ) c.allowWidening = false; 472 } 473 243 474 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) { 244 475 env.print( out ); -
src/ResolvExpr/TypeEnvironment.h
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:24:58 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:35:45 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 19 17:00:10 2019 13 // Update Count : 10 14 14 // 15 15 … … 18 18 #include <iostream> // for ostream 19 19 #include <list> // for list, list<>::iterator, list<>... 20 #include <map> // for map, map<>::value_compare 21 #include <set> // for set 20 #include <map> // for map, map<>::value_compare 21 #include <unordered_map> 22 #include <set> // for set 22 23 #include <string> // for string 24 #include <utility> // for move, swap 25 26 #include "WidenMode.h" // for WidenMode 23 27 24 28 #include "SynTree/Declaration.h" // for TypeDecl::Data, DeclarationWit... … … 36 40 // declarations. 37 41 // 38 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator. 42 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this 43 // comparator. 39 44 // 40 45 // Note: since this compares pointers for position, minor changes in the source file that affect 41 46 // memory layout can alter compilation time in unpredictable ways. For example, the placement 42 47 // of a line directive can reorder type pointers with respect to each other so that assertions 43 // are seen in different orders, causing a potentially different number of unification calls when 44 // resolving assertions. I've seen a TU go from 36 seconds to 27 seconds by reordering line directives 45 // alone, so it would be nice to fix this comparison so that assertions compare more consistently. 46 // I've tried to modify this to compare on mangle name instead of type as the second comparator, but 47 // this causes some assertions to never be recorded. More investigation is needed. 48 // are seen in different orders, causing a potentially different number of unification calls 49 // when resolving assertions. I've seen a TU go from 36 seconds to 27 seconds by reordering 50 // line directives alone, so it would be nice to fix this comparison so that assertions compare 51 // more consistently. I've tried to modify this to compare on mangle name instead of type as 52 // the second comparator, but this causes some assertions to never be recorded. More 53 // investigation is needed. 48 54 struct AssertCompare { 49 bool operator()( DeclarationWithType * d1,DeclarationWithType * d2 ) const {55 bool operator()( const DeclarationWithType * d1, const DeclarationWithType * d2 ) const { 50 56 int cmp = d1->get_name().compare( d2->get_name() ); 51 57 return cmp < 0 || … … 54 60 }; 55 61 struct AssertionSetValue { 56 bool isUsed; 57 // chain of Unique IDs of the assertion declarations. The first ID in the chain is the ID of an assertion on the current type, 58 // with each successive ID being the ID of an assertion pulled in by the previous ID. The last ID in the chain is 59 // the ID of the assertion that pulled in the current assertion. 60 std::list< UniqueId > idChain; 62 bool isUsed; ///< True if assertion needs to be resolved 63 UniqueId resnSlot; ///< ID of slot assertion belongs to 64 65 AssertionSetValue() : isUsed(false), resnSlot(0) {} 61 66 }; 62 typedef std::map< DeclarationWithType*, AssertionSetValue, AssertCompare > AssertionSet; 63 typedef std::map< std::string, TypeDecl::Data > OpenVarSet; 67 typedef std::map< const DeclarationWithType *, AssertionSetValue, AssertCompare > AssertionSet; 68 typedef std::unordered_map< std::string, TypeDecl::Data > OpenVarSet; 69 70 /// merges one set of open vars into another 71 static inline void mergeOpenVars( OpenVarSet& dst, const OpenVarSet& src ) { 72 for ( const auto& entry : src ) { dst[ entry.first ] = entry.second; } 73 } 64 74 65 75 void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 ); … … 68 78 struct EqvClass { 69 79 std::set< std::string > vars; 70 Type * type;80 Type * type; 71 81 bool allowWidening; 72 82 TypeDecl::Data data; … … 77 87 EqvClass( const EqvClass &other ); 78 88 EqvClass( const EqvClass &other, const Type *ty ); 89 EqvClass( EqvClass &&other ); 79 90 EqvClass &operator=( const EqvClass &other ); 91 EqvClass &operator=( EqvClass &&other ); 80 92 ~EqvClass(); 81 93 void print( std::ostream &os, Indenter indent = {} ) const; 94 95 /// Takes ownership of `ty`, freeing old `type` 96 void set_type(Type* ty); 82 97 }; 83 98 84 99 class TypeEnvironment { 100 using ClassList = std::list< EqvClass >; 85 101 public: 86 102 const EqvClass* lookup( const std::string &var ) const; 87 void add( const EqvClass &eqvClass );103 private: 88 104 void add( EqvClass &&eqvClass ); 105 public: 89 106 void add( const Type::ForallList &tyDecls ); 90 107 void add( const TypeSubstitution & sub ); … … 94 111 bool isEmpty() const { return env.empty(); } 95 112 void print( std::ostream &os, Indenter indent = {} ) const; 96 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ); 113 114 /// Simply concatenate the second environment onto this one; no safety checks performed 97 115 void simpleCombine( const TypeEnvironment &second ); 116 117 private: 118 /// Unifies the type bound of to with the type bound of from, returning false if fails 119 bool mergeBound( EqvClass& to, const EqvClass& from, OpenVarSet& openVars, const SymTab::Indexer& indexer ); 120 121 /// Merges two type classes from local environment, returning false if fails 122 bool mergeClasses( ClassList::iterator to, ClassList::iterator from, OpenVarSet& openVars, const SymTab::Indexer& indexer ); 123 124 public: 125 /// Merges the second environment with this one, checking compatibility. 126 /// Returns false if fails, but does NOT roll back partial changes. 127 bool combine( const TypeEnvironment& second, OpenVarSet& openVars, const SymTab::Indexer& indexer ); 128 98 129 void extractOpenVars( OpenVarSet &openVars ) const; 99 130 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } … … 103 134 void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ); 104 135 105 typedef std::list< EqvClass >::iterator iterator; 106 iterator begin() { return env.begin(); } 107 iterator end() { return env.end(); } 108 typedef std::list< EqvClass >::const_iterator const_iterator; 109 const_iterator begin() const { return env.begin(); } 110 const_iterator end() const { return env.end(); } 136 /// Binds the type class represented by `typeInst` to the type `bindTo`; will add 137 /// the class if needed. Returns false on failure. 138 bool bindVar( const TypeInstType * typeInst, Type * bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 139 140 /// Binds the type classes represented by `var1` and `var2` together; will add 141 /// one or both classes if needed. Returns false on failure. 142 bool bindVarToVar( const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 143 144 /// Disallows widening for all bindings in the environment 145 void forbidWidening(); 146 147 using iterator = ClassList::const_iterator; 148 iterator begin() const { return env.begin(); } 149 iterator end() const { return env.end(); } 150 111 151 private: 112 std::list< EqvClass > env; 113 std::list< EqvClass >::iterator internal_lookup( const std::string &var ); 152 ClassList env; 153 154 ClassList::iterator internal_lookup( const std::string &var ); 114 155 }; 115 156 -
src/ResolvExpr/Unify.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:27:10 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 16 16:22:54 201713 // Update Count : 4 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 4 10:00:00 2019 13 // Update Count : 44 14 14 // 15 15 16 #include <cassert> // for assertf, assert17 #include <iterator> // for back_insert_iterator, back_inserter18 #include <map> // for _Rb_tree_const_iterator, _Rb_tree_i...19 #include <memory> // for unique_ptr20 #include <set> // for set21 #include <string> // for string, operator==, operator!=, bas...22 #include <utility> // for pair, move23 24 #include "Common/PassVisitor.h" // for PassVisitor25 #include "FindOpenVars.h" // for findOpenVars26 #include "Parser/LinkageSpec.h" // for C27 #include "SynTree/Constant.h" // for Constant28 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data, Declarati...29 #include "SynTree/Expression.h" // for TypeExpr, Expression, ConstantExpr30 #include "SynTree/Mutator.h" // for Mutator31 #include "SynTree/Type.h" // for Type, TypeInstType, FunctionType32 #include "SynTree/Visitor.h" // for Visitor33 #include "Tuples/Tuples.h" // for isTtype34 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet35 16 #include "Unify.h" 36 #include "typeops.h" // for flatten, occurs, commonType 17 18 #include <cassert> // for assertf, assert 19 #include <iterator> // for back_insert_iterator, back_inserter 20 #include <map> // for _Rb_tree_const_iterator, _Rb_tree_i... 21 #include <memory> // for unique_ptr 22 #include <set> // for set 23 #include <string> // for string, operator==, operator!=, bas... 24 #include <utility> // for pair, move 25 #include <vector> 26 27 #include "AST/Decl.hpp" 28 #include "AST/Node.hpp" 29 #include "AST/Pass.hpp" 30 #include "AST/Type.hpp" 31 #include "AST/TypeEnvironment.hpp" 32 #include "Common/PassVisitor.h" // for PassVisitor 33 #include "FindOpenVars.h" // for findOpenVars 34 #include "Parser/LinkageSpec.h" // for C 35 #include "SynTree/Constant.h" // for Constant 36 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data, Declarati... 37 #include "SynTree/Expression.h" // for TypeExpr, Expression, ConstantExpr 38 #include "SynTree/Mutator.h" // for Mutator 39 #include "SynTree/Type.h" // for Type, TypeInstType, FunctionType 40 #include "SynTree/Visitor.h" // for Visitor 41 #include "Tuples/Tuples.h" // for isTtype 42 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet 43 #include "typeops.h" // for flatten, occurs, commonType 44 45 namespace ast { 46 class SymbolTable; 47 } 37 48 38 49 namespace SymTab { … … 44 55 namespace ResolvExpr { 45 56 46 struct Unify : public WithShortCircuiting {47 Unify ( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );57 struct Unify_old : public WithShortCircuiting { 58 Unify_old( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 48 59 49 60 bool get_result() const { return result; } … … 77 88 AssertionSet &haveAssertions; 78 89 const OpenVarSet &openVars; 79 WidenMode widen Mode;90 WidenMode widen; 80 91 const SymTab::Indexer &indexer; 81 92 }; … … 83 94 /// Attempts an inexact unification of type1 and type2. 84 95 /// Returns false if no such unification; if the types can be unified, sets common (unless they unify exactly and have identical type qualifiers) 85 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common ); 86 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 87 88 bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 96 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common ); 97 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 98 99 bool unifyExact( 100 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 101 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 102 WidenMode widen, const ast::SymbolTable & symtab ); 103 104 bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 89 105 TypeEnvironment newEnv; 90 106 OpenVarSet openVars, closedVars; // added closedVars 91 107 AssertionSet needAssertions, haveAssertions; 92 Type * newFirst = first->clone(), *newSecond = second->clone();108 Type * newFirst = first->clone(), * newSecond = second->clone(); 93 109 env.apply( newFirst ); 94 110 env.apply( newSecond ); … … 105 121 } 106 122 107 bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 123 bool typesCompatible( 124 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 125 const ast::TypeEnvironment & env ) { 126 ast::TypeEnvironment newEnv; 127 ast::OpenVarSet open, closed; 128 ast::AssertionSet need, have; 129 130 ast::ptr<ast::Type> newFirst{ first }, newSecond{ second }; 131 env.apply( newFirst ); 132 env.apply( newSecond ); 133 134 findOpenVars( newFirst, open, closed, need, have, FirstClosed ); 135 findOpenVars( newSecond, open, closed, need, have, FirstOpen ); 136 137 return unifyExact( 138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 } 140 141 bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 108 142 TypeEnvironment newEnv; 109 143 OpenVarSet openVars; … … 129 163 } 130 164 131 bool isFtype( Type *type ) { 132 if ( dynamic_cast< FunctionType* >( type ) ) { 133 return true; 134 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) { 135 return typeInst->get_isFtype(); 136 } // if 137 return false; 138 } 139 140 bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) { 141 switch ( data.kind ) { 142 case TypeDecl::Dtype: 143 // to bind to an object type variable, the type must not be a function type. 144 // if the type variable is specified to be a complete type then the incoming 145 // type must also be complete 146 // xxx - should this also check that type is not a tuple type and that it's not a ttype? 147 return ! isFtype( type ) && (! data.isComplete || type->isComplete() ); 148 case TypeDecl::Ftype: 149 return isFtype( type ); 150 case TypeDecl::Ttype: 151 // ttype unifies with any tuple type 152 return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type ); 153 } // switch 154 return false; 155 } 156 157 bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 158 // remove references from other, so that type variables can only bind to value types 159 other = other->stripReferences(); 160 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() ); 161 assert( tyvar != openVars.end() ); 162 if ( ! tyVarCompatible( tyvar->second, other ) ) { 163 return false; 164 } // if 165 if ( occurs( other, typeInst->get_name(), env ) ) { 166 return false; 167 } // if 168 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) { 169 if ( curClass->type ) { 170 Type *common = 0; 171 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to 172 std::unique_ptr< Type > newType( curClass->type->clone() ); 173 newType->get_qualifiers() = typeInst->get_qualifiers(); 174 if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) { 175 if ( common ) { 176 common->get_qualifiers() = Type::Qualifiers(); 177 env.add( EqvClass{ *curClass, common } ); 178 } // if 179 return true; 180 } else { 181 return false; 182 } // if 183 } else { 184 EqvClass newClass { *curClass, other }; 185 newClass.type->get_qualifiers() = Type::Qualifiers(); 186 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond; 187 env.add( std::move(newClass) ); 188 } // if 189 } else { 190 EqvClass newClass; 191 newClass.vars.insert( typeInst->get_name() ); 192 newClass.type = other->clone(); 193 newClass.type->get_qualifiers() = Type::Qualifiers(); 194 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond; 195 newClass.data = data; 196 env.add( newClass ); 197 } // if 198 return true; 199 } 200 201 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 202 bool result = true; 203 const EqvClass *class1 = env.lookup( var1->get_name() ); 204 const EqvClass *class2 = env.lookup( var2->get_name() ); 205 bool widen1 = false, widen2 = false; 206 Type *type1 = nullptr, *type2 = nullptr; 207 208 if ( class1 ) { 209 if ( class1->type ) { 210 if ( occurs( class1->type, var2->get_name(), env ) ) { 211 return false; 212 } // if 213 type1 = class1->type->clone(); 214 } // if 215 widen1 = widenMode.widenFirst && class1->allowWidening; 216 } // if 217 if ( class2 ) { 218 if ( class2->type ) { 219 if ( occurs( class2->type, var1->get_name(), env ) ) { 220 return false; 221 } // if 222 type2 = class2->type->clone(); 223 } // if 224 widen2 = widenMode.widenSecond && class2->allowWidening; 225 } // if 226 227 if ( type1 && type2 ) { 228 // std::cerr << "has type1 && type2" << std::endl; 229 WidenMode newWidenMode ( widen1, widen2 ); 230 Type *common = 0; 231 if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) { 232 EqvClass newClass1 = *class1; 233 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 234 newClass1.allowWidening = widen1 && widen2; 235 if ( common ) { 236 common->get_qualifiers() = Type::Qualifiers(); 237 delete newClass1.type; 238 newClass1.type = common; 239 } // if 240 env.add( std::move(newClass1) ); 241 } else { 242 result = false; 243 } // if 244 } else if ( class1 && class2 ) { 245 if ( type1 ) { 246 EqvClass newClass1 = *class1; 247 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 248 newClass1.allowWidening = widen1; 249 env.add( std::move(newClass1) ); 250 } else { 251 EqvClass newClass2 = *class2; 252 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() ); 253 newClass2.allowWidening = widen2; 254 env.add( std::move(newClass2) ); 255 } // if 256 } else if ( class1 ) { 257 EqvClass newClass1 = *class1; 258 newClass1.vars.insert( var2->get_name() ); 259 newClass1.allowWidening = widen1; 260 env.add( std::move(newClass1) ); 261 } else if ( class2 ) { 262 EqvClass newClass2 = *class2; 263 newClass2.vars.insert( var1->get_name() ); 264 newClass2.allowWidening = widen2; 265 env.add( std::move(newClass2) ); 266 } else { 267 EqvClass newClass; 268 newClass.vars.insert( var1->get_name() ); 269 newClass.vars.insert( var2->get_name() ); 270 newClass.allowWidening = widen1 && widen2; 271 newClass.data = data; 272 env.add( newClass ); 273 } // if 274 delete type1; 275 delete type2; 276 return result; 165 bool typesCompatibleIgnoreQualifiers( 166 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 167 const ast::TypeEnvironment & env ) { 168 ast::TypeEnvironment newEnv; 169 ast::OpenVarSet open; 170 ast::AssertionSet need, have; 171 172 ast::ptr<ast::Type> newFirst{ first }, newSecond{ second }; 173 env.apply( newFirst ); 174 env.apply( newSecond ); 175 reset_qualifiers( newFirst ); 176 reset_qualifiers( newSecond ); 177 178 return unifyExact( 179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 277 180 } 278 181 … … 299 202 } 300 203 301 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen Mode, const SymTab::Indexer &indexer ) {204 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ) { 302 205 #ifdef DEBUG 303 206 TypeEnvironment debugEnv( env ); … … 320 223 bool isopen2 = var2 && ( entry2 != openVars.end() ); 321 224 322 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 323 result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 225 if ( isopen1 && isopen2 ) { 226 if ( entry1->second.kind != entry2->second.kind ) { 227 result = false; 228 } else { 229 result = env.bindVarToVar( 230 var1, var2, TypeDecl::Data{ entry1->second, entry2->second }, needAssertions, 231 haveAssertions, openVars, widen, indexer ); 232 } 324 233 } else if ( isopen1 ) { 325 result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );326 } else if ( isopen2 ) { // TODO: swap widen Modevalues in call, since type positions are flipped?327 result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );234 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widen, indexer ); 235 } else if ( isopen2 ) { // TODO: swap widen values in call, since type positions are flipped? 236 result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widen, indexer ); 328 237 } else { 329 PassVisitor<Unify > comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );238 PassVisitor<Unify_old> comparator( type2, env, needAssertions, haveAssertions, openVars, widen, indexer ); 330 239 type1->accept( comparator ); 331 240 result = comparator.pass.get_result(); … … 352 261 } 353 262 354 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen Mode, const SymTab::Indexer &indexer, Type *&common ) {263 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common ) { 355 264 Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers(); 356 265 type1->get_qualifiers() = Type::Qualifiers(); … … 364 273 std::cerr << std::endl; 365 274 #endif 366 if ( ! unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widen Mode, indexer ) ) {275 if ( ! unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widen, indexer ) ) { 367 276 #ifdef DEBUG 368 277 std::cerr << "unifyInexact: no exact unification found" << std::endl; 369 278 #endif 370 if ( ( common = commonType( type1, type2, widen Mode.widenFirst, widenMode.widenSecond, indexer, env, openVars ) ) ) {371 common-> get_qualifiers() = tq1 | tq2;279 if ( ( common = commonType( type1, type2, widen.first, widen.second, indexer, env, openVars ) ) ) { 280 common->tq = tq1.unify( tq2 ); 372 281 #ifdef DEBUG 373 282 std::cerr << "unifyInexact: common type is "; … … 384 293 } else { 385 294 if ( tq1 != tq2 ) { 386 if ( ( tq1 > tq2 || widen Mode.widenFirst ) && ( tq2 > tq1 || widenMode.widenSecond ) ) {295 if ( ( tq1 > tq2 || widen.first ) && ( tq2 > tq1 || widen.second ) ) { 387 296 common = type1->clone(); 388 common-> get_qualifiers() = tq1 | tq2;297 common->tq = tq1.unify( tq2 ); 389 298 result = true; 390 299 } else { … … 393 302 } else { 394 303 common = type1->clone(); 395 common-> get_qualifiers() = tq1 | tq2;304 common->tq = tq1.unify( tq2 ); 396 305 result = true; 397 306 } // if … … 402 311 } 403 312 404 Unify ::Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )405 : result( false ), type2( type2 ), env( env ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), openVars( openVars ), widen Mode( widenMode), indexer( indexer ) {406 } 407 408 void Unify ::postvisit( __attribute__((unused)) VoidType *voidType) {313 Unify_old::Unify_old( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ) 314 : result( false ), type2( type2 ), env( env ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), openVars( openVars ), widen( widen ), indexer( indexer ) { 315 } 316 317 void Unify_old::postvisit( __attribute__((unused)) VoidType *voidType) { 409 318 result = dynamic_cast< VoidType* >( type2 ); 410 319 } 411 320 412 void Unify ::postvisit(BasicType *basicType) {321 void Unify_old::postvisit(BasicType *basicType) { 413 322 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) { 414 323 result = basicType->get_kind() == otherBasic->get_kind(); … … 438 347 } 439 348 440 void Unify ::postvisit(PointerType *pointerType) {349 void Unify_old::postvisit(PointerType *pointerType) { 441 350 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) { 442 351 result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); … … 446 355 } 447 356 448 void Unify ::postvisit(ReferenceType *refType) {357 void Unify_old::postvisit(ReferenceType *refType) { 449 358 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) { 450 359 result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); … … 454 363 } 455 364 456 void Unify ::postvisit(ArrayType *arrayType) {365 void Unify_old::postvisit(ArrayType *arrayType) { 457 366 ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 ); 458 367 // to unify, array types must both be VLA or both not VLA … … 534 443 /// If this isn't done then argument lists can have wildly different 535 444 /// size and structure, when they should be compatible. 536 struct TtypeExpander : public WithShortCircuiting {445 struct TtypeExpander_old : public WithShortCircuiting { 537 446 TypeEnvironment & tenv; 538 TtypeExpander ( TypeEnvironment & tenv ) : tenv( tenv ) {}447 TtypeExpander_old( TypeEnvironment & tenv ) : tenv( tenv ) {} 539 448 void premutate( TypeInstType * ) { visit_children = false; } 540 449 Type * postmutate( TypeInstType * typeInst ) { … … 555 464 dst.clear(); 556 465 for ( DeclarationWithType * dcl : src ) { 557 PassVisitor<TtypeExpander > expander( env );466 PassVisitor<TtypeExpander_old> expander( env ); 558 467 dcl->acceptMutator( expander ); 559 468 std::list< Type * > types; … … 570 479 } 571 480 572 void Unify ::postvisit(FunctionType *functionType) {481 void Unify_old::postvisit(FunctionType *functionType) { 573 482 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 574 483 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { … … 581 490 582 491 // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors 583 if ( (flatFunc->parameters.size() == flatOther->parameters.size() && flatFunc->returnVals.size() == flatOther->returnVals.size()) || flatFunc->isTtype() || flatOther->isTtype() ) { 492 if ( 493 (flatFunc->parameters.size() == flatOther->parameters.size() && 494 flatFunc->returnVals.size() == flatOther->returnVals.size()) 495 || flatFunc->isTtype() 496 || flatOther->isTtype() 497 ) { 584 498 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 585 499 if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { … … 597 511 598 512 template< typename RefType > 599 void Unify ::handleRefType( RefType *inst, Type *other ) {513 void Unify_old::handleRefType( RefType *inst, Type *other ) { 600 514 // check that other type is compatible and named the same 601 515 RefType *otherStruct = dynamic_cast< RefType* >( other ); … … 604 518 605 519 template< typename RefType > 606 void Unify ::handleGenericRefType( RefType *inst, Type *other ) {520 void Unify_old::handleGenericRefType( RefType *inst, Type *other ) { 607 521 // Check that other type is compatible and named the same 608 522 handleRefType( inst, other ); … … 672 586 } 673 587 674 void Unify ::postvisit(StructInstType *structInst) {588 void Unify_old::postvisit(StructInstType *structInst) { 675 589 handleGenericRefType( structInst, type2 ); 676 590 } 677 591 678 void Unify ::postvisit(UnionInstType *unionInst) {592 void Unify_old::postvisit(UnionInstType *unionInst) { 679 593 handleGenericRefType( unionInst, type2 ); 680 594 } 681 595 682 void Unify ::postvisit(EnumInstType *enumInst) {596 void Unify_old::postvisit(EnumInstType *enumInst) { 683 597 handleRefType( enumInst, type2 ); 684 598 } 685 599 686 void Unify ::postvisit(TraitInstType *contextInst) {600 void Unify_old::postvisit(TraitInstType *contextInst) { 687 601 handleRefType( contextInst, type2 ); 688 602 } 689 603 690 void Unify ::postvisit(TypeInstType *typeInst) {604 void Unify_old::postvisit(TypeInstType *typeInst) { 691 605 assert( openVars.find( typeInst->get_name() ) == openVars.end() ); 692 606 TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 ); … … 743 657 } 744 658 745 void Unify ::postvisit(TupleType *tupleType) {659 void Unify_old::postvisit(TupleType *tupleType) { 746 660 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 747 661 std::unique_ptr<TupleType> flat1( tupleType->clone() ); … … 749 663 std::list<Type *> types1, types2; 750 664 751 PassVisitor<TtypeExpander > expander( env );665 PassVisitor<TtypeExpander_old> expander( env ); 752 666 flat1->acceptMutator( expander ); 753 667 flat2->acceptMutator( expander ); … … 760 674 } 761 675 762 void Unify ::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {676 void Unify_old::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) { 763 677 result = dynamic_cast< VarArgsType* >( type2 ); 764 678 } 765 679 766 void Unify ::postvisit( __attribute__((unused)) ZeroType *zeroType ) {680 void Unify_old::postvisit( __attribute__((unused)) ZeroType *zeroType ) { 767 681 result = dynamic_cast< ZeroType* >( type2 ); 768 682 } 769 683 770 void Unify ::postvisit( __attribute__((unused)) OneType *oneType ) {684 void Unify_old::postvisit( __attribute__((unused)) OneType *oneType ) { 771 685 result = dynamic_cast< OneType* >( type2 ); 772 686 } 773 687 774 // xxx - compute once and store in the FunctionType?775 688 Type * extractResultType( FunctionType * function ) { 776 689 if ( function->get_returnVals().size() == 0 ) { … … 786 699 } 787 700 } 701 702 class Unify_new final : public ast::WithShortCircuiting { 703 const ast::Type * type2; 704 ast::TypeEnvironment & tenv; 705 ast::AssertionSet & need; 706 ast::AssertionSet & have; 707 const ast::OpenVarSet & open; 708 WidenMode widen; 709 const ast::SymbolTable & symtab; 710 public: 711 bool result; 712 713 Unify_new( 714 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 715 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 716 const ast::SymbolTable & symtab ) 717 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 718 symtab(symtab), result(false) {} 719 720 void previsit( const ast::Node * ) { visit_children = false; } 721 722 void postvisit( const ast::VoidType * ) { 723 result = dynamic_cast< const ast::VoidType * >( type2 ); 724 } 725 726 void postvisit( const ast::BasicType * basic ) { 727 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) { 728 result = basic->kind == basic2->kind; 729 } 730 } 731 732 void postvisit( const ast::PointerType * pointer ) { 733 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 734 result = unifyExact( 735 pointer->base, pointer2->base, tenv, need, have, open, 736 noWiden(), symtab ); 737 } 738 } 739 740 void postvisit( const ast::ArrayType * array ) { 741 auto array2 = dynamic_cast< const ast::ArrayType * >( type2 ); 742 if ( ! array2 ) return; 743 744 // to unify, array types must both be VLA or both not VLA and both must have a 745 // dimension expression or not have a dimension 746 if ( array->isVarLen != array2->isVarLen ) return; 747 if ( ! array->isVarLen && ! array2->isVarLen 748 && array->dimension && array2->dimension ) { 749 auto ce1 = array->dimension.as< ast::ConstantExpr >(); 750 auto ce2 = array2->dimension.as< ast::ConstantExpr >(); 751 752 // see C11 Reference Manual 6.7.6.2.6 753 // two array types with size specifiers that are integer constant expressions are 754 // compatible if both size specifiers have the same constant value 755 if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return; 756 } 757 758 result = unifyExact( 759 array->base, array2->base, tenv, need, have, open, noWiden(), 760 symtab ); 761 } 762 763 void postvisit( const ast::ReferenceType * ref ) { 764 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 765 result = unifyExact( 766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 767 symtab ); 768 } 769 } 770 771 private: 772 /// Replaces ttype variables with their bound types. 773 /// If this isn't done when satifying ttype assertions, then argument lists can have 774 /// different size and structure when they should be compatible. 775 struct TtypeExpander_new : public ast::WithShortCircuiting { 776 ast::TypeEnvironment & tenv; 777 778 TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {} 779 780 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 781 if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name ) ) { 782 // expand ttype parameter into its actual type 783 if ( clz->data.kind == ast::TypeVar::Ttype && clz->bound ) { 784 return clz->bound; 785 } 786 } 787 return typeInst; 788 } 789 }; 790 791 /// returns flattened version of `src` 792 static std::vector< ast::ptr< ast::DeclWithType > > flattenList( 793 const std::vector< ast::ptr< ast::DeclWithType > > & src, ast::TypeEnvironment & env 794 ) { 795 std::vector< ast::ptr< ast::DeclWithType > > dst; 796 dst.reserve( src.size() ); 797 for ( const ast::DeclWithType * d : src ) { 798 ast::Pass<TtypeExpander_new> expander{ env }; 799 d = d->accept( expander ); 800 auto types = flatten( d->get_type() ); 801 for ( ast::ptr< ast::Type > & t : types ) { 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play 803 // a role in the unification of function types, since they do not determine 804 // whether a function is callable. 805 // NOTE: **must** consider at least mutex qualifier, since functions can be 806 // overloaded on outermost mutex and a mutex function has different 807 // requirements than a non-mutex function 808 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 809 dst.emplace_back( new ast::ObjectDecl{ d->location, "", t } ); 810 } 811 } 812 return dst; 813 } 814 815 /// Creates a tuple type based on a list of DeclWithType 816 template< typename Iter > 817 static ast::ptr< ast::Type > tupleFromDecls( Iter crnt, Iter end ) { 818 std::vector< ast::ptr< ast::Type > > types; 819 while ( crnt != end ) { 820 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 821 // that this results in a flat tuple 822 flatten( (*crnt)->get_type(), types ); 823 824 ++crnt; 825 } 826 827 return { new ast::TupleType{ std::move(types) } }; 828 } 829 830 template< typename Iter > 831 static bool unifyDeclList( 832 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 833 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 834 const ast::SymbolTable & symtab 835 ) { 836 while ( crnt1 != end1 && crnt2 != end2 ) { 837 const ast::Type * t1 = (*crnt1)->get_type(); 838 const ast::Type * t2 = (*crnt2)->get_type(); 839 bool isTuple1 = Tuples::isTtype( t1 ); 840 bool isTuple2 = Tuples::isTtype( t2 ); 841 842 // assumes here that ttype *must* be last parameter 843 if ( isTuple1 && ! isTuple2 ) { 844 // combine remainder of list2, then unify 845 return unifyExact( 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 847 noWiden(), symtab ); 848 } else if ( ! isTuple1 && isTuple2 ) { 849 // combine remainder of list1, then unify 850 return unifyExact( 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 852 noWiden(), symtab ); 853 } 854 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 857 ) return false; 858 859 ++crnt1; ++crnt2; 860 } 861 862 // May get to the end of one argument list before the other. This is only okay if the 863 // other is a ttype 864 if ( crnt1 != end1 ) { 865 // try unifying empty tuple with ttype 866 const ast::Type * t1 = (*crnt1)->get_type(); 867 if ( ! Tuples::isTtype( t1 ) ) return false; 868 return unifyExact( 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 870 noWiden(), symtab ); 871 } else if ( crnt2 != end2 ) { 872 // try unifying empty tuple with ttype 873 const ast::Type * t2 = (*crnt2)->get_type(); 874 if ( ! Tuples::isTtype( t2 ) ) return false; 875 return unifyExact( 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 877 noWiden(), symtab ); 878 } 879 880 return true; 881 } 882 883 static bool unifyDeclList( 884 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 885 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 886 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 887 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 888 ) { 889 return unifyDeclList( 890 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 891 symtab ); 892 } 893 894 static void markAssertionSet( ast::AssertionSet & assns, const ast::DeclWithType * assn ) { 895 auto i = assns.find( assn ); 896 if ( i != assns.end() ) { 897 i->second.isUsed = true; 898 } 899 } 900 901 /// mark all assertions in `type` used in both `assn1` and `assn2` 902 static void markAssertions( 903 ast::AssertionSet & assn1, ast::AssertionSet & assn2, 904 const ast::ParameterizedType * type 905 ) { 906 for ( const auto & tyvar : type->forall ) { 907 for ( const ast::DeclWithType * assert : tyvar->assertions ) { 908 markAssertionSet( assn1, assert ); 909 markAssertionSet( assn2, assert ); 910 } 911 } 912 } 913 914 public: 915 void postvisit( const ast::FunctionType * func ) { 916 auto func2 = dynamic_cast< const ast::FunctionType * >( type2 ); 917 if ( ! func2 ) return; 918 919 if ( func->isVarArgs != func2->isVarArgs ) return; 920 921 // Flatten the parameter lists for both functions so that tuple structure does not 922 // affect unification. Does not actually mutate function parameters. 923 auto params = flattenList( func->params, tenv ); 924 auto params2 = flattenList( func2->params, tenv ); 925 926 // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 927 // where the ttype is to prevent errors 928 if ( 929 ( params.size() != params2.size() || func->returns.size() != func2->returns.size() ) 930 && ! func->isTtype() 931 && ! func2->isTtype() 932 ) return; 933 934 if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return; 935 if ( ! unifyDeclList( 936 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 937 938 markAssertions( have, need, func ); 939 markAssertions( have, need, func2 ); 940 941 result = true; 942 } 943 944 private: 945 template< typename RefType > 946 const RefType * handleRefType( const RefType * inst, const ast::Type * other ) { 947 // check that the other type is compatible and named the same 948 auto otherInst = dynamic_cast< const RefType * >( other ); 949 result = otherInst && inst->name == otherInst->name; 950 return otherInst; 951 } 952 953 /// Creates a tuple type based on a list of TypeExpr 954 template< typename Iter > 955 static const ast::Type * tupleFromExprs( 956 const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs 957 ) { 958 std::vector< ast::ptr< ast::Type > > types; 959 do { 960 types.emplace_back( param->type ); 961 962 ++crnt; 963 if ( crnt == end ) break; 964 param = strict_dynamic_cast< const ast::TypeExpr * >( crnt->get() ); 965 } while(true); 966 967 return new ast::TupleType{ std::move(types), qs }; 968 } 969 970 template< typename RefType > 971 void handleGenericRefType( const RefType * inst, const ast::Type * other ) { 972 // check that other type is compatible and named the same 973 const RefType * inst2 = handleRefType( inst, other ); 974 if ( ! inst2 ) return; 975 976 // check that parameters of types unify, if any 977 const std::vector< ast::ptr< ast::Expr > > & params = inst->params; 978 const std::vector< ast::ptr< ast::Expr > > & params2 = inst2->params; 979 980 auto it = params.begin(); 981 auto jt = params2.begin(); 982 for ( ; it != params.end() && jt != params2.end(); ++it, ++jt ) { 983 auto param = strict_dynamic_cast< const ast::TypeExpr * >( it->get() ); 984 auto param2 = strict_dynamic_cast< const ast::TypeExpr * >( jt->get() ); 985 986 ast::ptr< ast::Type > pty = param->type; 987 ast::ptr< ast::Type > pty2 = param2->type; 988 989 bool isTuple = Tuples::isTtype( pty ); 990 bool isTuple2 = Tuples::isTtype( pty2 ); 991 992 if ( isTuple && isTuple2 ) { 993 ++it; ++jt; // skip ttype parameters before break 994 } else if ( isTuple ) { 995 // bundle remaining params into tuple 996 pty2 = tupleFromExprs( param2, jt, params2.end(), pty->qualifiers ); 997 ++it; // skip ttype parameter for break 998 } else if ( isTuple2 ) { 999 // bundle remaining params into tuple 1000 pty = tupleFromExprs( param, it, params.end(), pty2->qualifiers ); 1001 ++jt; // skip ttype parameter for break 1002 } 1003 1004 if ( ! unifyExact( 1005 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1006 result = false; 1007 return; 1008 } 1009 1010 // ttype parameter should be last 1011 if ( isTuple || isTuple2 ) break; 1012 } 1013 result = it == params.end() && jt == params2.end(); 1014 } 1015 1016 public: 1017 void postvisit( const ast::StructInstType * aggrType ) { 1018 handleGenericRefType( aggrType, type2 ); 1019 } 1020 1021 void postvisit( const ast::UnionInstType * aggrType ) { 1022 handleGenericRefType( aggrType, type2 ); 1023 } 1024 1025 void postvisit( const ast::EnumInstType * aggrType ) { 1026 handleRefType( aggrType, type2 ); 1027 } 1028 1029 void postvisit( const ast::TraitInstType * aggrType ) { 1030 handleRefType( aggrType, type2 ); 1031 } 1032 1033 void postvisit( const ast::TypeInstType * typeInst ) { 1034 assert( open.find( typeInst->name ) == open.end() ); 1035 handleRefType( typeInst, type2 ); 1036 } 1037 1038 private: 1039 /// Creates a tuple type based on a list of Type 1040 static ast::ptr< ast::Type > tupleFromTypes( 1041 const std::vector< ast::ptr< ast::Type > > & tys 1042 ) { 1043 std::vector< ast::ptr< ast::Type > > out; 1044 for ( const ast::Type * ty : tys ) { 1045 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1046 // that this results in a flat tuple 1047 flatten( ty, out ); 1048 } 1049 1050 return { new ast::TupleType{ std::move(out) } }; 1051 } 1052 1053 static bool unifyList( 1054 const std::vector< ast::ptr< ast::Type > > & list1, 1055 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1056 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1057 const ast::SymbolTable & symtab 1058 ) { 1059 auto crnt1 = list1.begin(); 1060 auto crnt2 = list2.begin(); 1061 while ( crnt1 != list1.end() && crnt2 != list2.end() ) { 1062 const ast::Type * t1 = *crnt1; 1063 const ast::Type * t2 = *crnt2; 1064 bool isTuple1 = Tuples::isTtype( t1 ); 1065 bool isTuple2 = Tuples::isTtype( t2 ); 1066 1067 // assumes ttype must be last parameter 1068 if ( isTuple1 && ! isTuple2 ) { 1069 // combine entirety of list2, then unify 1070 return unifyExact( 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1072 noWiden(), symtab ); 1073 } else if ( ! isTuple1 && isTuple2 ) { 1074 // combine entirety of list1, then unify 1075 return unifyExact( 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1077 noWiden(), symtab ); 1078 } 1079 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1082 ) return false; 1083 1084 ++crnt1; ++crnt2; 1085 } 1086 1087 if ( crnt1 != list1.end() ) { 1088 // try unifying empty tuple type with ttype 1089 const ast::Type * t1 = *crnt1; 1090 if ( ! Tuples::isTtype( t1 ) ) return false; 1091 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1092 // from Rob's code 1093 return unifyExact( 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1095 noWiden(), symtab ); 1096 } else if ( crnt2 != list2.end() ) { 1097 // try unifying empty tuple with ttype 1098 const ast::Type * t2 = *crnt2; 1099 if ( ! Tuples::isTtype( t2 ) ) return false; 1100 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1101 // from Rob's code 1102 return unifyExact( 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1104 noWiden(), symtab ); 1105 } 1106 1107 return true; 1108 } 1109 1110 public: 1111 void postvisit( const ast::TupleType * tuple ) { 1112 auto tuple2 = dynamic_cast< const ast::TupleType * >( type2 ); 1113 if ( ! tuple2 ) return; 1114 1115 ast::Pass<TtypeExpander_new> expander{ tenv }; 1116 const ast::Type * flat = tuple->accept( expander ); 1117 const ast::Type * flat2 = tuple2->accept( expander ); 1118 1119 auto types = flatten( flat ); 1120 auto types2 = flatten( flat2 ); 1121 1122 result = unifyList( types, types2, tenv, need, have, open, symtab ); 1123 } 1124 1125 void postvisit( const ast::VarArgsType * ) { 1126 result = dynamic_cast< const ast::VarArgsType * >( type2 ); 1127 } 1128 1129 void postvisit( const ast::ZeroType * ) { 1130 result = dynamic_cast< const ast::ZeroType * >( type2 ); 1131 } 1132 1133 void postvisit( const ast::OneType * ) { 1134 result = dynamic_cast< const ast::OneType * >( type2 ); 1135 } 1136 1137 private: 1138 template< typename RefType > void handleRefType( RefType *inst, Type *other ); 1139 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other ); 1140 }; 1141 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1145 ast::OpenVarSet & open, const ast::SymbolTable & symtab 1146 ) { 1147 ast::ptr<ast::Type> common; 1148 return unify( type1, type2, env, need, have, open, symtab, common ); 1149 } 1150 1151 bool unify( 1152 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1153 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1154 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1155 ) { 1156 ast::OpenVarSet closed; 1157 findOpenVars( type1, open, closed, need, have, FirstClosed ); 1158 findOpenVars( type2, open, closed, need, have, FirstOpen ); 1159 return unifyInexact( 1160 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1161 } 1162 1163 bool unifyExact( 1164 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1165 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1166 WidenMode widen, const ast::SymbolTable & symtab 1167 ) { 1168 if ( type1->qualifiers != type2->qualifiers ) return false; 1169 1170 auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 ); 1171 auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 ); 1172 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name ) : open.end(), 1174 entry2 = var2 ? open.find( var2->name ) : open.end(); 1175 bool isopen1 = entry1 != open.end(); 1176 bool isopen2 = entry2 != open.end(); 1177 1178 if ( isopen1 && isopen2 ) { 1179 if ( entry1->second.kind != entry2->second.kind ) return false; 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 1182 open, widen, symtab ); 1183 } else if ( isopen1 ) { 1184 return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab ); 1185 } else if ( isopen2 ) { 1186 return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab ); 1187 } else { 1188 ast::Pass<Unify_new> comparator{ type2, env, need, have, open, widen, symtab }; 1189 type1->accept( comparator ); 1190 return comparator.pass.result; 1191 } 1192 } 1193 1194 bool unifyInexact( 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1198 ast::ptr<ast::Type> & common 1199 ) { 1200 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 1201 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1203 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1205 reset_qualifiers( t1 ); 1206 reset_qualifiers( t2 ); 1207 1208 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1209 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones 1210 1211 // if exact unification on unqualified types, try to merge qualifiers 1212 if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) { 1213 common = type1; 1214 reset_qualifiers( common, q1 | q2 ); 1215 return true; 1216 } else { 1217 return false; 1218 } 1219 1220 } else if (( common = commonType( t1, t2, widen, symtab, env, open ) )) { 1221 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones 1222 1223 // no exact unification, but common type 1224 reset_qualifiers( common, q1 | q2 ); 1225 return true; 1226 } else { 1227 return false; 1228 } 1229 } 1230 1231 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) { 1232 if ( func->returns.empty() ) return new ast::VoidType{}; 1233 if ( func->returns.size() == 1 ) return func->returns[0]->get_type(); 1234 1235 std::vector<ast::ptr<ast::Type>> tys; 1236 for ( const ast::DeclWithType * decl : func->returns ) { 1237 tys.emplace_back( decl->get_type() ); 1238 } 1239 return new ast::TupleType{ std::move(tys) }; 1240 } 788 1241 } // namespace ResolvExpr 789 1242 -
src/ResolvExpr/Unify.h
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 13:09:04 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 21 23:09:34 201713 // Update Count : 311 // 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 … … 18 18 #include <list> // for list 19 19 20 #include "AST/Node.hpp" // for ptr 21 #include "AST/TypeEnvironment.hpp" // for TypeEnvironment, AssertionSet, OpenVarSet 20 22 #include "Common/utility.h" // for deleteAll 21 23 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data 22 24 #include "TypeEnvironment.h" // for AssertionSet, OpenVarSet 25 #include "WidenMode.h" // for WidenMode 23 26 24 27 class Type; 25 28 class TypeInstType; 26 29 namespace SymTab { 27 class Indexer; 28 } // namespace SymTab 30 class Indexer; 31 } 32 33 namespace ast { 34 class SymbolTable; 35 class Type; 36 } 29 37 30 38 namespace ResolvExpr { 31 struct WidenMode {32 WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}33 WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }34 WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }35 WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }36 WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }37 operator bool() { return widenFirst && widenSecond; }38 39 bool widenFirst : 1, widenSecond : 1;40 };41 42 bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );43 39 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 44 40 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType ); 45 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 ); 46 43 47 44 template< typename Iterator1, typename Iterator2 > … … 72 69 } 73 70 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 ); 75 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 ); 80 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 ); 85 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 ); 91 74 92 } // namespace ResolvExpr 75 93 -
src/ResolvExpr/module.mk
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 SRC += ResolvExpr/AlternativeFinder.cc \ 18 ResolvExpr/Alternative.cc \ 19 ResolvExpr/Unify.cc \ 20 ResolvExpr/PtrsAssignable.cc \ 21 ResolvExpr/CommonType.cc \ 22 ResolvExpr/ConversionCost.cc \ 23 ResolvExpr/CastCost.cc \ 24 ResolvExpr/PtrsCastable.cc \ 25 ResolvExpr/AdjustExprType.cc \ 26 ResolvExpr/AlternativePrinter.cc \ 27 ResolvExpr/Resolver.cc \ 28 ResolvExpr/ResolveTypeof.cc \ 29 ResolvExpr/RenameVars.cc \ 30 ResolvExpr/FindOpenVars.cc \ 31 ResolvExpr/PolyCost.cc \ 32 ResolvExpr/Occurs.cc \ 33 ResolvExpr/TypeEnvironment.cc \ 34 ResolvExpr/CurrentObject.cc \ 35 ResolvExpr/ExplodedActual.cc 17 SRC_RESOLVEXPR = \ 18 ResolvExpr/AdjustExprType.cc \ 19 ResolvExpr/Alternative.cc \ 20 ResolvExpr/AlternativeFinder.cc \ 21 ResolvExpr/Candidate.cpp \ 22 ResolvExpr/CandidateFinder.cpp \ 23 ResolvExpr/CastCost.cc \ 24 ResolvExpr/CommonType.cc \ 25 ResolvExpr/ConversionCost.cc \ 26 ResolvExpr/CurrentObject.cc \ 27 ResolvExpr/ExplodedActual.cc \ 28 ResolvExpr/ExplodedArg.cpp \ 29 ResolvExpr/FindOpenVars.cc \ 30 ResolvExpr/Occurs.cc \ 31 ResolvExpr/PolyCost.cc \ 32 ResolvExpr/PtrsAssignable.cc \ 33 ResolvExpr/PtrsCastable.cc \ 34 ResolvExpr/RenameVars.cc \ 35 ResolvExpr/ResolveAssertions.cc \ 36 ResolvExpr/Resolver.cc \ 37 ResolvExpr/ResolveTypeof.cc \ 38 ResolvExpr/SatisfyAssertions.cpp \ 39 ResolvExpr/SpecCost.cc \ 40 ResolvExpr/TypeEnvironment.cc \ 41 ResolvExpr/Unify.cc 42 43 SRC += $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc 44 SRCDEMANGLE += $(SRC_RESOLVEXPR) -
src/ResolvExpr/typeops.h
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 07:28:22 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:36:18 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:36:00 2019 13 // Update Count : 5 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" 26 #include "AST/Type.hpp" 27 #include "AST/TypeEnvironment.hpp" 20 28 #include "SynTree/SynTree.h" 21 29 #include "SynTree/Type.h" 22 #include "SymTab/Indexer.h" 23 #include "Cost.h" 24 #include "TypeEnvironment.h" 30 31 namespace SymTab { 32 class Indexer; 33 } 25 34 26 35 namespace ResolvExpr { … … 54 63 // in AdjustExprType.cc 55 64 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function 56 void adjustExprType( Type *& type, const TypeEnvironment &env, const SymTab::Indexer &indexer );65 void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 57 66 58 67 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer … … 60 69 61 70 template< typename ForwardIterator > 62 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {71 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) { 63 72 while ( begin != end ) { 64 73 adjustExprType( *begin++, env, indexer ); … … 66 75 } 67 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 68 81 // in CastCost.cc 69 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 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, const ast::SymbolTable & symtab, 86 const ast::TypeEnvironment & env ); 70 87 71 88 // in ConversionCost.cc 72 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 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, const ast::SymbolTable & symtab, 93 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 ); 73 98 74 99 // in PtrsAssignable.cc 75 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ); 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 ); 76 103 77 104 // in PtrsCastable.cc 78 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 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 ); 79 109 80 110 // in Unify.cc 81 bool isFtype( Type *type ); 82 bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 83 bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 84 85 inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) { 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 ) { 86 115 TypeEnvironment env; 87 116 return typesCompatible( t1, t2, indexer, env ); 88 117 } 89 118 90 inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {119 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 91 120 TypeEnvironment env; 92 121 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 93 122 } 94 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 95 132 /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value. 96 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 ); 97 136 98 137 // in CommonType.cc 99 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 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, WidenMode widen, 141 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open ); 100 142 101 143 // in PolyCost.cc 102 int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 144 int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 145 int polyCost( 146 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 147 148 // in SpecCost.cc 149 int specCost( Type * type ); 150 int specCost( const ast::Type * type ); 103 151 104 152 // in Occurs.cc 105 bool occurs( Type *type, std::string varName, const TypeEnvironment &env ); 153 bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env ); 154 // new AST version in TypeEnvironment.cpp (only place it was used in old AST) 155 156 template<typename Iter> 157 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) { 158 while ( begin != end ) { 159 if ( occurs( ty, *begin, env ) ) return true; 160 ++begin; 161 } 162 return false; 163 } 106 164 107 165 // in AlternativeFinder.cc 108 166 void referenceToRvalueConversion( Expression *& expr, Cost & cost ); 109 110 // flatten tuple type into list of types 167 // in CandidateFinder.cpp 168 const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost ); 169 170 /// flatten tuple type into list of types 111 171 template< typename OutputIterator > 112 172 void flatten( Type * type, OutputIterator out ) { … … 119 179 } 120 180 } 181 182 /// flatten tuple type into existing list of types 183 static inline void flatten( 184 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 185 ) { 186 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 187 for ( const ast::Type * t : tupleType->types ) { 188 flatten( t, out ); 189 } 190 } else { 191 out.emplace_back( type ); 192 } 193 } 194 195 /// flatten tuple type into list of types 196 static inline std::vector< ast::ptr< ast::Type > > flatten( const ast::Type * type ) { 197 std::vector< ast::ptr< ast::Type > > out; 198 out.reserve( type->size() ); 199 flatten( type, out ); 200 return out; 201 } 202 203 // in TypeEnvironment.cc 204 bool isFtype( const Type * type ); 121 205 } // namespace ResolvExpr 206 207 namespace ast { 208 // in TypeEnvironment.cpp 209 bool isFtype( const ast::Type * type ); 210 } // namespace ast 122 211 123 212 // Local Variables: // -
src/SymTab/Autogen.cc
r7951100 rb067d9b 24 24 #include <vector> // for vector 25 25 26 #include "AST/Decl.hpp" 26 27 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 27 28 #include "Common/PassVisitor.h" // for PassVisitor … … 41 42 42 43 namespace SymTab { 43 Type * SizeType = 0;44 45 44 /// Data used to generate functions generically. Specifically, the name of the generated function and a function which generates the routine protoype 46 45 struct FuncData { 47 typedef FunctionType * (*TypeGen)( Type * );46 typedef FunctionType * (*TypeGen)( Type *, bool ); 48 47 FuncData( const std::string & fname, const TypeGen & genType ) : fname( fname ), genType( genType ) {} 49 48 std::string fname; … … 211 210 } 212 211 212 bool isUnnamedBitfield( const ast::ObjectDecl * obj ) { 213 return obj && obj->name.empty() && obj->bitfieldWidth; 214 } 215 213 216 /// inserts a forward declaration for functionDecl into declsToAdd 214 217 void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) { … … 231 234 232 235 /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *) 233 FunctionType * genDefaultType( Type * paramType ) { 234 const auto & typeParams = getGenericParams( paramType ); 236 FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic ) { 235 237 FunctionType *ftype = new FunctionType( Type::Qualifiers(), false ); 236 cloneAll( typeParams, ftype->forall ); 238 if ( maybePolymorphic ) { 239 // only copy in 240 const auto & typeParams = getGenericParams( paramType ); 241 cloneAll( typeParams, ftype->forall ); 242 } 237 243 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr ); 238 244 ftype->parameters.push_back( dstParam ); … … 241 247 242 248 /// given type T, generate type of copy ctor, i.e. function type void (*) (T *, T) 243 FunctionType * genCopyType( Type * paramType ) {244 FunctionType *ftype = genDefaultType( paramType );249 FunctionType * genCopyType( Type * paramType, bool maybePolymorphic ) { 250 FunctionType *ftype = genDefaultType( paramType, maybePolymorphic ); 245 251 ObjectDecl *srcParam = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr ); 246 252 ftype->parameters.push_back( srcParam ); … … 249 255 250 256 /// given type T, generate type of assignment, i.e. function type T (*) (T *, T) 251 FunctionType * genAssignType( Type * paramType ) {252 FunctionType *ftype = genCopyType( paramType );257 FunctionType * genAssignType( Type * paramType, bool maybePolymorphic ) { 258 FunctionType *ftype = genCopyType( paramType, maybePolymorphic ); 253 259 ObjectDecl *returnVal = new ObjectDecl( "_ret", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr ); 254 260 ftype->returnVals.push_back( returnVal ); … … 308 314 for ( const FuncData & d : data ) { 309 315 // generate a function (?{}, ?=?, ^?{}) based on the current FuncData. 310 FunctionType * ftype = d.genType( type );316 FunctionType * ftype = d.genType( type, true ); 311 317 312 318 // destructor for concurrent type must be mutex … … 387 393 388 394 void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) { 389 InitTweak::InitExpander srcParam( src );395 InitTweak::InitExpander_old srcParam( src ); 390 396 391 397 // assign to destination -
src/SymTab/Autogen.h
r7951100 rb067d9b 17 17 18 18 #include <cassert> // for assert 19 #include <iterator> // for back_inserter 19 20 #include <string> // for string 20 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" 21 28 #include "CodeGen/OperatorTable.h" 22 29 #include "Common/UniqueName.h" // for UniqueName 30 #include "Common/utility.h" // for splice 23 31 #include "InitTweak/InitTweak.h" // for InitExpander 24 32 #include "SynTree/Constant.h" // for Constant … … 36 44 /// returns true if obj's name is the empty string and it has a bitfield width 37 45 bool isUnnamedBitfield( ObjectDecl * obj ); 38 39 /// size_t type - set when size_t typedef is seen. Useful in a few places, 40 /// such as in determining array dimension type 41 extern Type * SizeType; 42 43 /// intrinsic dereference operator for unqualified types - set when *? function is seen in FindSpecialDeclarations. 44 /// Useful for creating dereference ApplicationExprs without a full resolver pass. 45 extern FunctionDecl * dereferenceOperator; 46 47 // generate the type of an assignment function for paramType 48 FunctionType * genAssignType( Type * paramType ); 49 50 // generate the type of a default constructor or destructor for paramType 51 FunctionType * genDefaultType( Type * paramType ); 52 53 // generate the type of a copy constructor for paramType 54 FunctionType * genCopyType( Type * paramType ); 46 bool isUnnamedBitfield( const ast::ObjectDecl * obj ); 47 48 /// generate the type of an assignment function for paramType. 49 /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic 50 FunctionType * genAssignType( Type * paramType, bool maybePolymorphic = true ); 51 52 /// generate the type of a default constructor or destructor for paramType. 53 /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic 54 FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic = true ); 55 56 /// generate the type of a copy constructor for paramType. 57 /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic 58 FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true ); 59 60 /// Enum for loop direction 61 enum LoopDirection { LoopBackward, LoopForward }; 55 62 56 63 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 57 64 template< typename OutputIterator > 58 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 65 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 66 67 template< typename OutIter > 68 ast::ptr< ast::Stmt > genCall( 69 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 70 const CodeLocation & loc, const std::string & fname, OutIter && out, 71 const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward ); 59 72 60 73 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 61 74 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 62 75 template< typename OutputIterator > 63 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {76 Statement * genScalarCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) { 64 77 bool isReferenceCtorDtor = false; 65 78 if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { … … 84 97 // type->get_qualifiers() = Type::Qualifiers(); 85 98 Type * castType = addCast->clone(); 86 castType->get_qualifiers() -= Type::Qualifiers( Type:: Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );99 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 87 100 // castType->set_lvalue( true ); // xxx - might not need this 88 101 dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) ); … … 111 124 } 112 125 126 /// inserts into out a generated call expression to function fname with arguments dstParam and 127 /// srcParam. Should only be called with non-array types. 128 /// optionally returns a statement which must be inserted prior to the containing loop, if 129 /// there is one 130 template< typename OutIter > 131 ast::ptr< ast::Stmt > genScalarCall( 132 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 133 const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type, 134 const ast::Type * addCast = nullptr 135 ) { 136 bool isReferenceCtorDtor = false; 137 if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { 138 // reference constructors are essentially application of the rebind operator. 139 // apply & to both arguments, do not need a cast 140 fname = "?=?"; 141 dstParam = new ast::AddressExpr{ dstParam }; 142 addCast = nullptr; 143 isReferenceCtorDtor = true; 144 } 145 146 // want to be able to generate assignment, ctor, and dtor generically, so fname is one of 147 // "?=?", "?{}", or "^?{}" 148 ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } }; 149 150 if ( addCast ) { 151 // cast to T& with qualifiers removed, so that qualified objects can be constructed and 152 // destructed with the same functions as non-qualified objects. Unfortunately, lvalue 153 // is considered a qualifier - for AddressExpr to resolve, its argument must have an 154 // lvalue-qualified type, so remove all qualifiers except lvalue. 155 // xxx -- old code actually removed lvalue too... 156 ast::ptr< ast::Type > guard = addCast; // prevent castType from mutating addCast 157 ast::ptr< ast::Type > castType = addCast; 158 ast::remove_qualifiers( 159 castType, 160 ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic ); 161 dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } }; 162 } 163 fExpr->args.emplace_back( dstParam ); 164 165 const ast::Stmt * listInit = srcParam.buildListInit( fExpr ); 166 167 // fetch next set of arguments 168 ++srcParam; 169 170 // return if adding reference fails -- will happen on default ctor and dtor 171 if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit; 172 173 std::vector< ast::ptr< ast::Expr > > args = *srcParam; 174 splice( fExpr->args, args ); 175 176 *out++ = new ast::ExprStmt{ loc, fExpr }; 177 178 srcParam.clearArrayIndices(); 179 180 return listInit; 181 } 182 113 183 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 114 184 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 115 185 template< typename OutputIterator > 116 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {186 void genArrayCall( InitTweak::InitExpander_old & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) { 117 187 static UniqueName indexName( "_index" ); 118 188 … … 175 245 } 176 246 247 /// Store in out a loop which calls fname on each element of the array with srcParam and 248 /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0 249 template< typename OutIter > 250 void genArrayCall( 251 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 252 const CodeLocation & loc, const std::string & fname, OutIter && out, 253 const ast::ArrayType * array, const ast::Type * addCast = nullptr, 254 LoopDirection forward = LoopForward 255 ) { 256 static UniqueName indexName( "_index" ); 257 258 // for a flexible array member nothing is done -- user must define own assignment 259 if ( ! array->dimension ) return; 260 261 if ( addCast ) { 262 // peel off array layer from cast 263 addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base; 264 } 265 266 ast::ptr< ast::Expr > begin, end, cmp, update; 267 268 if ( forward ) { 269 // generate: for ( int i = 0; i < N; ++i ) 270 begin = ast::ConstantExpr::from_int( loc, 0 ); 271 end = array->dimension; 272 cmp = new ast::NameExpr{ loc, "?<?" }; 273 update = new ast::NameExpr{ loc, "++?" }; 274 } else { 275 // generate: for ( int i = N-1; i >= 0; --i ) 276 begin = new ast::UntypedExpr{ 277 loc, new ast::NameExpr{ loc, "?-?" }, 278 { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } }; 279 end = ast::ConstantExpr::from_int( loc, 0 ); 280 cmp = new ast::NameExpr{ loc, "?>=?" }; 281 update = new ast::NameExpr{ loc, "--?" }; 282 } 283 284 ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{ 285 loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt }, 286 new ast::SingleInit{ loc, begin } }; 287 288 ast::ptr< ast::Expr > cond = new ast::UntypedExpr{ 289 loc, cmp, { new ast::VariableExpr{ loc, index }, end } }; 290 291 ast::ptr< ast::Expr > inc = new ast::UntypedExpr{ 292 loc, update, { new ast::VariableExpr{ loc, index } } }; 293 294 ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{ 295 loc, new ast::NameExpr{ loc, "?[?]" }, 296 { dstParam, new ast::VariableExpr{ loc, index } } }; 297 298 // srcParam must keep track of the array indices to build the source parameter and/or 299 // array list initializer 300 srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension ); 301 302 // for stmt's body, eventually containing call 303 ast::CompoundStmt * body = new ast::CompoundStmt{ loc }; 304 ast::ptr< ast::Stmt > listInit = genCall( 305 srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast, 306 forward ); 307 308 // block containing the stmt and index variable 309 ast::CompoundStmt * block = new ast::CompoundStmt{ loc }; 310 block->push_back( new ast::DeclStmt{ loc, index } ); 311 if ( listInit ) { block->push_back( listInit ); } 312 block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } ); 313 314 *out++ = block; 315 } 316 177 317 template< typename OutputIterator > 178 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {318 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) { 179 319 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 180 320 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); … … 185 325 } 186 326 327 template< typename OutIter > 328 ast::ptr< ast::Stmt > genCall( 329 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 330 const CodeLocation & loc, const std::string & fname, OutIter && out, 331 const ast::Type * type, const ast::Type * addCast, LoopDirection forward 332 ) { 333 if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) { 334 genArrayCall( 335 srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast, 336 forward ); 337 return {}; 338 } else { 339 return genScalarCall( 340 srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast ); 341 } 342 } 343 187 344 /// inserts into out a generated call expression to function fname with arguments dstParam 188 345 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the … … 190 347 /// ImplicitCtorDtorStmt node. 191 348 template< typename OutputIterator > 192 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {349 void genImplicitCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 193 350 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 194 351 assert( obj ); … … 218 375 } 219 376 } 377 378 static inline ast::ptr< ast::Stmt > genImplicitCall( 379 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 380 const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj, 381 LoopDirection forward = LoopForward 382 ) { 383 // unnamed bit fields are not copied as they cannot be accessed 384 if ( isUnnamedBitfield( obj ) ) return {}; 385 386 ast::ptr< ast::Type > addCast = nullptr; 387 if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) { 388 assert( dstParam->result ); 389 addCast = dstParam->result; 390 } 391 392 std::vector< ast::ptr< ast::Stmt > > stmts; 393 genCall( 394 srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward ); 395 396 if ( stmts.empty() ) { 397 return {}; 398 } else if ( stmts.size() == 1 ) { 399 const ast::Stmt * callStmt = stmts.front(); 400 if ( addCast ) { 401 // implicitly generated ctor/dtor calls should be wrapped so that later passes are 402 // aware they were generated. 403 callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt }; 404 } 405 return callStmt; 406 } else { 407 assert( false ); 408 return {}; 409 } 410 } 220 411 } // namespace SymTab 221 412 -
src/SymTab/FixFunction.cc
r7951100 rb067d9b 18 18 #include <list> // for list 19 19 20 #include "Common/utility.h" // for maybeClone 20 #include "AST/Decl.hpp" 21 #include "AST/Pass.hpp" 22 #include "AST/Type.hpp" 23 #include "Common/utility.h" // for maybeClone, copy 21 24 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarati... 22 25 #include "SynTree/Expression.h" // for Expression … … 24 27 25 28 namespace SymTab { 26 FixFunction::FixFunction() : isVoid( false ) {} 29 class FixFunction_old : public WithShortCircuiting { 30 typedef Mutator Parent; 31 public: 32 FixFunction_old() : isVoid( false ) {} 27 33 34 void premutate(FunctionDecl *functionDecl); 35 DeclarationWithType* postmutate(FunctionDecl *functionDecl); 28 36 29 DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) { 37 Type * postmutate(ArrayType * arrayType); 38 39 void premutate(ArrayType * arrayType); 40 void premutate(VoidType * voidType); 41 void premutate(BasicType * basicType); 42 void premutate(PointerType * pointerType); 43 void premutate(StructInstType * aggregateUseType); 44 void premutate(UnionInstType * aggregateUseType); 45 void premutate(EnumInstType * aggregateUseType); 46 void premutate(TraitInstType * aggregateUseType); 47 void premutate(TypeInstType * aggregateUseType); 48 void premutate(TupleType * tupleType); 49 void premutate(VarArgsType * varArgsType); 50 void premutate(ZeroType * zeroType); 51 void premutate(OneType * oneType); 52 53 bool isVoid; 54 }; 55 56 DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) { 30 57 // can't delete function type because it may contain assertions, so transfer ownership to new object 31 58 ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes ); 59 pointer->location = functionDecl->location; 32 60 functionDecl->attributes.clear(); 33 61 functionDecl->type = nullptr; … … 40 68 // does not cause an error 41 69 42 Type * FixFunction ::postmutate(ArrayType *arrayType) {70 Type * FixFunction_old::postmutate(ArrayType *arrayType) { 43 71 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 44 72 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic ); 73 pointerType->location = arrayType->location; 45 74 arrayType->base = nullptr; 46 75 arrayType->dimension = nullptr; … … 49 78 } 50 79 51 void FixFunction ::premutate(VoidType *) {80 void FixFunction_old::premutate(VoidType *) { 52 81 isVoid = true; 53 82 } 54 83 55 void FixFunction ::premutate(FunctionDecl *) { visit_children = false; }56 void FixFunction ::premutate(ArrayType *) { visit_children = false; }57 void FixFunction ::premutate(BasicType *) { visit_children = false; }58 void FixFunction ::premutate(PointerType *) { visit_children = false; }59 void FixFunction ::premutate(StructInstType *) { visit_children = false; }60 void FixFunction ::premutate(UnionInstType *) { visit_children = false; }61 void FixFunction ::premutate(EnumInstType *) { visit_children = false; }62 void FixFunction ::premutate(TraitInstType *) { visit_children = false; }63 void FixFunction ::premutate(TypeInstType *) { visit_children = false; }64 void FixFunction ::premutate(TupleType *) { visit_children = false; }65 void FixFunction ::premutate(VarArgsType *) { visit_children = false; }66 void FixFunction ::premutate(ZeroType *) { visit_children = false; }67 void FixFunction ::premutate(OneType *) { visit_children = false; }84 void FixFunction_old::premutate(FunctionDecl *) { visit_children = false; } 85 void FixFunction_old::premutate(ArrayType *) { visit_children = false; } 86 void FixFunction_old::premutate(BasicType *) { visit_children = false; } 87 void FixFunction_old::premutate(PointerType *) { visit_children = false; } 88 void FixFunction_old::premutate(StructInstType *) { visit_children = false; } 89 void FixFunction_old::premutate(UnionInstType *) { visit_children = false; } 90 void FixFunction_old::premutate(EnumInstType *) { visit_children = false; } 91 void FixFunction_old::premutate(TraitInstType *) { visit_children = false; } 92 void FixFunction_old::premutate(TypeInstType *) { visit_children = false; } 93 void FixFunction_old::premutate(TupleType *) { visit_children = false; } 94 void FixFunction_old::premutate(VarArgsType *) { visit_children = false; } 95 void FixFunction_old::premutate(ZeroType *) { visit_children = false; } 96 void FixFunction_old::premutate(OneType *) { visit_children = false; } 68 97 69 98 bool fixFunction( DeclarationWithType *& dwt ) { 70 PassVisitor<FixFunction > fixer;99 PassVisitor<FixFunction_old> fixer; 71 100 dwt = dwt->acceptMutator( fixer ); 72 101 return fixer.pass.isVoid; 73 102 } 103 104 namespace { 105 struct FixFunction_new final : public ast::WithShortCircuiting { 106 bool isVoid = false; 107 108 void premutate( const ast::FunctionDecl * ) { visit_children = false; } 109 110 const ast::DeclWithType * postmutate( const ast::FunctionDecl * func ) { 111 return new ast::ObjectDecl{ 112 func->location, func->name, new ast::PointerType{ func->type }, nullptr, 113 func->storage, func->linkage, nullptr, copy( func->attributes ) }; 114 } 115 116 void premutate( const ast::ArrayType * ) { visit_children = false; } 117 118 const ast::Type * postmutate( const ast::ArrayType * array ) { 119 return new ast::PointerType{ 120 array->base, array->dimension, array->isVarLen, array->isStatic, 121 array->qualifiers }; 122 } 123 124 void premutate( const ast::VoidType * ) { isVoid = true; } 125 126 void premutate( const ast::BasicType * ) { visit_children = false; } 127 void premutate( const ast::PointerType * ) { visit_children = false; } 128 void premutate( const ast::StructInstType * ) { visit_children = false; } 129 void premutate( const ast::UnionInstType * ) { visit_children = false; } 130 void premutate( const ast::EnumInstType * ) { visit_children = false; } 131 void premutate( const ast::TraitInstType * ) { visit_children = false; } 132 void premutate( const ast::TypeInstType * ) { visit_children = false; } 133 void premutate( const ast::TupleType * ) { visit_children = false; } 134 void premutate( const ast::VarArgsType * ) { visit_children = false; } 135 void premutate( const ast::ZeroType * ) { visit_children = false; } 136 void premutate( const ast::OneType * ) { visit_children = false; } 137 }; 138 } // anonymous namespace 139 140 const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ) { 141 ast::Pass< FixFunction_new > fixer; 142 dwt = dwt->accept( fixer ); 143 isVoid |= fixer.pass.isVoid; 144 return dwt; 145 } 146 74 147 } // namespace SymTab 75 148 -
src/SymTab/FixFunction.h
r7951100 rb067d9b 19 19 #include "SynTree/SynTree.h" // for Types 20 20 21 namespace ast { 22 class DeclWithType; 23 } 24 21 25 namespace SymTab { 22 /// Replaces function and array types by equivalent pointer types. 23 class FixFunction : public WithShortCircuiting { 24 typedef Mutator Parent; 25 public: 26 FixFunction(); 26 /// Replaces function and array types by equivalent pointer types. Returns true if type is 27 /// void 28 bool fixFunction( DeclarationWithType *& ); 27 29 28 void premutate(FunctionDecl *functionDecl); 29 DeclarationWithType* postmutate(FunctionDecl *functionDecl); 30 31 Type * postmutate(ArrayType * arrayType); 32 33 void premutate(ArrayType * arrayType); 34 void premutate(VoidType * voidType); 35 void premutate(BasicType * basicType); 36 void premutate(PointerType * pointerType); 37 void premutate(StructInstType * aggregateUseType); 38 void premutate(UnionInstType * aggregateUseType); 39 void premutate(EnumInstType * aggregateUseType); 40 void premutate(TraitInstType * aggregateUseType); 41 void premutate(TypeInstType * aggregateUseType); 42 void premutate(TupleType * tupleType); 43 void premutate(VarArgsType * varArgsType); 44 void premutate(ZeroType * zeroType); 45 void premutate(OneType * oneType); 46 47 bool isVoid; 48 }; 49 50 bool fixFunction( DeclarationWithType *& ); 30 /// Returns declaration with function and array types replaced by equivalent pointer types. 31 /// Sets isVoid to true if type is void 32 const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ); 51 33 } // namespace SymTab 52 34 -
src/SymTab/Indexer.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:37:33 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Aug 17 16:08:40 201713 // Update Count : 2 011 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Mar 8 13:55:00 2019 13 // Update Count : 21 14 14 // 15 15 … … 17 17 18 18 #include <cassert> // for assert, strict_dynamic_cast 19 #include <iostream> // for operator<<, basic_ostream, ostream20 19 #include <string> // for string, operator<<, operator!= 20 #include <memory> // for shared_ptr, make_shared 21 21 #include <unordered_map> // for operator!=, unordered_map<>::const... 22 22 #include <unordered_set> // for unordered_set 23 23 #include <utility> // for pair, make_pair, move 24 #include <vector> // for vector 24 25 25 26 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 26 27 #include "Common/SemanticError.h" // for SemanticError 27 28 #include "Common/utility.h" // for cloneAll 28 #include "GenPoly/GenPoly.h" 29 #include "Common/Stats/Counter.h" // for counters 30 #include "GenPoly/GenPoly.h" // for getFunctionType 29 31 #include "InitTweak/InitTweak.h" // for isConstructor, isCopyFunction, isC... 30 32 #include "Mangler.h" // for Mangler … … 38 40 #include "SynTree/Type.h" // for Type, StructInstType, UnionInstType 39 41 40 #define debugPrint(x) if ( doDebug ) { std::cerr << x; }41 42 42 namespace SymTab { 43 std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) { 44 return out << "(" << data.id << "," << data.baseExpr << ")"; 45 } 46 47 typedef std::unordered_map< std::string, Indexer::IdData > MangleTable; 48 typedef std::unordered_map< std::string, MangleTable > IdTable; 49 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; 50 typedef std::unordered_map< std::string, StructDecl* > StructTable; 51 typedef std::unordered_map< std::string, EnumDecl* > EnumTable; 52 typedef std::unordered_map< std::string, UnionDecl* > UnionTable; 53 typedef std::unordered_map< std::string, TraitDecl* > TraitTable; 54 55 void dump( const IdTable &table, std::ostream &os ) { 56 for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) { 57 for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) { 58 os << mangle->second << std::endl; 59 } 60 } 61 } 62 63 template< typename Decl > 64 void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) { 65 for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) { 66 os << it->second << std::endl; 67 } // for 68 } 69 70 struct Indexer::Impl { 71 Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(), 72 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 73 Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ), 74 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 75 unsigned long refCount; ///< Number of references to these tables 76 unsigned long scope; ///< Scope these tables are associated with 77 unsigned long size; ///< Number of elements stored in this table 78 const Indexer base; ///< Base indexer this extends 79 80 IdTable idTable; ///< Identifier namespace 81 TypeTable typeTable; ///< Type namespace 82 StructTable structTable; ///< Struct namespace 83 EnumTable enumTable; ///< Enum namespace 84 UnionTable unionTable; ///< Union namespace 85 TraitTable traitTable; ///< Trait namespace 86 }; 87 88 Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) { 89 if ( ! toClone ) return 0; 90 91 // shorten the search chain by skipping empty links 92 Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone; 93 if ( ret ) { ++ret->refCount; } 94 95 return ret; 96 } 97 98 void Indexer::deleteRef( Indexer::Impl *toFree ) { 99 if ( ! toFree ) return; 100 101 if ( --toFree->refCount == 0 ) delete toFree; 102 } 103 104 void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const { 105 // only need to perform this step for constructors, destructors, and assignment functions 106 if ( ! CodeGen::isCtorDtorAssign( id ) ) return; 107 108 // helpful data structure to organize properties for a type 109 struct ValueType { 110 struct DeclBall { // properties for this particular decl 111 IdData decl; 112 bool isUserDefinedFunc; 113 bool isCopyFunc; 43 44 // Statistics block 45 namespace { 46 static inline auto stats() { 47 using namespace Stats::Counters; 48 static auto group = build<CounterGroup>("Indexers"); 49 static struct { 50 SimpleCounter * count; 51 AverageCounter<double> * size; 52 SimpleCounter * new_scopes; 53 SimpleCounter * lazy_scopes; 54 AverageCounter<double> * avg_scope_depth; 55 MaxCounter<size_t> * max_scope_depth; 56 SimpleCounter * add_calls; 57 SimpleCounter * lookup_calls; 58 SimpleCounter * map_lookups; 59 SimpleCounter * map_mutations; 60 } ret = { 61 .count = build<SimpleCounter>("Count", group), 62 .size = build<AverageCounter<double>>("Average Size", group), 63 .new_scopes = build<SimpleCounter>("Scopes", group), 64 .lazy_scopes = build<SimpleCounter>("Lazy Scopes", group), 65 .avg_scope_depth = build<AverageCounter<double>>("Average Scope", group), 66 .max_scope_depth = build<MaxCounter<size_t>>("Max Scope", group), 67 .add_calls = build<SimpleCounter>("Add Calls", group), 68 .lookup_calls = build<SimpleCounter>("Lookup Calls", group), 69 .map_lookups = build<SimpleCounter>("Map Lookups", group), 70 .map_mutations = build<SimpleCounter>("Map Mutations", group) 114 71 }; 115 // properties for this type 116 bool existsUserDefinedCopyFunc = false; // user-defined copy ctor found 117 BaseSyntaxNode * deleteStmt = nullptr; // non-null if a user-defined function is found 118 std::list< DeclBall > decls; 119 120 // another FunctionDecl for the current type was found - determine 121 // if it has special properties and update data structure accordingly 122 ValueType & operator+=( IdData data ) { 123 DeclarationWithType * function = data.id; 124 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage ); 125 bool isCopyFunc = InitTweak::isCopyFunction( function, function->name ); 126 decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } ); 127 existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc); 128 if ( isUserDefinedFunc && ! data.deleteStmt ) { 129 // any user-defined function can act as an implicit delete statement for generated constructors. 130 // a delete stmt should not act as an implicit delete statement. 131 deleteStmt = data.id; 132 } 133 return *this; 134 } 135 }; // ValueType 136 137 std::list< IdData > copy; 138 copy.splice( copy.end(), out ); 139 140 // organize discovered declarations by type 141 std::unordered_map< std::string, ValueType > funcMap; 142 for ( auto decl : copy ) { 143 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) { 144 std::list< DeclarationWithType * > & params = function->type->parameters; 145 assert( ! params.empty() ); 146 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 147 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 148 assert( base ); 149 funcMap[ Mangler::mangle( base ) ] += decl; 150 } else { 151 out.push_back( decl ); 152 } 153 } 154 155 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine 156 // the set of ctor/dtor/assign that can be used by the requester. In particular, if the user defines 157 // a default ctor, then the generated default ctor is unavailable, likewise for copy ctor 158 // and dtor. If the user defines any ctor/dtor, then no generated field ctors are available. 159 // If the user defines any ctor then the generated default ctor is unavailable (intrinsic default 160 // ctor must be overridden exactly). If the user defines anything that looks like a copy constructor, 161 // then the generated copy constructor is unavailable, and likewise for the assignment operator. 162 for ( std::pair< const std::string, ValueType > & pair : funcMap ) { 163 ValueType & val = pair.second; 164 for ( ValueType::DeclBall ball : val.decls ) { 165 bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic; 166 bool isCopyFunc = ball.isCopyFunc; 167 bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc; 168 // only implicitly delete non-user defined functions that are not intrinsic, and are 169 // not copy functions (assignment or copy constructor), unless a user-defined copy function exists. 170 // deleteStmt will be non-null only if a user-defined function is found. 171 if (isNotUserDefinedFunc && (! isCopyFunc || existsUserDefinedCopyFunc)) { 172 ball.decl.deleteStmt = val.deleteStmt; 173 } 174 out.push_back( ball.decl ); 175 } 176 } 177 } 178 179 void Indexer::makeWritable() { 180 if ( ! tables ) { 181 // create indexer if not yet set 182 tables = new Indexer::Impl( scope ); 183 } else if ( tables->refCount > 1 || tables->scope != scope ) { 184 // make this indexer the base of a fresh indexer at the current scope 185 tables = new Indexer::Impl( scope, std::move( *this ) ); 186 } 187 } 188 189 Indexer::Indexer() : tables( 0 ), scope( 0 ) {} 190 191 Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {} 192 193 Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) { 194 that.tables = 0; 195 } 72 return ret; 73 } 74 } 75 76 Indexer::Indexer() 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; } 196 79 197 80 Indexer::~Indexer() { 198 deleteRef( tables ); 199 } 200 201 Indexer& Indexer::operator= ( const Indexer &that ) { 202 deleteRef( tables ); 203 204 tables = newRef( that.tables ); 205 scope = that.scope; 206 doDebug = that.doDebug; 207 208 return *this; 209 } 210 211 Indexer& Indexer::operator= ( Indexer &&that ) { 212 deleteRef( tables ); 213 214 tables = that.tables; 215 scope = that.scope; 216 doDebug = that.doDebug; 217 218 that.tables = 0; 219 220 return *this; 221 } 222 223 void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const { 224 std::unordered_set< std::string > foundMangleNames; 225 226 Indexer::Impl *searchTables = tables; 227 while ( searchTables ) { 228 229 IdTable::const_iterator decls = searchTables->idTable.find( id ); 230 if ( decls != searchTables->idTable.end() ) { 231 const MangleTable &mangleTable = decls->second; 232 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 233 // mark the mangled name as found, skipping this insertion if a declaration for that name has already been found 234 if ( foundMangleNames.insert( decl->first ).second == false ) continue; 235 236 out.push_back( decl->second ); 237 } 238 } 239 240 // get declarations from base indexers 241 searchTables = searchTables->base.tables; 242 } 243 244 // some special functions, e.g. constructors and destructors 245 // remove autogenerated functions when they are defined so that 246 // they can never be matched 247 removeSpecialOverrides( id, out ); 248 } 249 250 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const { 251 if ( ! tables ) return 0; 252 253 TypeTable::const_iterator ret = tables->typeTable.find( id ); 254 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id ); 255 } 256 257 StructDecl *Indexer::lookupStruct( const std::string &id ) const { 258 if ( ! tables ) return 0; 259 260 StructTable::const_iterator ret = tables->structTable.find( id ); 261 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id ); 262 } 263 264 EnumDecl *Indexer::lookupEnum( const std::string &id ) const { 265 if ( ! tables ) return 0; 266 267 EnumTable::const_iterator ret = tables->enumTable.find( id ); 268 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id ); 269 } 270 271 UnionDecl *Indexer::lookupUnion( const std::string &id ) const { 272 if ( ! tables ) return 0; 273 274 UnionTable::const_iterator ret = tables->unionTable.find( id ); 275 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id ); 276 } 277 278 TraitDecl *Indexer::lookupTrait( const std::string &id ) const { 279 if ( ! tables ) return 0; 280 281 TraitTable::const_iterator ret = tables->traitTable.find( id ); 282 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id ); 283 } 284 285 const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 286 if ( ! tables ) return nullptr; 287 if ( tables->scope < scope ) return nullptr; 288 289 IdTable::const_iterator decls = tables->idTable.find( id ); 290 if ( decls != tables->idTable.end() ) { 291 const MangleTable &mangleTable = decls->second; 292 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 293 if ( decl != mangleTable.end() ) return &decl->second; 294 } 295 296 return tables->base.lookupIdAtScope( id, mangleName, scope ); 297 } 298 299 Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) { 300 return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope )); 301 } 302 303 bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 304 if ( ! tables ) return false; 305 if ( tables->scope < scope ) return false; 306 307 IdTable::const_iterator decls = tables->idTable.find( id ); 308 if ( decls != tables->idTable.end() ) { 309 const MangleTable &mangleTable = decls->second; 310 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 311 // check for C decls with the same name, skipping those with a compatible type (by mangleName) 312 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true; 313 } 314 } 315 316 return tables->base.hasIncompatibleCDecl( id, mangleName, scope ); 317 } 318 319 bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 320 if ( ! tables ) return false; 321 if ( tables->scope < scope ) return false; 322 323 IdTable::const_iterator decls = tables->idTable.find( id ); 324 if ( decls != tables->idTable.end() ) { 325 const MangleTable &mangleTable = decls->second; 326 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 327 // check for C decls with the same name, skipping 328 // those with an incompatible type (by mangleName) 329 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true; 330 } 331 } 332 333 return tables->base.hasCompatibleCDecl( id, mangleName, scope ); 334 } 335 336 NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const { 337 if ( ! tables ) return 0; 338 if ( tables->scope < scope ) return 0; 339 340 TypeTable::const_iterator ret = tables->typeTable.find( id ); 341 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope ); 342 } 343 344 StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const { 345 if ( ! tables ) return 0; 346 if ( tables->scope < scope ) return 0; 347 348 StructTable::const_iterator ret = tables->structTable.find( id ); 349 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope ); 350 } 351 352 EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const { 353 if ( ! tables ) return 0; 354 if ( tables->scope < scope ) return 0; 355 356 EnumTable::const_iterator ret = tables->enumTable.find( id ); 357 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope ); 358 } 359 360 UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const { 361 if ( ! tables ) return 0; 362 if ( tables->scope < scope ) return 0; 363 364 UnionTable::const_iterator ret = tables->unionTable.find( id ); 365 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope ); 366 } 367 368 TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const { 369 if ( ! tables ) return 0; 370 if ( tables->scope < scope ) return 0; 371 372 TraitTable::const_iterator ret = tables->traitTable.find( id ); 373 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope ); 374 } 375 376 bool isFunction( DeclarationWithType * decl ) { 81 stats().size->push( idTable ? idTable->size() : 0 ); 82 } 83 84 void Indexer::lazyInitScope() { 85 if ( repScope < scope ) { 86 ++* stats().lazy_scopes; 87 // create rollback 88 prevScope = std::make_shared<Indexer>( * this ); 89 // update repScope 90 repScope = scope; 91 } 92 } 93 94 void Indexer::enterScope() { 95 ++scope; 96 97 ++* stats().new_scopes; 98 stats().avg_scope_depth->push( scope ); 99 stats().max_scope_depth->push( scope ); 100 } 101 102 void Indexer::leaveScope() { 103 if ( repScope == scope ) { 104 Ptr prev = prevScope; // make sure prevScope stays live 105 * this = std::move(* prevScope); // replace with previous scope 106 } 107 108 --scope; 109 } 110 111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const { 112 ++* stats().lookup_calls; 113 if ( ! idTable ) return; 114 115 ++* stats().map_lookups; 116 auto decls = idTable->find( id ); 117 if ( decls == idTable->end() ) return; 118 119 for ( auto decl : *(decls->second) ) { 120 out.push_back( decl.second ); 121 } 122 } 123 124 const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const { 125 ++* stats().lookup_calls; 126 if ( ! typeTable ) return nullptr; 127 ++* stats().map_lookups; 128 auto it = typeTable->find( id ); 129 return it == typeTable->end() ? nullptr : it->second.decl; 130 } 131 132 const StructDecl * Indexer::lookupStruct( const std::string & id ) const { 133 ++* stats().lookup_calls; 134 if ( ! structTable ) return nullptr; 135 ++* stats().map_lookups; 136 auto it = structTable->find( id ); 137 return it == structTable->end() ? nullptr : it->second.decl; 138 } 139 140 const EnumDecl * Indexer::lookupEnum( const std::string & id ) const { 141 ++* stats().lookup_calls; 142 if ( ! enumTable ) return nullptr; 143 ++* stats().map_lookups; 144 auto it = enumTable->find( id ); 145 return it == enumTable->end() ? nullptr : it->second.decl; 146 } 147 148 const UnionDecl * Indexer::lookupUnion( const std::string & id ) const { 149 ++* stats().lookup_calls; 150 if ( ! unionTable ) return nullptr; 151 ++* stats().map_lookups; 152 auto it = unionTable->find( id ); 153 return it == unionTable->end() ? nullptr : it->second.decl; 154 } 155 156 const TraitDecl * Indexer::lookupTrait( const std::string & id ) const { 157 ++* stats().lookup_calls; 158 if ( ! traitTable ) return nullptr; 159 ++* stats().map_lookups; 160 auto it = traitTable->find( id ); 161 return it == traitTable->end() ? nullptr : it->second.decl; 162 } 163 164 const Indexer * Indexer::atScope( unsigned long target ) const { 165 // by lazy construction, final indexer in list has repScope 0, cannot be > target 166 // otherwise, will find first scope representing the target 167 const Indexer * indexer = this; 168 while ( indexer->repScope > target ) { 169 indexer = indexer->prevScope.get(); 170 } 171 return indexer; 172 } 173 174 const NamedTypeDecl * Indexer::globalLookupType( const std::string & id ) const { 175 return atScope( 0 )->lookupType( id ); 176 } 177 178 const StructDecl * Indexer::globalLookupStruct( const std::string & id ) const { 179 return atScope( 0 )->lookupStruct( id ); 180 } 181 182 const UnionDecl * Indexer::globalLookupUnion( const std::string & id ) const { 183 return atScope( 0 )->lookupUnion( id ); 184 } 185 186 const EnumDecl * Indexer::globalLookupEnum( const std::string & id ) const { 187 return atScope( 0 )->lookupEnum( id ); 188 } 189 190 bool isFunction( const DeclarationWithType * decl ) { 377 191 return GenPoly::getFunctionType( decl->get_type() ); 378 192 } 379 193 380 bool isObject( DeclarationWithType * decl ) {194 bool isObject( const DeclarationWithType * decl ) { 381 195 return ! isFunction( decl ); 382 196 } 383 197 384 bool isDefinition( DeclarationWithType * decl ) {385 if ( FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl ) ) {198 bool isDefinition( const DeclarationWithType * decl ) { 199 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) { 386 200 // a function is a definition if it has a body 387 201 return func->statements; … … 393 207 } 394 208 395 bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) { 396 // if we're giving the same name mangling to things of different types then there is something wrong 209 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, const DeclarationWithType * added, 212 Indexer::OnConflict handleConflicts, const Declaration * deleteStmt ) { 213 // if we're giving the same name mangling to things of different types then there is 214 // something wrong 397 215 assert( (isObject( added ) && isObject( existing.id ) ) 398 216 || ( isFunction( added ) && isFunction( existing.id ) ) ); 399 217 400 if ( LinkageSpec::isOverridable( existing.id-> get_linkage()) ) {218 if ( LinkageSpec::isOverridable( existing.id->linkage ) ) { 401 219 // new definition shadows the autogenerated one, even at the same scope 402 220 return false; 403 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing.id->get_type(), Indexer() ) ) { 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 223 added->get_type(), existing.id->get_type(), Indexer() ) ) { 404 224 405 225 // it is a conflict if one declaration is deleted and the other is not 406 226 if ( deleteStmt && ! existing.deleteStmt ) { 407 return handleConflicts( existing, "deletion of defined identifier " ); 227 if ( handleConflicts.mode == OnConflict::Error ) { 228 SemanticError( added, "deletion of defined identifier " ); 229 } 230 return true; 408 231 } else if ( ! deleteStmt && existing.deleteStmt ) { 409 return handleConflicts( existing, "definition of deleted identifier " ); 232 if ( handleConflicts.mode == OnConflict::Error ) { 233 SemanticError( added, "definition of deleted identifier " ); 234 } 235 return true; 410 236 } 411 237 412 238 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 413 if ( isFunction( added ) ) { 414 return handleConflicts( existing, "duplicate function definition for " ); 239 if ( handleConflicts.mode == OnConflict::Error ) { 240 SemanticError( added, 241 isFunction( added ) ? 242 "duplicate function definition for " : 243 "duplicate object definition for " ); 244 } 245 return true; 246 } // if 247 } else { 248 if ( handleConflicts.mode == OnConflict::Error ) { 249 SemanticError( added, "duplicate definition for " ); 250 } 251 return true; 252 } // if 253 254 return true; 255 } 256 257 bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const { 258 if ( ! idTable ) return false; 259 260 ++* stats().map_lookups; 261 auto decls = idTable->find( id ); 262 if ( decls == idTable->end() ) return false; 263 264 for ( auto decl : *(decls->second) ) { 265 // skip other scopes (hidden by this decl) 266 if ( decl.second.scope != scope ) continue; 267 // check for C decl with compatible type (by mangleName) 268 if ( ! LinkageSpec::isMangled( decl.second.id->linkage ) && decl.first == mangleName ) { 269 return true; 270 } 271 } 272 273 return false; 274 } 275 276 bool Indexer::hasIncompatibleCDecl(const std::string & id, const std::string &mangleName ) const { 277 if ( ! idTable ) return false; 278 279 ++* stats().map_lookups; 280 auto decls = idTable->find( id ); 281 if ( decls == idTable->end() ) return false; 282 283 for ( auto decl : *(decls->second) ) { 284 // skip other scopes (hidden by this decl) 285 if ( decl.second.scope != scope ) continue; 286 // check for C decl with incompatible type (by manglename) 287 if ( ! LinkageSpec::isMangled( decl.second.id->linkage ) && decl.first != mangleName ) { 288 return true; 289 } 290 } 291 292 return false; 293 } 294 295 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 296 std::string getOtypeKey( const FunctionDecl * function ) { 297 auto& params = function->type->parameters; 298 assert( ! params.empty() ); 299 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 300 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 301 assert( base ); 302 return Mangler::mangle( base ); 303 } 304 305 /// gets the declaration for the function acting on a type specified by otype key, 306 /// nullptr if none such 307 const FunctionDecl * getFunctionForOtype( const DeclarationWithType * decl, const std::string& otypeKey ) { 308 const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ); 309 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr; 310 return func; 311 } 312 313 bool Indexer::removeSpecialOverrides(Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 314 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 315 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 316 // if the user defines a default ctor, then the generated default ctor is unavailable, 317 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 318 // field ctors are available. If the user defines any ctor then the generated default ctor 319 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 320 // anything that looks like a copy constructor, then the generated copy constructor is 321 // unavailable, and likewise for the assignment operator. 322 323 // only relevant on function declarations 324 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( data.id ); 325 if ( ! function ) return true; 326 // only need to perform this check for constructors, destructors, and assignment functions 327 if ( ! CodeGen::isCtorDtorAssign( data.id->name ) ) return true; 328 329 // set up information for this type 330 bool dataIsUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage ); 331 bool dataIsCopyFunc = InitTweak::isCopyFunction( function, function->name ); 332 std::string dataOtypeKey = getOtypeKey( function ); 333 334 if ( dataIsUserDefinedFunc && dataIsCopyFunc ) { 335 // this is a user-defined copy function 336 // if this is the first such, delete/remove non-user-defined overloads as needed 337 std::vector< std::string > removed; 338 std::vector< MangleTable::value_type > deleted; 339 bool alreadyUserDefinedFunc = false; 340 341 for ( const auto& entry : * mangleTable ) { 342 // skip decls that aren't functions or are for the wrong type 343 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 344 if ( ! decl ) continue; 345 346 bool isCopyFunc = InitTweak::isCopyFunction( decl, decl->name ); 347 if ( ! LinkageSpec::isOverridable( decl->linkage ) ) { 348 // matching user-defined function 349 if ( isCopyFunc ) { 350 // mutation already performed, return early 351 return true; 352 } else { 353 // note that non-copy deletions already performed 354 alreadyUserDefinedFunc = true; 355 } 415 356 } else { 416 return handleConflicts( existing, "duplicate object definition for " ); 417 } // if 418 } // if 419 } else { 420 return handleConflicts( existing, "duplicate definition for " ); 421 } // if 422 357 // non-user-defined function; mark for deletion/removal as appropriate 358 if ( isCopyFunc ) { 359 removed.push_back( entry.first ); 360 } else if ( ! alreadyUserDefinedFunc ) { 361 deleted.push_back( entry ); 362 } 363 } 364 } 365 366 // perform removals from mangle table, and deletions if necessary 367 for ( const auto& key : removed ) { 368 ++* stats().map_mutations; 369 mangleTable = mangleTable->erase( key ); 370 } 371 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 372 ++* stats().map_mutations; 373 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 374 } 375 } else if ( dataIsUserDefinedFunc ) { 376 // this is a user-defined non-copy function 377 // if this is the first user-defined function, delete non-user-defined overloads 378 std::vector< MangleTable::value_type > deleted; 379 380 for ( const auto& entry : * mangleTable ) { 381 // skip decls that aren't functions or are for the wrong type 382 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 383 if ( ! decl ) continue; 384 385 // exit early if already a matching user-defined function; 386 // earlier function will have mutated table 387 if ( ! LinkageSpec::isOverridable( decl->linkage ) ) return true; 388 389 // skip mutating intrinsic functions 390 if ( decl->linkage == LinkageSpec::Intrinsic ) continue; 391 392 // user-defined non-copy functions do not override copy functions 393 if ( InitTweak::isCopyFunction( decl, decl->name ) ) continue; 394 395 // this function to be deleted after mangleTable iteration is complete 396 deleted.push_back( entry ); 397 } 398 399 // mark deletions to update mangle table 400 // this needs to be a separate loop because of iterator invalidation 401 for ( const auto& entry : deleted ) { 402 ++* stats().map_mutations; 403 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 404 } 405 } else if ( function->linkage != LinkageSpec::Intrinsic ) { 406 // this is an overridable generated function 407 // if there already exists a matching user-defined function, delete this appropriately 408 for ( const auto& entry : * mangleTable ) { 409 // skip decls that aren't functions or are for the wrong type 410 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 411 if ( ! decl ) continue; 412 413 // skip non-user-defined functions 414 if ( LinkageSpec::isOverridable( decl->linkage ) ) continue; 415 416 if ( dataIsCopyFunc ) { 417 // remove current function if exists a user-defined copy function 418 // since the signatures for copy functions don't need to match exactly, using 419 // a delete statement is the wrong approach 420 if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false; 421 } else { 422 // mark current function deleted by first user-defined function found 423 data.deleteStmt = decl; 424 return true; 425 } 426 } 427 } 428 429 // nothing (more) to fix, return true 423 430 return true; 424 431 } 425 432 426 void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) { 427 if ( decl->name == "" ) return; 428 debugPrint( "Adding Id " << decl->name << std::endl ); 429 makeWritable(); 430 433 void Indexer::addId(const DeclarationWithType * decl, OnConflict handleConflicts, const Expression * baseExpr, 434 const Declaration * deleteStmt ) { 435 ++* stats().add_calls; 431 436 const std::string &name = decl->name; 437 if ( name == "" ) return; 438 432 439 std::string mangleName; 433 440 if ( LinkageSpec::isOverridable( decl->linkage ) ) { 434 // mangle the name without including the appropriate suffix, so overridable routines are placed into the435 // same "bucket" as their user defined versions.441 // mangle the name without including the appropriate suffix, so overridable routines 442 // are placed into the same "bucket" as their user defined versions. 436 443 mangleName = Mangler::mangle( decl, false ); 437 444 } else { … … 439 446 } // if 440 447 441 // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage 442 if ( ! LinkageSpec::isMangled( decl->linkage ) ) { 443 // NOTE this is broken in Richard's original code in such a way that it never triggers (it 444 // doesn't check decls that have the same manglename, and all C-linkage decls are defined to 445 // have their name as their manglename, hence the error can never trigger). 446 // The code here is closer to correct, but name mangling would have to be completely 447 // isomorphic to C type-compatibility, which it may not be. 448 if ( hasIncompatibleCDecl( name, mangleName, scope ) ) { 448 // this ensures that no two declarations with the same unmangled name at the same scope 449 // both have C linkage 450 if ( LinkageSpec::isMangled( decl->linkage ) ) { 451 // Check that a Cforall declaration doesn't override any C declaration 452 if ( hasCompatibleCDecl( name, mangleName ) ) { 453 SemanticError( decl, "Cforall declaration hides C function " ); 454 } 455 } else { 456 // NOTE: only correct if name mangling is completely isomorphic to C 457 // type-compatibility, which it may not be. 458 if ( hasIncompatibleCDecl( name, mangleName ) ) { 449 459 SemanticError( decl, "conflicting overload of C function " ); 450 460 } 451 } else { 452 // Check that a Cforall declaration doesn't override any C declaration 453 if ( hasCompatibleCDecl( name, mangleName, scope ) ) { 454 SemanticError( decl, "Cforall declaration hides C function " ); 455 } 456 } 457 458 // Skip repeat declarations of the same identifier 459 IdData * existing = lookupIdAtScope( name, mangleName, scope ); 460 if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return; 461 462 // add to indexer 463 tables->idTable[ name ][ mangleName ] = IdData{ decl, baseExpr, deleteStmt }; 464 ++tables->size; 465 } 466 467 void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) { 461 } 462 463 // ensure tables exist and add identifier 464 MangleTable::Ptr mangleTable; 465 if ( ! idTable ) { 466 idTable = IdTable::new_ptr(); 467 mangleTable = MangleTable::new_ptr(); 468 } else { 469 ++* stats().map_lookups; 470 auto decls = idTable->find( name ); 471 if ( decls == idTable->end() ) { 472 mangleTable = MangleTable::new_ptr(); 473 } else { 474 mangleTable = decls->second; 475 // skip in-scope repeat declarations of same identifier 476 ++* stats().map_lookups; 477 auto existing = mangleTable->find( mangleName ); 478 if ( existing != mangleTable->end() 479 && existing->second.scope == scope 480 && existing->second.id ) { 481 if ( addedIdConflicts( existing->second, decl, handleConflicts, deleteStmt ) ) { 482 if ( handleConflicts.mode == OnConflict::Delete ) { 483 // set delete expression for conflicting identifier 484 lazyInitScope(); 485 * stats().map_mutations += 2; 486 idTable = idTable->set( 487 name, 488 mangleTable->set( 489 mangleName, 490 IdData{ existing->second, handleConflicts.deleteStmt } ) ); 491 } 492 return; 493 } 494 } 495 } 496 } 497 498 // add/overwrite with new identifier 499 lazyInitScope(); 500 IdData data{ decl, baseExpr, deleteStmt, scope }; 501 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 502 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 503 * stats().map_mutations += 2; 504 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) ); 505 } 506 507 void Indexer::addId( const DeclarationWithType * decl, const Expression * baseExpr ) { 468 508 // default handling of conflicts is to raise an error 469 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );470 } 471 472 void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode* deleteStmt ) {509 addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr ); 510 } 511 512 void Indexer::addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ) { 473 513 // default handling of conflicts is to raise an error 474 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, nullptr, deleteStmt );475 } 476 477 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {478 if ( existing-> get_base() == 0) {514 addId( decl, OnConflict::error(), nullptr, deleteStmt ); 515 } 516 517 bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) { 518 if ( existing->base == nullptr ) { 479 519 return false; 480 } else if ( added-> get_base() == 0) {520 } else if ( added->base == nullptr ) { 481 521 return true; 482 522 } else { 483 SemanticError( added, "redeclaration of " ); 484 } 485 } 486 487 void Indexer::addType( NamedTypeDecl *decl ) { 488 debugPrint( "Adding type " << decl->name << std::endl ); 489 makeWritable(); 490 491 const std::string &id = decl->get_name(); 492 TypeTable::iterator existing = tables->typeTable.find( id ); 493 if ( existing == tables->typeTable.end() ) { 494 NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope ); 495 if ( ! parent || ! addedTypeConflicts( parent, decl ) ) { 496 tables->typeTable.insert( existing, std::make_pair( id, decl ) ); 497 ++tables->size; 498 } 499 } else { 500 if ( ! addedTypeConflicts( existing->second, decl ) ) { 501 existing->second = decl; 502 } 503 } 504 } 505 506 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) { 523 assert( existing->base && added->base ); 524 // typedef redeclarations are errors only if types are different 525 if ( ! ResolvExpr::typesCompatible( existing->base, added->base, Indexer() ) ) { 526 SemanticError( added->location, "redeclaration of " + added->name ); 527 } 528 } 529 // does not need to be added to the table if both existing and added have a base that are 530 // the same 531 return true; 532 } 533 534 void Indexer::addType( const NamedTypeDecl * decl ) { 535 ++* stats().add_calls; 536 const std::string & id = decl->name; 537 538 if ( ! typeTable ) { 539 typeTable = TypeTable::new_ptr(); 540 } else { 541 ++* stats().map_lookups; 542 auto existing = typeTable->find( id ); 543 if ( existing != typeTable->end() 544 && existing->second.scope == scope 545 && addedTypeConflicts( existing->second.decl, decl ) ) return; 546 } 547 548 lazyInitScope(); 549 ++* stats().map_mutations; 550 typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } ); 551 } 552 553 bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) { 507 554 if ( ! existing->body ) { 508 555 return false; … … 513 560 } 514 561 515 void Indexer::addStruct( const std::string &id ) { 516 debugPrint( "Adding fwd decl for struct " << id << std::endl ); 562 void Indexer::addStruct( const std::string & id ) { 517 563 addStruct( new StructDecl( id ) ); 518 564 } 519 565 520 void Indexer::addStruct( StructDecl *decl ) { 521 debugPrint( "Adding struct " << decl->name << std::endl ); 522 makeWritable(); 523 524 const std::string &id = decl->get_name(); 525 StructTable::iterator existing = tables->structTable.find( id ); 526 if ( existing == tables->structTable.end() ) { 527 StructDecl *parent = tables->base.lookupStructAtScope( id, scope ); 528 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 529 tables->structTable.insert( existing, std::make_pair( id, decl ) ); 530 ++tables->size; 531 } 532 } else { 533 if ( ! addedDeclConflicts( existing->second, decl ) ) { 534 existing->second = decl; 535 } 536 } 537 } 538 539 void Indexer::addEnum( EnumDecl *decl ) { 540 debugPrint( "Adding enum " << decl->name << std::endl ); 541 makeWritable(); 542 543 const std::string &id = decl->get_name(); 544 EnumTable::iterator existing = tables->enumTable.find( id ); 545 if ( existing == tables->enumTable.end() ) { 546 EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope ); 547 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 548 tables->enumTable.insert( existing, std::make_pair( id, decl ) ); 549 ++tables->size; 550 } 551 } else { 552 if ( ! addedDeclConflicts( existing->second, decl ) ) { 553 existing->second = decl; 554 } 555 } 556 } 557 558 void Indexer::addUnion( const std::string &id ) { 559 debugPrint( "Adding fwd decl for union " << id << std::endl ); 566 void Indexer::addStruct( const StructDecl * decl ) { 567 ++* stats().add_calls; 568 const std::string & id = decl->name; 569 570 if ( ! structTable ) { 571 structTable = StructTable::new_ptr(); 572 } else { 573 ++* stats().map_lookups; 574 auto existing = structTable->find( id ); 575 if ( existing != structTable->end() 576 && existing->second.scope == scope 577 && addedDeclConflicts( existing->second.decl, decl ) ) return; 578 } 579 580 lazyInitScope(); 581 ++* stats().map_mutations; 582 structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } ); 583 } 584 585 void Indexer::addEnum( const EnumDecl * decl ) { 586 ++* stats().add_calls; 587 const std::string & id = decl->name; 588 589 if ( ! enumTable ) { 590 enumTable = EnumTable::new_ptr(); 591 } else { 592 ++* stats().map_lookups; 593 auto existing = enumTable->find( id ); 594 if ( existing != enumTable->end() 595 && existing->second.scope == scope 596 && addedDeclConflicts( existing->second.decl, decl ) ) return; 597 } 598 599 lazyInitScope(); 600 ++* stats().map_mutations; 601 enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } ); 602 } 603 604 void Indexer::addUnion( const std::string & id ) { 560 605 addUnion( new UnionDecl( id ) ); 561 606 } 562 607 563 void Indexer::addUnion( UnionDecl *decl ) {564 debugPrint( "Adding union " << decl->name << std::endl );565 makeWritable();566 567 const std::string &id = decl->get_name();568 UnionTable::iterator existing = tables->unionTable.find( id);569 if ( existing == tables->unionTable.end() ){570 UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );571 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {572 tables->unionTable.insert( existing, std::make_pair( id, decl ) );573 ++tables->size;574 }575 } else {576 if ( ! addedDeclConflicts( existing->second, decl ) ) { 577 existing->second = decl;578 }579 }580 } 581 582 void Indexer::addTrait( TraitDecl *decl ) {583 debugPrint( "Adding trait " << decl->name << std::endl );584 makeWritable();585 586 const std::string &id = decl->get_name();587 TraitTable::iterator existing = tables->traitTable.find( id);588 if ( existing == tables->traitTable.end() ){589 TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );590 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {591 tables->traitTable.insert( existing, std::make_pair( id, decl ) );592 ++tables->size;593 }594 } else {595 if ( ! addedDeclConflicts( existing->second, decl ) ) { 596 existing->second = decl;597 }598 }599 } 600 601 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunctionhandleConflicts ) {608 void Indexer::addUnion( const UnionDecl * decl ) { 609 ++* stats().add_calls; 610 const std::string & id = decl->name; 611 612 if ( ! unionTable ) { 613 unionTable = UnionTable::new_ptr(); 614 } else { 615 ++* stats().map_lookups; 616 auto existing = unionTable->find( id ); 617 if ( existing != unionTable->end() 618 && existing->second.scope == scope 619 && addedDeclConflicts( existing->second.decl, decl ) ) return; 620 } 621 622 lazyInitScope(); 623 ++* stats().map_mutations; 624 unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } ); 625 } 626 627 void Indexer::addTrait( const TraitDecl * decl ) { 628 ++* stats().add_calls; 629 const std::string & id = decl->name; 630 631 if ( ! traitTable ) { 632 traitTable = TraitTable::new_ptr(); 633 } else { 634 ++* stats().map_lookups; 635 auto existing = traitTable->find( id ); 636 if ( existing != traitTable->end() 637 && existing->second.scope == scope 638 && addedDeclConflicts( existing->second.decl, decl ) ) return; 639 } 640 641 lazyInitScope(); 642 ++* stats().map_mutations; 643 traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } ); 644 } 645 646 void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) { 602 647 for ( Declaration * decl : aggr->members ) { 603 648 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 604 649 addId( dwt, handleConflicts, expr ); 605 650 if ( dwt->name == "" ) { 606 Type * t = dwt->get_type()->stripReferences();607 if ( dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType *>( t ) ) {651 const Type * t = dwt->get_type()->stripReferences(); 652 if ( dynamic_cast<const StructInstType *>( t ) || dynamic_cast<const UnionInstType *>( t ) ) { 608 653 Expression * base = expr->clone(); 609 654 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost? … … 616 661 } 617 662 618 void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode* withStmt ) {619 for ( Expression * expr : withExprs ) {663 void Indexer::addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ) { 664 for ( const Expression * expr : withExprs ) { 620 665 if ( expr->result ) { 621 666 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); 622 667 assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() ); 623 668 624 addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) { 625 // on conflict, delete the identifier 626 existing.deleteStmt = withStmt; 627 return true; 628 }); 669 addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) ); 629 670 } 630 671 } … … 644 685 } 645 686 646 void Indexer::addFunctionType( FunctionType * ftype ) {687 void Indexer::addFunctionType( const FunctionType * ftype ) { 647 688 addTypes( ftype->forall ); 648 689 addIds( ftype->returnVals ); 649 690 addIds( ftype->parameters ); 650 }651 652 void Indexer::enterScope() {653 ++scope;654 655 if ( doDebug ) {656 std::cerr << "--- Entering scope " << scope << std::endl;657 }658 }659 660 void Indexer::leaveScope() {661 using std::cerr;662 663 assert( scope > 0 && "cannot leave initial scope" );664 if ( doDebug ) {665 cerr << "--- Leaving scope " << scope << " containing" << std::endl;666 }667 --scope;668 669 while ( tables && tables->scope > scope ) {670 if ( doDebug ) {671 dump( tables->idTable, cerr );672 dump( tables->typeTable, cerr );673 dump( tables->structTable, cerr );674 dump( tables->enumTable, cerr );675 dump( tables->unionTable, cerr );676 dump( tables->traitTable, cerr );677 }678 679 // swap tables for base table until we find one at an appropriate scope680 Indexer::Impl *base = newRef( tables->base.tables );681 deleteRef( tables );682 tables = base;683 }684 }685 686 void Indexer::print( std::ostream &os, int indent ) const {687 using std::cerr;688 689 if ( tables ) {690 os << "--- scope " << tables->scope << " ---" << std::endl;691 692 os << "===idTable===" << std::endl;693 dump( tables->idTable, os );694 os << "===typeTable===" << std::endl;695 dump( tables->typeTable, os );696 os << "===structTable===" << std::endl;697 dump( tables->structTable, os );698 os << "===enumTable===" << std::endl;699 dump( tables->enumTable, os );700 os << "===unionTable===" << std::endl;701 dump( tables->unionTable, os );702 os << "===contextTable===" << std::endl;703 dump( tables->traitTable, os );704 705 tables->base.print( os, indent );706 } else {707 os << "--- end ---" << std::endl;708 }709 710 691 } 711 692 … … 715 696 Expression * base = baseExpr->clone(); 716 697 ResolvExpr::referenceToRvalueConversion( base, cost ); 717 ret = new MemberExpr( id, base );698 ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base ); 718 699 // xxx - this introduces hidden environments, for now remove them. 719 700 // std::swap( base->env, ret->env ); … … 721 702 base->env = nullptr; 722 703 } else { 723 ret = new VariableExpr( id);724 } 725 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt);704 ret = new VariableExpr( const_cast<DeclarationWithType *>(id) ); 705 } 706 if ( deleteStmt ) ret = new DeletedExpr( ret, const_cast<Declaration *>(deleteStmt) ); 726 707 return ret; 727 708 } -
src/SymTab/Indexer.h
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:38:55 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Aug 17 16:09:12 201713 // Update Count : 811 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Mar 8 13:55:00 2019 13 // Update Count : 9 14 14 // 15 15 16 16 #pragma once 17 17 18 #include < iosfwd> // for ostream19 #include <list> // for list20 #include < string> // for string21 #include < functional> // for function18 #include <functional> // for function 19 #include <list> // for list 20 #include <memory> // for shared_ptr, enable_shared_from_this 21 #include <string> // for string 22 22 23 #include " SynTree/Visitor.h" // for Visitor24 #include "SynTree/SynTree.h" // for AST nodes23 #include "Common/PersistentMap.h" // for PersistentMap 24 #include "SynTree/SynTree.h" // for AST nodes 25 25 26 26 namespace ResolvExpr { 27 class Cost;27 class Cost; 28 28 } 29 29 30 30 namespace SymTab { 31 class Indexer {32 public:31 class Indexer : public std::enable_shared_from_this<SymTab::Indexer> { 32 public: 33 33 explicit Indexer(); 34 virtual ~Indexer(); 34 35 35 Indexer( const Indexer &that ); 36 Indexer( Indexer &&that ); 37 virtual ~Indexer(); 38 Indexer& operator= ( const Indexer &that ); 39 Indexer& operator= ( Indexer &&that ); 40 41 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer 42 // explicitly when scopes begin and end 36 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 37 // tell the indexer explicitly when scopes begin and end 43 38 void enterScope(); 44 39 void leaveScope(); 45 40 46 41 struct IdData { 47 DeclarationWithType * id = nullptr;48 Expression * baseExpr = nullptr; // WithExpr42 const DeclarationWithType * id = nullptr; 43 const Expression * baseExpr = nullptr; // WithExpr 49 44 50 45 /// non-null if this declaration is deleted 51 BaseSyntaxNode * deleteStmt = nullptr; 46 const Declaration * deleteStmt = nullptr; 47 /// scope of identifier 48 unsigned long scope = 0; 52 49 53 50 // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members. 54 51 IdData() = default; 55 IdData( DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ) {} 52 IdData( 53 const DeclarationWithType * id, const Expression * baseExpr, const Declaration * deleteStmt, 54 unsigned long scope ) 55 : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {} 56 IdData( const IdData& o, const Declaration * deleteStmt ) 57 : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {} 56 58 57 59 Expression * combine( ResolvExpr::Cost & cost ) const; … … 59 61 60 62 /// Gets all declarations with the given ID 61 void lookupId( const std::string & id, std::list< IdData > &out ) const;63 void lookupId( const std::string & id, std::list< IdData > &out ) const; 62 64 /// Gets the top-most type declaration with the given ID 63 NamedTypeDecl *lookupType( const std::string &id ) const;65 const NamedTypeDecl * lookupType( const std::string & id ) const; 64 66 /// Gets the top-most struct declaration with the given ID 65 StructDecl *lookupStruct( const std::string &id ) const;67 const StructDecl * lookupStruct( const std::string & id ) const; 66 68 /// Gets the top-most enum declaration with the given ID 67 EnumDecl *lookupEnum( const std::string &id ) const;69 const EnumDecl * lookupEnum( const std::string & id ) const; 68 70 /// Gets the top-most union declaration with the given ID 69 UnionDecl *lookupUnion( const std::string &id ) const;71 const UnionDecl * lookupUnion( const std::string & id ) const; 70 72 /// Gets the top-most trait declaration with the given ID 71 TraitDecl *lookupTrait( const std::string &id ) const;73 const TraitDecl * lookupTrait( const std::string & id ) const; 72 74 73 void print( std::ostream &os, int indent = 0 ) const; 75 /// Gets the type declaration with the given ID at global scope 76 const NamedTypeDecl * globalLookupType( const std::string & id ) const; 77 /// Gets the struct declaration with the given ID at global scope 78 const StructDecl * globalLookupStruct( const std::string & id ) const; 79 /// Gets the union declaration with the given ID at global scope 80 const UnionDecl * globalLookupUnion( const std::string & id ) const; 81 /// Gets the enum declaration with the given ID at global scope 82 const EnumDecl * globalLookupEnum( const std::string & id ) const; 74 83 75 /// looks up a specific mangled ID at the given scope 76 IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ); 77 const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const; 78 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 79 bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const; 80 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name 81 bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const; 82 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope) 83 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const; 84 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const; 85 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const; 86 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const; 87 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 84 void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr ); 85 void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ); 88 86 89 typedef std::function<bool(IdData &, const std::string &)> ConflictFunction; 90 91 void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr ); 92 void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ); 93 94 void addType( NamedTypeDecl *decl ); 95 void addStruct( const std::string &id ); 96 void addStruct( StructDecl *decl ); 97 void addEnum( EnumDecl *decl ); 98 void addUnion( const std::string &id ); 99 void addUnion( UnionDecl *decl ); 100 void addTrait( TraitDecl *decl ); 87 void addType( const NamedTypeDecl * decl ); 88 void addStruct( const std::string & id ); 89 void addStruct( const StructDecl * decl ); 90 void addEnum( const EnumDecl * decl ); 91 void addUnion( const std::string & id ); 92 void addUnion( const UnionDecl * decl ); 93 void addTrait( const TraitDecl * decl ); 101 94 102 95 /// adds all of the IDs from WithStmt exprs 103 void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ); 104 105 /// adds all of the members of the Aggregate (addWith helper) 106 void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction ); 96 void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ); 107 97 108 98 /// convenience function for adding a list of Ids to the indexer … … 113 103 114 104 /// convenience function for adding all of the declarations in a function type to the indexer 115 void addFunctionType( FunctionType * ftype );105 void addFunctionType( const FunctionType * ftype ); 116 106 117 bool doDebug = false; ///< Display debugging trace?118 107 private: 119 struct Impl; 108 /// Wraps a Decl * with a scope 109 template<typename Decl> 110 struct Scoped { 111 const Decl * decl; ///< declaration 112 unsigned long scope; ///< scope of this declaration 120 113 121 Impl *tables; ///< Copy-on-write instance of table data structure122 unsigned long scope; ///< Scope index of this pointer114 Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {} 115 }; 123 116 124 /// Takes a new ref to a table (returns null if null) 125 static Impl *newRef( Impl *toClone ); 126 /// Clears a ref to a table (does nothing if null) 127 static void deleteRef( Impl *toFree ); 117 using Ptr = std::shared_ptr<const Indexer>; 128 118 129 // Removes matching autogenerated constructors and destructors 130 // so that they will not be selected 131 // void removeSpecialOverrides( FunctionDecl *decl ); 132 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const; 119 using MangleTable = PersistentMap< std::string, IdData >; 120 using IdTable = PersistentMap< std::string, MangleTable::Ptr >; 121 using TypeTable = PersistentMap< std::string, Scoped<NamedTypeDecl> >; 122 using StructTable = PersistentMap< std::string, Scoped<StructDecl> >; 123 using EnumTable = PersistentMap< std::string, Scoped<EnumDecl> >; 124 using UnionTable = PersistentMap< std::string, Scoped<UnionDecl> >; 125 using TraitTable = PersistentMap< std::string, Scoped<TraitDecl> >; 133 126 134 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) 135 void makeWritable(); 127 IdTable::Ptr idTable; ///< identifier namespace 128 TypeTable::Ptr typeTable; ///< type namespace 129 StructTable::Ptr structTable; ///< struct namespace 130 EnumTable::Ptr enumTable; ///< enum namespace 131 UnionTable::Ptr unionTable; ///< union namespace 132 TraitTable::Ptr traitTable; ///< trait namespace 133 134 Ptr prevScope; ///< reference to indexer for parent scope 135 unsigned long scope; ///< Scope index of this indexer 136 unsigned long repScope; ///< Scope index of currently represented scope 137 138 /// Ensures that a proper backtracking scope exists before a mutation 139 void lazyInitScope(); 140 141 /// Gets the indexer at the given scope 142 const Indexer * atScope( unsigned long scope ) const; 143 144 /// Removes matching autogenerated constructors and destructors so that they will not be 145 /// selected. If returns false, passed decl should not be added. 146 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable ); 147 148 /// Options for handling identifier conflicts 149 struct OnConflict { 150 enum { 151 Error, ///< Throw a semantic error 152 Delete ///< Delete the earlier version with the delete statement 153 } mode; 154 const Declaration * deleteStmt; ///< Statement that deletes this expression 155 156 private: 157 OnConflict() : mode(Error), deleteStmt(nullptr) {} 158 OnConflict( const Declaration * d ) : mode(Delete), deleteStmt(d) {} 159 public: 160 OnConflict( const OnConflict& ) = default; 161 162 static OnConflict error() { return {}; } 163 static OnConflict deleteWith( const Declaration * d ) { return { d }; } 164 }; 165 166 /// true if the existing identifier conflicts with the added identifier 167 bool addedIdConflicts( 168 const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts, 169 const Declaration * deleteStmt ); 136 170 137 171 /// common code for addId, addDeletedId, etc. 138 void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr ); 172 void addId(const DeclarationWithType * decl, OnConflict handleConflicts, 173 const Expression * baseExpr = nullptr, const Declaration * deleteStmt = nullptr ); 174 175 /// adds all of the members of the Aggregate (addWith helper) 176 void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ); 177 178 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name 179 bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 180 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 181 bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 139 182 }; 140 183 } // namespace SymTab -
src/SymTab/Mangler.cc
r7951100 rb067d9b 10 10 // Created On : Sun May 17 21:40:29 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 15:49:26 201713 // Update Count : 2 312 // Last Modified On : Tue Jul 30 13:46:10 2019 13 // Update Count : 26 14 14 // 15 15 #include "Mangler.h" 16 16 17 #include <algorithm> // for copy, transform18 #include <cassert> // for assert, assertf19 #include <functional> // for const_mem_fun_t, mem_fun20 #include <iterator> // for ostream_iterator, back_insert_ite...21 #include <list> // for _List_iterator, list, _List_const...22 #include <string> // for string, char_traits, operator<<23 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup17 #include <algorithm> // for copy, transform 18 #include <cassert> // for assert, assertf 19 #include <functional> // for const_mem_fun_t, mem_fun 20 #include <iterator> // for ostream_iterator, back_insert_ite... 21 #include <list> // for _List_iterator, list, _List_const... 22 #include <string> // for string, char_traits, operator<< 23 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 25 25 #include "Common/PassVisitor.h" 26 #include "Common/SemanticError.h" // for SemanticError 27 #include "Common/utility.h" // for toString 28 #include "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... 29 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType 30 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<< 31 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora... 26 #include "Common/SemanticError.h" // for SemanticError 27 #include "Common/utility.h" // for toString 28 #include "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... 29 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 30 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType 31 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<< 32 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora... 33 34 #include "AST/Pass.hpp" 32 35 33 36 namespace SymTab { … … 35 38 namespace { 36 39 /// Mangles names to a unique C identifier 37 struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards { 38 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 39 Mangler( const Mangler & ) = delete; 40 41 void previsit( BaseSyntaxNode * ) { visit_children = false; } 42 43 void postvisit( ObjectDecl * declaration ); 44 void postvisit( FunctionDecl * declaration ); 45 void postvisit( TypeDecl * declaration ); 46 47 void postvisit( VoidType * voidType ); 48 void postvisit( BasicType * basicType ); 49 void postvisit( PointerType * pointerType ); 50 void postvisit( ArrayType * arrayType ); 51 void postvisit( ReferenceType * refType ); 52 void postvisit( FunctionType * functionType ); 53 void postvisit( StructInstType * aggregateUseType ); 54 void postvisit( UnionInstType * aggregateUseType ); 55 void postvisit( EnumInstType * aggregateUseType ); 56 void postvisit( TypeInstType * aggregateUseType ); 57 void postvisit( TraitInstType * inst ); 58 void postvisit( TupleType * tupleType ); 59 void postvisit( VarArgsType * varArgsType ); 60 void postvisit( ZeroType * zeroType ); 61 void postvisit( OneType * oneType ); 40 struct Mangler_old : public WithShortCircuiting, public WithVisitorRef<Mangler_old>, public WithGuards { 41 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 42 Mangler_old( const Mangler_old & ) = delete; 43 44 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 45 46 void postvisit( const ObjectDecl * declaration ); 47 void postvisit( const FunctionDecl * declaration ); 48 void postvisit( const TypeDecl * declaration ); 49 50 void postvisit( const VoidType * voidType ); 51 void postvisit( const BasicType * basicType ); 52 void postvisit( const PointerType * pointerType ); 53 void postvisit( const ArrayType * arrayType ); 54 void postvisit( const ReferenceType * refType ); 55 void postvisit( const FunctionType * functionType ); 56 void postvisit( const StructInstType * aggregateUseType ); 57 void postvisit( const UnionInstType * aggregateUseType ); 58 void postvisit( const EnumInstType * aggregateUseType ); 59 void postvisit( const TypeInstType * aggregateUseType ); 60 void postvisit( const TraitInstType * inst ); 61 void postvisit( const TupleType * tupleType ); 62 void postvisit( const VarArgsType * varArgsType ); 63 void postvisit( const ZeroType * zeroType ); 64 void postvisit( const OneType * oneType ); 65 void postvisit( const QualifiedType * qualType ); 62 66 63 67 std::string get_mangleName() { return mangleName.str(); } … … 72 76 bool mangleGenericParams; ///< Include generic parameters in name mangling if true 73 77 bool inFunctionType = false; ///< Include type qualifiers if false. 74 75 void mangleDecl( DeclarationWithType *declaration ); 76 void mangleRef( ReferenceToType *refType, std::string prefix ); 77 78 void printQualifiers( Type *type ); 79 }; // Mangler 78 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type 79 80 public: 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 82 int nextVarNum, const VarMapType& varNums ); 83 84 private: 85 void mangleDecl( const DeclarationWithType * declaration ); 86 void mangleRef( const ReferenceToType * refType, std::string prefix ); 87 88 void printQualifiers( const Type *type ); 89 }; // Mangler_old 80 90 } // namespace 81 91 82 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {83 PassVisitor<Mangler > mangler( mangleOverridable, typeMode, mangleGenericParams );92 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 93 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams ); 84 94 maybeAccept( decl, mangler ); 85 95 return mangler.pass.get_mangleName(); 86 96 } 87 97 88 std::string mangleType( Type * ty ) {89 PassVisitor<Mangler > mangler( false, true, true );98 std::string mangleType( const Type * ty ) { 99 PassVisitor<Mangler_old> mangler( false, true, true ); 90 100 maybeAccept( ty, mangler ); 91 101 return mangler.pass.get_mangleName(); 92 102 } 93 103 94 std::string mangleConcrete( Type * ty ) {95 PassVisitor<Mangler > mangler( false, false, false );104 std::string mangleConcrete( const Type * ty ) { 105 PassVisitor<Mangler_old> mangler( false, false, false ); 96 106 maybeAccept( ty, mangler ); 97 107 return mangler.pass.get_mangleName(); … … 99 109 100 110 namespace { 101 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 102 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {} 103 104 void Mangler::mangleDecl( DeclarationWithType * declaration ) { 111 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 112 : nextVarNum( 0 ), isTopLevel( true ), 113 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 114 mangleGenericParams( mangleGenericParams ) {} 115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 117 int nextVarNum, const VarMapType& varNums ) 118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 119 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 120 mangleGenericParams( mangleGenericParams ) {} 121 122 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) { 105 123 bool wasTopLevel = isTopLevel; 106 124 if ( isTopLevel ) { … … 109 127 isTopLevel = false; 110 128 } // if 111 mangleName << "__";129 mangleName << Encoding::manglePrefix; 112 130 CodeGen::OperatorInfo opInfo; 113 131 if ( operatorLookup( declaration->get_name(), opInfo ) ) { 114 mangleName << opInfo.outputName ;132 mangleName << opInfo.outputName.size() << opInfo.outputName; 115 133 } else { 116 mangleName << declaration->get_name(); 117 } // if 118 mangleName << "__"; 134 mangleName << declaration->name.size() << declaration->name; 135 } // if 119 136 maybeAccept( declaration->get_type(), *visitor ); 120 137 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) { … … 122 139 // so they need a different name mangling 123 140 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) { 124 mangleName << "autogen__";141 mangleName << Encoding::autogen; 125 142 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) { 126 mangleName << "intrinsic__";143 mangleName << Encoding::intrinsic; 127 144 } else { 128 145 // if we add another kind of overridable function, this has to change … … 133 150 } 134 151 135 void Mangler ::postvisit(ObjectDecl * declaration ) {152 void Mangler_old::postvisit( const ObjectDecl * declaration ) { 136 153 mangleDecl( declaration ); 137 154 } 138 155 139 void Mangler ::postvisit(FunctionDecl * declaration ) {156 void Mangler_old::postvisit( const FunctionDecl * declaration ) { 140 157 mangleDecl( declaration ); 141 158 } 142 159 143 void Mangler ::postvisit(VoidType * voidType ) {160 void Mangler_old::postvisit( const VoidType * voidType ) { 144 161 printQualifiers( voidType ); 145 mangleName << "v"; 146 } 147 148 void Mangler::postvisit( BasicType * basicType ) { 149 static const char *btLetter[] = { 150 "b", // Bool 151 "c", // Char 152 "Sc", // SignedChar 153 "Uc", // UnsignedChar 154 "s", // ShortSignedInt 155 "Us", // ShortUnsignedInt 156 "i", // SignedInt 157 "Ui", // UnsignedInt 158 "l", // LongSignedInt 159 "Ul", // LongUnsignedInt 160 "q", // LongLongSignedInt 161 "Uq", // LongLongUnsignedInt 162 "f", // Float 163 "d", // Double 164 "r", // LongDouble 165 "Xf", // FloatComplex 166 "Xd", // DoubleComplex 167 "Xr", // LongDoubleComplex 168 "If", // FloatImaginary 169 "Id", // DoubleImaginary 170 "Ir", // LongDoubleImaginary 171 "w", // SignedInt128 172 "Uw", // UnsignedInt128 173 "x", // Float80 174 "y", // Float128 175 }; 176 static_assert( 177 sizeof(btLetter)/sizeof(btLetter[0]) == BasicType::NUMBER_OF_BASIC_TYPES, 178 "Each basic type kind should have a corresponding mangler letter" 179 ); 180 162 mangleName << Encoding::void_t; 163 } 164 165 void Mangler_old::postvisit( const BasicType * basicType ) { 181 166 printQualifiers( basicType ); 182 assert ( basicType->get_kind() < sizeof(btLetter)/sizeof(btLetter[0]));183 mangleName << btLetter[ basicType->get_kind()];184 } 185 186 void Mangler ::postvisit(PointerType * pointerType ) {167 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind ); 168 mangleName << Encoding::basicTypes[ basicType->kind ]; 169 } 170 171 void Mangler_old::postvisit( const PointerType * pointerType ) { 187 172 printQualifiers( pointerType ); 188 173 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers 189 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";174 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer; 190 175 maybeAccept( pointerType->base, *visitor ); 191 176 } 192 177 193 void Mangler ::postvisit(ArrayType * arrayType ) {178 void Mangler_old::postvisit( const ArrayType * arrayType ) { 194 179 // TODO: encode dimension 195 180 printQualifiers( arrayType ); 196 mangleName << "A0";181 mangleName << Encoding::array << "0"; 197 182 maybeAccept( arrayType->base, *visitor ); 198 183 } 199 184 200 void Mangler ::postvisit(ReferenceType * refType ) {185 void Mangler_old::postvisit( const ReferenceType * refType ) { 201 186 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload. 202 187 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.), … … 217 202 } 218 203 219 void Mangler ::postvisit(FunctionType * functionType ) {204 void Mangler_old::postvisit( const FunctionType * functionType ) { 220 205 printQualifiers( functionType ); 221 mangleName << "F";206 mangleName << Encoding::function; 222 207 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters, 223 208 // since qualifiers on outermost parameter type do not differentiate function types, e.g., … … 226 211 inFunctionType = true; 227 212 std::list< Type* > returnTypes = getTypes( functionType->returnVals ); 228 acceptAll( returnTypes, *visitor ); 213 if (returnTypes.empty()) mangleName << Encoding::void_t; 214 else acceptAll( returnTypes, *visitor ); 229 215 mangleName << "_"; 230 216 std::list< Type* > paramTypes = getTypes( functionType->parameters ); … … 233 219 } 234 220 235 void Mangler ::mangleRef(ReferenceToType * refType, std::string prefix ) {221 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) { 236 222 printQualifiers( refType ); 237 223 238 mangleName << ( refType->name.length() + prefix.length() ) << prefix<< refType->name;224 mangleName << prefix << refType->name.length() << refType->name; 239 225 240 226 if ( mangleGenericParams ) { 241 std::list< Expression* >& params = refType->parameters;227 const std::list< Expression* > & params = refType->parameters; 242 228 if ( ! params.empty() ) { 243 229 mangleName << "_"; 244 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param) {245 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );246 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString( *param));230 for ( const Expression * param : params ) { 231 const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param ); 232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 247 233 maybeAccept( paramType->type, *visitor ); 248 234 } … … 252 238 } 253 239 254 void Mangler ::postvisit(StructInstType * aggregateUseType ) {255 mangleRef( aggregateUseType, "s");256 } 257 258 void Mangler ::postvisit(UnionInstType * aggregateUseType ) {259 mangleRef( aggregateUseType, "u");260 } 261 262 void Mangler ::postvisit(EnumInstType * aggregateUseType ) {263 mangleRef( aggregateUseType, "e");264 } 265 266 void Mangler ::postvisit(TypeInstType * typeInst ) {240 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) { 241 mangleRef( aggregateUseType, Encoding::struct_t ); 242 } 243 244 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) { 245 mangleRef( aggregateUseType, Encoding::union_t ); 246 } 247 248 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) { 249 mangleRef( aggregateUseType, Encoding::enum_t ); 250 } 251 252 void Mangler_old::postvisit( const TypeInstType * typeInst ) { 267 253 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 268 254 if ( varNum == varNums.end() ) { 269 mangleRef( typeInst, "t");255 mangleRef( typeInst, Encoding::type ); 270 256 } else { 271 257 printQualifiers( typeInst ); 272 std::ostringstream numStream; 273 numStream << varNum->second.first; 274 switch ( (TypeDecl::Kind )varNum->second.second ) { 275 case TypeDecl::Dtype: 276 mangleName << "d"; 277 break; 278 case TypeDecl::Ftype: 279 mangleName << "f"; 280 break; 281 case TypeDecl::Ttype: 282 mangleName << "tVARGS"; 283 break; 284 default: 285 assert( false ); 286 } // switch 287 mangleName << numStream.str(); 288 } // if 289 } 290 291 void Mangler::postvisit( TraitInstType * inst ) { 258 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g. 259 // forall(dtype T) void f(T); 260 // forall(dtype S) void f(S); 261 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they 262 // are first found and prefixing with the appropriate encoding for the type class. 263 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second ); 264 mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first; 265 } // if 266 } 267 268 void Mangler_old::postvisit( const TraitInstType * inst ) { 292 269 printQualifiers( inst ); 293 mangleName << "_Y" << inst->name << "_";294 } 295 296 void Mangler ::postvisit(TupleType * tupleType ) {270 mangleName << inst->name.size() << inst->name; 271 } 272 273 void Mangler_old::postvisit( const TupleType * tupleType ) { 297 274 printQualifiers( tupleType ); 298 mangleName << "T";275 mangleName << Encoding::tuple << tupleType->types.size(); 299 276 acceptAll( tupleType->types, *visitor ); 300 mangleName << "_"; 301 } 302 303 void Mangler::postvisit( VarArgsType * varArgsType ) { 277 } 278 279 void Mangler_old::postvisit( const VarArgsType * varArgsType ) { 304 280 printQualifiers( varArgsType ); 305 mangleName << "VARGS"; 306 } 307 308 void Mangler::postvisit( ZeroType * ) { 309 mangleName << "Z"; 310 } 311 312 void Mangler::postvisit( OneType * ) { 313 mangleName << "O"; 314 } 315 316 void Mangler::postvisit( TypeDecl * decl ) { 317 static const char *typePrefix[] = { "BT", "BD", "BF" }; 318 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name; 281 static const std::string vargs = "__builtin_va_list"; 282 mangleName << Encoding::type << vargs.size() << vargs; 283 } 284 285 void Mangler_old::postvisit( const ZeroType * ) { 286 mangleName << Encoding::zero; 287 } 288 289 void Mangler_old::postvisit( const OneType * ) { 290 mangleName << Encoding::one; 291 } 292 293 void Mangler_old::postvisit( const QualifiedType * qualType ) { 294 bool inqual = inQualifiedType; 295 if (! inqual ) { 296 // N marks the start of a qualified type 297 inQualifiedType = true; 298 mangleName << Encoding::qualifiedTypeStart; 299 } 300 maybeAccept( qualType->parent, *visitor ); 301 maybeAccept( qualType->child, *visitor ); 302 if ( ! inqual ) { 303 // E marks the end of a qualified type 304 inQualifiedType = false; 305 mangleName << Encoding::qualifiedTypeEnd; 306 } 307 } 308 309 void Mangler_old::postvisit( const TypeDecl * decl ) { 310 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 311 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. 312 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply 313 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed 314 // aside from the assert false. 315 assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl)); 316 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind ); 317 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name; 319 318 } 320 319 … … 325 324 } 326 325 327 void Mangler ::printQualifiers(Type * type ) {326 void Mangler_old::printQualifiers( const Type * type ) { 328 327 // skip if not including qualifiers 329 328 if ( typeMode ) return; 330 if ( ! type-> get_forall().empty() ) {329 if ( ! type->forall.empty() ) { 331 330 std::list< std::string > assertionNames; 332 int tcount = 0, dcount = 0, fcount = 0, vcount = 0;333 mangleName << "A";334 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i) {335 switch ( (*i)->get_kind()) {331 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 332 mangleName << Encoding::forall; 333 for ( const TypeDecl * i : type->forall ) { 334 switch ( i->kind ) { 336 335 case TypeDecl::Dtype: 337 336 dcount++; … … 346 345 assert( false ); 347 346 } // switch 348 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); 349 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { 350 PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams ); 351 sub_mangler.pass.nextVarNum = nextVarNum; 352 sub_mangler.pass.isTopLevel = false; 353 sub_mangler.pass.varNums = varNums; 354 (*assert)->accept( sub_mangler ); 355 assertionNames.push_back( sub_mangler.pass.mangleName.str() ); 347 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind ); 348 for ( const DeclarationWithType * assert : i->assertions ) { 349 PassVisitor<Mangler_old> sub_mangler( 350 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 351 assert->accept( sub_mangler ); 352 assertionNames.push_back( sub_mangler.pass.get_mangleName() ); 353 acount++; 356 354 } // for 357 355 } // for 358 mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";356 mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_"; 359 357 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); 360 358 mangleName << "_"; … … 363 361 // these qualifiers do not distinguish the outermost type of a function parameter 364 362 if ( type->get_const() ) { 365 mangleName << "C";363 mangleName << Encoding::qualifiers.at(Type::Const); 366 364 } // if 367 365 if ( type->get_volatile() ) { 368 mangleName << "V";366 mangleName << Encoding::qualifiers.at(Type::Volatile); 369 367 } // if 370 368 // Removed due to restrict not affecting function compatibility in GCC … … 373 371 // } // if 374 372 if ( type->get_atomic() ) { 375 mangleName << "A";373 mangleName << Encoding::qualifiers.at(Type::Atomic); 376 374 } // if 377 375 } 378 376 if ( type->get_mutex() ) { 379 mangleName << "M"; 380 } // if 381 if ( type->get_lvalue() ) { 382 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues 383 mangleName << "L"; 384 } 385 377 mangleName << Encoding::qualifiers.at(Type::Mutex); 378 } // if 386 379 if ( inFunctionType ) { 387 380 // turn off inFunctionType so that types can be differentiated for nested qualifiers … … 394 387 } // namespace SymTab 395 388 389 namespace Mangle { 390 namespace { 391 /// Mangles names to a unique C identifier 392 struct Mangler_new : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler_new>, public ast::WithGuards { 393 Mangler_new( Mangle::Mode mode ); 394 Mangler_new( const Mangler_new & ) = delete; 395 396 void previsit( const ast::Node * ) { visit_children = false; } 397 398 void postvisit( const ast::ObjectDecl * declaration ); 399 void postvisit( const ast::FunctionDecl * declaration ); 400 void postvisit( const ast::TypeDecl * declaration ); 401 402 void postvisit( const ast::VoidType * voidType ); 403 void postvisit( const ast::BasicType * basicType ); 404 void postvisit( const ast::PointerType * pointerType ); 405 void postvisit( const ast::ArrayType * arrayType ); 406 void postvisit( const ast::ReferenceType * refType ); 407 void postvisit( const ast::FunctionType * functionType ); 408 void postvisit( const ast::StructInstType * aggregateUseType ); 409 void postvisit( const ast::UnionInstType * aggregateUseType ); 410 void postvisit( const ast::EnumInstType * aggregateUseType ); 411 void postvisit( const ast::TypeInstType * aggregateUseType ); 412 void postvisit( const ast::TraitInstType * inst ); 413 void postvisit( const ast::TupleType * tupleType ); 414 void postvisit( const ast::VarArgsType * varArgsType ); 415 void postvisit( const ast::ZeroType * zeroType ); 416 void postvisit( const ast::OneType * oneType ); 417 void postvisit( const ast::QualifiedType * qualType ); 418 419 std::string get_mangleName() { return mangleName.str(); } 420 private: 421 std::ostringstream mangleName; ///< Mangled name being constructed 422 typedef std::map< std::string, std::pair< int, int > > VarMapType; 423 VarMapType varNums; ///< Map of type variables to indices 424 int nextVarNum; ///< Next type variable index 425 bool isTopLevel; ///< Is the Mangler at the top level 426 bool mangleOverridable; ///< Specially mangle overridable built-in methods 427 bool typeMode; ///< Produce a unique mangled name for a type 428 bool mangleGenericParams; ///< Include generic parameters in name mangling if true 429 bool inFunctionType = false; ///< Include type qualifiers if false. 430 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type 431 432 private: 433 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 434 int nextVarNum, const VarMapType& varNums ); 435 friend class ast::Pass<Mangler_new>; 436 437 private: 438 void mangleDecl( const ast::DeclWithType *declaration ); 439 void mangleRef( const ast::ReferenceToType *refType, std::string prefix ); 440 441 void printQualifiers( const ast::Type *type ); 442 }; // Mangler_new 443 } // namespace 444 445 446 std::string mangle( const ast::Node * decl, Mangle::Mode mode ) { 447 ast::Pass<Mangler_new> mangler( mode ); 448 maybeAccept( decl, mangler ); 449 return mangler.pass.get_mangleName(); 450 } 451 452 namespace { 453 Mangler_new::Mangler_new( Mangle::Mode mode ) 454 : nextVarNum( 0 ), isTopLevel( true ), 455 mangleOverridable ( ! mode.no_overrideable ), 456 typeMode ( mode.type ), 457 mangleGenericParams( ! mode.no_generic_params ) {} 458 459 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 460 int nextVarNum, const VarMapType& varNums ) 461 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 462 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 463 mangleGenericParams( mangleGenericParams ) {} 464 465 void Mangler_new::mangleDecl( const ast::DeclWithType * decl ) { 466 bool wasTopLevel = isTopLevel; 467 if ( isTopLevel ) { 468 varNums.clear(); 469 nextVarNum = 0; 470 isTopLevel = false; 471 } // if 472 mangleName << Encoding::manglePrefix; 473 CodeGen::OperatorInfo opInfo; 474 if ( operatorLookup( decl->name, opInfo ) ) { 475 mangleName << opInfo.outputName.size() << opInfo.outputName; 476 } else { 477 mangleName << decl->name.size() << decl->name; 478 } // if 479 maybeAccept( decl->get_type(), *visitor ); 480 if ( mangleOverridable && decl->linkage.is_overrideable ) { 481 // want to be able to override autogenerated and intrinsic routines, 482 // so they need a different name mangling 483 if ( decl->linkage == ast::Linkage::AutoGen ) { 484 mangleName << Encoding::autogen; 485 } else if ( decl->linkage == ast::Linkage::Intrinsic ) { 486 mangleName << Encoding::intrinsic; 487 } else { 488 // if we add another kind of overridable function, this has to change 489 assert( false && "unknown overrideable linkage" ); 490 } // if 491 } 492 isTopLevel = wasTopLevel; 493 } 494 495 void Mangler_new::postvisit( const ast::ObjectDecl * decl ) { 496 mangleDecl( decl ); 497 } 498 499 void Mangler_new::postvisit( const ast::FunctionDecl * decl ) { 500 mangleDecl( decl ); 501 } 502 503 void Mangler_new::postvisit( const ast::VoidType * voidType ) { 504 printQualifiers( voidType ); 505 mangleName << Encoding::void_t; 506 } 507 508 void Mangler_new::postvisit( const ast::BasicType * basicType ) { 509 printQualifiers( basicType ); 510 assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind ); 511 mangleName << Encoding::basicTypes[ basicType->kind ]; 512 } 513 514 void Mangler_new::postvisit( const ast::PointerType * pointerType ) { 515 printQualifiers( pointerType ); 516 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers 517 if ( ! pointerType->base.as<ast::FunctionType>() ) mangleName << Encoding::pointer; 518 maybe_accept( pointerType->base.get(), *visitor ); 519 } 520 521 void Mangler_new::postvisit( const ast::ArrayType * arrayType ) { 522 // TODO: encode dimension 523 printQualifiers( arrayType ); 524 mangleName << Encoding::array << "0"; 525 maybeAccept( arrayType->base.get(), *visitor ); 526 } 527 528 void Mangler_new::postvisit( const ast::ReferenceType * refType ) { 529 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload. 530 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.), 531 // by pretending every reference type is a function parameter. 532 GuardValue( inFunctionType ); 533 inFunctionType = true; 534 printQualifiers( refType ); 535 maybeAccept( refType->base.get(), *visitor ); 536 } 537 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 545 void Mangler_new::postvisit( const ast::FunctionType * functionType ) { 546 printQualifiers( functionType ); 547 mangleName << Encoding::function; 548 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters, 549 // since qualifiers on outermost parameter type do not differentiate function types, e.g., 550 // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different 551 GuardValue( inFunctionType ); 552 inFunctionType = true; 553 std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns ); 554 if (returnTypes.empty()) mangleName << Encoding::void_t; 555 else accept_each( returnTypes, *visitor ); 556 mangleName << "_"; 557 std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params ); 558 accept_each( paramTypes, *visitor ); 559 mangleName << "_"; 560 } 561 562 void Mangler_new::mangleRef( const ast::ReferenceToType * refType, std::string prefix ) { 563 printQualifiers( refType ); 564 565 mangleName << prefix << refType->name.length() << refType->name; 566 567 if ( mangleGenericParams ) { 568 if ( ! refType->params.empty() ) { 569 mangleName << "_"; 570 for ( const ast::Expr * param : refType->params ) { 571 auto paramType = dynamic_cast< const ast::TypeExpr * >( param ); 572 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 573 maybeAccept( paramType->type.get(), *visitor ); 574 } 575 mangleName << "_"; 576 } 577 } 578 } 579 580 void Mangler_new::postvisit( const ast::StructInstType * aggregateUseType ) { 581 mangleRef( aggregateUseType, Encoding::struct_t ); 582 } 583 584 void Mangler_new::postvisit( const ast::UnionInstType * aggregateUseType ) { 585 mangleRef( aggregateUseType, Encoding::union_t ); 586 } 587 588 void Mangler_new::postvisit( const ast::EnumInstType * aggregateUseType ) { 589 mangleRef( aggregateUseType, Encoding::enum_t ); 590 } 591 592 void Mangler_new::postvisit( const ast::TypeInstType * typeInst ) { 593 VarMapType::iterator varNum = varNums.find( typeInst->name ); 594 if ( varNum == varNums.end() ) { 595 mangleRef( typeInst, Encoding::type ); 596 } else { 597 printQualifiers( typeInst ); 598 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g. 599 // forall(dtype T) void f(T); 600 // forall(dtype S) void f(S); 601 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they 602 // are first found and prefixing with the appropriate encoding for the type class. 603 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second ); 604 mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first; 605 } // if 606 } 607 608 void Mangler_new::postvisit( const ast::TraitInstType * inst ) { 609 printQualifiers( inst ); 610 mangleName << inst->name.size() << inst->name; 611 } 612 613 void Mangler_new::postvisit( const ast::TupleType * tupleType ) { 614 printQualifiers( tupleType ); 615 mangleName << Encoding::tuple << tupleType->types.size(); 616 accept_each( tupleType->types, *visitor ); 617 } 618 619 void Mangler_new::postvisit( const ast::VarArgsType * varArgsType ) { 620 printQualifiers( varArgsType ); 621 static const std::string vargs = "__builtin_va_list"; 622 mangleName << Encoding::type << vargs.size() << vargs; 623 } 624 625 void Mangler_new::postvisit( const ast::ZeroType * ) { 626 mangleName << Encoding::zero; 627 } 628 629 void Mangler_new::postvisit( const ast::OneType * ) { 630 mangleName << Encoding::one; 631 } 632 633 void Mangler_new::postvisit( const ast::QualifiedType * qualType ) { 634 bool inqual = inQualifiedType; 635 if (! inqual ) { 636 // N marks the start of a qualified type 637 inQualifiedType = true; 638 mangleName << Encoding::qualifiedTypeStart; 639 } 640 maybeAccept( qualType->parent.get(), *visitor ); 641 maybeAccept( qualType->child.get(), *visitor ); 642 if ( ! inqual ) { 643 // E marks the end of a qualified type 644 inQualifiedType = false; 645 mangleName << Encoding::qualifiedTypeEnd; 646 } 647 } 648 649 void Mangler_new::postvisit( const ast::TypeDecl * decl ) { 650 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 651 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. 652 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply 653 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed 654 // aside from the assert false. 655 assertf(false, "Mangler_new should not visit typedecl: %s", toCString(decl)); 656 assertf( decl->kind < ast::TypeVar::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind ); 657 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name; 658 } 659 660 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) { 661 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) { 662 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl; 663 } // for 664 } 665 666 void Mangler_new::printQualifiers( const ast::Type * type ) { 667 // skip if not including qualifiers 668 if ( typeMode ) return; 669 if ( auto ptype = dynamic_cast< const ast::ParameterizedType * >(type) ) { 670 if ( ! ptype->forall.empty() ) { 671 std::list< std::string > assertionNames; 672 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 673 mangleName << Encoding::forall; 674 for ( const ast::TypeDecl * decl : ptype->forall ) { 675 switch ( decl->kind ) { 676 case ast::TypeVar::Kind::Dtype: 677 dcount++; 678 break; 679 case ast::TypeVar::Kind::Ftype: 680 fcount++; 681 break; 682 case ast::TypeVar::Kind::Ttype: 683 vcount++; 684 break; 685 default: 686 assert( false ); 687 } // switch 688 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 689 for ( const ast::DeclWithType * assert : decl->assertions ) { 690 ast::Pass<Mangler_new> sub_mangler( 691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 692 assert->accept( sub_mangler ); 693 assertionNames.push_back( sub_mangler.pass.get_mangleName() ); 694 acount++; 695 } // for 696 } // for 697 mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_"; 698 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); 699 mangleName << "_"; 700 } // if 701 } // if 702 if ( ! inFunctionType ) { 703 // these qualifiers do not distinguish the outermost type of a function parameter 704 if ( type->is_const() ) { 705 mangleName << Encoding::qualifiers.at(Type::Const); 706 } // if 707 if ( type->is_volatile() ) { 708 mangleName << Encoding::qualifiers.at(Type::Volatile); 709 } // if 710 // Removed due to restrict not affecting function compatibility in GCC 711 // if ( type->get_isRestrict() ) { 712 // mangleName << "E"; 713 // } // if 714 if ( type->is_atomic() ) { 715 mangleName << Encoding::qualifiers.at(Type::Atomic); 716 } // if 717 } 718 if ( type->is_mutex() ) { 719 mangleName << Encoding::qualifiers.at(Type::Mutex); 720 } // if 721 if ( inFunctionType ) { 722 // turn off inFunctionType so that types can be differentiated for nested qualifiers 723 GuardValue( inFunctionType ); 724 inFunctionType = false; 725 } 726 } 727 } // namespace 728 } // namespace Mangle 729 396 730 // Local Variables: // 397 731 // tab-width: 4 // -
src/SymTab/Mangler.h
r7951100 rb067d9b 21 21 #include <utility> // for pair 22 22 23 #include "AST/Bitfield.hpp" 24 #include "AST/Fwd.hpp" 23 25 #include "SynTree/SynTree.h" // for Types 24 26 #include "SynTree/Visitor.h" // for Visitor, maybeAccept 27 28 // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling 29 // The CFA name mangling scheme is based closely on the itanium C++ name mangling scheme, with the following key differences: 30 // * Variable names are also mangled to include type information, not just functions 31 // * CFA does not have template expansion, so the rules for function specialization do not apply. 32 // * CFA instead has to handle type parameters and assertion parameters. 33 // * Currently name compression is not implemented. 34 35 namespace ResolvExpr { 36 class TypeEnvironment; 37 } 25 38 26 39 namespace SymTab { 27 40 namespace Mangler { 28 41 /// Mangle syntax tree object; primary interface to clients 29 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );42 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true ); 30 43 31 44 /// Mangle a type name; secondary interface 32 std::string mangleType( Type* ty );45 std::string mangleType( const Type * ty ); 33 46 /// Mangle ignoring generic type parameters 34 std::string mangleConcrete( Type* ty ); 47 std::string mangleConcrete( const Type * ty ); 48 49 namespace Encoding { 50 extern const std::string manglePrefix; 51 extern const std::string basicTypes[]; 52 extern const std::map<int, std::string> qualifiers; 53 54 extern const std::string void_t; 55 extern const std::string zero; 56 extern const std::string one; 57 58 extern const std::string function; 59 extern const std::string tuple; 60 extern const std::string pointer; 61 extern const std::string array; 62 extern const std::string qualifiedTypeStart; 63 extern const std::string qualifiedTypeEnd; 64 65 extern const std::string forall; 66 extern const std::string typeVariables[]; 67 68 extern const std::string struct_t; 69 extern const std::string union_t; 70 extern const std::string enum_t; 71 extern const std::string type; 72 73 extern const std::string autogen; 74 extern const std::string intrinsic; 75 }; 35 76 } // Mangler 36 77 } // SymTab 78 79 namespace Mangle { 80 /// Bitflags for mangle modes 81 enum { 82 NoOverrideable = 1 << 0, 83 Type = 1 << 1, 84 NoGenericParams = 1 << 2 85 }; 86 87 /// Bitflag type for mangler modes 88 struct mangle_flags { 89 union { 90 unsigned int val; 91 struct { 92 bool no_overrideable : 1; 93 bool type : 1; 94 bool no_generic_params : 1; 95 }; 96 }; 97 98 constexpr mangle_flags( unsigned int val ) : val(val) {} 99 }; 100 101 using Mode = bitfield<mangle_flags>; 102 103 static inline Mode typeMode() { return NoOverrideable | Type; } 104 105 /// Mangle declaration name 106 std::string mangle( const ast::Node * decl, Mode mode = {} ); 107 108 namespace Encoding { 109 using namespace SymTab::Mangler::Encoding; 110 }; 111 } 112 113 extern "C" { 114 char * cforall_demangle(const char *, int); 115 } 37 116 38 117 // Local Variables: // -
src/SymTab/Validate.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:50:04 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Aug 28 13:47:23 201713 // Update Count : 3 5911 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Aug 7 6:42:00 2019 13 // Update Count : 360 14 14 // 15 15 … … 44 44 #include <list> // for list 45 45 #include <string> // for string 46 #include <unordered_map> // for unordered_map 46 47 #include <utility> // for pair 47 48 49 #include "AST/Chain.hpp" 50 #include "AST/Decl.hpp" 51 #include "AST/Node.hpp" 52 #include "AST/Pass.hpp" 53 #include "AST/SymbolTable.hpp" 54 #include "AST/Type.hpp" 55 #include "AST/TypeSubstitution.hpp" 48 56 #include "CodeGen/CodeGenerator.h" // for genName 49 57 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 50 58 #include "ControlStruct/Mutate.h" // for ForExprMutator 59 #include "Common/CodeLocation.h" // for CodeLocation 60 #include "Common/Stats.h" // for Stats::Heap 51 61 #include "Common/PassVisitor.h" // for PassVisitor, WithDeclsToAdd 52 62 #include "Common/ScopedMap.h" // for ScopedMap … … 61 71 #include "Parser/LinkageSpec.h" // for C 62 72 #include "ResolvExpr/typeops.h" // for typesCompatible 73 #include "ResolvExpr/Resolver.h" // for findSingleExpression 74 #include "ResolvExpr/ResolveTypeof.h" // for resolveTypeof 63 75 #include "SymTab/Autogen.h" // for SizeType 64 76 #include "SynTree/Attribute.h" // for noAttributes, Attribute … … 72 84 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 73 85 #include "SynTree/Visitor.h" // for Visitor 86 #include "Validate/HandleAttributes.h" // for handleAttributes 87 #include "Validate/FindSpecialDecls.h" // for FindSpecialDecls 74 88 75 89 class CompoundStmt; … … 77 91 class SwitchStmt; 78 92 79 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }93 #define debugPrint( x ) if ( doDebug ) x 80 94 81 95 namespace SymTab { 96 /// hoists declarations that are difficult to hoist while parsing 97 struct HoistTypeDecls final : public WithDeclsToAdd { 98 void previsit( SizeofExpr * ); 99 void previsit( AlignofExpr * ); 100 void previsit( UntypedOffsetofExpr * ); 101 void previsit( CompoundLiteralExpr * ); 102 void handleType( Type * ); 103 }; 104 105 struct FixQualifiedTypes final : public WithIndexer { 106 Type * postmutate( QualifiedType * ); 107 }; 108 82 109 struct HoistStruct final : public WithDeclsToAdd, public WithGuards { 83 110 /// Flattens nested struct types 84 111 static void hoistStruct( std::list< Declaration * > &translationUnit ); 85 112 86 void previsit( EnumInstType * enumInstType );87 void previsit( StructInstType * structInstType );88 void previsit( UnionInstType * unionInstType );89 113 void previsit( StructDecl * aggregateDecl ); 90 114 void previsit( UnionDecl * aggregateDecl ); 91 115 void previsit( StaticAssertDecl * assertDecl ); 116 void previsit( StructInstType * type ); 117 void previsit( UnionInstType * type ); 118 void previsit( EnumInstType * type ); 92 119 93 120 private: 94 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl ); 95 122 96 123 AggregateDecl * parentAggr = nullptr; … … 106 133 107 134 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 108 struct EnumAndPointerDecay {109 void previsit( EnumDecl * aggregateDecl );110 void previsit( FunctionType * func );135 struct EnumAndPointerDecay_old { 136 void previsit( EnumDecl * aggregateDecl ); 137 void previsit( FunctionType * func ); 111 138 }; 112 139 113 140 /// Associates forward declarations of aggregates with their definitions 114 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards { 115 LinkReferenceToTypes( const Indexer *indexer ); 116 void postvisit( TypeInstType *typeInst ); 117 118 void postvisit( EnumInstType *enumInst ); 119 void postvisit( StructInstType *structInst ); 120 void postvisit( UnionInstType *unionInst ); 121 void postvisit( TraitInstType *traitInst ); 122 123 void postvisit( EnumDecl *enumDecl ); 124 void postvisit( StructDecl *structDecl ); 125 void postvisit( UnionDecl *unionDecl ); 141 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 142 LinkReferenceToTypes_old( const Indexer * indexer ); 143 void postvisit( TypeInstType * typeInst ); 144 145 void postvisit( EnumInstType * enumInst ); 146 void postvisit( StructInstType * structInst ); 147 void postvisit( UnionInstType * unionInst ); 148 void postvisit( TraitInstType * traitInst ); 149 void previsit( QualifiedType * qualType ); 150 void postvisit( QualifiedType * qualType ); 151 152 void postvisit( EnumDecl * enumDecl ); 153 void postvisit( StructDecl * structDecl ); 154 void postvisit( UnionDecl * unionDecl ); 126 155 void postvisit( TraitDecl * traitDecl ); 127 156 128 void previsit( StructDecl * structDecl );129 void previsit( UnionDecl * unionDecl );157 void previsit( StructDecl * structDecl ); 158 void previsit( UnionDecl * unionDecl ); 130 159 131 160 void renameGenericParams( std::list< TypeDecl * > & params ); 132 161 133 162 private: 134 const Indexer * local_indexer;163 const Indexer * local_indexer; 135 164 136 165 typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType; … … 145 174 146 175 /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID. 147 struct ForallPointerDecay final {176 struct ForallPointerDecay_old final { 148 177 void previsit( ObjectDecl * object ); 149 178 void previsit( FunctionDecl * func ); … … 165 194 }; 166 195 167 struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards{168 EliminateTypedef() : scopeLevel( 0 ) {}196 struct ReplaceTypedef final : public WithVisitorRef<ReplaceTypedef>, public WithGuards, public WithShortCircuiting, public WithDeclsToAdd { 197 ReplaceTypedef() : scopeLevel( 0 ) {} 169 198 /// Replaces typedefs by forward declarations 170 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 171 199 static void replaceTypedef( std::list< Declaration * > &translationUnit ); 200 201 void premutate( QualifiedType * ); 202 Type * postmutate( QualifiedType * qualType ); 172 203 Type * postmutate( TypeInstType * aggregateUseType ); 173 204 Declaration * postmutate( TypedefDecl * typeDecl ); … … 180 211 181 212 void premutate( CompoundStmt * compoundStmt ); 182 CompoundStmt * postmutate( CompoundStmt * compoundStmt );183 213 184 214 void premutate( StructDecl * structDecl ); 185 Declaration * postmutate( StructDecl * structDecl );186 215 void premutate( UnionDecl * unionDecl ); 187 Declaration * postmutate( UnionDecl * unionDecl );188 216 void premutate( EnumDecl * enumDecl ); 189 Declaration * postmutate( EnumDecl * enumDecl ); 190 Declaration * postmutate( TraitDecl * contextDecl ); 217 void premutate( TraitDecl * ); 191 218 192 219 void premutate( FunctionType * ftype ); … … 194 221 private: 195 222 template<typename AggDecl> 196 AggDecl *handleAggregate( AggDecl * aggDecl );197 198 template<typename AggDecl>199 223 void addImplicitTypedef( AggDecl * aggDecl ); 224 template< typename AggDecl > 225 void handleAggregate( AggDecl * aggr ); 200 226 201 227 typedef std::unique_ptr<TypedefDecl> TypedefDeclPtr; 202 228 typedef ScopedMap< std::string, std::pair< TypedefDeclPtr, int > > TypedefMap; 203 typedef std::map< std::string, TypeDecl * > TypeDeclMap;229 typedef ScopedMap< std::string, TypeDecl * > TypeDeclMap; 204 230 TypedefMap typedefNames; 205 231 TypeDeclMap typedeclNames; 206 232 int scopeLevel; 207 233 bool inFunctionType = false; 234 }; 235 236 struct EliminateTypedef { 237 /// removes TypedefDecls from the AST 238 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 239 240 template<typename AggDecl> 241 void handleAggregate( AggDecl * aggregateDecl ); 242 243 void previsit( StructDecl * aggregateDecl ); 244 void previsit( UnionDecl * aggregateDecl ); 245 void previsit( CompoundStmt * compoundStmt ); 208 246 }; 209 247 … … 214 252 static void verify( std::list< Declaration * > &translationUnit ); 215 253 216 void previsit( FunctionDecl * funcDecl );254 void previsit( FunctionDecl * funcDecl ); 217 255 }; 218 256 … … 223 261 }; 224 262 225 struct ArrayLength { 263 struct FixObjectType : public WithIndexer { 264 /// resolves typeof type in object, function, and type declarations 265 static void fix( std::list< Declaration * > & translationUnit ); 266 267 void previsit( ObjectDecl * ); 268 void previsit( FunctionDecl * ); 269 void previsit( TypeDecl * ); 270 }; 271 272 struct ArrayLength : public WithIndexer { 226 273 /// for array types without an explicit length, compute the length and store it so that it 227 274 /// is known to the rest of the phases. For example, … … 234 281 235 282 void previsit( ObjectDecl * objDecl ); 283 void previsit( ArrayType * arrayType ); 236 284 }; 237 285 … … 239 287 Type::StorageClasses storageClasses; 240 288 241 void premutate( ObjectDecl * objectDecl );242 Expression * postmutate( CompoundLiteralExpr * compLitExpr );289 void premutate( ObjectDecl * objectDecl ); 290 Expression * postmutate( CompoundLiteralExpr * compLitExpr ); 243 291 }; 244 292 … … 250 298 }; 251 299 252 FunctionDecl * dereferenceOperator = nullptr;253 struct FindSpecialDeclarations final {254 void previsit( FunctionDecl * funcDecl );255 };256 257 300 void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) { 258 PassVisitor<EnumAndPointerDecay > epc;259 PassVisitor<LinkReferenceToTypes > lrt( nullptr );260 PassVisitor<ForallPointerDecay > fpd;301 PassVisitor<EnumAndPointerDecay_old> epc; 302 PassVisitor<LinkReferenceToTypes_old> lrt( nullptr ); 303 PassVisitor<ForallPointerDecay_old> fpd; 261 304 PassVisitor<CompoundLiteral> compoundliteral; 262 305 PassVisitor<ValidateGenericParameters> genericParams; 263 PassVisitor<FindSpecialDeclarations> finder;264 306 PassVisitor<LabelAddressFixer> labelAddrFixer; 265 266 EliminateTypedef::eliminateTypedef( translationUnit ); 267 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 268 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 269 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling 270 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 271 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes 272 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 273 ReturnChecker::checkFunctionReturns( translationUnit ); 274 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen 275 Concurrency::applyKeywords( translationUnit ); 276 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution 277 ControlStruct::hoistControlDecls( translationUnit ); // hoist initialization out of for statements; must happen before autogenerateRoutines 278 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay 279 Concurrency::implementMutexFuncs( translationUnit ); 280 Concurrency::implementThreadStarter( translationUnit ); 281 mutateAll( translationUnit, compoundliteral ); 282 ArrayLength::computeLength( translationUnit ); 283 acceptAll( translationUnit, finder ); // xxx - remove this pass soon 284 mutateAll( translationUnit, labelAddrFixer ); 285 } 286 287 void validateType( Type *type, const Indexer *indexer ) { 288 PassVisitor<EnumAndPointerDecay> epc; 289 PassVisitor<LinkReferenceToTypes> lrt( indexer ); 290 PassVisitor<ForallPointerDecay> fpd; 307 PassVisitor<HoistTypeDecls> hoistDecls; 308 PassVisitor<FixQualifiedTypes> fixQual; 309 310 { 311 Stats::Heap::newPass("validate-A"); 312 Stats::Time::BlockGuard guard("validate-A"); 313 acceptAll( translationUnit, hoistDecls ); 314 ReplaceTypedef::replaceTypedef( translationUnit ); 315 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 316 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling 317 } 318 { 319 Stats::Heap::newPass("validate-B"); 320 Stats::Time::BlockGuard guard("validate-B"); 321 Stats::Time::TimeBlock("Link Reference To Types", [&]() { 322 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 323 }); 324 Stats::Time::TimeBlock("Fix Qualified Types", [&]() { 325 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed 326 }); 327 Stats::Time::TimeBlock("Hoist Structs", [&]() { 328 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 329 }); 330 Stats::Time::TimeBlock("Eliminate Typedefs", [&]() { 331 EliminateTypedef::eliminateTypedef( translationUnit ); // 332 }); 333 } 334 { 335 Stats::Heap::newPass("validate-C"); 336 Stats::Time::BlockGuard guard("validate-C"); 337 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes_old 338 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 339 ReturnChecker::checkFunctionReturns( translationUnit ); 340 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen 341 } 342 { 343 Stats::Heap::newPass("validate-D"); 344 Stats::Time::BlockGuard guard("validate-D"); 345 Stats::Time::TimeBlock("Apply Concurrent Keywords", [&]() { 346 Concurrency::applyKeywords( translationUnit ); 347 }); 348 Stats::Time::TimeBlock("Forall Pointer Decay", [&]() { 349 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution 350 }); 351 Stats::Time::TimeBlock("Hoist Control Declarations", [&]() { 352 ControlStruct::hoistControlDecls( translationUnit ); // hoist initialization out of for statements; must happen before autogenerateRoutines 353 }); 354 Stats::Time::TimeBlock("Generate Autogen routines", [&]() { 355 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old 356 }); 357 } 358 { 359 Stats::Heap::newPass("validate-E"); 360 Stats::Time::BlockGuard guard("validate-E"); 361 Stats::Time::TimeBlock("Implement Mutex Func", [&]() { 362 Concurrency::implementMutexFuncs( translationUnit ); 363 }); 364 Stats::Time::TimeBlock("Implement Thread Start", [&]() { 365 Concurrency::implementThreadStarter( translationUnit ); 366 }); 367 Stats::Time::TimeBlock("Compound Literal", [&]() { 368 mutateAll( translationUnit, compoundliteral ); 369 }); 370 Stats::Time::TimeBlock("Resolve With Expressions", [&]() { 371 ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables 372 }); 373 } 374 { 375 Stats::Heap::newPass("validate-F"); 376 Stats::Time::BlockGuard guard("validate-F"); 377 Stats::Time::TimeBlock("Fix Object Type", [&]() { 378 FixObjectType::fix( translationUnit ); 379 }); 380 Stats::Time::TimeBlock("Array Length", [&]() { 381 ArrayLength::computeLength( translationUnit ); 382 }); 383 Stats::Time::TimeBlock("Find Special Declarations", [&]() { 384 Validate::findSpecialDecls( translationUnit ); 385 }); 386 Stats::Time::TimeBlock("Fix Label Address", [&]() { 387 mutateAll( translationUnit, labelAddrFixer ); 388 }); 389 Stats::Time::TimeBlock("Handle Attributes", [&]() { 390 Validate::handleAttributes( translationUnit ); 391 }); 392 } 393 } 394 395 void validateType( Type * type, const Indexer * indexer ) { 396 PassVisitor<EnumAndPointerDecay_old> epc; 397 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); 398 PassVisitor<ForallPointerDecay_old> fpd; 291 399 type->accept( epc ); 292 400 type->accept( lrt ); … … 294 402 } 295 403 404 405 void HoistTypeDecls::handleType( Type * type ) { 406 // some type declarations are buried in expressions and not easy to hoist during parsing; hoist them here 407 AggregateDecl * aggr = nullptr; 408 if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) { 409 aggr = inst->baseStruct; 410 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) { 411 aggr = inst->baseUnion; 412 } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( type ) ) { 413 aggr = inst->baseEnum; 414 } 415 if ( aggr && aggr->body ) { 416 declsToAddBefore.push_front( aggr ); 417 } 418 } 419 420 void HoistTypeDecls::previsit( SizeofExpr * expr ) { 421 handleType( expr->type ); 422 } 423 424 void HoistTypeDecls::previsit( AlignofExpr * expr ) { 425 handleType( expr->type ); 426 } 427 428 void HoistTypeDecls::previsit( UntypedOffsetofExpr * expr ) { 429 handleType( expr->type ); 430 } 431 432 void HoistTypeDecls::previsit( CompoundLiteralExpr * expr ) { 433 handleType( expr->result ); 434 } 435 436 437 Type * FixQualifiedTypes::postmutate( QualifiedType * qualType ) { 438 Type * parent = qualType->parent; 439 Type * child = qualType->child; 440 if ( dynamic_cast< GlobalScopeType * >( qualType->parent ) ) { 441 // .T => lookup T at global scope 442 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) { 443 auto td = indexer.globalLookupType( inst->name ); 444 if ( ! td ) { 445 SemanticError( qualType->location, toString("Use of undefined global type ", inst->name) ); 446 } 447 auto base = td->base; 448 assert( base ); 449 Type * ret = base->clone(); 450 ret->get_qualifiers() = qualType->get_qualifiers(); 451 return ret; 452 } else { 453 // .T => T is not a type name 454 assertf( false, "unhandled global qualified child type: %s", toCString(child) ); 455 } 456 } else { 457 // S.T => S must be an aggregate type, find the declaration for T in S. 458 AggregateDecl * aggr = nullptr; 459 if ( StructInstType * inst = dynamic_cast< StructInstType * >( parent ) ) { 460 aggr = inst->baseStruct; 461 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * > ( parent ) ) { 462 aggr = inst->baseUnion; 463 } else { 464 SemanticError( qualType->location, toString("Qualified type requires an aggregate on the left, but has: ", parent) ); 465 } 466 assert( aggr ); // TODO: need to handle forward declarations 467 for ( Declaration * member : aggr->members ) { 468 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) { 469 // name on the right is a typedef 470 if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) { 471 if ( aggr->name == inst->name ) { 472 assert( aggr->base ); 473 Type * ret = aggr->base->clone(); 474 ret->get_qualifiers() = qualType->get_qualifiers(); 475 TypeSubstitution sub = parent->genericSubstitution(); 476 sub.apply(ret); 477 return ret; 478 } 479 } 480 } else { 481 // S.T - S is not an aggregate => error 482 assertf( false, "unhandled qualified child type: %s", toCString(qualType) ); 483 } 484 } 485 // failed to find a satisfying definition of type 486 SemanticError( qualType->location, toString("Undefined type in qualified type: ", qualType) ); 487 } 488 489 // ... may want to link canonical SUE definition to each forward decl so that it becomes easier to lookup? 490 } 491 492 296 493 void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) { 297 494 PassVisitor<HoistStruct> hoister; … … 299 496 } 300 497 301 bool shouldHoist( Declaration * decl ) {498 bool shouldHoist( Declaration * decl ) { 302 499 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl ); 303 500 } 304 501 502 namespace { 503 void qualifiedName( AggregateDecl * aggr, std::ostringstream & ss ) { 504 if ( aggr->parent ) qualifiedName( aggr->parent, ss ); 505 ss << "__" << aggr->name; 506 } 507 508 // mangle nested type names using entire parent chain 509 std::string qualifiedName( AggregateDecl * aggr ) { 510 std::ostringstream ss; 511 qualifiedName( aggr, ss ); 512 return ss.str(); 513 } 514 } 515 305 516 template< typename AggDecl > 306 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) { 307 518 if ( parentAggr ) { 519 aggregateDecl->parent = parentAggr; 520 aggregateDecl->name = qualifiedName( aggregateDecl ); 308 521 // Add elements in stack order corresponding to nesting structure. 309 522 declsToAddBefore.push_front( aggregateDecl ); … … 316 529 } 317 530 318 void HoistStruct::previsit( EnumInstType * inst ) {319 if ( inst->baseEnum && inst->baseEnum->body ) {320 declsToAddBefore.push_front( inst->baseEnum );321 }322 }323 324 void HoistStruct::previsit( StructInstType * inst ) {325 if ( inst->baseStruct && inst->baseStruct->body ) {326 declsToAddBefore.push_front( inst->baseStruct );327 }328 }329 330 void HoistStruct::previsit( UnionInstType * inst ) {331 if ( inst->baseUnion && inst->baseUnion->body ) {332 declsToAddBefore.push_front( inst->baseUnion );333 }334 }335 336 531 void HoistStruct::previsit( StaticAssertDecl * assertDecl ) { 337 532 if ( parentAggr ) { … … 348 543 } 349 544 350 void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) { 545 void HoistStruct::previsit( StructInstType * type ) { 546 // need to reset type name after expanding to qualified name 547 assert( type->baseStruct ); 548 type->name = type->baseStruct->name; 549 } 550 551 void HoistStruct::previsit( UnionInstType * type ) { 552 assert( type->baseUnion ); 553 type->name = type->baseUnion->name; 554 } 555 556 void HoistStruct::previsit( EnumInstType * type ) { 557 assert( type->baseEnum ); 558 type->name = type->baseEnum->name; 559 } 560 561 562 bool isTypedef( Declaration * decl ) { 563 return dynamic_cast< TypedefDecl * >( decl ); 564 } 565 566 void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) { 567 PassVisitor<EliminateTypedef> eliminator; 568 acceptAll( translationUnit, eliminator ); 569 filter( translationUnit, isTypedef, true ); 570 } 571 572 template< typename AggDecl > 573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) { 574 filter( aggregateDecl->members, isTypedef, true ); 575 } 576 577 void EliminateTypedef::previsit( StructDecl * aggregateDecl ) { 578 handleAggregate( aggregateDecl ); 579 } 580 581 void EliminateTypedef::previsit( UnionDecl * aggregateDecl ) { 582 handleAggregate( aggregateDecl ); 583 } 584 585 void EliminateTypedef::previsit( CompoundStmt * compoundStmt ) { 586 // remove and delete decl stmts 587 filter( compoundStmt->kids, [](Statement * stmt) { 588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 589 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) { 590 return true; 591 } // if 592 } // if 593 return false; 594 }, true); 595 } 596 597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) { 351 598 // Set the type of each member of the enumeration to be EnumConstant 352 for ( std::list< Declaration * >::iterator i = enumDecl-> get_members().begin(); i != enumDecl->get_members().end(); ++i ) {353 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );599 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { 600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i ); 354 601 assert( obj ); 355 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl-> get_name()) );602 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) ); 356 603 } // for 357 604 } … … 380 627 } 381 628 382 void EnumAndPointerDecay ::previsit( FunctionType *func ) {629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) { 383 630 // Fix up parameters and return types 384 631 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 386 633 } 387 634 388 LinkReferenceToTypes ::LinkReferenceToTypes( const Indexer *other_indexer ) {635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) { 389 636 if ( other_indexer ) { 390 637 local_indexer = other_indexer; … … 394 641 } 395 642 396 void LinkReferenceToTypes ::postvisit( EnumInstType *enumInst ) {397 EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name());643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) { 644 const EnumDecl * st = local_indexer->lookupEnum( enumInst->name ); 398 645 // it's not a semantic error if the enum is not found, just an implicit forward declaration 399 646 if ( st ) { 400 //assert( ! enumInst->get_baseEnum() || enumInst->get_baseEnum()->get_members().empty() || ! st->get_members().empty() ); 401 enumInst->set_baseEnum( st ); 402 } // if 403 if ( ! st || st->get_members().empty() ) { 647 enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node 648 } // if 649 if ( ! st || ! st->body ) { 404 650 // use of forward declaration 405 forwardEnums[ enumInst-> get_name()].push_back( enumInst );651 forwardEnums[ enumInst->name ].push_back( enumInst ); 406 652 } // if 407 653 } … … 415 661 } 416 662 417 void LinkReferenceToTypes ::postvisit( StructInstType *structInst ) {418 StructDecl *st = local_indexer->lookupStruct( structInst->get_name());663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) { 664 const StructDecl * st = local_indexer->lookupStruct( structInst->name ); 419 665 // it's not a semantic error if the struct is not found, just an implicit forward declaration 420 666 if ( st ) { 421 //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() ); 422 structInst->set_baseStruct( st ); 423 } // if 424 if ( ! st || st->get_members().empty() ) { 667 structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node 668 } // if 669 if ( ! st || ! st->body ) { 425 670 // use of forward declaration 426 forwardStructs[ structInst-> get_name()].push_back( structInst );671 forwardStructs[ structInst->name ].push_back( structInst ); 427 672 } // if 428 673 checkGenericParameters( structInst ); 429 674 } 430 675 431 void LinkReferenceToTypes ::postvisit( UnionInstType *unionInst ) {432 UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name());676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) { 677 const UnionDecl * un = local_indexer->lookupUnion( unionInst->name ); 433 678 // it's not a semantic error if the union is not found, just an implicit forward declaration 434 679 if ( un ) { 435 unionInst-> set_baseUnion( un );436 } // if 437 if ( ! un || un->get_members().empty()) {680 unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node 681 } // if 682 if ( ! un || ! un->body ) { 438 683 // use of forward declaration 439 forwardUnions[ unionInst-> get_name()].push_back( unionInst );684 forwardUnions[ unionInst->name ].push_back( unionInst ); 440 685 } // if 441 686 checkGenericParameters( unionInst ); 687 } 688 689 void LinkReferenceToTypes_old::previsit( QualifiedType * ) { 690 visit_children = false; 691 } 692 693 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 694 // linking only makes sense for the 'oldest ancestor' of the qualified type 695 qualType->parent->accept( * visitor ); 442 696 } 443 697 … … 450 704 DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 ); 451 705 if ( dwt1 && dwt2 ) { 452 if ( dwt1-> get_name() == dwt2->get_name()&& ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {706 if ( dwt1->name == dwt2->name && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) { 453 707 // std::cerr << "=========== equal:" << std::endl; 454 708 // std::cerr << "d1: " << d1 << std::endl; … … 475 729 template< typename Iterator > 476 730 void expandAssertions( TraitInstType * inst, Iterator out ) { 477 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", to String( inst ).c_str() );731 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toCString( inst ) ); 478 732 std::list< DeclarationWithType * > asserts; 479 733 for ( Declaration * decl : inst->baseTrait->members ) { … … 484 738 } 485 739 486 void LinkReferenceToTypes ::postvisit( TraitDecl * traitDecl ) {740 void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) { 487 741 if ( traitDecl->name == "sized" ) { 488 742 // "sized" is a special trait - flick the sized status on for the type variable … … 506 760 } 507 761 508 void LinkReferenceToTypes ::postvisit( TraitInstType * traitInst ) {762 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 509 763 // handle other traits 510 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );764 const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name ); 511 765 if ( ! traitDecl ) { 512 766 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); 513 767 } // if 514 if ( traitDecl-> get_parameters().size() != traitInst->get_parameters().size() ) {768 if ( traitDecl->parameters.size() != traitInst->parameters.size() ) { 515 769 SemanticError( traitInst, "incorrect number of trait parameters: " ); 516 770 } // if 517 traitInst->baseTrait = traitDecl;771 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node 518 772 519 773 // need to carry over the 'sized' status of each decl in the instance 520 for ( auto p : group_iterate( traitDecl-> get_parameters(), traitInst->get_parameters()) ) {774 for ( auto p : group_iterate( traitDecl->parameters, traitInst->parameters ) ) { 521 775 TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) ); 522 776 if ( ! expr ) { … … 525 779 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) { 526 780 TypeDecl * formalDecl = std::get<0>(p); 527 TypeDecl * instDecl = inst-> get_baseType();781 TypeDecl * instDecl = inst->baseType; 528 782 if ( formalDecl->get_sized() ) instDecl->set_sized( true ); 529 783 } … … 532 786 } 533 787 534 void LinkReferenceToTypes ::postvisit( EnumDecl *enumDecl ) {788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) { 535 789 // visit enum members first so that the types of self-referencing members are updated properly 536 if ( ! enumDecl->get_members().empty()) {537 ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl-> get_name());790 if ( enumDecl->body ) { 791 ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name ); 538 792 if ( fwds != forwardEnums.end() ) { 539 793 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 540 (* inst )->set_baseEnum( enumDecl );794 (* inst)->baseEnum = enumDecl; 541 795 } // for 542 796 forwardEnums.erase( fwds ); 543 797 } // if 544 } // if 545 } 546 547 void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) { 798 799 for ( Declaration * member : enumDecl->members ) { 800 ObjectDecl * field = strict_dynamic_cast<ObjectDecl *>( member ); 801 if ( field->init ) { 802 // need to resolve enumerator initializers early so that other passes that determine if an expression is constexpr have the appropriate information. 803 SingleInit * init = strict_dynamic_cast<SingleInit *>( field->init ); 804 ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer ); 805 } 806 } 807 } // if 808 } 809 810 void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) { 548 811 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 549 812 // forall(otype T) … … 563 826 } 564 827 565 void LinkReferenceToTypes ::previsit( StructDecl * structDecl ) {828 void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) { 566 829 renameGenericParams( structDecl->parameters ); 567 830 } 568 831 569 void LinkReferenceToTypes ::previsit( UnionDecl * unionDecl ) {832 void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) { 570 833 renameGenericParams( unionDecl->parameters ); 571 834 } 572 835 573 void LinkReferenceToTypes ::postvisit( StructDecl *structDecl ) {836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) { 574 837 // visit struct members first so that the types of self-referencing members are updated properly 575 838 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) 576 if ( ! structDecl->get_members().empty()) {577 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl-> get_name());839 if ( structDecl->body ) { 840 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->name ); 578 841 if ( fwds != forwardStructs.end() ) { 579 842 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 580 (* inst )->set_baseStruct( structDecl );843 (* inst)->baseStruct = structDecl; 581 844 } // for 582 845 forwardStructs.erase( fwds ); … … 585 848 } 586 849 587 void LinkReferenceToTypes ::postvisit( UnionDecl *unionDecl ) {588 if ( ! unionDecl->get_members().empty()) {589 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl-> get_name());850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) { 851 if ( unionDecl->body ) { 852 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 590 853 if ( fwds != forwardUnions.end() ) { 591 854 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 592 (* inst )->set_baseUnion( unionDecl );855 (* inst)->baseUnion = unionDecl; 593 856 } // for 594 857 forwardUnions.erase( fwds ); … … 597 860 } 598 861 599 void LinkReferenceToTypes ::postvisit( TypeInstType *typeInst ) {862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) { 600 863 // ensure generic parameter instances are renamed like the base type 601 864 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 602 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name()) ) {603 if ( TypeDecl *typeDecl = dynamic_cast<TypeDecl * >( namedTypeDecl ) ) {604 typeInst->set_isFtype( typeDecl-> get_kind()== TypeDecl::Ftype );865 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) { 866 if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) { 867 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype ); 605 868 } // if 606 869 } // if … … 614 877 // expand trait instances into their members 615 878 for ( DeclarationWithType * assertion : asserts ) { 616 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 617 880 // expand trait instance into all of its members 618 881 expandAssertions( traitInst, back_inserter( type->assertions ) ); … … 634 897 } 635 898 636 void ForallPointerDecay ::previsit( ObjectDecl *object ) {899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) { 637 900 // ensure that operator names only apply to functions or function pointers 638 901 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 642 905 } 643 906 644 void ForallPointerDecay ::previsit( FunctionDecl *func ) {907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) { 645 908 func->fixUniqueId(); 646 909 } 647 910 648 void ForallPointerDecay ::previsit( FunctionType * ftype ) {911 void ForallPointerDecay_old::previsit( FunctionType * ftype ) { 649 912 forallFixer( ftype->forall, ftype ); 650 913 } 651 914 652 void ForallPointerDecay ::previsit( StructDecl * aggrDecl ) {915 void ForallPointerDecay_old::previsit( StructDecl * aggrDecl ) { 653 916 forallFixer( aggrDecl->parameters, aggrDecl ); 654 917 } 655 918 656 void ForallPointerDecay ::previsit( UnionDecl * aggrDecl ) {919 void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) { 657 920 forallFixer( aggrDecl->parameters, aggrDecl ); 658 921 } … … 679 942 680 943 681 bool isTypedef( Declaration *decl ) { 682 return dynamic_cast< TypedefDecl * >( decl ); 683 } 684 685 void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) { 686 PassVisitor<EliminateTypedef> eliminator; 944 void ReplaceTypedef::replaceTypedef( std::list< Declaration * > &translationUnit ) { 945 PassVisitor<ReplaceTypedef> eliminator; 687 946 mutateAll( translationUnit, eliminator ); 688 947 if ( eliminator.pass.typedefNames.count( "size_t" ) ) { 689 948 // grab and remember declaration of size_t 690 SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone();949 Validate::SizeType = eliminator.pass.typedefNames["size_t"].first->base->clone(); 691 950 } else { 692 951 // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong 693 952 // eventually should have a warning for this case. 694 SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 695 } 696 filter( translationUnit, isTypedef, true ); 697 } 698 699 Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) { 953 Validate::SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 954 } 955 } 956 957 void ReplaceTypedef::premutate( QualifiedType * ) { 958 visit_children = false; 959 } 960 961 Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) { 962 // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type 963 qualType->parent = qualType->parent->acceptMutator( * visitor ); 964 return qualType; 965 } 966 967 Type * ReplaceTypedef::postmutate( TypeInstType * typeInst ) { 700 968 // instances of typedef types will come here. If it is an instance 701 969 // of a typdef type, link the instance to its actual type. 702 TypedefMap::const_iterator def = typedefNames.find( typeInst-> get_name());970 TypedefMap::const_iterator def = typedefNames.find( typeInst->name ); 703 971 if ( def != typedefNames.end() ) { 704 Type *ret = def->second.first->base->clone(); 972 Type * ret = def->second.first->base->clone(); 973 ret->location = typeInst->location; 705 974 ret->get_qualifiers() |= typeInst->get_qualifiers(); 706 975 // attributes are not carried over from typedef to function parameters/return values … … 713 982 // place instance parameters on the typedef'd type 714 983 if ( ! typeInst->parameters.empty() ) { 715 ReferenceToType * rtt = dynamic_cast<ReferenceToType*>(ret);984 ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret); 716 985 if ( ! rtt ) { 717 986 SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name ); 718 987 } 719 rtt-> get_parameters().clear();988 rtt->parameters.clear(); 720 989 cloneAll( typeInst->parameters, rtt->parameters ); 721 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters 722 991 } // if 723 992 delete typeInst; 724 993 return ret; 725 994 } else { 726 TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() ); 727 assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->name.c_str() ); 995 TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->name ); 996 if ( base == typedeclNames.end() ) { 997 SemanticError( typeInst->location, toString("Use of undefined type ", typeInst->name) ); 998 } 728 999 typeInst->set_baseType( base->second ); 729 } // if 730 return typeInst; 1000 return typeInst; 1001 } // if 1002 assert( false ); 731 1003 } 732 1004 … … 745 1017 } 746 1018 747 Declaration * EliminateTypedef::postmutate( TypedefDecl * tyDecl ) {748 if ( typedefNames.count( tyDecl-> get_name() ) == 1 && typedefNames[ tyDecl->get_name()].second == scopeLevel ) {1019 Declaration * ReplaceTypedef::postmutate( TypedefDecl * tyDecl ) { 1020 if ( typedefNames.count( tyDecl->name ) == 1 && typedefNames[ tyDecl->name ].second == scopeLevel ) { 749 1021 // typedef to the same name from the same scope 750 1022 // must be from the same type 751 1023 752 Type * t1 = tyDecl-> get_base();753 Type * t2 = typedefNames[ tyDecl-> get_name() ].first->get_base();1024 Type * t1 = tyDecl->base; 1025 Type * t2 = typedefNames[ tyDecl->name ].first->base; 754 1026 if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) { 755 1027 SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name ); … … 763 1035 } 764 1036 } else { 765 typedefNames[ tyDecl-> get_name()] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );1037 typedefNames[ tyDecl->name ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel ); 766 1038 } // if 767 1039 … … 771 1043 // struct screen; 772 1044 // because the expansion of the typedef is: 773 // void rtn( SCREEN * p ) => void rtn( struct screen *p )1045 // void rtn( SCREEN * p ) => void rtn( struct screen * p ) 774 1046 // hence the type-name "screen" must be defined. 775 1047 // Note, qualifiers on the typedef are superfluous for the forward declaration. 776 1048 777 Type *designatorType = tyDecl->get_base()->stripDeclarator(); 778 if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) { 779 return new StructDecl( aggDecl->get_name(), DeclarationNode::Struct, noAttributes, tyDecl->get_linkage() ); 780 } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 781 return new UnionDecl( aggDecl->get_name(), noAttributes, tyDecl->get_linkage() ); 782 } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 783 return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() ); 784 } else { 785 return tyDecl->clone(); 786 } // if 787 } 788 789 void EliminateTypedef::premutate( TypeDecl * typeDecl ) { 790 TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() ); 1049 Type * designatorType = tyDecl->base->stripDeclarator(); 1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) { 1051 declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) ); 1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 1053 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 1055 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 1056 } // if 1057 return tyDecl->clone(); 1058 } 1059 1060 void ReplaceTypedef::premutate( TypeDecl * typeDecl ) { 1061 TypedefMap::iterator i = typedefNames.find( typeDecl->name ); 791 1062 if ( i != typedefNames.end() ) { 792 1063 typedefNames.erase( i ) ; 793 1064 } // if 794 1065 795 typedeclNames [ typeDecl->get_name() ] = typeDecl;796 } 797 798 void EliminateTypedef::premutate( FunctionDecl * ) {1066 typedeclNames.insert( typeDecl->name, typeDecl ); 1067 } 1068 1069 void ReplaceTypedef::premutate( FunctionDecl * ) { 799 1070 GuardScope( typedefNames ); 800 } 801 802 void EliminateTypedef::premutate( ObjectDecl * ) { 1071 GuardScope( typedeclNames ); 1072 } 1073 1074 void ReplaceTypedef::premutate( ObjectDecl * ) { 803 1075 GuardScope( typedefNames ); 804 } 805 806 DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) { 807 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type? 1076 GuardScope( typedeclNames ); 1077 } 1078 1079 DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) { 1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type? 808 1081 // replace the current object declaration with a function declaration 809 FunctionDecl * newDecl = new FunctionDecl( objDecl-> get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() );810 objDecl-> get_attributes().clear();1082 FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() ); 1083 objDecl->attributes.clear(); 811 1084 objDecl->set_type( nullptr ); 812 1085 delete objDecl; … … 816 1089 } 817 1090 818 void EliminateTypedef::premutate( CastExpr * ) {1091 void ReplaceTypedef::premutate( CastExpr * ) { 819 1092 GuardScope( typedefNames ); 820 } 821 822 void EliminateTypedef::premutate( CompoundStmt * ) { 1093 GuardScope( typedeclNames ); 1094 } 1095 1096 void ReplaceTypedef::premutate( CompoundStmt * ) { 823 1097 GuardScope( typedefNames ); 1098 GuardScope( typedeclNames ); 824 1099 scopeLevel += 1; 825 1100 GuardAction( [this](){ scopeLevel -= 1; } ); 826 1101 } 827 1102 828 CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) {829 // remove and delete decl stmts830 filter( compoundStmt->kids, [](Statement * stmt) {831 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {832 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {833 return true;834 } // if835 } // if836 return false;837 }, true);838 return compoundStmt;839 }840 841 // there may be typedefs nested within aggregates. in order for everything to work properly, these should be removed842 // as well843 1103 template<typename AggDecl> 844 AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) { 845 filter( aggDecl->members, isTypedef, true ); 846 return aggDecl; 847 } 848 849 template<typename AggDecl> 850 void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 1104 void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 851 1105 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 852 Type * type = nullptr;1106 Type * type = nullptr; 853 1107 if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) { 854 1108 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ); … … 860 1114 TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) ); 861 1115 typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel ); 862 } // if 863 } 864 865 void EliminateTypedef::premutate( StructDecl * structDecl ) { 1116 // add the implicit typedef to the AST 1117 declsToAddBefore.push_back( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type->clone(), aggDecl->get_linkage() ) ); 1118 } // if 1119 } 1120 1121 template< typename AggDecl > 1122 void ReplaceTypedef::handleAggregate( AggDecl * aggr ) { 1123 SemanticErrorException errors; 1124 1125 ValueGuard< std::list<Declaration * > > oldBeforeDecls( declsToAddBefore ); 1126 ValueGuard< std::list<Declaration * > > oldAfterDecls ( declsToAddAfter ); 1127 declsToAddBefore.clear(); 1128 declsToAddAfter.clear(); 1129 1130 GuardScope( typedefNames ); 1131 GuardScope( typedeclNames ); 1132 mutateAll( aggr->parameters, * visitor ); 1133 1134 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. 1135 for ( std::list< Declaration * >::iterator i = aggr->members.begin(); i != aggr->members.end(); ++i ) { 1136 if ( !declsToAddAfter.empty() ) { aggr->members.splice( i, declsToAddAfter ); } 1137 1138 try { 1139 * i = maybeMutate( * i, * visitor ); 1140 } catch ( SemanticErrorException &e ) { 1141 errors.append( e ); 1142 } 1143 1144 if ( !declsToAddBefore.empty() ) { aggr->members.splice( i, declsToAddBefore ); } 1145 } 1146 1147 if ( !declsToAddAfter.empty() ) { aggr->members.splice( aggr->members.end(), declsToAddAfter ); } 1148 if ( !errors.isEmpty() ) { throw errors; } 1149 } 1150 1151 void ReplaceTypedef::premutate( StructDecl * structDecl ) { 1152 visit_children = false; 866 1153 addImplicitTypedef( structDecl ); 867 } 868 869 870 Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) { 871 return handleAggregate( structDecl ); 872 } 873 874 void EliminateTypedef::premutate( UnionDecl * unionDecl ) { 1154 handleAggregate( structDecl ); 1155 } 1156 1157 void ReplaceTypedef::premutate( UnionDecl * unionDecl ) { 1158 visit_children = false; 875 1159 addImplicitTypedef( unionDecl ); 876 } 877 878 Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) { 879 return handleAggregate( unionDecl ); 880 } 881 882 void EliminateTypedef::premutate( EnumDecl * enumDecl ) { 1160 handleAggregate( unionDecl ); 1161 } 1162 1163 void ReplaceTypedef::premutate( EnumDecl * enumDecl ) { 883 1164 addImplicitTypedef( enumDecl ); 884 1165 } 885 1166 886 Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) { 887 return handleAggregate( enumDecl ); 888 } 889 890 Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) { 891 return handleAggregate( traitDecl ); 892 } 893 894 void EliminateTypedef::premutate( FunctionType * ) { 1167 void ReplaceTypedef::premutate( FunctionType * ) { 895 1168 GuardValue( inFunctionType ); 896 1169 inFunctionType = true; 1170 } 1171 1172 void ReplaceTypedef::premutate( TraitDecl * ) { 1173 GuardScope( typedefNames ); 1174 GuardScope( typedeclNames); 897 1175 } 898 1176 … … 939 1217 for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) { 940 1218 if ( i < args.size() ) { 941 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );942 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) ); 1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() ); 943 1221 } else if ( i == args.size() ) { 944 Type * defaultType = (* paramIter)->get_init();1222 Type * defaultType = (* paramIter)->get_init(); 945 1223 if ( defaultType ) { 946 1224 args.push_back( new TypeExpr( defaultType->clone() ) ); 947 sub.add( (* paramIter)->get_name(), defaultType->clone() );1225 sub.add( (* paramIter)->get_name(), defaultType->clone() ); 948 1226 } 949 1227 } … … 964 1242 } 965 1243 966 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) { 967 1245 storageClasses = objectDecl->get_storageClasses(); 968 1246 } 969 1247 970 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) { 971 1249 // transform [storage_class] ... (struct S){ 3, ... }; 972 1250 // into [storage_class] struct S temp = { 3, ... }; 973 1251 static UniqueName indexName( "_compLit" ); 974 1252 975 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() ); 976 1254 compLitExpr->set_result( nullptr ); 977 1255 compLitExpr->set_initializer( nullptr ); … … 1011 1289 TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 1012 1290 // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false. 1013 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) ); 1014 1292 deleteAll( retVals ); 1015 1293 retVals.clear(); … … 1018 1296 } 1019 1297 1298 void FixObjectType::fix( std::list< Declaration * > & translationUnit ) { 1299 PassVisitor<FixObjectType> fixer; 1300 acceptAll( translationUnit, fixer ); 1301 } 1302 1303 void FixObjectType::previsit( ObjectDecl * objDecl ) { 1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer ); 1305 objDecl->set_type( new_type ); 1306 } 1307 1308 void FixObjectType::previsit( FunctionDecl * funcDecl ) { 1309 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer ); 1310 funcDecl->set_type( new_type ); 1311 } 1312 1313 void FixObjectType::previsit( TypeDecl * typeDecl ) { 1314 if ( typeDecl->get_base() ) { 1315 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer ); 1316 typeDecl->set_base( new_type ); 1317 } // if 1318 } 1319 1020 1320 void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) { 1021 1321 PassVisitor<ArrayLength> len; … … 1024 1324 1025 1325 void ArrayLength::previsit( ObjectDecl * objDecl ) { 1026 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) { 1027 if ( at->get_dimension() ) return; 1028 if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) { 1029 at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) ); 1030 } 1326 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) { 1327 if ( at->dimension ) return; 1328 if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->init ) ) { 1329 at->dimension = new ConstantExpr( Constant::from_ulong( init->initializers.size() ) ); 1330 } 1331 } 1332 } 1333 1334 void ArrayLength::previsit( ArrayType * type ) { 1335 if ( type->dimension ) { 1336 // need to resolve array dimensions early so that constructor code can correctly determine 1337 // if a type is a VLA (and hence whether its elements need to be constructed) 1338 ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer ); 1339 1340 // must re-evaluate whether a type is a VLA, now that more information is available 1341 // (e.g. the dimension may have been an enumerator, which was unknown prior to this step) 1342 type->isVarLen = ! InitTweak::isConstExpr( type->dimension ); 1031 1343 } 1032 1344 } … … 1062 1374 } 1063 1375 1064 void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) { 1065 if ( ! dereferenceOperator ) { 1066 if ( funcDecl->get_name() == "*?" && funcDecl->get_linkage() == LinkageSpec::Intrinsic ) { 1067 FunctionType * ftype = funcDecl->get_functionType(); 1068 if ( ftype->get_parameters().size() == 1 && ftype->get_parameters().front()->get_type()->get_qualifiers() == Type::Qualifiers() ) { 1069 dereferenceOperator = funcDecl; 1376 namespace { 1377 /// Replaces enum types by int, and function/array types in function parameter and return 1378 /// lists by appropriate pointers 1379 struct EnumAndPointerDecay_new { 1380 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) { 1381 // set the type of each member of the enumeration to be EnumConstant 1382 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1383 // build new version of object with EnumConstant 1384 ast::ptr< ast::ObjectDecl > obj = 1385 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1386 obj.get_and_mutate()->type = 1387 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1388 1389 // set into decl 1390 ast::EnumDecl * mut = mutate( enumDecl ); 1391 mut->members[i] = obj.get(); 1392 enumDecl = mut; 1393 } 1394 return enumDecl; 1395 } 1396 1397 static const ast::FunctionType * fixFunctionList( 1398 const ast::FunctionType * func, 1399 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1400 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1401 ) { 1402 const auto & dwts = func->* field; 1403 unsigned nvals = dwts.size(); 1404 bool hasVoid = false; 1405 for ( unsigned i = 0; i < nvals; ++i ) { 1406 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1407 } 1408 1409 // the only case in which "void" is valid is where it is the only one in the list 1410 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1411 SemanticError( 1412 dwts.front()->location, func, "invalid type void in function type" ); 1413 } 1414 1415 // one void is the only thing in the list, remove it 1416 if ( hasVoid ) { 1417 func = ast::mutate_field( 1418 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1419 } 1420 1421 return func; 1422 } 1423 1424 const ast::FunctionType * previsit( const ast::FunctionType * func ) { 1425 func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs ); 1426 return fixFunctionList( func, &ast::FunctionType::returns ); 1427 } 1428 }; 1429 1430 /// expand assertions from a trait instance, performing appropriate type variable substitutions 1431 void expandAssertions( 1432 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1433 ) { 1434 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) ); 1435 1436 // build list of trait members, substituting trait decl parameters for instance parameters 1437 ast::TypeSubstitution sub{ 1438 inst->base->params.begin(), inst->base->params.end(), inst->params.begin() }; 1439 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base 1440 for ( ast::ptr< ast::Decl > decl : inst->base->members ) { 1441 auto member = decl.strict_as< ast::DeclWithType >(); 1442 sub.apply( member ); 1443 out.emplace_back( member ); 1444 } 1445 } 1446 1447 /// Associates forward declarations of aggregates with their definitions 1448 class LinkReferenceToTypes_new final 1449 : public ast::WithSymbolTable, public ast::WithGuards, public 1450 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1451 1452 // these maps of uses of forward declarations of types need to have the actual type 1453 // declaration switched in * after * they have been traversed. To enable this in the 1454 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1455 // before it is placed in the map, properly updating its parents in the usual traversal, 1456 // then can have the actual mutation applied later 1457 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >; 1458 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >; 1459 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >; 1460 1461 const CodeLocation & location; 1462 const ast::SymbolTable * localSymtab; 1463 1464 ForwardEnumsType forwardEnums; 1465 ForwardStructsType forwardStructs; 1466 ForwardUnionsType forwardUnions; 1467 1468 /// true if currently in a generic type body, so that type parameter instances can be 1469 /// renamed appropriately 1470 bool inGeneric = false; 1471 1472 public: 1473 /// contstruct using running symbol table 1474 LinkReferenceToTypes_new( const CodeLocation & loc ) 1475 : location( loc ), localSymtab( &symtab ) {} 1476 1477 /// construct using provided symbol table 1478 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1479 : location( loc ), localSymtab( &syms ) {} 1480 1481 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 1482 // ensure generic parameter instances are renamed like the base type 1483 if ( inGeneric && typeInst->base ) { 1484 typeInst = ast::mutate_field( 1485 typeInst, &ast::TypeInstType::name, typeInst->base->name ); 1486 } 1487 1488 if ( 1489 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1490 localSymtab->lookupType( typeInst->name ) ) 1491 ) { 1492 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind ); 1493 } 1494 1495 return typeInst; 1496 } 1497 1498 const ast::Type * postvisit( const ast::EnumInstType * inst ) { 1499 const ast::EnumDecl * decl = localSymtab->lookupEnum( inst->name ); 1500 // not a semantic error if the enum is not found, just an implicit forward declaration 1501 if ( decl ) { 1502 inst = ast::mutate_field( inst, &ast::EnumInstType::base, decl ); 1503 } 1504 if ( ! decl || ! decl->body ) { 1505 // forward declaration 1506 auto mut = mutate( inst ); 1507 forwardEnums.emplace( inst->name, mut ); 1508 inst = mut; 1509 } 1510 return inst; 1511 } 1512 1513 void checkGenericParameters( const ast::ReferenceToType * inst ) { 1514 for ( const ast::Expr * param : inst->params ) { 1515 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) { 1516 SemanticError( 1517 location, inst, "Expression parameters for generic types are currently " 1518 "unsupported: " ); 1070 1519 } 1071 1520 } 1072 1521 } 1073 } 1522 1523 const ast::StructInstType * postvisit( const ast::StructInstType * inst ) { 1524 const ast::StructDecl * decl = localSymtab->lookupStruct( inst->name ); 1525 // not a semantic error if the struct is not found, just an implicit forward declaration 1526 if ( decl ) { 1527 inst = ast::mutate_field( inst, &ast::StructInstType::base, decl ); 1528 } 1529 if ( ! decl || ! decl->body ) { 1530 // forward declaration 1531 auto mut = mutate( inst ); 1532 forwardStructs.emplace( inst->name, mut ); 1533 inst = mut; 1534 } 1535 checkGenericParameters( inst ); 1536 return inst; 1537 } 1538 1539 const ast::UnionInstType * postvisit( const ast::UnionInstType * inst ) { 1540 const ast::UnionDecl * decl = localSymtab->lookupUnion( inst->name ); 1541 // not a semantic error if the struct is not found, just an implicit forward declaration 1542 if ( decl ) { 1543 inst = ast::mutate_field( inst, &ast::UnionInstType::base, decl ); 1544 } 1545 if ( ! decl || ! decl->body ) { 1546 // forward declaration 1547 auto mut = mutate( inst ); 1548 forwardUnions.emplace( inst->name, mut ); 1549 inst = mut; 1550 } 1551 checkGenericParameters( inst ); 1552 return inst; 1553 } 1554 1555 const ast::Type * postvisit( const ast::TraitInstType * traitInst ) { 1556 // handle other traits 1557 const ast::TraitDecl * traitDecl = localSymtab->lookupTrait( traitInst->name ); 1558 if ( ! traitDecl ) { 1559 SemanticError( location, "use of undeclared trait " + traitInst->name ); 1560 } 1561 if ( traitDecl->params.size() != traitInst->params.size() ) { 1562 SemanticError( location, traitInst, "incorrect number of trait parameters: " ); 1563 } 1564 traitInst = ast::mutate_field( traitInst, &ast::TraitInstType::base, traitDecl ); 1565 1566 // need to carry over the "sized" status of each decl in the instance 1567 for ( unsigned i = 0; i < traitDecl->params.size(); ++i ) { 1568 auto expr = traitInst->params[i].as< ast::TypeExpr >(); 1569 if ( ! expr ) { 1570 SemanticError( 1571 traitInst->params[i].get(), "Expression parameters for trait instances " 1572 "are currently unsupported: " ); 1573 } 1574 1575 if ( auto inst = expr->type.as< ast::TypeInstType >() ) { 1576 if ( traitDecl->params[i]->sized && ! inst->base->sized ) { 1577 // traitInst = ast::mutate_field_index( 1578 // traitInst, &ast::TraitInstType::params, i, 1579 // ... 1580 // ); 1581 ast::TraitInstType * mut = ast::mutate( traitInst ); 1582 ast::chain_mutate( mut->params[i] ) 1583 ( &ast::TypeExpr::type ) 1584 ( &ast::TypeInstType::base )->sized = true; 1585 traitInst = mut; 1586 } 1587 } 1588 } 1589 1590 return traitInst; 1591 } 1592 1593 void previsit( const ast::QualifiedType * ) { visit_children = false; } 1594 1595 const ast::Type * postvisit( const ast::QualifiedType * qualType ) { 1596 // linking only makes sense for the "oldest ancestor" of the qualified type 1597 return ast::mutate_field( 1598 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) ); 1599 } 1600 1601 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) { 1602 // visit enum members first so that the types of self-referencing members are updated 1603 // properly 1604 if ( ! enumDecl->body ) return enumDecl; 1605 1606 // update forward declarations to point here 1607 auto fwds = forwardEnums.equal_range( enumDecl->name ); 1608 if ( fwds.first != fwds.second ) { 1609 auto inst = fwds.first; 1610 do { 1611 // forward decl is stored * mutably * in map, can thus be updated 1612 inst->second->base = enumDecl; 1613 } while ( ++inst != fwds.second ); 1614 forwardEnums.erase( fwds.first, fwds.second ); 1615 } 1616 1617 // ensure that enumerator initializers are properly set 1618 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1619 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1620 if ( field->init ) { 1621 // need to resolve enumerator initializers early so that other passes that 1622 // determine if an expression is constexpr have appropriate information 1623 auto init = field->init.strict_as< ast::SingleInit >(); 1624 1625 enumDecl = ast::mutate_field_index( 1626 enumDecl, &ast::EnumDecl::members, i, 1627 ast::mutate_field( field, &ast::ObjectDecl::init, 1628 ast::mutate_field( init, &ast::SingleInit::value, 1629 ResolvExpr::findSingleExpression( 1630 init->value, new ast::BasicType{ ast::BasicType::SignedInt }, 1631 symtab ) ) ) ); 1632 } 1633 } 1634 1635 return enumDecl; 1636 } 1637 1638 /// rename generic type parameters uniquely so that they do not conflict with user defined 1639 /// function forall parameters, e.g. the T in Box and the T in f, below 1640 /// forall(otype T) 1641 /// struct Box { 1642 /// T x; 1643 /// }; 1644 /// forall(otype T) 1645 /// void f(Box(T) b) { 1646 /// ... 1647 /// } 1648 template< typename AggrDecl > 1649 const AggrDecl * renameGenericParams( const AggrDecl * aggr ) { 1650 GuardValue( inGeneric ); 1651 inGeneric = ! aggr->params.empty(); 1652 1653 for ( unsigned i = 0; i < aggr->params.size(); ++i ) { 1654 const ast::TypeDecl * td = aggr->params[i]; 1655 1656 aggr = ast::mutate_field_index( 1657 aggr, &AggrDecl::params, i, 1658 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) ); 1659 } 1660 return aggr; 1661 } 1662 1663 const ast::StructDecl * previsit( const ast::StructDecl * structDecl ) { 1664 return renameGenericParams( structDecl ); 1665 } 1666 1667 void postvisit( const ast::StructDecl * structDecl ) { 1668 // visit struct members first so that the types of self-referencing members are 1669 // updated properly 1670 if ( ! structDecl->body ) return; 1671 1672 // update forward declarations to point here 1673 auto fwds = forwardStructs.equal_range( structDecl->name ); 1674 if ( fwds.first != fwds.second ) { 1675 auto inst = fwds.first; 1676 do { 1677 // forward decl is stored * mutably * in map, can thus be updated 1678 inst->second->base = structDecl; 1679 } while ( ++inst != fwds.second ); 1680 forwardStructs.erase( fwds.first, fwds.second ); 1681 } 1682 } 1683 1684 const ast::UnionDecl * previsit( const ast::UnionDecl * unionDecl ) { 1685 return renameGenericParams( unionDecl ); 1686 } 1687 1688 void postvisit( const ast::UnionDecl * unionDecl ) { 1689 // visit union members first so that the types of self-referencing members are updated 1690 // properly 1691 if ( ! unionDecl->body ) return; 1692 1693 // update forward declarations to point here 1694 auto fwds = forwardUnions.equal_range( unionDecl->name ); 1695 if ( fwds.first != fwds.second ) { 1696 auto inst = fwds.first; 1697 do { 1698 // forward decl is stored * mutably * in map, can thus be updated 1699 inst->second->base = unionDecl; 1700 } while ( ++inst != fwds.second ); 1701 forwardUnions.erase( fwds.first, fwds.second ); 1702 } 1703 } 1704 1705 const ast::Decl * postvisit( const ast::TraitDecl * traitDecl ) { 1706 // set the "sized" status for the special "sized" trait 1707 if ( traitDecl->name == "sized" ) { 1708 assertf( traitDecl->params.size() == 1, "Built-in trait 'sized' has incorrect " 1709 "number of parameters: %zd", traitDecl->params.size() ); 1710 1711 traitDecl = ast::mutate_field_index( 1712 traitDecl, &ast::TraitDecl::params, 0, 1713 ast::mutate_field( 1714 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) ); 1715 } 1716 1717 // move assertions from type parameters into the body of the trait 1718 std::vector< ast::ptr< ast::DeclWithType > > added; 1719 for ( const ast::TypeDecl * td : traitDecl->params ) { 1720 for ( const ast::DeclWithType * assn : td->assertions ) { 1721 auto inst = dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1722 if ( inst ) { 1723 expandAssertions( inst, added ); 1724 } else { 1725 added.emplace_back( assn ); 1726 } 1727 } 1728 } 1729 if ( ! added.empty() ) { 1730 auto mut = mutate( traitDecl ); 1731 for ( const ast::DeclWithType * decl : added ) { 1732 mut->members.emplace_back( decl ); 1733 } 1734 traitDecl = mut; 1735 } 1736 1737 return traitDecl; 1738 } 1739 }; 1740 1741 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1742 /// each object and function declaration a unique ID 1743 class ForallPointerDecay_new { 1744 const CodeLocation & location; 1745 public: 1746 ForallPointerDecay_new( const CodeLocation & loc ) : location( loc ) {} 1747 1748 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) { 1749 // ensure that operator names only apply to functions or function pointers 1750 if ( 1751 CodeGen::isOperator( obj->name ) 1752 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() ) 1753 ) { 1754 SemanticError( obj->location, toCString( "operator ", obj->name.c_str(), " is not " 1755 "a function or function pointer." ) ); 1756 } 1757 1758 // ensure object has unique ID 1759 if ( obj->uniqueId ) return obj; 1760 auto mut = mutate( obj ); 1761 mut->fixUniqueId(); 1762 return mut; 1763 } 1764 1765 const ast::FunctionDecl * previsit( const ast::FunctionDecl * func ) { 1766 // ensure function has unique ID 1767 if ( func->uniqueId ) return func; 1768 auto mut = mutate( func ); 1769 mut->fixUniqueId(); 1770 return mut; 1771 } 1772 1773 /// Fix up assertions -- flattens assertion lists, removing all trait instances 1774 template< typename node_t, typename parent_t > 1775 static const node_t * forallFixer( 1776 const CodeLocation & loc, const node_t * node, 1777 ast::ParameterizedType::ForallList parent_t::* forallField 1778 ) { 1779 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) { 1780 const ast::TypeDecl * type = (node->* forallField)[i]; 1781 if ( type->assertions.empty() ) continue; 1782 1783 std::vector< ast::ptr< ast::DeclWithType > > asserts; 1784 asserts.reserve( type->assertions.size() ); 1785 1786 // expand trait instances into their members 1787 for ( const ast::DeclWithType * assn : type->assertions ) { 1788 auto traitInst = 1789 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1790 if ( traitInst ) { 1791 // expand trait instance to all its members 1792 expandAssertions( traitInst, asserts ); 1793 } else { 1794 // pass other assertions through 1795 asserts.emplace_back( assn ); 1796 } 1797 } 1798 1799 // apply FixFunction to every assertion to check for invalid void type 1800 for ( ast::ptr< ast::DeclWithType > & assn : asserts ) { 1801 bool isVoid = false; 1802 assn = fixFunction( assn, isVoid ); 1803 if ( isVoid ) { 1804 SemanticError( loc, node, "invalid type void in assertion of function " ); 1805 } 1806 } 1807 1808 // place mutated assertion list in node 1809 auto mut = mutate( type ); 1810 mut->assertions = move( asserts ); 1811 node = ast::mutate_field_index( node, forallField, i, mut ); 1812 } 1813 return node; 1814 } 1815 1816 const ast::FunctionType * previsit( const ast::FunctionType * ftype ) { 1817 return forallFixer( location, ftype, &ast::FunctionType::forall ); 1818 } 1819 1820 const ast::StructDecl * previsit( const ast::StructDecl * aggrDecl ) { 1821 return forallFixer( aggrDecl->location, aggrDecl, &ast::StructDecl::params ); 1822 } 1823 1824 const ast::UnionDecl * previsit( const ast::UnionDecl * aggrDecl ) { 1825 return forallFixer( aggrDecl->location, aggrDecl, &ast::UnionDecl::params ); 1826 } 1827 }; 1828 } // anonymous namespace 1829 1830 const ast::Type * validateType( 1831 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1832 ast::Pass< EnumAndPointerDecay_new > epc; 1833 ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab }; 1834 ast::Pass< ForallPointerDecay_new > fpd{ loc }; 1835 1836 return type->accept( epc )->accept( lrt )->accept( fpd ); 1837 } 1838 1074 1839 } // namespace SymTab 1075 1840 -
src/SymTab/Validate.h
r7951100 rb067d9b 19 19 #include <list> // for list 20 20 21 class Declaration; 22 class Type; 21 struct CodeLocation; 22 class Declaration; 23 class Type; 24 25 namespace ast { 26 class Type; 27 class SymbolTable; 28 } 23 29 24 30 namespace SymTab { … … 28 34 void validate( std::list< Declaration * > &translationUnit, bool doDebug = false ); 29 35 void validateType( Type *type, const Indexer *indexer ); 36 37 const ast::Type * validateType( 38 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ); 30 39 } // namespace SymTab 31 40 -
src/SymTab/module.mk
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 SRC += SymTab/Indexer.cc \ 18 SymTab/Mangler.cc \ 19 SymTab/Validate.cc \ 20 SymTab/FixFunction.cc \ 21 SymTab/Autogen.cc 17 SRC_SYMTAB = \ 18 SymTab/Autogen.cc \ 19 SymTab/FixFunction.cc \ 20 SymTab/Indexer.cc \ 21 SymTab/Mangler.cc \ 22 SymTab/ManglerCommon.cc \ 23 SymTab/Validate.cc 24 25 SRC += $(SRC_SYMTAB) 26 SRCDEMANGLE += $(SRC_SYMTAB) SymTab/Demangle.cc -
src/SynTree/AddressExpr.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 23:54:44 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : T ue Apr 26 12:35:13 201613 // Update Count : 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 28 13:13:38 2019 13 // Update Count : 10 14 14 // 15 15 … … 42 42 AddressExpr::AddressExpr( Expression *arg ) : Expression(), arg( arg ) { 43 43 if ( arg->result ) { 44 if ( arg-> result->get_lvalue() ) {44 if ( arg->get_lvalue() ) { 45 45 // lvalue, retains all layers of reference and gains a pointer inside the references 46 46 set_result( addrType( arg->result ) ); 47 47 } else { 48 48 // taking address of non-lvalue -- must be a reference, loses one layer of reference 49 ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( arg->result ); 50 set_result( addrType( refType->base ) ); 49 if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( arg->result ) ) { 50 set_result( addrType( refType->base ) ); 51 } else { 52 SemanticError( arg->result, "Attempt to take address of non-lvalue expression: " ); 53 } // if 51 54 } 52 // result of & is never an lvalue53 get_result()->set_lvalue( false );54 55 } 55 56 } -
src/SynTree/AggregateDecl.cc
r7951100 rb067d9b 86 86 std::string TraitDecl::typeString() const { return "trait"; } 87 87 88 namespace {89 long long int getConstValue( Expression * expr ) {90 if ( CastExpr * castExpr = dynamic_cast< CastExpr * > ( expr ) ) {91 return getConstValue( castExpr->arg );92 } else if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {93 return constExpr->intValue();94 // can be -1, +1, etc.95 // } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( expr ) ) {96 // if ( untypedExpr-> )97 } else {98 assertf( false, "Unhandled expression type in getConstValue for enumerators: %s", toString( expr ).c_str() );99 }100 }101 }102 103 88 bool EnumDecl::valueOf( Declaration * enumerator, long long int & value ) { 104 89 if ( enumValues.empty() ) { … … 108 93 if ( field->init ) { 109 94 SingleInit * init = strict_dynamic_cast< SingleInit * >( field->init ); 110 currentValue = getConstValue( init->value ); 95 auto result = eval( init->value ); 96 if ( ! result.second ) SemanticError( init->location, toString( "Non-constexpr in initialization of enumerator: ", field ) ); 97 currentValue = result.first; 111 98 } 112 99 assertf( enumValues.count( field->name ) == 0, "Enum %s has multiple members with the name %s", name.c_str(), field->name.c_str() ); -
src/SynTree/ApplicationExpr.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Tue Apr 26 12:41:06 201613 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Aug 12 14:28:00 2019 13 // Update Count : 5 14 14 // 15 15 … … 25 25 #include "Declaration.h" // for Declaration 26 26 #include "Expression.h" // for ParamEntry, ApplicationExpr, Expression 27 #include "InitTweak/InitTweak.h" // for getFunction 27 28 #include "ResolvExpr/typeops.h" // for extractResultType 28 29 #include "Type.h" // for Type, PointerType, FunctionType 29 30 31 ParamEntry::ParamEntry( UniqueId decl, Declaration * declptr, Type * actualType, Type * formalType, Expression* expr ) 32 : decl( decl ), declptr( declptr ), actualType( actualType ), formalType( formalType ), expr( expr ) { 33 } 34 30 35 ParamEntry::ParamEntry( const ParamEntry &other ) : 31 decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ), inferParams( new InferredParams( *other.inferParams ) ) { 32 } 33 34 ParamEntry &ParamEntry::operator=( const ParamEntry &other ) { 35 if ( &other == this ) return *this; 36 decl = other.decl; 37 // xxx - this looks like a memory leak 38 actualType = maybeClone( other.actualType ); 39 formalType = maybeClone( other.formalType ); 40 expr = maybeClone( other.expr ); 41 *inferParams = *other.inferParams; 42 return *this; 36 decl( other.decl ), declptr( maybeClone( other.declptr ) ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) { 43 37 } 44 38 45 39 ParamEntry::~ParamEntry() { 40 delete declptr; 46 41 delete actualType; 47 42 delete formalType; … … 50 45 51 46 ParamEntry::ParamEntry( ParamEntry && other ) : 52 decl( other.decl ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr ), inferParams( std::move( other.inferParams ) ) { 53 other.actualType = nullptr; 54 other.formalType = nullptr; 55 other.expr = nullptr; 47 decl( other.decl ), declptr( other.declptr ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr ) { 48 new (&other) ParamEntry(); 56 49 } 57 50 58 51 ParamEntry & ParamEntry::operator=( ParamEntry && other ) { 59 52 if ( &other == this ) return *this; 60 delete actualType; 61 delete formalType; 62 delete expr; 63 decl = other.decl; 64 actualType = other.actualType; 65 formalType = other.formalType; 66 expr = other.expr; 67 other.actualType = nullptr; 68 other.formalType = nullptr; 69 other.expr = nullptr; 70 inferParams = std::move( other.inferParams ); 53 this->~ParamEntry(); 54 new (this) ParamEntry(other.decl, other.declptr, other.actualType, other.formalType, other.expr); 55 new (&other) ParamEntry(); 56 71 57 return *this; 72 58 } … … 91 77 } 92 78 79 bool ApplicationExpr::get_lvalue() const { 80 // from src/GenPoly/Lvalue.cc: isIntrinsicReference 81 static std::set<std::string> lvalueFunctions = { "*?", "?[?]" }; 82 if ( const DeclarationWithType * func = InitTweak::getFunction( this ) ) { 83 return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name); 84 } 85 return false; 86 } 87 93 88 void ApplicationExpr::print( std::ostream &os, Indenter indent ) const { 94 89 os << "Application of" << std::endl << indent+1; -
src/SynTree/ArrayType.cc
r7951100 rb067d9b 26 26 ArrayType::ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes ) 27 27 : Type( tq, attributes ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic ) { 28 base->set_lvalue( false );29 28 } 30 29 -
src/SynTree/Attribute.cc
r7951100 rb067d9b 21 21 #include "Expression.h" // for Expression 22 22 23 Attribute::Attribute( const Attribute &other ) : name( other.name ) {23 Attribute::Attribute( const Attribute &other ) : BaseSyntaxNode( other ), name( other.name ) { 24 24 cloneAll( other.parameters, parameters ); 25 25 } -
src/SynTree/Attribute.h
r7951100 rb067d9b 50 50 Attribute * clone() const override { return new Attribute( *this ); } 51 51 virtual void accept( Visitor & v ) override { v.visit( this ); } 52 virtual void accept( Visitor & v ) const override { v.visit( this ); } 52 53 virtual Attribute * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 53 54 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/BaseSyntaxNode.h
r7951100 rb067d9b 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Feb 14 07:44:20 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Aug 17 13:44:0013 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 10 16:13:49 2019 13 // Update Count : 4 14 14 // 15 15 … … 18 18 #include "Common/CodeLocation.h" 19 19 #include "Common/Indenter.h" 20 #include "Common/Stats.h" 21 20 22 class Visitor; 21 23 class Mutator; … … 23 25 class BaseSyntaxNode { 24 26 public: 27 static Stats::Counters::SimpleCounter* new_nodes; 28 25 29 CodeLocation location; 30 31 BaseSyntaxNode() { ++*new_nodes; } 32 BaseSyntaxNode( const BaseSyntaxNode & o ) : location(o.location) { ++*new_nodes; } 33 BaseSyntaxNode & operator=( const BaseSyntaxNode & ) = default; 26 34 27 35 virtual ~BaseSyntaxNode() {} … … 29 37 virtual BaseSyntaxNode * clone() const = 0; 30 38 virtual void accept( Visitor & v ) = 0; 39 virtual void accept( Visitor & v ) const = 0; 31 40 virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 0; 32 /// Notes:33 /// * each node is responsible for indenting its children.34 /// * Expressions should not finish with a newline, since the expression's parent has better information.41 /// Notes: 42 /// * each node is responsible for indenting its children. 43 /// * Expressions should not finish with a newline, since the expression's parent has better information. 35 44 virtual void print( std::ostream & os, Indenter indent = {} ) const = 0; 36 void print( std::ostream & os, unsigned int indent ) {37 print( os, Indenter{ Indenter::tabsize, indent });38 }39 45 }; 40 46 -
src/SynTree/BasicType.cc
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 14:14:03 201713 // Update Count : 1 112 // Last Modified On : Sun Aug 4 21:07:44 2019 13 // Update Count : 13 14 14 // 15 15 … … 30 30 31 31 bool BasicType::isInteger() const { 32 switch ( kind ) { 33 case Bool: 34 case Char: 35 case SignedChar: 36 case UnsignedChar: 37 case ShortSignedInt: 38 case ShortUnsignedInt: 39 case SignedInt: 40 case UnsignedInt: 41 case LongSignedInt: 42 case LongUnsignedInt: 43 case LongLongSignedInt: 44 case LongLongUnsignedInt: 45 case SignedInt128: 46 case UnsignedInt128: 47 return true; 48 case Float: 49 case Double: 50 case LongDouble: 51 case FloatComplex: 52 case DoubleComplex: 53 case LongDoubleComplex: 54 case FloatImaginary: 55 case DoubleImaginary: 56 case LongDoubleImaginary: 57 case Float80: 58 case Float128: 59 return false; 60 case NUMBER_OF_BASIC_TYPES: 61 assert( false ); 62 } // switch 63 assert( false ); 64 return false; 32 return kind <= UnsignedInt128; 65 33 } 66 34 -
src/SynTree/CommaExpr.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Mon May 02 15:19:44201613 // Update Count : 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Arg 12 16:11:00 2016 13 // Update Count : 2 14 14 // 15 15 … … 23 23 CommaExpr::CommaExpr( Expression *arg1, Expression *arg2 ) 24 24 : Expression(), arg1( arg1 ), arg2( arg2 ) { 25 // xxx - result of a comma expression is never an lvalue, so should set lvalue26 // to false on all result types. Actually doing this causes some strange things27 // to happen in later passes (particularly, Specialize, Lvalue, and Box). This needs to be looked into.28 25 set_result( maybeClone( arg2->get_result() ) ); 29 // get_type->set_isLvalue( false );30 26 } 31 27 … … 37 33 delete arg1; 38 34 delete arg2; 35 } 36 37 bool CommaExpr::get_lvalue() const { 38 // This is wrong by C, but the current implementation uses it. 39 // (ex: Specialize, Lvalue and Box) 40 return arg2->get_lvalue(); 39 41 } 40 42 -
src/SynTree/Constant.cc
r7951100 rb067d9b 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 Jul 14 14:50:00 201713 // Update Count : 2911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 13 18:11:22 2019 13 // Update Count : 32 14 14 // 15 15 … … 19 19 20 20 #include "Constant.h" 21 #include "Expression.h" // for ConstantExpr 21 22 #include "Type.h" // for BasicType, Type, Type::Qualifiers, PointerType 22 23 23 Constant::Constant( Type * type, std::string rep, unsigned long long val ) : type( type ), rep( rep ), val( val ) {} 24 Constant::Constant( Type * type, std::string rep, double val ) : type( type ), rep( rep ), val( val ) {} 24 Constant::Constant( Type * type, std::string rep, std::optional<unsigned long long> ival ) : type( type ), rep( rep ), ival( ival ) {} 25 25 26 Constant::Constant( const Constant &other ) : rep( other.rep ), val( other.val ) {26 Constant::Constant( const Constant &other ) : BaseSyntaxNode( other ), rep( other.rep ), ival( other.ival ) { 27 27 type = other.type->clone(); 28 28 } … … 34 34 } 35 35 36 Constant Constant::from_char( char c ) {37 return Constant( new BasicType( Type::Qualifiers(), BasicType::Char ), std::to_string( c ), (unsigned long long int)c );38 }39 40 36 Constant Constant::from_int( int i ) { 41 37 return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ), (unsigned long long int)i ); … … 44 40 Constant Constant::from_ulong( unsigned long i ) { 45 41 return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ), (unsigned long long int)i ); 46 }47 48 Constant Constant::from_double( double d ) {49 return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ), d );50 42 } 51 43 … … 63 55 unsigned long long Constant::get_ival() const { 64 56 assertf( strict_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve ival from non-integer constant." ); 65 return val.ival; 66 } 67 68 double Constant::get_dval() const { 69 assertf( ! strict_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve dval from integer constant." ); 70 return val.dval; 57 return ival.value(); 71 58 } 72 59 73 60 void Constant::print( std::ostream &os, Indenter ) const { 74 os << "(" << rep << " " << val.ival;61 os << "(" << rep << " " << (ival ? toString(ival.value()) : "") ; 75 62 if ( type ) { 76 63 os << ": "; -
src/SynTree/Constant.h
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:54:46 201713 // Update Count : 1 712 // Last Modified On : Wed Jul 10 15:57:38 2019 13 // Update Count : 19 14 14 // 15 15 … … 18 18 #include <iosfwd> // for ostream 19 19 #include <string> // for string 20 #include <optional> // for optional 20 21 21 22 #include "BaseSyntaxNode.h" … … 27 28 class Constant : public BaseSyntaxNode { 28 29 public: 29 Constant( Type * type, std::string rep, unsigned long long val ); 30 Constant( Type * type, std::string rep, double val ); 30 Constant( Type * type, std::string rep, std::optional<unsigned long long> i ); 31 31 Constant( const Constant & other ); 32 Constant & operator=( const Constant & ) = default; 32 33 virtual ~Constant(); 33 34 34 virtual Constant * clone() const { return new Constant( *this ); }35 virtual Constant * clone() const override { return new Constant( *this ); } 35 36 36 37 Type * get_type() { return type; } … … 39 40 void set_value( std::string newValue ) { rep = newValue; } 40 41 unsigned long long get_ival() const; 41 double get_dval() const;42 42 43 43 /// generates a boolean constant of the given bool 44 44 static Constant from_bool( bool b ); 45 /// generates a char constant of the given char46 static Constant from_char( char c );47 45 /// generates an integer constant of the given int 48 46 static Constant from_int( int i ); 49 47 /// generates an integer constant of the given unsigned long int 50 48 static Constant from_ulong( unsigned long i ); 51 /// generates a floating point constant of the given double52 static Constant from_double( double d );53 49 54 50 /// generates a null pointer value for the given type. void * if omitted. 55 51 static Constant null( Type * ptrtype = nullptr ); 56 52 57 virtual void accept( Visitor & v ) { v.visit( this ); } 58 virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); } 59 virtual void print( std::ostream & os, Indenter indent = 0 ) const; 60 private: 53 virtual void accept( Visitor & v ) override { v.visit( this ); } 54 virtual void accept( Visitor & v ) const override { v.visit( this ); } 55 virtual Constant * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 56 virtual void print( std::ostream & os, Indenter indent = 0 ) const override; 57 61 58 Type * type; 62 59 std::string rep; 63 union Val { 64 unsigned long long ival; 65 double dval; 66 Val( unsigned long long ival ) : ival( ival ) {} 67 Val( double dval ) : dval( dval ) {} 68 } val; 60 std::optional<unsigned long long> ival; 69 61 }; 70 62 -
src/SynTree/DeclReplacer.cc
r7951100 rb067d9b 30 30 bool debug; 31 31 public: 32 size_t replaced; 33 34 public: 32 35 DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 33 36 … … 38 41 void previsit( TypeInstType * inst ); 39 42 }; 43 44 /// Mutator that replaces uses of declarations with arbitrary expressions, according to the supplied mapping 45 struct ExprDeclReplacer { 46 private: 47 const ExprMap & exprMap; 48 bool debug; 49 public: 50 size_t replaced; 51 52 public: 53 ExprDeclReplacer( const ExprMap & exprMap, bool debug = false ); 54 55 // replace variable with new node from expr map 56 Expression * postmutate( VariableExpr * varExpr ); 57 }; 40 58 } 41 59 42 voidreplace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) {60 size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) { 43 61 PassVisitor<DeclReplacer> replacer( declMap, typeMap, debug ); 44 62 maybeAccept( node, replacer ); 63 return replacer.pass.replaced; 45 64 } 46 65 47 voidreplace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) {66 size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) { 48 67 TypeMap typeMap; 49 re place( node, declMap, typeMap, debug );68 return replace( node, declMap, typeMap, debug ); 50 69 } 51 70 52 voidreplace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) {71 size_t replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) { 53 72 DeclMap declMap; 54 replace( node, declMap, typeMap, debug ); 73 return replace( node, declMap, typeMap, debug ); 74 } 75 76 size_t replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug ) { 77 PassVisitor<ExprDeclReplacer> replacer( exprMap, debug ); 78 node = maybeMutate( node, replacer ); 79 return replacer.pass.replaced; 55 80 } 56 81 57 82 namespace { 58 DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ) {}83 DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ), replaced( 0 ) {} 59 84 60 85 // replace variable with new node from decl map … … 62 87 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 63 88 if ( declMap.count( varExpr->var ) ) { 89 replaced++; 64 90 auto replacement = declMap.at( varExpr->var ); 65 91 if ( debug ) { … … 72 98 void DeclReplacer::previsit( TypeInstType * inst ) { 73 99 if ( typeMap.count( inst->baseType ) ) { 100 replaced++; 74 101 auto replacement = typeMap.at( inst->baseType ); 75 102 if ( debug ) { … … 79 106 } 80 107 } 108 109 ExprDeclReplacer::ExprDeclReplacer( const ExprMap & exprMap, bool debug ) : exprMap( exprMap ), debug( debug ), replaced( 0 ) {} 110 111 Expression * ExprDeclReplacer::postmutate( VariableExpr * varExpr ) { 112 if ( exprMap.count( varExpr->var ) ) { 113 replaced++; 114 Expression * replacement = exprMap.at( varExpr->var )->clone(); 115 if ( debug ) { 116 std::cerr << "replacing variable reference: " << (void*)varExpr->var << " " << varExpr->var << " with " << (void*)replacement << " " << replacement << std::endl; 117 } 118 std::swap( varExpr->env, replacement->env ); 119 delete varExpr; 120 return replacement; 121 } 122 return varExpr; 123 } 81 124 } 82 125 } // namespace VarExprReplacer -
src/SynTree/DeclReplacer.h
r7951100 rb067d9b 26 26 typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap; 27 27 typedef std::map< TypeDecl *, TypeDecl * > TypeMap; 28 typedef std::map< DeclarationWithType *, Expression * > ExprMap; 28 29 29 void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false ); 30 void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false ); 31 void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 30 size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false ); 31 size_t replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false ); 32 size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 33 34 size_t replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug = false); 35 36 template<typename T> 37 size_t replace( T *& node, const ExprMap & exprMap, bool debug = false ) { 38 if ( ! node ) return 0ul; 39 BaseSyntaxNode * arg = node; 40 size_t replaced = replace( arg, exprMap, debug ); 41 node = dynamic_cast<T *>( arg ); 42 assertf( node, "DeclReplacer fundamentally changed the type of its argument." ); 43 return replaced; 44 } 32 45 } 33 46 -
src/SynTree/Declaration.cc
r7951100 rb067d9b 27 27 28 28 static UniqueId lastUniqueId = 0; 29 typedef std::map< UniqueId, Declaration* > IdMapType;30 static IdMapType idMap;31 29 32 30 Declaration::Declaration( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) 33 : name( name ), linkage( linkage ), storageClasses( scs ), uniqueId( 0) {31 : name( name ), linkage( linkage ), uniqueId( 0 ), storageClasses( scs ) { 34 32 } 35 33 36 34 Declaration::Declaration( const Declaration &other ) 37 : BaseSyntaxNode( other ), name( other.name ), linkage( other.linkage ), extension( other.extension ), storageClasses( other.storageClasses ), uniqueId( other.uniqueId) {35 : BaseSyntaxNode( other ), name( other.name ), linkage( other.linkage ), extension( other.extension ), uniqueId( other.uniqueId ), storageClasses( other.storageClasses ) { 38 36 } 39 37 … … 45 43 if ( uniqueId ) return; 46 44 uniqueId = ++lastUniqueId; 47 idMap[ uniqueId ] = this;48 45 } 49 50 Declaration *Declaration::declFromId( UniqueId id ) {51 IdMapType::const_iterator i = idMap.find( id );52 return i != idMap.end() ? i->second : 0;53 }54 55 void Declaration::dumpIds( std::ostream &os ) {56 for ( IdMapType::const_iterator i = idMap.begin(); i != idMap.end(); ++i ) {57 os << i->first << " -> ";58 i->second->printShort( os );59 os << std::endl;60 } // for61 }62 63 46 64 47 AsmDecl::AsmDecl( AsmStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) { -
src/SynTree/Declaration.h
r7951100 rb067d9b 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 Sep 3 19:24:06 201713 // Update Count : 13 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr May 2 10:47:00 2019 13 // Update Count : 135 14 14 // 15 15 … … 19 19 #include <iosfwd> // for ostream 20 20 #include <list> // for list 21 #include <unordered_map> // for unordered_map 21 22 #include <string> // for string, operator+, allocator, to_string 22 23 … … 62 63 void fixUniqueId( void ); 63 64 virtual Declaration *clone() const override = 0; 64 virtual void accept( Visitor &v ) override = 0; 65 virtual void accept( Visitor & v ) override = 0; 66 virtual void accept( Visitor & v ) const override = 0; 65 67 virtual Declaration *acceptMutator( Mutator &m ) override = 0; 66 68 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; 67 69 virtual void printShort( std::ostream &os, Indenter indent = {} ) const = 0; 68 70 69 static void dumpIds( std::ostream &os ); 70 static Declaration *declFromId( UniqueId id ); 71 72 private: 71 UniqueId uniqueId; 73 72 Type::StorageClasses storageClasses; 74 UniqueId uniqueId; 73 private: 75 74 }; 76 75 … … 141 140 142 141 virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); } 143 virtual void accept( Visitor &v ) override { v.visit( this ); } 142 virtual void accept( Visitor & v ) override { v.visit( this ); } 143 virtual void accept( Visitor & v ) const override { v.visit( this ); } 144 144 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 145 145 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 166 166 CompoundStmt *get_statements() const { return statements; } 167 167 void set_statements( CompoundStmt *newValue ) { statements = newValue; } 168 bool has_body() const { return NULL != statements; } 168 169 169 170 static FunctionDecl * newFunction( const std::string & name, FunctionType * type, CompoundStmt * statements ); 170 171 171 172 virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); } 172 virtual void accept( Visitor &v ) override { v.visit( this ); } 173 virtual void accept( Visitor & v ) override { v.visit( this ); } 174 virtual void accept( Visitor & v ) const override { v.visit( this ); } 173 175 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 174 176 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 202 204 typedef NamedTypeDecl Parent; 203 205 public: 204 enum Kind { Dtype, Ftype, Ttype };206 enum Kind { Dtype, Ftype, Ttype, NUMBER_OF_KINDS }; 205 207 206 208 Type * init; … … 211 213 TypeDecl::Kind kind; 212 214 bool isComplete; 215 213 216 Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {} 214 217 Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {} 215 218 Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {} 219 Data( const Data& d1, const Data& d2 ) 220 : kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {} 221 216 222 bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; } 217 223 bool operator!=(const Data & other) const { return !(*this == other);} … … 235 241 236 242 virtual TypeDecl *clone() const override { return new TypeDecl( *this ); } 237 virtual void accept( Visitor & v ) override { v.visit( this ); }238 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); }239 virtual void print( std::ostream &os, Indenter indent = {} ) const override;240 241 private: 243 virtual void accept( Visitor & v ) override { v.visit( this ); } 244 virtual void accept( Visitor & v ) const override { v.visit( this ); } 245 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 246 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 247 242 248 Kind kind; 243 249 }; … … 254 260 255 261 virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); } 256 virtual void accept( Visitor &v ) override { v.visit( this ); } 262 virtual void accept( Visitor & v ) override { v.visit( this ); } 263 virtual void accept( Visitor & v ) const override { v.visit( this ); } 257 264 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 258 265 private: … … 266 273 bool body; 267 274 std::list< Attribute * > attributes; 275 AggregateDecl * parent = nullptr; 268 276 269 277 AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ); … … 280 288 AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; } 281 289 282 virtual void print( std::ostream &os, Indenter indent = {} ) const override ;290 virtual void print( std::ostream &os, Indenter indent = {} ) const override final; 283 291 virtual void printShort( std::ostream &os, Indenter indent = {} ) const override; 284 292 protected: … … 297 305 298 306 virtual StructDecl *clone() const override { return new StructDecl( *this ); } 299 virtual void accept( Visitor & v ) override { v.visit( this ); }300 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); }301 private: 307 virtual void accept( Visitor & v ) override { v.visit( this ); } 308 virtual void accept( Visitor & v ) const override { v.visit( this ); } 309 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 302 310 DeclarationNode::Aggregate kind; 311 private: 303 312 virtual std::string typeString() const override; 304 313 }; … … 311 320 312 321 virtual UnionDecl *clone() const override { return new UnionDecl( *this ); } 313 virtual void accept( Visitor &v ) override { v.visit( this ); } 322 virtual void accept( Visitor & v ) override { v.visit( this ); } 323 virtual void accept( Visitor & v ) const override { v.visit( this ); } 314 324 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 315 325 private: … … 326 336 327 337 virtual EnumDecl *clone() const override { return new EnumDecl( *this ); } 328 virtual void accept( Visitor &v ) override { v.visit( this ); } 329 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 330 private: 331 std::map< std::string, long long int > enumValues; 338 virtual void accept( Visitor & v ) override { v.visit( this ); } 339 virtual void accept( Visitor & v ) const override { v.visit( this ); } 340 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 341 private: 342 std::unordered_map< std::string, long long int > enumValues; 332 343 virtual std::string typeString() const override; 333 344 }; … … 342 353 343 354 virtual TraitDecl *clone() const override { return new TraitDecl( *this ); } 344 virtual void accept( Visitor &v ) override { v.visit( this ); } 345 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 346 private: 347 virtual std::string typeString() const override; 355 virtual void accept( Visitor & v ) override { v.visit( this ); } 356 virtual void accept( Visitor & v ) const override { v.visit( this ); } 357 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 358 private: 359 virtual std::string typeString() const override; 360 }; 361 362 class WithStmt : public Declaration { 363 public: 364 std::list< Expression * > exprs; 365 Statement * stmt; 366 367 WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 368 WithStmt( const WithStmt & other ); 369 virtual ~WithStmt(); 370 371 virtual WithStmt * clone() const override { return new WithStmt( *this ); } 372 virtual void accept( Visitor & v ) override { v.visit( this ); } 373 virtual void accept( Visitor & v ) const override { v.visit( this ); } 374 virtual Declaration * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 375 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 376 virtual void printShort( std::ostream & os, Indenter indent = {} ) const override { print(os, indent); } 348 377 }; 349 378 … … 360 389 361 390 virtual AsmDecl *clone() const override { return new AsmDecl( *this ); } 362 virtual void accept( Visitor &v ) override { v.visit( this ); } 391 virtual void accept( Visitor & v ) override { v.visit( this ); } 392 virtual void accept( Visitor & v ) const override { v.visit( this ); } 363 393 virtual AsmDecl *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 364 394 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 376 406 377 407 virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); } 378 virtual void accept( Visitor &v ) override { v.visit( this ); } 408 virtual void accept( Visitor & v ) override { v.visit( this ); } 409 virtual void accept( Visitor & v ) const override { v.visit( this ); } 379 410 virtual StaticAssertDecl * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 380 411 virtual void print( std::ostream &os, Indenter indent = {} ) const override; -
src/SynTree/Expression.cc
r7951100 rb067d9b 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 : T ue Jul 25 14:15:47 201713 // Update Count : 5411 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 15 13:43:00 2019 13 // Update Count : 64 14 14 // 15 15 … … 19 19 #include <iostream> // for ostream, operator<<, basic_ostream 20 20 #include <list> // for list, _List_iterator, list<>::co... 21 #include <set> // for set 21 22 22 23 #include "Common/utility.h" // for maybeClone, cloneAll, deleteAll … … 33 34 #include "GenPoly/Lvalue.h" 34 35 35 void printInferParams( const InferredParams & inferParams, std::ostream & os, Indenter indent, int level ) {36 void printInferParams( const InferredParams & inferParams, std::ostream & os, Indenter indent, int level ) { 36 37 if ( ! inferParams.empty() ) { 37 38 os << indent << "with inferred parameters " << level << ":" << std::endl; 38 39 for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) { 39 40 os << indent+1; 40 Declaration::declFromId( i->second.decl )->printShort( os, indent+1 ); 41 assert(i->second.declptr); 42 i->second.declptr->printShort( os, indent+1 ); 41 43 os << std::endl; 42 printInferParams( *i->second.inferParams, os, indent+1, level+1 );44 printInferParams( i->second.expr->inferParams, os, indent+1, level+1 ); 43 45 } // for 44 46 } // if … … 47 49 Expression::Expression() : result( 0 ), env( 0 ) {} 48 50 49 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ) { 50 } 51 Expression::Expression( const Expression & other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ), resnSlots( other.resnSlots ) {} 51 52 52 53 void Expression::spliceInferParams( Expression * other ) { … … 55 56 inferParams[p.first] = std::move( p.second ); 56 57 } 58 resnSlots.insert( resnSlots.end(), other->resnSlots.begin(), other->resnSlots.end() ); 57 59 } 58 60 … … 62 64 } 63 65 64 void Expression::print( std::ostream &os, Indenter indent ) const { 66 bool Expression::get_lvalue() const { 67 return false; 68 } 69 70 void Expression::print( std::ostream & os, Indenter indent ) const { 65 71 printInferParams( inferParams, os, indent+1, 0 ); 66 72 … … 79 85 } 80 86 81 ConstantExpr::ConstantExpr( const ConstantExpr & other) : Expression( other ), constant( other.constant ) {87 ConstantExpr::ConstantExpr( const ConstantExpr & other) : Expression( other ), constant( other.constant ) { 82 88 } 83 89 84 90 ConstantExpr::~ConstantExpr() {} 85 91 86 void ConstantExpr::print( std::ostream & os, Indenter indent ) const {92 void ConstantExpr::print( std::ostream & os, Indenter indent ) const { 87 93 os << "constant expression " ; 88 94 constant.print( os ); … … 103 109 } 104 110 111 VariableExpr::VariableExpr() : Expression(), var( nullptr ) {} 112 105 113 VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) { 106 114 assert( var ); 107 115 assert( var->get_type() ); 108 116 Type * type = var->get_type()->clone(); 109 type->set_lvalue( true );110 117 111 118 // xxx - doesn't quite work yet - get different alternatives with the same cost … … 117 124 // long long int value; 118 125 // if ( decl->valueOf( var, value ) ) { 119 // type->set_lvalue( false ); 126 // type->set_lvalue( false ); // Would have to move to get_lvalue. 120 127 // } 121 128 // } … … 124 131 } 125 132 126 VariableExpr::VariableExpr( const VariableExpr & other ) : Expression( other ), var( other.var ) {133 VariableExpr::VariableExpr( const VariableExpr & other ) : Expression( other ), var( other.var ) { 127 134 } 128 135 129 136 VariableExpr::~VariableExpr() { 130 137 // don't delete the declaration, since it points somewhere else in the tree 138 } 139 140 bool VariableExpr::get_lvalue() const { 141 // It isn't always an lvalue, but it is never an rvalue. 142 return true; 131 143 } 132 144 … … 137 149 } 138 150 139 void VariableExpr::print( std::ostream & os, Indenter indent ) const {151 void VariableExpr::print( std::ostream & os, Indenter indent ) const { 140 152 os << "Variable Expression: "; 141 153 var->printShort(os, indent); … … 143 155 } 144 156 145 SizeofExpr::SizeofExpr( Expression * expr_ ) :157 SizeofExpr::SizeofExpr( Expression * expr_ ) : 146 158 Expression(), expr(expr_), type(0), isType(false) { 147 159 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 148 160 } 149 161 150 SizeofExpr::SizeofExpr( Type * type_ ) :162 SizeofExpr::SizeofExpr( Type * type_ ) : 151 163 Expression(), expr(0), type(type_), isType(true) { 152 164 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 153 165 } 154 166 155 SizeofExpr::SizeofExpr( const SizeofExpr & other ) :167 SizeofExpr::SizeofExpr( const SizeofExpr & other ) : 156 168 Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) { 157 169 } … … 162 174 } 163 175 164 void SizeofExpr::print( std::ostream & os, Indenter indent) const {176 void SizeofExpr::print( std::ostream & os, Indenter indent) const { 165 177 os << "Sizeof Expression on: "; 166 178 if (isType) type->print(os, indent+1); … … 169 181 } 170 182 171 AlignofExpr::AlignofExpr( Expression * expr_ ) :183 AlignofExpr::AlignofExpr( Expression * expr_ ) : 172 184 Expression(), expr(expr_), type(0), isType(false) { 173 185 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 174 186 } 175 187 176 AlignofExpr::AlignofExpr( Type * type_ ) :188 AlignofExpr::AlignofExpr( Type * type_ ) : 177 189 Expression(), expr(0), type(type_), isType(true) { 178 190 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 179 191 } 180 192 181 AlignofExpr::AlignofExpr( const AlignofExpr & other ) :193 AlignofExpr::AlignofExpr( const AlignofExpr & other ) : 182 194 Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) { 183 195 } … … 188 200 } 189 201 190 void AlignofExpr::print( std::ostream & os, Indenter indent) const {202 void AlignofExpr::print( std::ostream & os, Indenter indent) const { 191 203 os << "Alignof Expression on: "; 192 204 if (isType) type->print(os, indent+1); … … 195 207 } 196 208 197 UntypedOffsetofExpr::UntypedOffsetofExpr( Type * type, const std::string &member ) :209 UntypedOffsetofExpr::UntypedOffsetofExpr( Type * type, const std::string & member ) : 198 210 Expression(), type(type), member(member) { 199 211 assert( type ); … … 201 213 } 202 214 203 UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr & other ) :215 UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr & other ) : 204 216 Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {} 205 217 … … 208 220 } 209 221 210 void UntypedOffsetofExpr::print( std::ostream & os, Indenter indent) const {222 void UntypedOffsetofExpr::print( std::ostream & os, Indenter indent) const { 211 223 os << "Untyped Offsetof Expression on member " << member << " of "; 212 224 type->print(os, indent+1); … … 214 226 } 215 227 216 OffsetofExpr::OffsetofExpr( Type * type, DeclarationWithType *member ) :228 OffsetofExpr::OffsetofExpr( Type * type, DeclarationWithType * member ) : 217 229 Expression(), type(type), member(member) { 218 230 assert( member ); … … 221 233 } 222 234 223 OffsetofExpr::OffsetofExpr( const OffsetofExpr & other ) :235 OffsetofExpr::OffsetofExpr( const OffsetofExpr & other ) : 224 236 Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {} 225 237 … … 228 240 } 229 241 230 void OffsetofExpr::print( std::ostream & os, Indenter indent) const {242 void OffsetofExpr::print( std::ostream & os, Indenter indent) const { 231 243 os << "Offsetof Expression on member " << member->name << " of "; 232 244 type->print(os, indent+1); … … 234 246 } 235 247 236 OffsetPackExpr::OffsetPackExpr( StructInstType * type ) : Expression(), type( type ) {248 OffsetPackExpr::OffsetPackExpr( StructInstType * type ) : Expression(), type( type ) { 237 249 assert( type ); 238 250 set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 239 251 } 240 252 241 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr & other ) : Expression( other ), type( maybeClone( other.type ) ) {}253 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr & other ) : Expression( other ), type( maybeClone( other.type ) ) {} 242 254 243 255 OffsetPackExpr::~OffsetPackExpr() { delete type; } 244 256 245 void OffsetPackExpr::print( std::ostream & os, Indenter indent ) const {257 void OffsetPackExpr::print( std::ostream & os, Indenter indent ) const { 246 258 os << "Offset pack expression on "; 247 259 type->print(os, indent+1); … … 249 261 } 250 262 251 AttrExpr::AttrExpr( Expression *attr, Expression *expr_ ) : 252 Expression(), attr( attr ), expr(expr_), type(0), isType(false) { 253 } 254 255 AttrExpr::AttrExpr( Expression *attr, Type *type_ ) : 256 Expression(), attr( attr ), expr(0), type(type_), isType(true) { 257 } 258 259 AttrExpr::AttrExpr( const AttrExpr &other ) : 260 Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) { 261 } 262 263 AttrExpr::~AttrExpr() { 264 delete attr; 265 delete expr; 266 delete type; 267 } 268 269 void AttrExpr::print( std::ostream &os, Indenter indent) const { 270 os << "Attr "; 271 attr->print( os, indent+1); 272 if ( isType || expr ) { 273 os << "applied to: "; 274 if (isType) type->print(os, indent+1); 275 else expr->print(os, indent+1); 276 } // if 277 Expression::print( os, indent ); 278 } 279 280 CastExpr::CastExpr( Expression *arg, Type *toType, bool isGenerated ) : Expression(), arg(arg), isGenerated( isGenerated ) { 263 CastExpr::CastExpr( Expression * arg, Type * toType, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) { 281 264 set_result(toType); 282 265 } 283 266 284 CastExpr::CastExpr( Expression * arg, bool isGenerated ) : Expression(),arg(arg), isGenerated( isGenerated ) {267 CastExpr::CastExpr( Expression * arg, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) { 285 268 set_result( new VoidType( Type::Qualifiers() ) ); 286 269 } 287 270 288 CastExpr::CastExpr( const CastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), isGenerated( other.isGenerated ) {271 CastExpr::CastExpr( const CastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), isGenerated( other.isGenerated ) { 289 272 } 290 273 … … 293 276 } 294 277 295 void CastExpr::print( std::ostream &os, Indenter indent ) const { 296 os << "Cast of:" << std::endl << indent+1; 278 bool CastExpr::get_lvalue() const { 279 // This is actually wrong by C, but it works with our current set-up. 280 return arg->get_lvalue(); 281 } 282 283 void CastExpr::print( std::ostream & os, Indenter indent ) const { 284 os << (isGenerated ? "Generated " : "Explicit ") << "Cast of:" << std::endl << indent+1; 297 285 arg->print(os, indent+1); 298 286 os << std::endl << indent << "... to:"; … … 306 294 } 307 295 308 KeywordCastExpr::KeywordCastExpr( Expression * arg, Target target ) : Expression(), arg(arg), target( target ) {309 } 310 311 KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {296 KeywordCastExpr::KeywordCastExpr( Expression * arg, Target target ) : Expression(), arg(arg), target( target ) { 297 } 298 299 KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) { 312 300 } 313 301 … … 327 315 } 328 316 329 void KeywordCastExpr::print( std::ostream & os, Indenter indent ) const {317 void KeywordCastExpr::print( std::ostream & os, Indenter indent ) const { 330 318 os << "Keyword Cast of:" << std::endl << indent+1; 331 319 arg->print(os, indent+1); … … 335 323 } 336 324 337 VirtualCastExpr::VirtualCastExpr( Expression * arg_, Type *toType ) : Expression(), arg(arg_) {325 VirtualCastExpr::VirtualCastExpr( Expression * arg_, Type * toType ) : Expression(), arg(arg_) { 338 326 set_result(toType); 339 327 } 340 328 341 VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ) {329 VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ) { 342 330 } 343 331 … … 346 334 } 347 335 348 void VirtualCastExpr::print( std::ostream & os, Indenter indent ) const {336 void VirtualCastExpr::print( std::ostream & os, Indenter indent ) const { 349 337 os << "Virtual Cast of:" << std::endl << indent+1; 350 338 arg->print(os, indent+1); … … 359 347 } 360 348 361 UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression * aggregate ) :349 UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression * aggregate ) : 362 350 Expression(), member(member), aggregate(aggregate) { 363 351 assert( aggregate ); 364 352 } 365 353 366 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr & other ) :354 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr & other ) : 367 355 Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) { 368 356 } … … 373 361 } 374 362 375 void UntypedMemberExpr::print( std::ostream &os, Indenter indent ) const { 363 bool UntypedMemberExpr::get_lvalue() const { 364 return aggregate->get_lvalue(); 365 } 366 367 void UntypedMemberExpr::print( std::ostream & os, Indenter indent ) const { 376 368 os << "Untyped Member Expression, with field: " << std::endl << indent+1; 377 369 member->print(os, indent+1 ); 378 os << indent << "... from aggregate: " << std::endl << indent+1;370 os << indent << "... from aggregate:" << std::endl << indent+1; 379 371 aggregate->print(os, indent+1); 380 372 Expression::print( os, indent ); 381 373 } 382 374 383 MemberExpr::MemberExpr( DeclarationWithType * member, Expression *aggregate ) :375 MemberExpr::MemberExpr( DeclarationWithType * member, Expression * aggregate ) : 384 376 Expression(), member(member), aggregate(aggregate) { 385 377 assert( member ); … … 391 383 sub.apply( res ); 392 384 result = res; 393 result->set_lvalue( true );394 385 result->get_qualifiers() |= aggregate->result->get_qualifiers(); 395 386 } 396 387 397 MemberExpr::MemberExpr( const MemberExpr & other ) :388 MemberExpr::MemberExpr( const MemberExpr & other ) : 398 389 Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) { 399 390 } … … 404 395 } 405 396 406 void MemberExpr::print( std::ostream &os, Indenter indent ) const { 407 os << "Member Expression, with field: " << std::endl; 397 bool MemberExpr::get_lvalue() const { 398 // This is actually wrong by C, but it works with our current set-up. 399 return true; 400 } 401 402 void MemberExpr::print( std::ostream & os, Indenter indent ) const { 403 os << "Member Expression, with field:" << std::endl; 408 404 os << indent+1; 409 405 member->print( os, indent+1 ); 410 os << std::endl << indent << "... from aggregate: " << std::endl << indent+1;406 os << std::endl << indent << "... from aggregate:" << std::endl << indent+1; 411 407 aggregate->print(os, indent + 1); 412 408 Expression::print( os, indent ); 413 409 } 414 410 415 UntypedExpr::UntypedExpr( Expression * function, const std::list<Expression *> &args ) :411 UntypedExpr::UntypedExpr( Expression * function, const std::list<Expression *> & args ) : 416 412 Expression(), function(function), args(args) {} 417 413 418 UntypedExpr::UntypedExpr( const UntypedExpr & other ) :414 UntypedExpr::UntypedExpr( const UntypedExpr & other ) : 419 415 Expression( other ), function( maybeClone( other.function ) ) { 420 416 cloneAll( other.args, args ); … … 435 431 // if references are still allowed in the AST, dereference returns a reference 436 432 ret->set_result( new ReferenceType( Type::Qualifiers(), ret->get_result() ) ); 437 } else {438 // references have been removed, in which case dereference returns an lvalue of the base type.439 ret->result->set_lvalue( true );440 433 } 441 434 } … … 454 447 } 455 448 456 457 void UntypedExpr::print( std::ostream &os, Indenter indent ) const { 458 os << "Applying untyped: " << std::endl; 449 bool UntypedExpr::get_lvalue() const { 450 // from src/GenPoly/Lvalue.cc: isIntrinsicReference 451 static std::set<std::string> lvalueFunctions = { "*?", "?[?]" }; 452 std::string fname = InitTweak::getFunctionName( const_cast< UntypedExpr * >( this ) ); 453 return lvalueFunctions.count(fname); 454 } 455 456 void UntypedExpr::print( std::ostream & os, Indenter indent ) const { 457 os << "Applying untyped:" << std::endl; 459 458 os << indent+1; 460 459 function->print(os, indent+1); 461 os << std::endl << indent << "...to: " << std::endl;460 os << std::endl << indent << "...to:" << std::endl; 462 461 printAll(args, os, indent+1); 463 462 Expression::print( os, indent ); … … 469 468 } 470 469 471 NameExpr::NameExpr( const NameExpr & other ) : Expression( other ), name( other.name ) {470 NameExpr::NameExpr( const NameExpr & other ) : Expression( other ), name( other.name ) { 472 471 } 473 472 474 473 NameExpr::~NameExpr() {} 475 474 476 void NameExpr::print( std::ostream & os, Indenter indent ) const {475 void NameExpr::print( std::ostream & os, Indenter indent ) const { 477 476 os << "Name: " << get_name(); 478 477 Expression::print( os, indent ); 479 478 } 480 479 481 LogicalExpr::LogicalExpr( Expression * arg1_, Expression *arg2_, bool andp ) :480 LogicalExpr::LogicalExpr( Expression * arg1_, Expression * arg2_, bool andp ) : 482 481 Expression(), arg1(arg1_), arg2(arg2_), isAnd(andp) { 483 482 set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 484 483 } 485 484 486 LogicalExpr::LogicalExpr( const LogicalExpr & other ) :485 LogicalExpr::LogicalExpr( const LogicalExpr & other ) : 487 486 Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), isAnd( other.isAnd ) { 488 487 } … … 493 492 } 494 493 495 void LogicalExpr::print( std::ostream & os, Indenter indent )const {494 void LogicalExpr::print( std::ostream & os, Indenter indent )const { 496 495 os << "Short-circuited operation (" << (isAnd ? "and" : "or") << ") on: "; 497 496 arg1->print(os); … … 504 503 Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {} 505 504 506 ConditionalExpr::ConditionalExpr( const ConditionalExpr & other ) :505 ConditionalExpr::ConditionalExpr( const ConditionalExpr & other ) : 507 506 Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), arg3( maybeClone( other.arg3 ) ) { 508 507 } … … 514 513 } 515 514 516 void ConditionalExpr::print( std::ostream &os, Indenter indent ) const { 515 bool ConditionalExpr::get_lvalue() const { 516 return false; 517 } 518 519 void ConditionalExpr::print( std::ostream & os, Indenter indent ) const { 517 520 os << "Conditional expression on: " << std::endl << indent+1; 518 521 arg1->print( os, indent+1 ); … … 527 530 528 531 529 void AsmExpr::print( std::ostream & os, Indenter indent ) const {532 void AsmExpr::print( std::ostream & os, Indenter indent ) const { 530 533 os << "Asm Expression: " << std::endl; 531 534 if ( inout ) inout->print( os, indent+1 ); … … 538 541 assert( callExpr ); 539 542 assert( callExpr->result ); 540 set_result( callExpr-> get_result()->clone() );543 set_result( callExpr->result->clone() ); 541 544 } 542 545 543 546 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) { 544 cloneAll( other.tempDecls, tempDecls );545 cloneAll( other.returnDecls, returnDecls );546 cloneAll( other.dtors, dtors );547 547 } 548 548 … … 550 550 set_env( nullptr ); // ImplicitCopyCtorExpr does not take ownership of an environment 551 551 delete callExpr; 552 deleteAll( tempDecls ); 553 deleteAll( returnDecls ); 554 deleteAll( dtors ); 555 } 556 557 void ImplicitCopyCtorExpr::print( std::ostream &os, Indenter indent ) const { 552 } 553 554 void ImplicitCopyCtorExpr::print( std::ostream & os, Indenter indent ) const { 558 555 os << "Implicit Copy Constructor Expression: " << std::endl << indent+1; 559 556 callExpr->print( os, indent+1 ); 560 os << std::endl << indent << "... with temporaries:" << std::endl;561 printAll( tempDecls, os, indent+1 );562 os << std::endl << indent << "... with return temporaries:" << std::endl;563 printAll( returnDecls, os, indent+1 );564 Expression::print( os, indent );565 557 } 566 558 … … 581 573 } 582 574 583 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const { 575 bool ConstructorExpr::get_lvalue() const { 576 return false; 577 } 578 579 void ConstructorExpr::print( std::ostream & os, Indenter indent ) const { 584 580 os << "Constructor Expression: " << std::endl << indent+1; 585 581 callExpr->print( os, indent + 2 ); … … 590 586 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : initializer( initializer ) { 591 587 assert( type && initializer ); 592 type->set_lvalue( true );593 588 set_result( type ); 594 589 } 595 590 596 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr & other ) : Expression( other ), initializer( other.initializer->clone() ) {}591 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr & other ) : Expression( other ), initializer( other.initializer->clone() ) {} 597 592 598 593 CompoundLiteralExpr::~CompoundLiteralExpr() { … … 600 595 } 601 596 602 void CompoundLiteralExpr::print( std::ostream &os, Indenter indent ) const { 597 bool CompoundLiteralExpr::get_lvalue() const { 598 return true; 599 } 600 601 void CompoundLiteralExpr::print( std::ostream & os, Indenter indent ) const { 603 602 os << "Compound Literal Expression: " << std::endl << indent+1; 604 603 result->print( os, indent+1 ); … … 608 607 } 609 608 610 RangeExpr::RangeExpr( Expression * low, Expression *high ) : low( low ), high( high ) {}611 RangeExpr::RangeExpr( const RangeExpr & other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}612 void RangeExpr::print( std::ostream & os, Indenter indent ) const {609 RangeExpr::RangeExpr( Expression * low, Expression * high ) : low( low ), high( high ) {} 610 RangeExpr::RangeExpr( const RangeExpr & other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {} 611 void RangeExpr::print( std::ostream & os, Indenter indent ) const { 613 612 os << "Range Expression: "; 614 613 low->print( os, indent ); … … 618 617 } 619 618 620 StmtExpr::StmtExpr( CompoundStmt * statements ) : statements( statements ) {619 StmtExpr::StmtExpr( CompoundStmt * statements ) : statements( statements ) { 621 620 computeResult(); 622 621 } 623 StmtExpr::StmtExpr( const StmtExpr & other ) : Expression( other ), statements( other.statements->clone()) {622 StmtExpr::StmtExpr( const StmtExpr & other ) : Expression( other ), statements( other.statements->clone() ), resultExpr( other.resultExpr ) { 624 623 cloneAll( other.returnDecls, returnDecls ); 625 624 cloneAll( other.dtors, dtors ); … … 650 649 } 651 650 } 652 void StmtExpr::print( std::ostream &os, Indenter indent ) const { 651 bool StmtExpr::get_lvalue() const { 652 return false; 653 } 654 void StmtExpr::print( std::ostream & os, Indenter indent ) const { 653 655 os << "Statement Expression: " << std::endl << indent+1; 654 656 statements->print( os, indent+1 ); … … 666 668 667 669 long long UniqueExpr::count = 0; 668 UniqueExpr::UniqueExpr( Expression * expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {670 UniqueExpr::UniqueExpr( Expression * expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) { 669 671 assert( expr ); 670 672 assert( count != -1 ); … … 674 676 } 675 677 } 676 UniqueExpr::UniqueExpr( const UniqueExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {678 UniqueExpr::UniqueExpr( const UniqueExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) { 677 679 } 678 680 UniqueExpr::~UniqueExpr() { … … 681 683 delete var; 682 684 } 683 void UniqueExpr::print( std::ostream & os, Indenter indent ) const {685 void UniqueExpr::print( std::ostream & os, Indenter indent ) const { 684 686 os << "Unique Expression with id:" << id << std::endl << indent+1; 685 687 expr->print( os, indent+1 ); … … 732 734 } 733 735 734 DeletedExpr::DeletedExpr( Expression * expr, BaseSyntaxNode* deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {736 DeletedExpr::DeletedExpr( Expression * expr, Declaration * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) { 735 737 assert( expr->result ); 736 738 result = expr->result->clone(); … … 746 748 os << std::endl << indent+1 << "... deleted by: "; 747 749 deleteStmt->print( os, indent+1 ); 750 } 751 752 753 DefaultArgExpr::DefaultArgExpr( Expression * expr ) : expr( expr ) { 754 assert( expr->result ); 755 result = expr->result->clone(); 756 } 757 DefaultArgExpr::DefaultArgExpr( const DefaultArgExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ) {} 758 DefaultArgExpr::~DefaultArgExpr() { 759 delete expr; 760 } 761 762 void DefaultArgExpr::print( std::ostream & os, Indenter indent ) const { 763 os << "Default Argument Expression" << std::endl << indent+1; 764 expr->print( os, indent+1 ); 748 765 } 749 766 -
src/SynTree/Expression.h
r7951100 rb067d9b 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 Sep 3 19:23:46 201713 // Update Count : 4811 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 15 13:46:00 2019 13 // Update Count : 54 14 14 // 15 15 … … 21 21 #include <memory> // for allocator, unique_ptr 22 22 #include <string> // for string 23 #include <vector> // for vector 23 24 24 25 #include "BaseSyntaxNode.h" // for BaseSyntaxNode … … 38 39 /// but subject to decay-to-pointer and type parameter renaming 39 40 struct ParamEntry { 40 ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ), inferParams( new InferredParams) {}41 ParamEntry( UniqueId decl, Type * actualType, Type * formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ), inferParams( new InferredParams ) {}41 ParamEntry(): decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {} 42 ParamEntry( UniqueId decl, Declaration * declptr, Type * actualType, Type * formalType, Expression* expr ); 42 43 ParamEntry( const ParamEntry & other ); 43 44 ParamEntry( ParamEntry && other ); 44 45 ~ParamEntry(); 45 ParamEntry & operator=( const ParamEntry & other );46 46 ParamEntry & operator=( ParamEntry && other ); 47 47 48 UniqueId decl; 49 Type * actualType; 50 Type * formalType; 48 UniqueId const decl; 49 Declaration * const declptr; 50 Type * const actualType; 51 Type * const formalType; 51 52 Expression * expr; 52 std::unique_ptr< InferredParams > inferParams;53 53 }; 54 54 … … 59 59 TypeSubstitution * env; 60 60 bool extension = false; 61 InferredParams inferParams; 61 InferredParams inferParams; ///< Post-resolution inferred parameter slots 62 std::vector<UniqueId> resnSlots; ///< Pre-resolution inferred parameter slots 63 64 // xxx - should turn inferParams+resnSlots into a union to save some memory 62 65 63 66 Expression(); … … 68 71 const Type * get_result() const { return result; } 69 72 void set_result( Type * newValue ) { result = newValue; } 73 virtual bool get_lvalue() const; 70 74 71 75 TypeSubstitution * get_env() const { return env; } … … 74 78 Expression * set_extension( bool exten ) { extension = exten; return this; } 75 79 76 InferredParams & get_inferParams() { return inferParams; }77 78 80 // move other's inferParams to this 79 81 void spliceInferParams( Expression * other ); … … 81 83 virtual Expression * clone() const override = 0; 82 84 virtual void accept( Visitor & v ) override = 0; 85 virtual void accept( Visitor & v ) const override = 0; 83 86 virtual Expression * acceptMutator( Mutator & m ) override = 0; 84 87 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 96 99 virtual ~ApplicationExpr(); 97 100 101 bool get_lvalue() const final; 102 98 103 Expression * get_function() const { return function; } 99 104 void set_function( Expression * newValue ) { function = newValue; } 100 105 std::list<Expression *>& get_args() { return args; } 101 106 102 virtual ApplicationExpr * clone() const { return new ApplicationExpr( * this ); } 103 virtual void accept( Visitor & v ) { v.visit( this ); } 104 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 105 virtual void print( std::ostream & os, Indenter indent = {} ) const; 107 virtual ApplicationExpr * clone() const override { return new ApplicationExpr( * this ); } 108 virtual void accept( Visitor & v ) override { v.visit( this ); } 109 virtual void accept( Visitor & v ) const override { v.visit( this ); } 110 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 111 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 106 112 }; 107 113 … … 118 124 virtual ~UntypedExpr(); 119 125 126 bool get_lvalue() const final; 127 120 128 Expression * get_function() const { return function; } 121 129 void set_function( Expression * newValue ) { function = newValue; } … … 128 136 static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 ); 129 137 130 virtual UntypedExpr * clone() const { return new UntypedExpr( * this ); } 131 virtual void accept( Visitor & v ) { v.visit( this ); } 132 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 133 virtual void print( std::ostream & os, Indenter indent = {} ) const; 138 virtual UntypedExpr * clone() const override { return new UntypedExpr( * this ); } 139 virtual void accept( Visitor & v ) override { v.visit( this ); } 140 virtual void accept( Visitor & v ) const override { v.visit( this ); } 141 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 142 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 134 143 }; 135 144 … … 146 155 void set_name( std::string newValue ) { name = newValue; } 147 156 148 virtual NameExpr * clone() const { return new NameExpr( * this ); } 149 virtual void accept( Visitor & v ) { v.visit( this ); } 150 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 151 virtual void print( std::ostream & os, Indenter indent = {} ) const; 157 virtual NameExpr * clone() const override { return new NameExpr( * this ); } 158 virtual void accept( Visitor & v ) override { v.visit( this ); } 159 virtual void accept( Visitor & v ) const override { v.visit( this ); } 160 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 161 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 152 162 }; 153 163 … … 167 177 void set_arg(Expression * newValue ) { arg = newValue; } 168 178 169 virtual AddressExpr * clone() const { return new AddressExpr( * this ); } 170 virtual void accept( Visitor & v ) { v.visit( this ); } 171 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 172 virtual void print( std::ostream & os, Indenter indent = {} ) const; 179 virtual AddressExpr * clone() const override { return new AddressExpr( * this ); } 180 virtual void accept( Visitor & v ) override { v.visit( this ); } 181 virtual void accept( Visitor & v ) const override { v.visit( this ); } 182 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 183 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 173 184 }; 174 185 … … 183 194 virtual ~LabelAddressExpr(); 184 195 185 virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); } 186 virtual void accept( Visitor & v ) { v.visit( this ); } 187 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 188 virtual void print( std::ostream & os, Indenter indent = {} ) const; 196 virtual LabelAddressExpr * clone() const override { return new LabelAddressExpr( * this ); } 197 virtual void accept( Visitor & v ) override { v.visit( this ); } 198 virtual void accept( Visitor & v ) const override { v.visit( this ); } 199 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 200 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 189 201 }; 190 202 … … 193 205 public: 194 206 Expression * arg; 195 bool isGenerated = true; // whether this cast appeared in the sourceprogram207 bool isGenerated = true; // cast generated implicitly by code generation or explicit in program 196 208 197 209 CastExpr( Expression * arg, bool isGenerated = true ); … … 201 213 virtual ~CastExpr(); 202 214 215 bool get_lvalue() const final; 216 203 217 Expression * get_arg() const { return arg; } 204 218 void set_arg( Expression * newValue ) { arg = newValue; } 205 219 206 virtual CastExpr * clone() const { return new CastExpr( * this ); } 207 virtual void accept( Visitor & v ) { v.visit( this ); } 208 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 209 virtual void print( std::ostream & os, Indenter indent = {} ) const; 220 virtual CastExpr * clone() const override { return new CastExpr( * this ); } 221 virtual void accept( Visitor & v ) override { v.visit( this ); } 222 virtual void accept( Visitor & v ) const override { v.visit( this ); } 223 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 224 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 210 225 }; 211 226 … … 224 239 const std::string & targetString() const; 225 240 226 virtual KeywordCastExpr * clone() const { return new KeywordCastExpr( * this ); } 227 virtual void accept( Visitor & v ) { v.visit( this ); } 228 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 229 virtual void print( std::ostream & os, Indenter indent = {} ) const; 241 virtual KeywordCastExpr * clone() const override { return new KeywordCastExpr( * this ); } 242 virtual void accept( Visitor & v ) override { v.visit( this ); } 243 virtual void accept( Visitor & v ) const override { v.visit( this ); } 244 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 245 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 230 246 }; 231 247 … … 242 258 void set_arg( Expression * newValue ) { arg = newValue; } 243 259 244 virtual VirtualCastExpr * clone() const { return new VirtualCastExpr( * this ); } 245 virtual void accept( Visitor & v ) { v.visit( this ); } 246 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 247 virtual void print( std::ostream & os, Indenter indent = {} ) const; 260 virtual VirtualCastExpr * clone() const override { return new VirtualCastExpr( * this ); } 261 virtual void accept( Visitor & v ) override { v.visit( this ); } 262 virtual void accept( Visitor & v ) const override { v.visit( this ); } 263 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 264 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 248 265 }; 249 266 … … 257 274 UntypedMemberExpr( const UntypedMemberExpr & other ); 258 275 virtual ~UntypedMemberExpr(); 276 277 bool get_lvalue() const final; 259 278 260 279 Expression * get_member() const { return member; } … … 263 282 void set_aggregate( Expression * newValue ) { aggregate = newValue; } 264 283 265 virtual UntypedMemberExpr * clone() const { return new UntypedMemberExpr( * this ); } 266 virtual void accept( Visitor & v ) { v.visit( this ); } 267 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 268 virtual void print( std::ostream & os, Indenter indent = {} ) const; 284 virtual UntypedMemberExpr * clone() const override { return new UntypedMemberExpr( * this ); } 285 virtual void accept( Visitor & v ) override { v.visit( this ); } 286 virtual void accept( Visitor & v ) const override { v.visit( this ); } 287 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 288 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 269 289 }; 270 290 … … 279 299 MemberExpr( const MemberExpr & other ); 280 300 virtual ~MemberExpr(); 301 302 bool get_lvalue() const final; 281 303 282 304 DeclarationWithType * get_member() const { return member; } … … 285 307 void set_aggregate( Expression * newValue ) { aggregate = newValue; } 286 308 287 virtual MemberExpr * clone() const { return new MemberExpr( * this ); } 288 virtual void accept( Visitor & v ) { v.visit( this ); } 289 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 290 virtual void print( std::ostream & os, Indenter indent = {} ) const; 309 virtual MemberExpr * clone() const override { return new MemberExpr( * this ); } 310 virtual void accept( Visitor & v ) override { v.visit( this ); } 311 virtual void accept( Visitor & v ) const override { v.visit( this ); } 312 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 313 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 291 314 }; 292 315 … … 297 320 DeclarationWithType * var; 298 321 322 VariableExpr(); 299 323 VariableExpr( DeclarationWithType * var ); 300 324 VariableExpr( const VariableExpr & other ); 301 325 virtual ~VariableExpr(); 302 326 327 bool get_lvalue() const final; 328 303 329 DeclarationWithType * get_var() const { return var; } 304 330 void set_var( DeclarationWithType * newValue ) { var = newValue; } … … 306 332 static VariableExpr * functionPointer( FunctionDecl * decl ); 307 333 308 virtual VariableExpr * clone() const { return new VariableExpr( * this ); } 309 virtual void accept( Visitor & v ) { v.visit( this ); } 310 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 311 virtual void print( std::ostream & os, Indenter indent = {} ) const; 334 virtual VariableExpr * clone() const override { return new VariableExpr( * this ); } 335 virtual void accept( Visitor & v ) override { v.visit( this ); } 336 virtual void accept( Visitor & v ) const override { v.visit( this ); } 337 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 338 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 312 339 }; 313 340 … … 327 354 long long int intValue() const; 328 355 329 virtual ConstantExpr * clone() const { return new ConstantExpr( * this ); } 330 virtual void accept( Visitor & v ) { v.visit( this ); } 331 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 332 virtual void print( std::ostream & os, Indenter indent = {} ) const; 356 virtual ConstantExpr * clone() const override { return new ConstantExpr( * this ); } 357 virtual void accept( Visitor & v ) override { v.visit( this ); } 358 virtual void accept( Visitor & v ) const override { v.visit( this ); } 359 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 360 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 333 361 }; 334 362 … … 352 380 void set_isType( bool newValue ) { isType = newValue; } 353 381 354 virtual SizeofExpr * clone() const { return new SizeofExpr( * this ); } 355 virtual void accept( Visitor & v ) { v.visit( this ); } 356 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 357 virtual void print( std::ostream & os, Indenter indent = {} ) const; 382 virtual SizeofExpr * clone() const override { return new SizeofExpr( * this ); } 383 virtual void accept( Visitor & v ) override { v.visit( this ); } 384 virtual void accept( Visitor & v ) const override { v.visit( this ); } 385 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 386 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 358 387 }; 359 388 … … 377 406 void set_isType( bool newValue ) { isType = newValue; } 378 407 379 virtual AlignofExpr * clone() const { return new AlignofExpr( * this ); } 380 virtual void accept( Visitor & v ) { v.visit( this ); } 381 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 382 virtual void print( std::ostream & os, Indenter indent = {} ) const; 408 virtual AlignofExpr * clone() const override { return new AlignofExpr( * this ); } 409 virtual void accept( Visitor & v ) override { v.visit( this ); } 410 virtual void accept( Visitor & v ) const override { v.visit( this ); } 411 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 412 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 383 413 }; 384 414 … … 398 428 void set_type( Type * newValue ) { type = newValue; } 399 429 400 virtual UntypedOffsetofExpr * clone() const { return new UntypedOffsetofExpr( * this ); } 401 virtual void accept( Visitor & v ) { v.visit( this ); } 402 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 403 virtual void print( std::ostream & os, Indenter indent = {} ) const; 430 virtual UntypedOffsetofExpr * clone() const override { return new UntypedOffsetofExpr( * this ); } 431 virtual void accept( Visitor & v ) override { v.visit( this ); } 432 virtual void accept( Visitor & v ) const override { v.visit( this ); } 433 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 434 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 404 435 }; 405 436 … … 419 450 void set_member( DeclarationWithType * newValue ) { member = newValue; } 420 451 421 virtual OffsetofExpr * clone() const { return new OffsetofExpr( * this ); } 422 virtual void accept( Visitor & v ) { v.visit( this ); } 423 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 424 virtual void print( std::ostream & os, Indenter indent = {} ) const; 452 virtual OffsetofExpr * clone() const override { return new OffsetofExpr( * this ); } 453 virtual void accept( Visitor & v ) override { v.visit( this ); } 454 virtual void accept( Visitor & v ) const override { v.visit( this ); } 455 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 456 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 425 457 }; 426 458 … … 437 469 void set_type( StructInstType * newValue ) { type = newValue; } 438 470 439 virtual OffsetPackExpr * clone() const { return new OffsetPackExpr( * this ); } 440 virtual void accept( Visitor & v ) { v.visit( this ); } 441 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 442 virtual void print( std::ostream & os, Indenter indent = {} ) const; 443 }; 444 445 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined) 446 class AttrExpr : public Expression { 447 public: 448 Expression * attr; 449 Expression * expr; 450 Type * type; 451 bool isType; 452 453 AttrExpr(Expression * attr, Expression * expr ); 454 AttrExpr( const AttrExpr & other ); 455 AttrExpr( Expression * attr, Type * type ); 456 virtual ~AttrExpr(); 457 458 Expression * get_attr() const { return attr; } 459 void set_attr( Expression * newValue ) { attr = newValue; } 460 Expression * get_expr() const { return expr; } 461 void set_expr( Expression * newValue ) { expr = newValue; } 462 Type * get_type() const { return type; } 463 void set_type( Type * newValue ) { type = newValue; } 464 bool get_isType() const { return isType; } 465 void set_isType( bool newValue ) { isType = newValue; } 466 467 virtual AttrExpr * clone() const { return new AttrExpr( * this ); } 468 virtual void accept( Visitor & v ) { v.visit( this ); } 469 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 470 virtual void print( std::ostream & os, Indenter indent = {} ) const; 471 virtual OffsetPackExpr * clone() const override { return new OffsetPackExpr( * this ); } 472 virtual void accept( Visitor & v ) override { v.visit( this ); } 473 virtual void accept( Visitor & v ) const override { v.visit( this ); } 474 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 475 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 471 476 }; 472 477 … … 487 492 void set_arg2( Expression * newValue ) { arg2 = newValue; } 488 493 489 virtual LogicalExpr * clone() const { return new LogicalExpr( * this ); } 490 virtual void accept( Visitor & v ) { v.visit( this ); } 491 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 492 virtual void print( std::ostream & os, Indenter indent = {} ) const; 494 virtual LogicalExpr * clone() const override { return new LogicalExpr( * this ); } 495 virtual void accept( Visitor & v ) override { v.visit( this ); } 496 virtual void accept( Visitor & v ) const override { v.visit( this ); } 497 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 498 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 493 499 494 500 private: … … 506 512 ConditionalExpr( const ConditionalExpr & other ); 507 513 virtual ~ConditionalExpr(); 514 515 bool get_lvalue() const final; 508 516 509 517 Expression * get_arg1() const { return arg1; } … … 514 522 void set_arg3( Expression * newValue ) { arg3 = newValue; } 515 523 516 virtual ConditionalExpr * clone() const { return new ConditionalExpr( * this ); } 517 virtual void accept( Visitor & v ) { v.visit( this ); } 518 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 519 virtual void print( std::ostream & os, Indenter indent = {} ) const; 524 virtual ConditionalExpr * clone() const override { return new ConditionalExpr( * this ); } 525 virtual void accept( Visitor & v ) override { v.visit( this ); } 526 virtual void accept( Visitor & v ) const override { v.visit( this ); } 527 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 528 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 520 529 }; 521 530 … … 529 538 CommaExpr( const CommaExpr & other ); 530 539 virtual ~CommaExpr(); 540 541 bool get_lvalue() const final; 531 542 532 543 Expression * get_arg1() const { return arg1; } … … 535 546 void set_arg2( Expression * newValue ) { arg2 = newValue; } 536 547 537 virtual CommaExpr * clone() const { return new CommaExpr( * this ); } 538 virtual void accept( Visitor & v ) { v.visit( this ); } 539 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 540 virtual void print( std::ostream & os, Indenter indent = {} ) const; 548 virtual CommaExpr * clone() const override { return new CommaExpr( * this ); } 549 virtual void accept( Visitor & v ) override { v.visit( this ); } 550 virtual void accept( Visitor & v ) const override { v.visit( this ); } 551 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 552 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 541 553 }; 542 554 … … 553 565 void set_type( Type * newValue ) { type = newValue; } 554 566 555 virtual TypeExpr * clone() const { return new TypeExpr( * this ); } 556 virtual void accept( Visitor & v ) { v.visit( this ); } 557 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 558 virtual void print( std::ostream & os, Indenter indent = {} ) const; 567 virtual TypeExpr * clone() const override { return new TypeExpr( * this ); } 568 virtual void accept( Visitor & v ) override { v.visit( this ); } 569 virtual void accept( Visitor & v ) const override { v.visit( this ); } 570 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 571 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 559 572 }; 560 573 … … 579 592 void set_operand( Expression * newValue ) { operand = newValue; } 580 593 581 virtual AsmExpr * clone() const { return new AsmExpr( * this ); } 582 virtual void accept( Visitor & v ) { v.visit( this ); } 583 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 584 virtual void print( std::ostream & os, Indenter indent = {} ) const; 594 virtual AsmExpr * clone() const override { return new AsmExpr( * this ); } 595 virtual void accept( Visitor & v ) override { v.visit( this ); } 596 virtual void accept( Visitor & v ) const override { v.visit( this ); } 597 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 598 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 585 599 586 600 // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints … … 591 605 class ImplicitCopyCtorExpr : public Expression { 592 606 public: 593 ApplicationExpr * callExpr; 594 std::list< ObjectDecl * > tempDecls; 595 std::list< ObjectDecl * > returnDecls; 596 std::list< Expression * > dtors; 607 ApplicationExpr * callExpr = nullptr; 597 608 598 609 ImplicitCopyCtorExpr( ApplicationExpr * callExpr ); … … 600 611 virtual ~ImplicitCopyCtorExpr(); 601 612 602 ApplicationExpr * get_callExpr() const { return callExpr; } 603 void set_callExpr( ApplicationExpr * newValue ) { callExpr = newValue; } 604 605 std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; } 606 std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; } 607 std::list< Expression * > & get_dtors() { return dtors; } 608 609 virtual ImplicitCopyCtorExpr * clone() const { return new ImplicitCopyCtorExpr( * this ); } 610 virtual void accept( Visitor & v ) { v.visit( this ); } 611 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 612 virtual void print( std::ostream & os, Indenter indent = {} ) const; 613 virtual ImplicitCopyCtorExpr * clone() const override { return new ImplicitCopyCtorExpr( * this ); } 614 virtual void accept( Visitor & v ) override { v.visit( this ); } 615 virtual void accept( Visitor & v ) const override { v.visit( this ); } 616 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 617 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 613 618 }; 614 619 … … 622 627 ~ConstructorExpr(); 623 628 629 bool get_lvalue() const final; 630 624 631 Expression * get_callExpr() const { return callExpr; } 625 632 void set_callExpr( Expression * newValue ) { callExpr = newValue; } 626 633 627 virtual ConstructorExpr * clone() const { return new ConstructorExpr( * this ); } 628 virtual void accept( Visitor & v ) { v.visit( this ); } 629 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 630 virtual void print( std::ostream & os, Indenter indent = {} ) const; 634 virtual ConstructorExpr * clone() const override { return new ConstructorExpr( * this ); } 635 virtual void accept( Visitor & v ) override { v.visit( this ); } 636 virtual void accept( Visitor & v ) const override { v.visit( this ); } 637 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 638 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 631 639 }; 632 640 … … 640 648 virtual ~CompoundLiteralExpr(); 641 649 650 bool get_lvalue() const final; 651 642 652 Initializer * get_initializer() const { return initializer; } 643 653 void set_initializer( Initializer * i ) { initializer = i; } 644 654 645 virtual CompoundLiteralExpr * clone() const { return new CompoundLiteralExpr( * this ); } 646 virtual void accept( Visitor & v ) { v.visit( this ); } 647 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 648 virtual void print( std::ostream & os, Indenter indent = {} ) const; 655 virtual CompoundLiteralExpr * clone() const override { return new CompoundLiteralExpr( * this ); } 656 virtual void accept( Visitor & v ) override { v.visit( this ); } 657 virtual void accept( Visitor & v ) const override { v.visit( this ); } 658 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 659 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 649 660 }; 650 661 … … 662 673 RangeExpr * set_high( Expression * high ) { RangeExpr::high = high; return this; } 663 674 664 virtual RangeExpr * clone() const { return new RangeExpr( * this ); } 665 virtual void accept( Visitor & v ) { v.visit( this ); } 666 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 667 virtual void print( std::ostream & os, Indenter indent = {} ) const; 675 virtual RangeExpr * clone() const override { return new RangeExpr( * this ); } 676 virtual void accept( Visitor & v ) override { v.visit( this ); } 677 virtual void accept( Visitor & v ) const override { v.visit( this ); } 678 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 679 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 668 680 }; 669 681 … … 679 691 std::list<Expression*>& get_exprs() { return exprs; } 680 692 681 virtual UntypedTupleExpr * clone() const { return new UntypedTupleExpr( * this ); } 682 virtual void accept( Visitor & v ) { v.visit( this ); } 683 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 684 virtual void print( std::ostream & os, Indenter indent = {} ) const; 693 virtual UntypedTupleExpr * clone() const override { return new UntypedTupleExpr( * this ); } 694 virtual void accept( Visitor & v ) override { v.visit( this ); } 695 virtual void accept( Visitor & v ) const override { v.visit( this ); } 696 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 697 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 685 698 }; 686 699 … … 694 707 virtual ~TupleExpr(); 695 708 709 bool get_lvalue() const final; 710 696 711 std::list<Expression*>& get_exprs() { return exprs; } 697 712 698 virtual TupleExpr * clone() const { return new TupleExpr( * this ); } 699 virtual void accept( Visitor & v ) { v.visit( this ); } 700 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 701 virtual void print( std::ostream & os, Indenter indent = {} ) const; 713 virtual TupleExpr * clone() const override { return new TupleExpr( * this ); } 714 virtual void accept( Visitor & v ) override { v.visit( this ); } 715 virtual void accept( Visitor & v ) const override { v.visit( this ); } 716 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 717 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 702 718 }; 703 719 … … 711 727 TupleIndexExpr( const TupleIndexExpr & other ); 712 728 virtual ~TupleIndexExpr(); 729 730 bool get_lvalue() const final; 713 731 714 732 Expression * get_tuple() const { return tuple; } … … 717 735 TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; } 718 736 719 virtual TupleIndexExpr * clone() const { return new TupleIndexExpr( * this ); } 720 virtual void accept( Visitor & v ) { v.visit( this ); } 721 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 722 virtual void print( std::ostream & os, Indenter indent = {} ) const; 737 virtual TupleIndexExpr * clone() const override { return new TupleIndexExpr( * this ); } 738 virtual void accept( Visitor & v ) override { v.visit( this ); } 739 virtual void accept( Visitor & v ) const override { v.visit( this ); } 740 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 741 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 723 742 }; 724 743 … … 735 754 StmtExpr * get_stmtExpr() const { return stmtExpr; } 736 755 737 virtual TupleAssignExpr * clone() const { return new TupleAssignExpr( * this ); } 738 virtual void accept( Visitor & v ) { v.visit( this ); } 739 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 740 virtual void print( std::ostream & os, Indenter indent = {} ) const; 756 virtual TupleAssignExpr * clone() const override { return new TupleAssignExpr( * this ); } 757 virtual void accept( Visitor & v ) override { v.visit( this ); } 758 virtual void accept( Visitor & v ) const override { v.visit( this ); } 759 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 760 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 761 762 friend class ConverterNewToOld; 763 private: 764 TupleAssignExpr( StmtExpr * stmts ); 741 765 }; 742 766 … … 748 772 std::list< Expression * > dtors; // destructor(s) for return variable(s) 749 773 774 // readonly 775 ExprStmt * resultExpr = nullptr; 776 750 777 StmtExpr( CompoundStmt * statements ); 751 778 StmtExpr( const StmtExpr & other ); 752 779 virtual ~StmtExpr(); 753 780 781 bool get_lvalue() const final; 782 754 783 CompoundStmt * get_statements() const { return statements; } 755 784 StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; } … … 761 790 std::list< Expression * > & get_dtors() { return dtors; } 762 791 763 virtual StmtExpr * clone() const { return new StmtExpr( * this ); } 764 virtual void accept( Visitor & v ) { v.visit( this ); } 765 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 766 virtual void print( std::ostream & os, Indenter indent = {} ) const; 792 virtual StmtExpr * clone() const override { return new StmtExpr( * this ); } 793 virtual void accept( Visitor & v ) override { v.visit( this ); } 794 virtual void accept( Visitor & v ) const override { v.visit( this ); } 795 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 796 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 767 797 }; 768 798 … … 788 818 int get_id() const { return id; } 789 819 790 virtual UniqueExpr * clone() const { return new UniqueExpr( * this ); } 791 virtual void accept( Visitor & v ) { v.visit( this ); } 792 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 793 virtual void print( std::ostream & os, Indenter indent = {} ) const; 820 virtual UniqueExpr * clone() const override { return new UniqueExpr( * this ); } 821 virtual void accept( Visitor & v ) override { v.visit( this ); } 822 virtual void accept( Visitor & v ) const override { v.visit( this ); } 823 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 824 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 794 825 795 826 private: … … 822 853 std::list<InitAlternative> & get_initAlts() { return initAlts; } 823 854 824 virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); } 825 virtual void accept( Visitor & v ) { v.visit( this ); } 826 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 827 virtual void print( std::ostream & os, Indenter indent = {} ) const; 855 virtual UntypedInitExpr * clone() const override { return new UntypedInitExpr( * this ); } 856 virtual void accept( Visitor & v ) override { v.visit( this ); } 857 virtual void accept( Visitor & v ) const override { v.visit( this ); } 858 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 859 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 828 860 }; 829 861 … … 843 875 InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; } 844 876 845 virtual InitExpr * clone() const { return new InitExpr( * this ); } 846 virtual void accept( Visitor & v ) { v.visit( this ); } 847 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 848 virtual void print( std::ostream & os, Indenter indent = {} ) const; 877 virtual InitExpr * clone() const override { return new InitExpr( * this ); } 878 virtual void accept( Visitor & v ) override { v.visit( this ); } 879 virtual void accept( Visitor & v ) const override { v.visit( this ); } 880 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 881 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 849 882 }; 850 883 … … 853 886 public: 854 887 Expression * expr; 855 BaseSyntaxNode* deleteStmt;856 857 DeletedExpr( Expression * expr, BaseSyntaxNode* deleteStmt );888 Declaration * deleteStmt; 889 890 DeletedExpr( Expression * expr, Declaration * deleteStmt ); 858 891 DeletedExpr( const DeletedExpr & other ); 859 892 ~DeletedExpr(); 860 893 861 virtual DeletedExpr * clone() const { return new DeletedExpr( * this ); } 862 virtual void accept( Visitor & v ) { v.visit( this ); } 863 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 864 virtual void print( std::ostream & os, Indenter indent = {} ) const; 894 virtual DeletedExpr * clone() const override { return new DeletedExpr( * this ); } 895 virtual void accept( Visitor & v ) override { v.visit( this ); } 896 virtual void accept( Visitor & v ) const override { v.visit( this ); } 897 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 898 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 899 }; 900 901 /// expression wrapping the use of a default argument - should never make it past the resolver. 902 class DefaultArgExpr : public Expression { 903 public: 904 Expression * expr; 905 906 DefaultArgExpr( Expression * expr ); 907 DefaultArgExpr( const DefaultArgExpr & other ); 908 ~DefaultArgExpr(); 909 910 virtual DefaultArgExpr * clone() const override { return new DefaultArgExpr( * this ); } 911 virtual void accept( Visitor & v ) override { v.visit( this ); } 912 virtual void accept( Visitor & v ) const override { v.visit( this ); } 913 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 914 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 865 915 }; 866 916 … … 887 937 virtual ~GenericExpr(); 888 938 889 virtual GenericExpr * clone() const { return new GenericExpr( * this ); } 890 virtual void accept( Visitor & v ) { v.visit( this ); } 891 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 892 virtual void print( std::ostream & os, Indenter indent = {} ) const; 939 virtual GenericExpr * clone() const override { return new GenericExpr( * this ); } 940 virtual void accept( Visitor & v ) override { v.visit( this ); } 941 virtual void accept( Visitor & v ) const override { v.visit( this ); } 942 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 943 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 893 944 }; 894 945 -
src/SynTree/FunctionDecl.cc
r7951100 rb067d9b 87 87 88 88 if ( statements ) { 89 os << indent << "... with body " << endl << indent+1;89 os << indent << "... with body" << endl << indent+1; 90 90 statements->print( os, indent+1 ); 91 91 } // if -
src/SynTree/FunctionType.cc
r7951100 rb067d9b 66 66 os << indent+1 << "accepting unspecified arguments" << endl; 67 67 } // if 68 os << indent << "... returning ";68 os << indent << "... returning"; 69 69 if ( returnVals.empty() ) { 70 os << " nothing" << endl;70 os << " nothing" << endl; 71 71 } else { 72 72 os << endl; -
src/SynTree/Initializer.h
r7951100 rb067d9b 38 38 39 39 virtual Designation * clone() const override { return new Designation( *this ); }; 40 virtual void accept( Visitor &v ) override { v.visit( this ); } 40 virtual void accept( Visitor & v ) override { v.visit( this ); } 41 virtual void accept( Visitor & v ) const override { v.visit( this ); } 41 42 virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 42 43 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 52 53 virtual ~Initializer(); 53 54 54 bool get_maybeConstructed() { return maybeConstructed; }55 bool get_maybeConstructed() const { return maybeConstructed; } 55 56 56 57 virtual Initializer *clone() const override = 0; 57 virtual void accept( Visitor &v ) override = 0; 58 virtual void accept( Visitor & v ) override = 0; 59 virtual void accept( Visitor & v ) const override = 0; 58 60 virtual Initializer *acceptMutator( Mutator &m ) override = 0; 59 61 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; … … 76 78 77 79 virtual SingleInit *clone() const override { return new SingleInit( *this); } 78 virtual void accept( Visitor &v ) override { v.visit( this ); } 80 virtual void accept( Visitor & v ) override { v.visit( this ); } 81 virtual void accept( Visitor & v ) const override { v.visit( this ); } 79 82 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 80 83 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 104 107 105 108 virtual ListInit *clone() const override { return new ListInit( *this ); } 106 virtual void accept( Visitor &v ) override { v.visit( this ); } 109 virtual void accept( Visitor & v ) override { v.visit( this ); } 110 virtual void accept( Visitor & v ) const override { v.visit( this ); } 107 111 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 108 112 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 133 137 134 138 ConstructorInit *clone() const override { return new ConstructorInit( *this ); } 135 virtual void accept( Visitor &v ) override { v.visit( this ); } 139 virtual void accept( Visitor & v ) override { v.visit( this ); } 140 virtual void accept( Visitor & v ) const override { v.visit( this ); } 136 141 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 137 142 virtual void print( std::ostream &os, Indenter indent = {} ) const override; -
src/SynTree/Label.h
r7951100 rb067d9b 35 35 operator std::string() const { return name; } 36 36 bool empty() { return name.empty(); } 37 private: 37 38 38 std::string name; 39 39 Statement * labelled; -
src/SynTree/Mutator.h
r7951100 rb067d9b 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 Jul 24 16:31:00 201713 // Update Count : 1 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:37:46 2019 13 // Update Count : 17 14 14 // 15 15 #pragma once … … 52 52 virtual Statement * mutate( FinallyStmt * catchStmt ) = 0; 53 53 virtual Statement * mutate( WaitForStmt * waitforStmt ) = 0; 54 virtual Statement* mutate( WithStmt * withStmt ) = 0;54 virtual Declaration * mutate( WithStmt * withStmt ) = 0; 55 55 virtual NullStmt * mutate( NullStmt * nullStmt ) = 0; 56 56 virtual Statement * mutate( DeclStmt * declStmt ) = 0; … … 74 74 virtual Expression * mutate( OffsetofExpr * offsetofExpr ) = 0; 75 75 virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) = 0; 76 virtual Expression * mutate( AttrExpr * attrExpr ) = 0;77 76 virtual Expression * mutate( LogicalExpr * logicalExpr ) = 0; 78 77 virtual Expression * mutate( ConditionalExpr * conditionalExpr ) = 0; … … 93 92 virtual Expression * mutate( InitExpr * initExpr ) = 0; 94 93 virtual Expression * mutate( DeletedExpr * delExpr ) = 0; 94 virtual Expression * mutate( DefaultArgExpr * argExpr ) = 0; 95 95 virtual Expression * mutate( GenericExpr * genExpr ) = 0; 96 96 … … 100 100 virtual Type * mutate( ArrayType * arrayType ) = 0; 101 101 virtual Type * mutate( ReferenceType * refType ) = 0; 102 virtual Type * mutate( QualifiedType * qualType ) = 0; 102 103 virtual Type * mutate( FunctionType * functionType ) = 0; 103 104 virtual Type * mutate( StructInstType * aggregateUseType ) = 0; … … 112 113 virtual Type * mutate( ZeroType * zeroType ) = 0; 113 114 virtual Type * mutate( OneType * oneType ) = 0; 115 virtual Type * mutate( GlobalScopeType * globalType ) = 0; 114 116 115 117 virtual Designation * mutate( Designation * designation ) = 0 ; … … 117 119 virtual Initializer * mutate( ListInit * listInit ) = 0 ; 118 120 virtual Initializer * mutate( ConstructorInit * ctorInit ) = 0 ; 119 120 virtual Subrange * mutate( Subrange * subrange ) = 0;121 121 122 122 virtual Constant * mutate( Constant * constant ) = 0; -
src/SynTree/ObjectDecl.cc
r7951100 rb067d9b 66 66 67 67 if ( ! attributes.empty() ) { 68 os << std::endl << indent << "... with attributes: " << std::endl;68 os << std::endl << indent << "... with attributes:" << std::endl; 69 69 printAll( attributes, os, indent+1 ); 70 70 } -
src/SynTree/ReferenceToType.cc
r7951100 rb067d9b 76 76 bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; } 77 77 78 AggregateDecl * StructInstType::getAggr() { return baseStruct; }78 AggregateDecl * StructInstType::getAggr() const { return baseStruct; } 79 79 80 80 TypeSubstitution StructInstType::genericSubstitution() const { … … 93 93 else { 94 94 Type::print( os, indent ); 95 os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body() << " ";95 os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body(); 96 96 if ( ! parameters.empty() ) { 97 97 os << endl << indent << "... with parameters" << endl; … … 119 119 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; } 120 120 121 AggregateDecl * UnionInstType::getAggr() { return baseUnion; }121 AggregateDecl * UnionInstType::getAggr() const { return baseUnion; } 122 122 123 123 TypeSubstitution UnionInstType::genericSubstitution() const { … … 136 136 else { 137 137 Type::print( os, indent ); 138 os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body() << " ";138 os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body(); 139 139 if ( ! parameters.empty() ) { 140 140 os << endl << indent << "... with parameters" << endl; … … 152 152 bool EnumInstType::isComplete() const { return baseEnum ? baseEnum->has_body() : false; } 153 153 154 AggregateDecl * EnumInstType::getAggr() const { return baseEnum; } 155 154 156 void EnumInstType::print( std::ostream &os, Indenter indent ) const { 155 157 using std::endl; … … 158 160 else { 159 161 Type::print( os, indent ); 160 os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body() << " ";162 os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body(); 161 163 } // if 162 164 } … … 203 205 204 206 Type::print( os, indent ); 205 os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type) ";207 os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type)"; 206 208 if ( ! parameters.empty() ) { 207 209 os << endl << indent << "... with parameters" << endl; -
src/SynTree/Statement.cc
r7951100 rb067d9b 493 493 494 494 495 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}496 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {495 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Declaration("", noStorageClasses, LinkageSpec::Cforall), exprs( exprs ), stmt( stmt ) {} 496 WithStmt::WithStmt( const WithStmt & other ) : Declaration( other ), stmt( maybeClone( other.stmt ) ) { 497 497 cloneAll( other.exprs, exprs ); 498 498 } -
src/SynTree/Statement.h
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Mar 8 14:53:02 201813 // Update Count : 7812 // Last Modified On : Tue Mar 12 09:01:53 2019 13 // Update Count : 83 14 14 // 15 15 … … 19 19 #include <list> // for list 20 20 #include <memory> // for allocator 21 #include <vector> // for vector21 #include <vector> // for vector 22 22 23 23 #include "BaseSyntaxNode.h" // for BaseSyntaxNode … … 43 43 const std::list<Label> & get_labels() const { return labels; } 44 44 45 virtual Statement *clone() const override = 0; 46 virtual void accept( Visitor &v ) override = 0; 47 virtual Statement *acceptMutator( Mutator &m ) override = 0; 48 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 45 virtual Statement * clone() const override = 0; 46 virtual void accept( Visitor & v ) override = 0; 47 virtual void accept( Visitor & v ) const override = 0; 48 virtual Statement * acceptMutator( Mutator & m ) override = 0; 49 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 49 50 }; 50 51 … … 55 56 CompoundStmt(); 56 57 CompoundStmt( std::list<Statement *> stmts ); 57 CompoundStmt( const CompoundStmt & other );58 CompoundStmt( const CompoundStmt & other ); 58 59 virtual ~CompoundStmt(); 59 60 … … 62 63 void push_front( Statement * stmt ) { kids.push_front( stmt ); } 63 64 64 virtual CompoundStmt *clone() const override { return new CompoundStmt( *this ); } 65 virtual void accept( Visitor &v ) override { v.visit( this ); } 66 virtual CompoundStmt *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 67 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 65 virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); } 66 virtual void accept( Visitor & v ) override { v.visit( this ); } 67 virtual void accept( Visitor & v ) const override { v.visit( this ); } 68 virtual CompoundStmt * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 69 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 68 70 }; 69 71 … … 72 74 NullStmt( const std::list<Label> & labels = {} ); 73 75 74 virtual NullStmt *clone() const override { return new NullStmt( *this ); } 75 virtual void accept( Visitor &v ) override { v.visit( this ); } 76 virtual NullStmt *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 77 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 76 virtual NullStmt * clone() const override { return new NullStmt( *this ); } 77 virtual void accept( Visitor & v ) override { v.visit( this ); } 78 virtual void accept( Visitor & v ) const override { v.visit( this ); } 79 virtual NullStmt * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 80 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 78 81 }; 79 82 80 83 class ExprStmt : public Statement { 81 84 public: 82 Expression * expr;83 84 ExprStmt( Expression * expr );85 ExprStmt( const ExprStmt & other );85 Expression * expr; 86 87 ExprStmt( Expression * expr ); 88 ExprStmt( const ExprStmt & other ); 86 89 virtual ~ExprStmt(); 87 90 88 Expression *get_expr() { return expr; } 89 void set_expr( Expression *newValue ) { expr = newValue; } 90 91 virtual ExprStmt *clone() const override { return new ExprStmt( *this ); } 92 virtual void accept( Visitor &v ) override { v.visit( this ); } 93 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 94 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 91 Expression * get_expr() { return expr; } 92 void set_expr( Expression * newValue ) { expr = newValue; } 93 94 virtual ExprStmt * clone() const override { return new ExprStmt( *this ); } 95 virtual void accept( Visitor & v ) override { v.visit( this ); } 96 virtual void accept( Visitor & v ) const override { v.visit( this ); } 97 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 98 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 95 99 }; 96 100 … … 98 102 public: 99 103 bool voltile; 100 Expression * instruction;104 Expression * instruction; 101 105 std::list<Expression *> output, input; 102 106 std::list<ConstantExpr *> clobber; 103 107 std::list<Label> gotolabels; 104 108 105 AsmStmt( bool voltile, Expression * instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );106 AsmStmt( const AsmStmt & other );109 AsmStmt( bool voltile, Expression * instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ); 110 AsmStmt( const AsmStmt & other ); 107 111 virtual ~AsmStmt(); 108 112 … … 114 118 void set_output( const std::list<Expression *> & newValue ) { output = newValue; } 115 119 std::list<Expression *> & get_input() { return input; } 116 void set_input( const std::list<Expression *> & newValue ) { input = newValue; }120 void set_input( const std::list<Expression *> & newValue ) { input = newValue; } 117 121 std::list<ConstantExpr *> & get_clobber() { return clobber; } 118 void set_clobber( const std::list<ConstantExpr *> & newValue ) { clobber = newValue; }122 void set_clobber( const std::list<ConstantExpr *> & newValue ) { clobber = newValue; } 119 123 std::list<Label> & get_gotolabels() { return gotolabels; } 120 void set_gotolabels( const std::list<Label> &newValue ) { gotolabels = newValue; } 121 122 virtual AsmStmt * clone() const { return new AsmStmt( *this ); } 123 virtual void accept( Visitor & v ) { v.visit( this ); } 124 virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); } 125 virtual void print( std::ostream & os, Indenter indent = {} ) const; 124 void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; } 125 126 virtual AsmStmt * clone() const override { return new AsmStmt( *this ); } 127 virtual void accept( Visitor & v ) override { v.visit( this ); } 128 virtual void accept( Visitor & v ) const override { v.visit( this ); } 129 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 130 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 126 131 }; 127 132 … … 133 138 virtual ~DirectiveStmt(){} 134 139 135 virtual DirectiveStmt * clone() const { return new DirectiveStmt( *this ); } 136 virtual void accept( Visitor & v ) { v.visit( this ); } 137 virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); } 138 virtual void print( std::ostream & os, Indenter indent = {} ) const; 140 virtual DirectiveStmt * clone() const override { return new DirectiveStmt( *this ); } 141 virtual void accept( Visitor & v ) override { v.visit( this ); } 142 virtual void accept( Visitor & v ) const override { v.visit( this ); } 143 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 144 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 139 145 }; 140 146 141 147 class IfStmt : public Statement { 142 148 public: 143 Expression * condition;144 Statement * thenPart;145 Statement * elsePart;149 Expression * condition; 150 Statement * thenPart; 151 Statement * elsePart; 146 152 std::list<Statement *> initialization; 147 153 148 IfStmt( Expression * condition, Statement *thenPart, Statement *elsePart,154 IfStmt( Expression * condition, Statement * thenPart, Statement * elsePart, 149 155 std::list<Statement *> initialization = std::list<Statement *>() ); 150 IfStmt( const IfStmt & other );156 IfStmt( const IfStmt & other ); 151 157 virtual ~IfStmt(); 152 158 153 std::list<Statement *> &get_initialization() { return initialization; } 154 Expression *get_condition() { return condition; } 155 void set_condition( Expression *newValue ) { condition = newValue; } 156 Statement *get_thenPart() { return thenPart; } 157 void set_thenPart( Statement *newValue ) { thenPart = newValue; } 158 Statement *get_elsePart() { return elsePart; } 159 void set_elsePart( Statement *newValue ) { elsePart = newValue; } 160 161 virtual IfStmt *clone() const override { return new IfStmt( *this ); } 162 virtual void accept( Visitor &v ) override { v.visit( this ); } 163 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 164 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 159 std::list<Statement *> & get_initialization() { return initialization; } 160 Expression * get_condition() { return condition; } 161 void set_condition( Expression * newValue ) { condition = newValue; } 162 Statement * get_thenPart() { return thenPart; } 163 void set_thenPart( Statement * newValue ) { thenPart = newValue; } 164 Statement * get_elsePart() { return elsePart; } 165 void set_elsePart( Statement * newValue ) { elsePart = newValue; } 166 167 virtual IfStmt * clone() const override { return new IfStmt( *this ); } 168 virtual void accept( Visitor & v ) override { v.visit( this ); } 169 virtual void accept( Visitor & v ) const override { v.visit( this ); } 170 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 171 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 165 172 }; 166 173 … … 170 177 std::list<Statement *> statements; 171 178 172 SwitchStmt( Expression * condition, const std::list<Statement *> &statements );173 SwitchStmt( const SwitchStmt & other );179 SwitchStmt( Expression * condition, const std::list<Statement *> & statements ); 180 SwitchStmt( const SwitchStmt & other ); 174 181 virtual ~SwitchStmt(); 175 182 176 Expression * get_condition() { return condition; }177 void set_condition( Expression * newValue ) { condition = newValue; }183 Expression * get_condition() { return condition; } 184 void set_condition( Expression * newValue ) { condition = newValue; } 178 185 179 186 std::list<Statement *> & get_statements() { return statements; } 180 187 181 virtual void accept( Visitor &v ) override { v.visit( this ); } 182 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 183 184 virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); } 185 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 188 virtual void accept( Visitor & v ) override { v.visit( this ); } 189 virtual void accept( Visitor & v ) const override { v.visit( this ); } 190 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 191 192 virtual SwitchStmt * clone() const override { return new SwitchStmt( *this ); } 193 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 186 194 187 195 }; … … 192 200 std::list<Statement *> stmts; 193 201 194 CaseStmt( Expression * conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw (SemanticErrorException);195 CaseStmt( const CaseStmt & other );202 CaseStmt( Expression * conditions, const std::list<Statement *> & stmts, bool isdef = false ) throw (SemanticErrorException); 203 CaseStmt( const CaseStmt & other ); 196 204 virtual ~CaseStmt(); 197 205 … … 201 209 void set_default(bool b) { _isDefault = b; } 202 210 203 Expression * &get_condition() { return condition; } 204 void set_condition( Expression *newValue ) { condition = newValue; } 205 206 std::list<Statement *> &get_statements() { return stmts; } 207 void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; } 208 209 virtual void accept( Visitor &v ) override { v.visit( this ); } 210 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 211 212 virtual CaseStmt *clone() const override { return new CaseStmt( *this ); } 213 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 211 Expression * & get_condition() { return condition; } 212 void set_condition( Expression * newValue ) { condition = newValue; } 213 214 std::list<Statement *> & get_statements() { return stmts; } 215 void set_statements( std::list<Statement *> & newValue ) { stmts = newValue; } 216 217 virtual void accept( Visitor & v ) override { v.visit( this ); } 218 virtual void accept( Visitor & v ) const override { v.visit( this ); } 219 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 220 221 virtual CaseStmt * clone() const override { return new CaseStmt( *this ); } 222 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 214 223 private: 215 224 bool _isDefault; … … 218 227 class WhileStmt : public Statement { 219 228 public: 220 Expression * condition;221 Statement * body;229 Expression * condition; 230 Statement * body; 222 231 std::list<Statement *> initialization; 223 232 bool isDoWhile; 224 233 225 WhileStmt( Expression *condition, 226 Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false ); 227 WhileStmt( const WhileStmt &other ); 234 WhileStmt( Expression * condition, Statement * body, std::list<Statement *> & initialization, bool isDoWhile = false ); 235 WhileStmt( const WhileStmt & other ); 228 236 virtual ~WhileStmt(); 229 237 230 Expression * get_condition() { return condition; }231 void set_condition( Expression * newValue ) { condition = newValue; }232 Statement * get_body() { return body; }233 void set_body( Statement * newValue ) { body = newValue; }238 Expression * get_condition() { return condition; } 239 void set_condition( Expression * newValue ) { condition = newValue; } 240 Statement * get_body() { return body; } 241 void set_body( Statement * newValue ) { body = newValue; } 234 242 bool get_isDoWhile() { return isDoWhile; } 235 243 void set_isDoWhile( bool newValue ) { isDoWhile = newValue; } 236 244 237 virtual WhileStmt *clone() const override { return new WhileStmt( *this ); } 238 virtual void accept( Visitor &v ) override { v.visit( this ); } 239 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 240 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 245 virtual WhileStmt * clone() const override { return new WhileStmt( *this ); } 246 virtual void accept( Visitor & v ) override { v.visit( this ); } 247 virtual void accept( Visitor & v ) const override { v.visit( this ); } 248 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 249 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 241 250 }; 242 251 … … 244 253 public: 245 254 std::list<Statement *> initialization; 246 Expression *condition; 247 Expression *increment; 248 Statement *body; 249 250 ForStmt( std::list<Statement *> initialization, 251 Expression *condition = 0, Expression *increment = 0, Statement *body = 0 ); 252 ForStmt( const ForStmt &other ); 255 Expression * condition; 256 Expression * increment; 257 Statement * body; 258 259 ForStmt( std::list<Statement *> initialization, Expression * condition = 0, Expression * increment = 0, Statement * body = 0 ); 260 ForStmt( const ForStmt & other ); 253 261 virtual ~ForStmt(); 254 262 255 std::list<Statement *> &get_initialization() { return initialization; } 256 Expression *get_condition() { return condition; } 257 void set_condition( Expression *newValue ) { condition = newValue; } 258 Expression *get_increment() { return increment; } 259 void set_increment( Expression *newValue ) { increment = newValue; } 260 Statement *get_body() { return body; } 261 void set_body( Statement *newValue ) { body = newValue; } 262 263 virtual ForStmt *clone() const override { return new ForStmt( *this ); } 264 virtual void accept( Visitor &v ) override { v.visit( this ); } 265 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 266 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 263 std::list<Statement *> & get_initialization() { return initialization; } 264 Expression * get_condition() { return condition; } 265 void set_condition( Expression * newValue ) { condition = newValue; } 266 Expression * get_increment() { return increment; } 267 void set_increment( Expression * newValue ) { increment = newValue; } 268 Statement * get_body() { return body; } 269 void set_body( Statement * newValue ) { body = newValue; } 270 271 virtual ForStmt * clone() const override { return new ForStmt( *this ); } 272 virtual void accept( Visitor & v ) override { v.visit( this ); } 273 virtual void accept( Visitor & v ) const override { v.visit( this ); } 274 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 275 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 267 276 }; 268 277 … … 274 283 const Label originalTarget; 275 284 Label target; 276 Expression * computedTarget;285 Expression * computedTarget; 277 286 Type type; 278 287 279 288 BranchStmt( Label target, Type ) throw (SemanticErrorException); 280 BranchStmt( Expression * computedTarget, Type ) throw (SemanticErrorException);289 BranchStmt( Expression * computedTarget, Type ) throw (SemanticErrorException); 281 290 282 291 Label get_originalTarget() { return originalTarget; } … … 284 293 void set_target( Label newValue ) { target = newValue; } 285 294 286 Expression * get_computedTarget() { return computedTarget; }295 Expression * get_computedTarget() { return computedTarget; } 287 296 void set_target( Expression * newValue ) { computedTarget = newValue; } 288 297 289 298 Type get_type() { return type; } 290 const char *get_typename() { return brType[ type ]; } 291 292 virtual BranchStmt *clone() const override { return new BranchStmt( *this ); } 293 virtual void accept( Visitor &v ) override { v.visit( this ); } 294 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 295 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 299 const char * get_typename() { return brType[ type ]; } 300 301 virtual BranchStmt * clone() const override { return new BranchStmt( *this ); } 302 virtual void accept( Visitor & v ) override { v.visit( this ); } 303 virtual void accept( Visitor & v ) const override { v.visit( this ); } 304 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 305 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 296 306 private: 297 static const char * brType[];307 static const char * brType[]; 298 308 }; 299 309 300 310 class ReturnStmt : public Statement { 301 311 public: 302 Expression * expr;303 304 ReturnStmt( Expression * expr );305 ReturnStmt( const ReturnStmt & other );312 Expression * expr; 313 314 ReturnStmt( Expression * expr ); 315 ReturnStmt( const ReturnStmt & other ); 306 316 virtual ~ReturnStmt(); 307 317 308 Expression *get_expr() { return expr; } 309 void set_expr( Expression *newValue ) { expr = newValue; } 310 311 virtual ReturnStmt *clone() const override { return new ReturnStmt( *this ); } 312 virtual void accept( Visitor &v ) override { v.visit( this ); } 313 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 314 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 318 Expression * get_expr() { return expr; } 319 void set_expr( Expression * newValue ) { expr = newValue; } 320 321 virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); } 322 virtual void accept( Visitor & v ) override { v.visit( this ); } 323 virtual void accept( Visitor & v ) const override { v.visit( this ); } 324 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 325 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 315 326 }; 316 327 … … 324 335 325 336 ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr ); 326 ThrowStmt( const ThrowStmt & other );337 ThrowStmt( const ThrowStmt & other ); 327 338 virtual ~ThrowStmt(); 328 339 … … 333 344 void set_target( Expression * newTarget ) { target = newTarget; } 334 345 335 virtual ThrowStmt *clone() const override { return new ThrowStmt( *this ); } 336 virtual void accept( Visitor &v ) override { v.visit( this ); } 337 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 338 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 346 virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); } 347 virtual void accept( Visitor & v ) override { v.visit( this ); } 348 virtual void accept( Visitor & v ) const override { v.visit( this ); } 349 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 350 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 339 351 }; 340 352 … … 345 357 FinallyStmt * finallyBlock; 346 358 347 TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );348 TryStmt( const TryStmt & other );359 TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> & handlers, FinallyStmt * finallyBlock = 0 ); 360 TryStmt( const TryStmt & other ); 349 361 virtual ~TryStmt(); 350 362 351 CompoundStmt * get_block() const { return block; }352 void set_block( CompoundStmt * newValue ) { block = newValue; }363 CompoundStmt * get_block() const { return block; } 364 void set_block( CompoundStmt * newValue ) { block = newValue; } 353 365 std::list<CatchStmt *>& get_catchers() { return handlers; } 354 366 355 FinallyStmt *get_finally() const { return finallyBlock; } 356 void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; } 357 358 virtual TryStmt *clone() const override { return new TryStmt( *this ); } 359 virtual void accept( Visitor &v ) override { v.visit( this ); } 360 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 361 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 367 FinallyStmt * get_finally() const { return finallyBlock; } 368 void set_finally( FinallyStmt * newValue ) { finallyBlock = newValue; } 369 370 virtual TryStmt * clone() const override { return new TryStmt( *this ); } 371 virtual void accept( Visitor & v ) override { v.visit( this ); } 372 virtual void accept( Visitor & v ) const override { v.visit( this ); } 373 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 374 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 362 375 }; 363 376 … … 367 380 368 381 const Kind kind; 369 Declaration * decl;370 Expression * cond;371 Statement * body;372 373 CatchStmt( Kind kind, Declaration * decl,374 Expression * cond, Statement *body );375 CatchStmt( const CatchStmt & other );382 Declaration * decl; 383 Expression * cond; 384 Statement * body; 385 386 CatchStmt( Kind kind, Declaration * decl, 387 Expression * cond, Statement * body ); 388 CatchStmt( const CatchStmt & other ); 376 389 virtual ~CatchStmt(); 377 390 378 391 Kind get_kind() { return kind; } 379 Declaration *get_decl() { return decl; } 380 void set_decl( Declaration *newValue ) { decl = newValue; } 381 Expression *get_cond() { return cond; } 382 void set_cond( Expression *newCond ) { cond = newCond; } 383 Statement *get_body() { return body; } 384 void set_body( Statement *newValue ) { body = newValue; } 385 386 virtual CatchStmt *clone() const override { return new CatchStmt( *this ); } 387 virtual void accept( Visitor &v ) override { v.visit( this ); } 388 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 389 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 392 Declaration * get_decl() { return decl; } 393 void set_decl( Declaration * newValue ) { decl = newValue; } 394 Expression * get_cond() { return cond; } 395 void set_cond( Expression * newCond ) { cond = newCond; } 396 Statement * get_body() { return body; } 397 void set_body( Statement * newValue ) { body = newValue; } 398 399 virtual CatchStmt * clone() const override { return new CatchStmt( *this ); } 400 virtual void accept( Visitor & v ) override { v.visit( this ); } 401 virtual void accept( Visitor & v ) const override { v.visit( this ); } 402 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 403 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 390 404 }; 391 405 392 406 class FinallyStmt : public Statement { 393 407 public: 394 CompoundStmt * block;395 396 FinallyStmt( CompoundStmt * block );397 FinallyStmt( const FinallyStmt & other );408 CompoundStmt * block; 409 410 FinallyStmt( CompoundStmt * block ); 411 FinallyStmt( const FinallyStmt & other ); 398 412 virtual ~FinallyStmt(); 399 413 400 CompoundStmt *get_block() const { return block; } 401 void set_block( CompoundStmt *newValue ) { block = newValue; } 402 403 virtual FinallyStmt *clone() const override { return new FinallyStmt( *this ); } 404 virtual void accept( Visitor &v ) override { v.visit( this ); } 405 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 406 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 414 CompoundStmt * get_block() const { return block; } 415 void set_block( CompoundStmt * newValue ) { block = newValue; } 416 417 virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); } 418 virtual void accept( Visitor & v ) override { v.visit( this ); } 419 virtual void accept( Visitor & v ) const override { v.visit( this ); } 420 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 421 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 407 422 }; 408 423 … … 438 453 } orelse; 439 454 440 virtual WaitForStmt *clone() const override { return new WaitForStmt( *this ); } 441 virtual void accept( Visitor &v ) override { v.visit( this ); } 442 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 443 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 444 445 }; 446 447 class WithStmt : public Statement { 448 public: 449 std::list< Expression * > exprs; 450 Statement * stmt; 451 452 WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 453 WithStmt( const WithStmt & other ); 454 virtual ~WithStmt(); 455 456 virtual WithStmt * clone() const override { return new WithStmt( *this ); } 457 virtual void accept( Visitor & v ) override { v.visit( this ); } 458 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 459 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 460 }; 455 virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); } 456 virtual void accept( Visitor & v ) override { v.visit( this ); } 457 virtual void accept( Visitor & v ) const override { v.visit( this ); } 458 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 459 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 460 461 }; 462 463 // class WithStmt : public Statement { 464 // public: 465 // std::list< Expression * > exprs; 466 // Statement * stmt; 467 468 // WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 469 // WithStmt( const WithStmt & other ); 470 // virtual ~WithStmt(); 471 472 // virtual WithStmt * clone() const override { return new WithStmt( *this ); } 473 // virtual void accept( Visitor & v ) override { v.visit( this ); } 474 // virtual void accept( Visitor & v ) const override { v.visit( this ); } 475 // virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 476 // virtual void print( std::ostream & os, Indenter indent = {} ) const override; 477 // }; 461 478 462 479 … … 464 481 class DeclStmt : public Statement { 465 482 public: 466 Declaration * decl;467 468 DeclStmt( Declaration * decl );469 DeclStmt( const DeclStmt & other );483 Declaration * decl; 484 485 DeclStmt( Declaration * decl ); 486 DeclStmt( const DeclStmt & other ); 470 487 virtual ~DeclStmt(); 471 488 472 Declaration * get_decl() const { return decl; }473 void set_decl( Declaration * newValue ) { decl = newValue; }474 475 virtual DeclStmt * clone() const override { return new DeclStmt( *this ); }476 virtual void accept( Visitor & v ) override { v.visit( this ); }477 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); }478 virtual void print( std::ostream &os, Indenter indent = {} ) const override;479 };480 481 482 /// represents an implicit application of a constructor or destructor. Qualifiers are replaced 483 /// immediately before and after the call so that qualified objects can be constructed484 /// with the same functions as unqualified objects.489 Declaration * get_decl() const { return decl; } 490 void set_decl( Declaration * newValue ) { decl = newValue; } 491 492 virtual DeclStmt * clone() const override { return new DeclStmt( *this ); } 493 virtual void accept( Visitor & v ) override { v.visit( this ); } 494 virtual void accept( Visitor & v ) const override { v.visit( this ); } 495 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 496 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 497 }; 498 499 500 /// represents an implicit application of a constructor or destructor. Qualifiers are replaced immediately before and 501 /// after the call so that qualified objects can be constructed with the same functions as unqualified objects. 485 502 class ImplicitCtorDtorStmt : public Statement { 486 503 public: … … 492 509 virtual ~ImplicitCtorDtorStmt(); 493 510 494 Statement * get_callStmt() const { return callStmt; }511 Statement * get_callStmt() const { return callStmt; } 495 512 void set_callStmt( Statement * newValue ) { callStmt = newValue; } 496 513 497 virtual ImplicitCtorDtorStmt *clone() const override { return new ImplicitCtorDtorStmt( *this ); } 498 virtual void accept( Visitor &v ) override { v.visit( this ); } 499 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 500 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 514 virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); } 515 virtual void accept( Visitor & v ) override { v.visit( this ); } 516 virtual void accept( Visitor & v ) const override { v.visit( this ); } 517 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 518 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 501 519 }; 502 520 -
src/SynTree/SynTree.h
r7951100 rb067d9b 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 Jul 24 16:54:00 201713 // Update Count : 1 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:37:45 2019 13 // Update Count : 12 14 14 // 15 15 … … 34 34 class NamedTypeDecl; 35 35 class TypeDecl; 36 class FtypeDecl;37 class DtypeDecl;38 36 class TypedefDecl; 39 37 class AsmDecl; … … 81 79 class OffsetofExpr; 82 80 class OffsetPackExpr; 83 class AttrExpr;84 81 class LogicalExpr; 85 82 class ConditionalExpr; … … 90 87 class ConstructorExpr; 91 88 class CompoundLiteralExpr; 92 class UntypedValofExpr;93 89 class RangeExpr; 94 90 class UntypedTupleExpr; … … 101 97 class InitExpr; 102 98 class DeletedExpr; 99 class DefaultArgExpr; 103 100 class GenericExpr; 104 101 … … 109 106 class ArrayType; 110 107 class ReferenceType; 108 class QualifiedType; 111 109 class FunctionType; 112 110 class ReferenceToType; … … 122 120 class ZeroType; 123 121 class OneType; 122 class GlobalScopeType; 124 123 125 124 class Designation; … … 128 127 class ListInit; 129 128 class ConstructorInit; 130 131 class Subrange;132 129 133 130 //template <class T> // emulate a union with templates? -
src/SynTree/TupleExpr.cc
r7951100 rb067d9b 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 : Fri Mar 17 09:42:29 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Aug 14 14:34:00 2019 13 // Update Count : 5 14 14 // 15 15 … … 57 57 } 58 58 59 bool TupleExpr::get_lvalue() const { 60 return false; 61 } 62 59 63 void TupleExpr::print( std::ostream &os, Indenter indent ) const { 60 64 os << "Tuple:" << std::endl; … … 67 71 assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d in expr %s", type->size(), index, toString( tuple ).c_str() ); 68 72 set_result( (*std::next( type->get_types().begin(), index ))->clone() ); 69 // like MemberExpr, TupleIndexExpr is always an lvalue70 get_result()->set_lvalue( true );71 73 } 72 74 … … 76 78 TupleIndexExpr::~TupleIndexExpr() { 77 79 delete tuple; 80 } 81 82 bool TupleIndexExpr::get_lvalue() const { 83 return tuple->get_lvalue(); 78 84 } 79 85 … … 105 111 } 106 112 113 TupleAssignExpr::TupleAssignExpr( 114 StmtExpr * s ) 115 : Expression(), stmtExpr(s) { 116 } 117 118 107 119 TupleAssignExpr::~TupleAssignExpr() { 108 120 delete stmtExpr; -
src/SynTree/Type.cc
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 15:16:32 201713 // Update Count : 3812 // Last Modified On : Sun Aug 4 21:05:07 2019 13 // Update Count : 45 14 14 // 15 15 #include "Type.h" … … 24 24 using namespace std; 25 25 26 const char * BasicType::typeNames[] = {26 const char * BasicType::typeNames[] = { 27 27 "_Bool", 28 28 "char", … … 37 37 "signed long long int", 38 38 "unsigned long long int", 39 "float",40 "double",41 "long double",42 "float _Complex",43 "double _Complex",44 "long double _Complex",45 "float _Imaginary",46 "double _Imaginary",47 "long double _Imaginary",48 39 "__int128", 49 40 "unsigned __int128", 41 "_Float16", 42 "_Float16 _Complex", 43 "_Float32", 44 "_Float32 _Complex", 45 "float", 46 "float _Complex", 47 //"float _Imaginary", 48 "_Float32x", 49 "_Float32x _Complex", 50 "_Float64", 51 "_Float64 _Complex", 52 "double", 53 "double _Complex", 54 //"double _Imaginary", 55 "_Float64x", 56 "_Float64x _Complex", 50 57 "__float80", 51 "__float128" 58 "_Float128", 59 "_Float128 _Complex", 60 "__float128", 61 "long double", 62 "long double _Complex", 63 //"long double _Imaginary", 64 "_Float128x", 65 "_Float128x _Complex", 52 66 }; 53 67 static_assert( 54 sizeof(BasicType::typeNames) /sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,68 sizeof(BasicType::typeNames) / sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES, 55 69 "Each basic type name should have a corresponding kind enum value" 56 70 ); … … 69 83 70 84 // These must remain in the same order as the corresponding bit fields. 71 const char * Type::FuncSpecifiersNames[] = { "inline", " fortran", "_Noreturn" };85 const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" }; 72 86 const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" }; 73 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", " lvalue", "mutex", "_Atomic" };87 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "mutex", "_Atomic" }; 74 88 75 89 Type * Type::stripDeclarator() { … … 86 100 } 87 101 102 const Type * Type::stripReferences() const { 103 const Type * type; 104 const ReferenceType * ref; 105 for ( type = this; (ref = dynamic_cast<const ReferenceType *>( type )); type = ref->base ); 106 return type; 107 } 108 88 109 int Type::referenceDepth() const { return 0; } 89 110 90 111 TypeSubstitution Type::genericSubstitution() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); } 91 112 92 void Type::print( std::ostream & os, Indenter indent ) const {113 void Type::print( std::ostream & os, Indenter indent ) const { 93 114 if ( ! forall.empty() ) { 94 115 os << "forall" << std::endl; … … 105 126 } 106 127 128 129 QualifiedType::QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child ) : Type( tq, {} ), parent( parent ), child( child ) { 130 } 131 132 QualifiedType::QualifiedType( const QualifiedType & other ) : Type( other ), parent( maybeClone( other.parent ) ), child( maybeClone( other.child ) ) { 133 } 134 135 QualifiedType::~QualifiedType() { 136 delete parent; 137 delete child; 138 } 139 140 void QualifiedType::print( std::ostream & os, Indenter indent ) const { 141 os << "Qualified Type:" << endl; 142 os << indent+1; 143 parent->print( os, indent+1 ); 144 os << endl << indent+1; 145 child->print( os, indent+1 ); 146 os << endl; 147 Type::print( os, indent+1 ); 148 } 149 150 GlobalScopeType::GlobalScopeType() : Type( Type::Qualifiers(), {} ) {} 151 152 void GlobalScopeType::print( std::ostream & os, Indenter ) const { 153 os << "Global Scope Type" << endl; 154 } 155 156 107 157 // Empty Variable declarations: 108 158 const Type::FuncSpecifiers noFuncSpecifiers; -
src/SynTree/Type.h
r7951100 rb067d9b 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 : Mon Sep 25 14:14:01 201713 // Update Count : 1 5411 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 4 09:58:00 2019 13 // Update Count : 170 14 14 // 15 15 … … 102 102 }; // StorageClasses 103 103 104 enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Lvalue = 1 << 3, Mutex = 1 << 4, Atomic = 1 << 5, NumTypeQualifier = 6};104 enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Mutex = 1 << 3, Atomic = 1 << 4, NumTypeQualifier = 5 }; 105 105 static const char * QualifiersNames[]; 106 106 union Qualifiers { 107 enum { Mask = ~ (Restrict | Lvalue)};107 enum { Mask = ~Restrict }; 108 108 unsigned int val; 109 109 struct { … … 111 111 bool is_restrict : 1; 112 112 bool is_volatile : 1; 113 bool is_lvalue : 1;114 113 bool is_mutex : 1; 115 114 bool is_atomic : 1; … … 131 130 bool operator>( Qualifiers other ) const { return *this != other && *this >= other; } 132 131 BFCommon( Qualifiers, NumTypeQualifier ) 132 133 Qualifiers unify( Qualifiers const & other ) const { 134 int or_flags = Mask & (val | other.val); 135 int and_flags = val & other.val; 136 return Qualifiers( or_flags | and_flags ); 137 } 133 138 }; // Qualifiers 134 139 … … 144 149 145 150 Qualifiers & get_qualifiers() { return tq; } 146 bool get_const() { return tq.is_const; } 147 bool get_volatile() { return tq.is_volatile; } 148 bool get_restrict() { return tq.is_restrict; } 149 bool get_lvalue() { return tq.is_lvalue; } 150 bool get_mutex() { return tq.is_mutex; } 151 bool get_atomic() { return tq.is_atomic; } 151 bool get_const() const { return tq.is_const; } 152 bool get_volatile() const { return tq.is_volatile; } 153 bool get_restrict() const { return tq.is_restrict; } 154 bool get_mutex() const { return tq.is_mutex; } 155 bool get_atomic() const { return tq.is_atomic; } 152 156 void set_const( bool newValue ) { tq.is_const = newValue; } 153 157 void set_volatile( bool newValue ) { tq.is_volatile = newValue; } 154 158 void set_restrict( bool newValue ) { tq.is_restrict = newValue; } 155 void set_lvalue( bool newValue ) { tq.is_lvalue = newValue; }156 159 void set_mutex( bool newValue ) { tq.is_mutex = newValue; } 157 160 void set_atomic( bool newValue ) { tq.is_atomic = newValue; } … … 172 175 /// return type without outer references 173 176 Type * stripReferences(); 177 const Type * stripReferences() const; 174 178 175 179 /// return the number of references occuring consecutively on the outermost layer of this type (i.e. do not count references nested within other types) … … 178 182 virtual bool isComplete() const { return true; } 179 183 180 virtual AggregateDecl * getAggr() { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }184 virtual AggregateDecl * getAggr() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); } 181 185 182 186 virtual TypeSubstitution genericSubstitution() const; … … 184 188 virtual Type *clone() const = 0; 185 189 virtual void accept( Visitor & v ) = 0; 190 virtual void accept( Visitor & v ) const = 0; 186 191 virtual Type *acceptMutator( Mutator & m ) = 0; 187 192 virtual void print( std::ostream & os, Indenter indent = {} ) const; … … 201 206 virtual VoidType *clone() const override { return new VoidType( *this ); } 202 207 virtual void accept( Visitor & v ) override { v.visit( this ); } 208 virtual void accept( Visitor & v ) const override { v.visit( this ); } 203 209 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 204 210 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 207 213 class BasicType : public Type { 208 214 public: 215 // GENERATED START, DO NOT EDIT 216 // GENERATED BY BasicTypes-gen.cc 209 217 enum Kind { 210 218 Bool, … … 220 228 LongLongSignedInt, 221 229 LongLongUnsignedInt, 222 Float,223 Double,224 LongDouble,225 FloatComplex,226 DoubleComplex,227 LongDoubleComplex,228 FloatImaginary,229 DoubleImaginary,230 LongDoubleImaginary,231 230 SignedInt128, 232 231 UnsignedInt128, 233 Float80, 234 Float128, 232 uFloat16, 233 uFloat16Complex, 234 uFloat32, 235 uFloat32Complex, 236 Float, 237 FloatComplex, 238 uFloat32x, 239 uFloat32xComplex, 240 uFloat64, 241 uFloat64Complex, 242 Double, 243 DoubleComplex, 244 uFloat64x, 245 uFloat64xComplex, 246 uuFloat80, 247 uFloat128, 248 uFloat128Complex, 249 uuFloat128, 250 LongDouble, 251 LongDoubleComplex, 252 uFloat128x, 253 uFloat128xComplex, 235 254 NUMBER_OF_BASIC_TYPES 236 255 } kind; 256 // GENERATED END 237 257 238 258 static const char *typeNames[]; // string names for basic types, MUST MATCH with Kind … … 240 260 BasicType( const Type::Qualifiers & tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 241 261 242 Kind get_kind() { return kind; }262 Kind get_kind() const { return kind; } 243 263 void set_kind( Kind newValue ) { kind = newValue; } 244 264 245 265 virtual BasicType *clone() const override { return new BasicType( *this ); } 246 266 virtual void accept( Visitor & v ) override { v.visit( this ); } 267 virtual void accept( Visitor & v ) const override { v.visit( this ); } 247 268 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 248 269 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 280 301 virtual PointerType *clone() const override { return new PointerType( *this ); } 281 302 virtual void accept( Visitor & v ) override { v.visit( this ); } 303 virtual void accept( Visitor & v ) const override { v.visit( this ); } 282 304 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 283 305 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 311 333 virtual ArrayType *clone() const override { return new ArrayType( *this ); } 312 334 virtual void accept( Visitor & v ) override { v.visit( this ); } 335 virtual void accept( Visitor & v ) const override { v.visit( this ); } 336 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 337 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 338 }; 339 340 class QualifiedType : public Type { 341 public: 342 Type * parent; 343 Type * child; 344 345 QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child ); 346 QualifiedType( const QualifiedType & tq ); 347 virtual ~QualifiedType(); 348 349 virtual QualifiedType *clone() const override { return new QualifiedType( *this ); } 350 virtual void accept( Visitor & v ) override { v.visit( this ); } 351 virtual void accept( Visitor & v ) const override { v.visit( this ); } 313 352 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 314 353 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 337 376 virtual ReferenceType *clone() const override { return new ReferenceType( *this ); } 338 377 virtual void accept( Visitor & v ) override { v.visit( this ); } 378 virtual void accept( Visitor & v ) const override { v.visit( this ); } 339 379 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 340 380 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 366 406 virtual FunctionType *clone() const override { return new FunctionType( *this ); } 367 407 virtual void accept( Visitor & v ) override { v.visit( this ); } 408 virtual void accept( Visitor & v ) const override { v.visit( this ); } 368 409 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 369 410 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 416 457 virtual bool isComplete() const override; 417 458 418 virtual AggregateDecl * getAggr() override;459 virtual AggregateDecl * getAggr() const override; 419 460 420 461 virtual TypeSubstitution genericSubstitution() const override; … … 426 467 virtual StructInstType *clone() const override { return new StructInstType( *this ); } 427 468 virtual void accept( Visitor & v ) override { v.visit( this ); } 469 virtual void accept( Visitor & v ) const override { v.visit( this ); } 428 470 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 429 471 … … 453 495 virtual bool isComplete() const override; 454 496 455 virtual AggregateDecl * getAggr() override;497 virtual AggregateDecl * getAggr() const override; 456 498 457 499 virtual TypeSubstitution genericSubstitution() const override; … … 463 505 virtual UnionInstType *clone() const override { return new UnionInstType( *this ); } 464 506 virtual void accept( Visitor & v ) override { v.visit( this ); } 507 virtual void accept( Visitor & v ) const override { v.visit( this ); } 465 508 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 466 509 … … 486 529 virtual bool isComplete() const override; 487 530 531 virtual AggregateDecl * getAggr() const override; 532 488 533 virtual EnumInstType *clone() const override { return new EnumInstType( *this ); } 489 534 virtual void accept( Visitor & v ) override { v.visit( this ); } 535 virtual void accept( Visitor & v ) const override { v.visit( this ); } 490 536 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 491 537 … … 511 557 virtual TraitInstType *clone() const override { return new TraitInstType( *this ); } 512 558 virtual void accept( Visitor & v ) override { v.visit( this ); } 559 virtual void accept( Visitor & v ) const override { v.visit( this ); } 513 560 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 514 561 private: … … 538 585 virtual TypeInstType *clone() const override { return new TypeInstType( *this ); } 539 586 virtual void accept( Visitor & v ) override { v.visit( this ); } 587 virtual void accept( Visitor & v ) const override { v.visit( this ); } 540 588 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 541 589 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 575 623 virtual TupleType *clone() const override { return new TupleType( *this ); } 576 624 virtual void accept( Visitor & v ) override { v.visit( this ); } 625 virtual void accept( Visitor & v ) const override { v.visit( this ); } 577 626 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 578 627 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 581 630 class TypeofType : public Type { 582 631 public: 583 Expression *expr; 584 585 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 632 Expression *expr; ///< expression to take the type of 633 bool is_basetypeof; ///< true iff is basetypeof type 634 635 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 636 TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 637 const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 586 638 TypeofType( const TypeofType& ); 587 639 virtual ~TypeofType(); … … 594 646 virtual TypeofType *clone() const override { return new TypeofType( *this ); } 595 647 virtual void accept( Visitor & v ) override { v.visit( this ); } 648 virtual void accept( Visitor & v ) const override { v.visit( this ); } 596 649 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 597 650 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 623 676 virtual AttrType *clone() const override { return new AttrType( *this ); } 624 677 virtual void accept( Visitor & v ) override { v.visit( this ); } 678 virtual void accept( Visitor & v ) const override { v.visit( this ); } 625 679 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 626 680 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 637 691 virtual VarArgsType *clone() const override { return new VarArgsType( *this ); } 638 692 virtual void accept( Visitor & v ) override { v.visit( this ); } 693 virtual void accept( Visitor & v ) const override { v.visit( this ); } 639 694 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 640 695 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 649 704 virtual ZeroType *clone() const override { return new ZeroType( *this ); } 650 705 virtual void accept( Visitor & v ) override { v.visit( this ); } 706 virtual void accept( Visitor & v ) const override { v.visit( this ); } 651 707 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 652 708 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 661 717 virtual OneType *clone() const override { return new OneType( *this ); } 662 718 virtual void accept( Visitor & v ) override { v.visit( this ); } 719 virtual void accept( Visitor & v ) const override { v.visit( this ); } 720 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 721 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 722 }; 723 724 class GlobalScopeType : public Type { 725 public: 726 GlobalScopeType(); 727 728 virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); } 729 virtual void accept( Visitor & v ) override { v.visit( this ); } 730 virtual void accept( Visitor & v ) const override { v.visit( this ); } 663 731 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 664 732 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/TypeSubstitution.cc
r7951100 rb067d9b 64 64 } 65 65 66 void TypeSubstitution::addVar( std::string formalExpr, Expression *actualExpr ) { 67 varEnv[ formalExpr ] = actualExpr; 68 } 69 66 70 void TypeSubstitution::remove( std::string formalType ) { 67 71 TypeEnvType::iterator i = typeEnv.find( formalType ); … … 108 112 namespace { 109 113 struct EnvTrimmer { 110 TypeSubstitution * env, * newEnv; 111 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 114 const TypeSubstitution * env; 115 TypeSubstitution * newEnv; 116 EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 112 117 void previsit( TypeDecl * tyDecl ) { 113 118 // transfer known bindings for seen type variables … … 120 125 121 126 /// reduce environment to just the parts that are referenced in a given expression 122 TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, TypeSubstitution * env ) {127 TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, const TypeSubstitution * env ) { 123 128 if ( env ) { 124 129 TypeSubstitution * newEnv = new TypeSubstitution(); -
src/SynTree/TypeSubstitution.h
r7951100 rb067d9b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:52:24 201713 // Update Count : 312 // Last Modified On : Tue Apr 30 22:52:47 2019 13 // Update Count : 9 14 14 // 15 15 … … 19 19 #include <iosfwd> // for ostream 20 20 #include <list> // for list<>::iterator, _List_iterator 21 #include < map> // for _Rb_tree_iterator, map, map<>::val...22 #include < set> // for set21 #include <unordered_map> 22 #include <unordered_set> 23 23 #include <string> // for string, operator!= 24 24 #include <utility> // for pair … … 39 39 TypeSubstitution &operator=( const TypeSubstitution &other ); 40 40 41 template< typename SynTreeClass > int apply( SynTreeClass *&input ) ;42 template< typename SynTreeClass > int applyFree( SynTreeClass *&input ) ;41 template< typename SynTreeClass > int apply( SynTreeClass *&input ) const; 42 template< typename SynTreeClass > int applyFree( SynTreeClass *&input ) const; 43 43 44 44 void add( std::string formalType, Type *actualType ); … … 48 48 bool empty() const; 49 49 50 void addVar( std::string formalExpr, Expression *actualExpr ); 51 50 52 template< typename FormalIterator, typename ActualIterator > 51 53 void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ); … … 56 58 57 59 /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr 58 static TypeSubstitution * newFromExpr( Expression * expr, TypeSubstitution * env );60 static TypeSubstitution * newFromExpr( Expression * expr, const TypeSubstitution * env ); 59 61 60 62 void normalize(); … … 78 80 friend class PassVisitor; 79 81 80 typedef std:: map< std::string, Type* > TypeEnvType;81 typedef std:: map< std::string, Expression* > VarEnvType;82 typedef std::unordered_map< std::string, Type * > TypeEnvType; 83 typedef std::unordered_map< std::string, Expression * > VarEnvType; 82 84 TypeEnvType typeEnv; 83 85 VarEnvType varEnv; … … 89 91 auto begin() const -> decltype( typeEnv.begin() ) { return typeEnv.begin(); } 90 92 auto end() const -> decltype( typeEnv. end() ) { return typeEnv. end(); } 93 94 auto beginVar() -> decltype( varEnv.begin() ) { return varEnv.begin(); } 95 auto endVar() -> decltype( varEnv. end() ) { return varEnv. end(); } 96 auto beginVar() const -> decltype( varEnv.begin() ) { return varEnv.begin(); } 97 auto endVar() const -> decltype( varEnv. end() ) { return varEnv. end(); } 91 98 }; 92 99 … … 98 105 ActualIterator actualIt = actualBegin; 99 106 for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) { 100 if ( TypeDecl *formal = dynamic_cast< TypeDecl * >( *formalIt ) ) {101 if ( TypeExpr *actual = dynamic_cast< TypeExpr * >( *actualIt ) ) {107 if ( TypeDecl *formal = dynamic_cast< TypeDecl * >( *formalIt ) ) { 108 if ( TypeExpr *actual = dynamic_cast< TypeExpr * >( *actualIt ) ) { 102 109 if ( formal->get_name() != "" ) { 103 110 TypeEnvType::iterator i = typeEnv.find( formal->get_name() ); … … 130 137 // definitition must happen after PassVisitor is included so that WithGuards can be used 131 138 struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> { 132 Substituter( TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}139 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {} 133 140 134 141 Type * postmutate( TypeInstType * aggregateUseType ); … … 143 150 void premutate( UnionInstType * aggregateUseType ); 144 151 145 TypeSubstitution & sub;152 const TypeSubstitution & sub; 146 153 int subCount = 0; 147 154 bool freeOnly; 148 typedef std:: set< std::string > BoundVarsType;155 typedef std::unordered_set< std::string > BoundVarsType; 149 156 BoundVarsType boundVars; 150 157 }; 151 158 152 159 template< typename SynTreeClass > 153 int TypeSubstitution::apply( SynTreeClass *&input ) {160 int TypeSubstitution::apply( SynTreeClass *&input ) const { 154 161 assert( input ); 155 162 PassVisitor<Substituter> sub( *this, false ); … … 163 170 164 171 template< typename SynTreeClass > 165 int TypeSubstitution::applyFree( SynTreeClass *&input ) {172 int TypeSubstitution::applyFree( SynTreeClass *&input ) const { 166 173 assert( input ); 167 174 PassVisitor<Substituter> sub( *this, true ); -
src/SynTree/TypeofType.cc
r7951100 rb067d9b 23 23 class Attribute; 24 24 25 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), expr( expr ) { 26 } 25 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, 26 const std::list< Attribute * > & attributes ) 27 : Type( tq, attributes ), expr( expr ), is_basetypeof(false) {} 27 28 28 TypeofType::TypeofType( const TypeofType &other ) : Type( other ), expr( maybeClone( other.expr ) ) { 29 } 29 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, bool is_basetypeof, 30 const std::list< Attribute * > & attributes ) 31 : Type( tq, attributes ), expr( expr ), is_basetypeof( is_basetypeof ) {} 32 33 TypeofType::TypeofType( const TypeofType &other ) 34 : Type( other ), expr( maybeClone( other.expr ) ), is_basetypeof( other.is_basetypeof ) {} 30 35 31 36 TypeofType::~TypeofType() { … … 35 40 void TypeofType::print( std::ostream &os, Indenter indent ) const { 36 41 Type::print( os, indent ); 42 if ( is_basetypeof ) { os << "base-"; } 37 43 os << "type-of expression "; 38 44 if ( expr ) { -
src/SynTree/Visitor.h
r7951100 rb067d9b 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 Jul 24 16:28:00 201713 // Update Count : 1 311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:21:49 2019 13 // Update Count : 14 14 14 // 15 15 … … 27 27 // of the given syntax node, but performs no other action. 28 28 29 virtual void visit( ObjectDecl * objectDecl ) = 0; 30 virtual void visit( FunctionDecl * functionDecl ) = 0; 31 virtual void visit( StructDecl * aggregateDecl ) = 0; 32 virtual void visit( UnionDecl * aggregateDecl ) = 0; 33 virtual void visit( EnumDecl * aggregateDecl ) = 0; 34 virtual void visit( TraitDecl * aggregateDecl ) = 0; 35 virtual void visit( TypeDecl * typeDecl ) = 0; 36 virtual void visit( TypedefDecl * typeDecl ) = 0; 37 virtual void visit( AsmDecl * asmDecl ) = 0; 38 virtual void visit( StaticAssertDecl * assertDecl ) = 0; 39 40 virtual void visit( CompoundStmt * compoundStmt ) = 0; 41 virtual void visit( ExprStmt * exprStmt ) = 0; 42 virtual void visit( AsmStmt * asmStmt ) = 0; 43 virtual void visit( DirectiveStmt * directiveStmt ) = 0; 44 virtual void visit( IfStmt * ifStmt ) = 0; 45 virtual void visit( WhileStmt * whileStmt ) = 0; 46 virtual void visit( ForStmt * forStmt ) = 0; 47 virtual void visit( SwitchStmt * switchStmt ) = 0; 48 virtual void visit( CaseStmt * caseStmt ) = 0; 49 virtual void visit( BranchStmt * branchStmt ) = 0; 50 virtual void visit( ReturnStmt * returnStmt ) = 0; 51 virtual void visit( ThrowStmt * throwStmt ) = 0; 52 virtual void visit( TryStmt * tryStmt ) = 0; 53 virtual void visit( CatchStmt * catchStmt ) = 0; 54 virtual void visit( FinallyStmt * finallyStmt ) = 0; 55 virtual void visit( WaitForStmt * waitforStmt ) = 0; 56 virtual void visit( WithStmt * withStmt ) = 0; 57 virtual void visit( NullStmt * nullStmt ) = 0; 58 virtual void visit( DeclStmt * declStmt ) = 0; 59 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0; 60 61 virtual void visit( ApplicationExpr * applicationExpr ) = 0; 62 virtual void visit( UntypedExpr * untypedExpr ) = 0; 63 virtual void visit( NameExpr * nameExpr ) = 0; 64 virtual void visit( CastExpr * castExpr ) = 0; 65 virtual void visit( KeywordCastExpr * castExpr ) = 0; 66 virtual void visit( VirtualCastExpr * castExpr ) = 0; 67 virtual void visit( AddressExpr * addressExpr ) = 0; 68 virtual void visit( LabelAddressExpr * labAddressExpr ) = 0; 69 virtual void visit( UntypedMemberExpr * memberExpr ) = 0; 70 virtual void visit( MemberExpr * memberExpr ) = 0; 71 virtual void visit( VariableExpr * variableExpr ) = 0; 72 virtual void visit( ConstantExpr * constantExpr ) = 0; 73 virtual void visit( SizeofExpr * sizeofExpr ) = 0; 74 virtual void visit( AlignofExpr * alignofExpr ) = 0; 75 virtual void visit( UntypedOffsetofExpr * offsetofExpr ) = 0; 76 virtual void visit( OffsetofExpr * offsetofExpr ) = 0; 77 virtual void visit( OffsetPackExpr * offsetPackExpr ) = 0; 78 virtual void visit( AttrExpr * attrExpr ) = 0; 79 virtual void visit( LogicalExpr * logicalExpr ) = 0; 80 virtual void visit( ConditionalExpr * conditionalExpr ) = 0; 81 virtual void visit( CommaExpr * commaExpr ) = 0; 82 virtual void visit( TypeExpr * typeExpr ) = 0; 83 virtual void visit( AsmExpr * asmExpr ) = 0; 84 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) = 0; 85 virtual void visit( ConstructorExpr * ctorExpr ) = 0; 86 virtual void visit( CompoundLiteralExpr * compLitExpr ) = 0; 87 virtual void visit( RangeExpr * rangeExpr ) = 0; 88 virtual void visit( UntypedTupleExpr * tupleExpr ) = 0; 89 virtual void visit( TupleExpr * tupleExpr ) = 0; 90 virtual void visit( TupleIndexExpr * tupleExpr ) = 0; 91 virtual void visit( TupleAssignExpr * assignExpr ) = 0; 92 virtual void visit( StmtExpr * stmtExpr ) = 0; 93 virtual void visit( UniqueExpr * uniqueExpr ) = 0; 94 virtual void visit( UntypedInitExpr * initExpr ) = 0; 95 virtual void visit( InitExpr * initExpr ) = 0; 96 virtual void visit( DeletedExpr * delExpr ) = 0; 97 virtual void visit( GenericExpr * genExpr ) = 0; 98 99 virtual void visit( VoidType * basicType ) = 0; 100 virtual void visit( BasicType * basicType ) = 0; 101 virtual void visit( PointerType * pointerType ) = 0; 102 virtual void visit( ArrayType * arrayType ) = 0; 103 virtual void visit( ReferenceType * refType ) = 0; 104 virtual void visit( FunctionType * functionType ) = 0; 105 virtual void visit( StructInstType * aggregateUseType ) = 0; 106 virtual void visit( UnionInstType * aggregateUseType ) = 0; 107 virtual void visit( EnumInstType * aggregateUseType ) = 0; 108 virtual void visit( TraitInstType * aggregateUseType ) = 0; 109 virtual void visit( TypeInstType * aggregateUseType ) = 0; 110 virtual void visit( TupleType * tupleType ) = 0; 111 virtual void visit( TypeofType * typeofType ) = 0; 112 virtual void visit( AttrType * attrType ) = 0; 113 virtual void visit( VarArgsType * varArgsType ) = 0; 114 virtual void visit( ZeroType * zeroType ) = 0; 115 virtual void visit( OneType * oneType ) = 0; 116 117 virtual void visit( Designation * designation ) = 0; 118 virtual void visit( SingleInit * singleInit ) = 0; 119 virtual void visit( ListInit * listInit ) = 0; 120 virtual void visit( ConstructorInit * ctorInit ) = 0; 121 122 virtual void visit( Subrange * subrange ) = 0; 123 124 virtual void visit( Constant * constant ) = 0; 125 126 virtual void visit( Attribute * attribute ) = 0; 29 virtual void visit( ObjectDecl * node ) { visit( const_cast<const ObjectDecl *>(node) ); } 30 virtual void visit( const ObjectDecl * objectDecl ) = 0; 31 virtual void visit( FunctionDecl * node ) { visit( const_cast<const FunctionDecl *>(node) ); } 32 virtual void visit( const FunctionDecl * functionDecl ) = 0; 33 virtual void visit( StructDecl * node ) { visit( const_cast<const StructDecl *>(node) ); } 34 virtual void visit( const StructDecl * aggregateDecl ) = 0; 35 virtual void visit( UnionDecl * node ) { visit( const_cast<const UnionDecl *>(node) ); } 36 virtual void visit( const UnionDecl * aggregateDecl ) = 0; 37 virtual void visit( EnumDecl * node ) { visit( const_cast<const EnumDecl *>(node) ); } 38 virtual void visit( const EnumDecl * aggregateDecl ) = 0; 39 virtual void visit( TraitDecl * node ) { visit( const_cast<const TraitDecl *>(node) ); } 40 virtual void visit( const TraitDecl * aggregateDecl ) = 0; 41 virtual void visit( TypeDecl * node ) { visit( const_cast<const TypeDecl *>(node) ); } 42 virtual void visit( const TypeDecl * typeDecl ) = 0; 43 virtual void visit( TypedefDecl * node ) { visit( const_cast<const TypedefDecl *>(node) ); } 44 virtual void visit( const TypedefDecl * typeDecl ) = 0; 45 virtual void visit( AsmDecl * node ) { visit( const_cast<const AsmDecl *>(node) ); } 46 virtual void visit( const AsmDecl * asmDecl ) = 0; 47 virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); } 48 virtual void visit( const StaticAssertDecl * assertDecl ) = 0; 49 50 virtual void visit( CompoundStmt * node ) { visit( const_cast<const CompoundStmt *>(node) ); } 51 virtual void visit( const CompoundStmt * compoundStmt ) = 0; 52 virtual void visit( ExprStmt * node ) { visit( const_cast<const ExprStmt *>(node) ); } 53 virtual void visit( const ExprStmt * exprStmt ) = 0; 54 virtual void visit( AsmStmt * node ) { visit( const_cast<const AsmStmt *>(node) ); } 55 virtual void visit( const AsmStmt * asmStmt ) = 0; 56 virtual void visit( DirectiveStmt * node ) { visit( const_cast<const DirectiveStmt *>(node) ); } 57 virtual void visit( const DirectiveStmt * directiveStmt ) = 0; 58 virtual void visit( IfStmt * node ) { visit( const_cast<const IfStmt *>(node) ); } 59 virtual void visit( const IfStmt * ifStmt ) = 0; 60 virtual void visit( WhileStmt * node ) { visit( const_cast<const WhileStmt *>(node) ); } 61 virtual void visit( const WhileStmt * whileStmt ) = 0; 62 virtual void visit( ForStmt * node ) { visit( const_cast<const ForStmt *>(node) ); } 63 virtual void visit( const ForStmt * forStmt ) = 0; 64 virtual void visit( SwitchStmt * node ) { visit( const_cast<const SwitchStmt *>(node) ); } 65 virtual void visit( const SwitchStmt * switchStmt ) = 0; 66 virtual void visit( CaseStmt * node ) { visit( const_cast<const CaseStmt *>(node) ); } 67 virtual void visit( const CaseStmt * caseStmt ) = 0; 68 virtual void visit( BranchStmt * node ) { visit( const_cast<const BranchStmt *>(node) ); } 69 virtual void visit( const BranchStmt * branchStmt ) = 0; 70 virtual void visit( ReturnStmt * node ) { visit( const_cast<const ReturnStmt *>(node) ); } 71 virtual void visit( const ReturnStmt * returnStmt ) = 0; 72 virtual void visit( ThrowStmt * node ) { visit( const_cast<const ThrowStmt *>(node) ); } 73 virtual void visit( const ThrowStmt * throwStmt ) = 0; 74 virtual void visit( TryStmt * node ) { visit( const_cast<const TryStmt *>(node) ); } 75 virtual void visit( const TryStmt * tryStmt ) = 0; 76 virtual void visit( CatchStmt * node ) { visit( const_cast<const CatchStmt *>(node) ); } 77 virtual void visit( const CatchStmt * catchStmt ) = 0; 78 virtual void visit( FinallyStmt * node ) { visit( const_cast<const FinallyStmt *>(node) ); } 79 virtual void visit( const FinallyStmt * finallyStmt ) = 0; 80 virtual void visit( WaitForStmt * node ) { visit( const_cast<const WaitForStmt *>(node) ); } 81 virtual void visit( const WaitForStmt * waitforStmt ) = 0; 82 virtual void visit( WithStmt * node ) { visit( const_cast<const WithStmt *>(node) ); } 83 virtual void visit( const WithStmt * withStmt ) = 0; 84 virtual void visit( NullStmt * node ) { visit( const_cast<const NullStmt *>(node) ); } 85 virtual void visit( const NullStmt * nullStmt ) = 0; 86 virtual void visit( DeclStmt * node ) { visit( const_cast<const DeclStmt *>(node) ); } 87 virtual void visit( const DeclStmt * declStmt ) = 0; 88 virtual void visit( ImplicitCtorDtorStmt * node ) { visit( const_cast<const ImplicitCtorDtorStmt *>(node) ); } 89 virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0; 90 91 virtual void visit( ApplicationExpr * node ) { visit( const_cast<const ApplicationExpr *>(node) ); } 92 virtual void visit( const ApplicationExpr * applicationExpr ) = 0; 93 virtual void visit( UntypedExpr * node ) { visit( const_cast<const UntypedExpr *>(node) ); } 94 virtual void visit( const UntypedExpr * untypedExpr ) = 0; 95 virtual void visit( NameExpr * node ) { visit( const_cast<const NameExpr *>(node) ); } 96 virtual void visit( const NameExpr * nameExpr ) = 0; 97 virtual void visit( CastExpr * node ) { visit( const_cast<const CastExpr *>(node) ); } 98 virtual void visit( const CastExpr * castExpr ) = 0; 99 virtual void visit( KeywordCastExpr * node ) { visit( const_cast<const KeywordCastExpr *>(node) ); } 100 virtual void visit( const KeywordCastExpr * castExpr ) = 0; 101 virtual void visit( VirtualCastExpr * node ) { visit( const_cast<const VirtualCastExpr *>(node) ); } 102 virtual void visit( const VirtualCastExpr * castExpr ) = 0; 103 virtual void visit( AddressExpr * node ) { visit( const_cast<const AddressExpr *>(node) ); } 104 virtual void visit( const AddressExpr * addressExpr ) = 0; 105 virtual void visit( LabelAddressExpr * node ) { visit( const_cast<const LabelAddressExpr *>(node) ); } 106 virtual void visit( const LabelAddressExpr * labAddressExpr ) = 0; 107 virtual void visit( UntypedMemberExpr * node ) { visit( const_cast<const UntypedMemberExpr *>(node) ); } 108 virtual void visit( const UntypedMemberExpr * memberExpr ) = 0; 109 virtual void visit( MemberExpr * node ) { visit( const_cast<const MemberExpr *>(node) ); } 110 virtual void visit( const MemberExpr * memberExpr ) = 0; 111 virtual void visit( VariableExpr * node ) { visit( const_cast<const VariableExpr *>(node) ); } 112 virtual void visit( const VariableExpr * variableExpr ) = 0; 113 virtual void visit( ConstantExpr * node ) { visit( const_cast<const ConstantExpr *>(node) ); } 114 virtual void visit( const ConstantExpr * constantExpr ) = 0; 115 virtual void visit( SizeofExpr * node ) { visit( const_cast<const SizeofExpr *>(node) ); } 116 virtual void visit( const SizeofExpr * sizeofExpr ) = 0; 117 virtual void visit( AlignofExpr * node ) { visit( const_cast<const AlignofExpr *>(node) ); } 118 virtual void visit( const AlignofExpr * alignofExpr ) = 0; 119 virtual void visit( UntypedOffsetofExpr * node ) { visit( const_cast<const UntypedOffsetofExpr *>(node) ); } 120 virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) = 0; 121 virtual void visit( OffsetofExpr * node ) { visit( const_cast<const OffsetofExpr *>(node) ); } 122 virtual void visit( const OffsetofExpr * offsetofExpr ) = 0; 123 virtual void visit( OffsetPackExpr * node ) { visit( const_cast<const OffsetPackExpr *>(node) ); } 124 virtual void visit( const OffsetPackExpr * offsetPackExpr ) = 0; 125 virtual void visit( LogicalExpr * node ) { visit( const_cast<const LogicalExpr *>(node) ); } 126 virtual void visit( const LogicalExpr * logicalExpr ) = 0; 127 virtual void visit( ConditionalExpr * node ) { visit( const_cast<const ConditionalExpr *>(node) ); } 128 virtual void visit( const ConditionalExpr * conditionalExpr ) = 0; 129 virtual void visit( CommaExpr * node ) { visit( const_cast<const CommaExpr *>(node) ); } 130 virtual void visit( const CommaExpr * commaExpr ) = 0; 131 virtual void visit( TypeExpr * node ) { visit( const_cast<const TypeExpr *>(node) ); } 132 virtual void visit( const TypeExpr * typeExpr ) = 0; 133 virtual void visit( AsmExpr * node ) { visit( const_cast<const AsmExpr *>(node) ); } 134 virtual void visit( const AsmExpr * asmExpr ) = 0; 135 virtual void visit( ImplicitCopyCtorExpr * node ) { visit( const_cast<const ImplicitCopyCtorExpr *>(node) ); } 136 virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) = 0; 137 virtual void visit( ConstructorExpr * node ) { visit( const_cast<const ConstructorExpr *>(node) ); } 138 virtual void visit( const ConstructorExpr * ctorExpr ) = 0; 139 virtual void visit( CompoundLiteralExpr * node ) { visit( const_cast<const CompoundLiteralExpr *>(node) ); } 140 virtual void visit( const CompoundLiteralExpr * compLitExpr ) = 0; 141 virtual void visit( RangeExpr * node ) { visit( const_cast<const RangeExpr *>(node) ); } 142 virtual void visit( const RangeExpr * rangeExpr ) = 0; 143 virtual void visit( UntypedTupleExpr * node ) { visit( const_cast<const UntypedTupleExpr *>(node) ); } 144 virtual void visit( const UntypedTupleExpr * tupleExpr ) = 0; 145 virtual void visit( TupleExpr * node ) { visit( const_cast<const TupleExpr *>(node) ); } 146 virtual void visit( const TupleExpr * tupleExpr ) = 0; 147 virtual void visit( TupleIndexExpr * node ) { visit( const_cast<const TupleIndexExpr *>(node) ); } 148 virtual void visit( const TupleIndexExpr * tupleExpr ) = 0; 149 virtual void visit( TupleAssignExpr * node ) { visit( const_cast<const TupleAssignExpr *>(node) ); } 150 virtual void visit( const TupleAssignExpr * assignExpr ) = 0; 151 virtual void visit( StmtExpr * node ) { visit( const_cast<const StmtExpr *>(node) ); } 152 virtual void visit( const StmtExpr * stmtExpr ) = 0; 153 virtual void visit( UniqueExpr * node ) { visit( const_cast<const UniqueExpr *>(node) ); } 154 virtual void visit( const UniqueExpr * uniqueExpr ) = 0; 155 virtual void visit( UntypedInitExpr * node ) { visit( const_cast<const UntypedInitExpr *>(node) ); } 156 virtual void visit( const UntypedInitExpr * initExpr ) = 0; 157 virtual void visit( InitExpr * node ) { visit( const_cast<const InitExpr *>(node) ); } 158 virtual void visit( const InitExpr * initExpr ) = 0; 159 virtual void visit( DeletedExpr * node ) { visit( const_cast<const DeletedExpr *>(node) ); } 160 virtual void visit( const DeletedExpr * delExpr ) = 0; 161 virtual void visit( DefaultArgExpr * node ) { visit( const_cast<const DefaultArgExpr *>(node) ); } 162 virtual void visit( const DefaultArgExpr * argExpr ) = 0; 163 virtual void visit( GenericExpr * node ) { visit( const_cast<const GenericExpr *>(node) ); } 164 virtual void visit( const GenericExpr * genExpr ) = 0; 165 166 virtual void visit( VoidType * node ) { visit( const_cast<const VoidType *>(node) ); } 167 virtual void visit( const VoidType * basicType ) = 0; 168 virtual void visit( BasicType * node ) { visit( const_cast<const BasicType *>(node) ); } 169 virtual void visit( const BasicType * basicType ) = 0; 170 virtual void visit( PointerType * node ) { visit( const_cast<const PointerType *>(node) ); } 171 virtual void visit( const PointerType * pointerType ) = 0; 172 virtual void visit( ArrayType * node ) { visit( const_cast<const ArrayType *>(node) ); } 173 virtual void visit( const ArrayType * arrayType ) = 0; 174 virtual void visit( ReferenceType * node ) { visit( const_cast<const ReferenceType *>(node) ); } 175 virtual void visit( const ReferenceType * refType ) = 0; 176 virtual void visit( QualifiedType * node ) { visit( const_cast<const QualifiedType *>(node) ); } 177 virtual void visit( const QualifiedType * qualType ) = 0; 178 virtual void visit( FunctionType * node ) { visit( const_cast<const FunctionType *>(node) ); } 179 virtual void visit( const FunctionType * functionType ) = 0; 180 virtual void visit( StructInstType * node ) { visit( const_cast<const StructInstType *>(node) ); } 181 virtual void visit( const StructInstType * aggregateUseType ) = 0; 182 virtual void visit( UnionInstType * node ) { visit( const_cast<const UnionInstType *>(node) ); } 183 virtual void visit( const UnionInstType * aggregateUseType ) = 0; 184 virtual void visit( EnumInstType * node ) { visit( const_cast<const EnumInstType *>(node) ); } 185 virtual void visit( const EnumInstType * aggregateUseType ) = 0; 186 virtual void visit( TraitInstType * node ) { visit( const_cast<const TraitInstType *>(node) ); } 187 virtual void visit( const TraitInstType * aggregateUseType ) = 0; 188 virtual void visit( TypeInstType * node ) { visit( const_cast<const TypeInstType *>(node) ); } 189 virtual void visit( const TypeInstType * aggregateUseType ) = 0; 190 virtual void visit( TupleType * node ) { visit( const_cast<const TupleType *>(node) ); } 191 virtual void visit( const TupleType * tupleType ) = 0; 192 virtual void visit( TypeofType * node ) { visit( const_cast<const TypeofType *>(node) ); } 193 virtual void visit( const TypeofType * typeofType ) = 0; 194 virtual void visit( AttrType * node ) { visit( const_cast<const AttrType *>(node) ); } 195 virtual void visit( const AttrType * attrType ) = 0; 196 virtual void visit( VarArgsType * node ) { visit( const_cast<const VarArgsType *>(node) ); } 197 virtual void visit( const VarArgsType * varArgsType ) = 0; 198 virtual void visit( ZeroType * node ) { visit( const_cast<const ZeroType *>(node) ); } 199 virtual void visit( const ZeroType * zeroType ) = 0; 200 virtual void visit( OneType * node ) { visit( const_cast<const OneType *>(node) ); } 201 virtual void visit( const OneType * oneType ) = 0; 202 virtual void visit( GlobalScopeType * node ) { visit( const_cast<const GlobalScopeType *>(node) ); } 203 virtual void visit( const GlobalScopeType * globalType ) = 0; 204 205 virtual void visit( Designation * node ) { visit( const_cast<const Designation *>(node) ); } 206 virtual void visit( const Designation * designation ) = 0; 207 virtual void visit( SingleInit * node ) { visit( const_cast<const SingleInit *>(node) ); } 208 virtual void visit( const SingleInit * singleInit ) = 0; 209 virtual void visit( ListInit * node ) { visit( const_cast<const ListInit *>(node) ); } 210 virtual void visit( const ListInit * listInit ) = 0; 211 virtual void visit( ConstructorInit * node ) { visit( const_cast<const ConstructorInit *>(node) ); } 212 virtual void visit( const ConstructorInit * ctorInit ) = 0; 213 214 virtual void visit( Constant * node ) { visit( const_cast<const Constant *>(node) ); } 215 virtual void visit( const Constant * constant ) = 0; 216 217 virtual void visit( Attribute * node ) { visit( const_cast<const Attribute *>(node) ); } 218 virtual void visit( const Attribute * attribute ) = 0; 127 219 }; 128 220 129 221 template< typename TreeType, typename VisitorType > 130 inline void maybeAccept( TreeType * tree, VisitorType &visitor ) {222 inline void maybeAccept( TreeType * tree, VisitorType & visitor ) { 131 223 if ( tree ) { 132 224 tree->accept( visitor ); … … 134 226 } 135 227 228 template< typename TreeType, typename VisitorType > 229 inline void maybeAccept( const TreeType * tree, VisitorType & visitor ) { 230 if ( tree ) { 231 tree->accept( visitor ); 232 } 233 } 234 136 235 template< typename Container, typename VisitorType > 137 inline void acceptAll( Container & container, VisitorType &visitor ) {236 inline void acceptAll( Container & container, VisitorType & visitor ) { 138 237 SemanticErrorException errors; 139 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i) {238 for ( auto * i : container ) { 140 239 try { 141 if ( *i ) { 142 (*i)->accept( visitor ); 240 if ( i ) { 241 i->accept( visitor ); 242 } 243 } catch( SemanticErrorException & e ) { 244 errors.append( e ); 245 } 246 } 247 if ( ! errors.isEmpty() ) { 248 throw errors; 249 } 250 } 251 252 template< typename Container, typename VisitorType > 253 inline void acceptAll( const Container & container, VisitorType & visitor ) { 254 SemanticErrorException errors; 255 for ( const auto * i : container ) { 256 try { 257 if ( i ) { 258 i->accept( visitor ); 143 259 } 144 260 } catch( SemanticErrorException &e ) { -
src/SynTree/module.mk
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 SRC += SynTree/Type.cc \ 18 SynTree/VoidType.cc \ 19 SynTree/BasicType.cc \ 20 SynTree/PointerType.cc \ 21 SynTree/ArrayType.cc \ 22 SynTree/ReferenceType.cc \ 23 SynTree/FunctionType.cc \ 24 SynTree/ReferenceToType.cc \ 25 SynTree/TupleType.cc \ 26 SynTree/TypeofType.cc \ 27 SynTree/AttrType.cc \ 28 SynTree/VarArgsType.cc \ 29 SynTree/ZeroOneType.cc \ 30 SynTree/Constant.cc \ 31 SynTree/Expression.cc \ 32 SynTree/TupleExpr.cc \ 33 SynTree/CommaExpr.cc \ 34 SynTree/TypeExpr.cc \ 35 SynTree/ApplicationExpr.cc \ 36 SynTree/AddressExpr.cc \ 37 SynTree/Statement.cc \ 38 SynTree/CompoundStmt.cc \ 39 SynTree/DeclStmt.cc \ 40 SynTree/Declaration.cc \ 41 SynTree/DeclarationWithType.cc \ 42 SynTree/ObjectDecl.cc \ 43 SynTree/FunctionDecl.cc \ 44 SynTree/AggregateDecl.cc \ 45 SynTree/NamedTypeDecl.cc \ 46 SynTree/TypeDecl.cc \ 47 SynTree/Initializer.cc \ 48 SynTree/TypeSubstitution.cc \ 49 SynTree/Attribute.cc \ 50 SynTree/DeclReplacer.cc 17 SRC_SYNTREE = \ 18 SynTree/Type.cc \ 19 SynTree/VoidType.cc \ 20 SynTree/BasicType.cc \ 21 SynTree/PointerType.cc \ 22 SynTree/ArrayType.cc \ 23 SynTree/ReferenceType.cc \ 24 SynTree/FunctionType.cc \ 25 SynTree/ReferenceToType.cc \ 26 SynTree/TupleType.cc \ 27 SynTree/TypeofType.cc \ 28 SynTree/AttrType.cc \ 29 SynTree/VarArgsType.cc \ 30 SynTree/ZeroOneType.cc \ 31 SynTree/Constant.cc \ 32 SynTree/Expression.cc \ 33 SynTree/TupleExpr.cc \ 34 SynTree/CommaExpr.cc \ 35 SynTree/TypeExpr.cc \ 36 SynTree/ApplicationExpr.cc \ 37 SynTree/AddressExpr.cc \ 38 SynTree/Statement.cc \ 39 SynTree/CompoundStmt.cc \ 40 SynTree/DeclStmt.cc \ 41 SynTree/Declaration.cc \ 42 SynTree/DeclarationWithType.cc \ 43 SynTree/ObjectDecl.cc \ 44 SynTree/FunctionDecl.cc \ 45 SynTree/AggregateDecl.cc \ 46 SynTree/NamedTypeDecl.cc \ 47 SynTree/TypeDecl.cc \ 48 SynTree/Initializer.cc \ 49 SynTree/TypeSubstitution.cc \ 50 SynTree/Attribute.cc \ 51 SynTree/DeclReplacer.cc 51 52 53 SRC += $(SRC_SYNTREE) 54 SRCDEMANGLE += $(SRC_SYNTREE) -
src/Tuples/Explode.cc
r7951100 rb067d9b 9 9 // Author : Rob Schluntz 10 10 // Created On : Wed Nov 9 13:12:24 2016 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Nov 9 13:20:24201613 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 12 16:40:00 2016 13 // Update Count : 3 14 14 // 15 15 … … 106 106 return expr; 107 107 } 108 109 namespace { 110 111 // Remove one level of reference from a reference type. 112 const ast::Type * getReferenceBase( const ast::Type * t ) { 113 if ( const ast::ReferenceType * ref = dynamic_cast< const ast::ReferenceType * >( t ) ) { 114 return ref->base; 115 } else { 116 assertf( false, "getReferenceBase for non-ref: %s", toString( t ).c_str() ); 117 return nullptr; 118 } 119 } 120 121 struct CastExploderCore { 122 bool castAdded = false; 123 bool foundUniqueExpr = false; 124 const ast::Expr * applyCast( const ast::Expr * expr, bool first = true ) { 125 // On tuple push the cast down. 126 if ( const ast::TupleExpr * tupleExpr = dynamic_cast< const ast::TupleExpr * >( expr ) ) { 127 foundUniqueExpr = true; 128 std::vector< ast::ptr< ast::Expr > > exprs; 129 for ( const ast::Expr * expr : tupleExpr->exprs ) { 130 exprs.emplace_back( applyCast( expr, false ) ); 131 //exprs.emplace_back( ast::ptr< ast::Expr >( applyCast( expr, false ) ) ); 132 } 133 if ( first ) { 134 castAdded = true; 135 const ast::Expr * tuple = new ast::TupleExpr{ 136 tupleExpr->location, std::move( exprs ) }; 137 return new ast::CastExpr{ tuple, new ast::ReferenceType{ tuple->result } }; 138 } else { 139 return new ast::TupleExpr( tupleExpr->location, std::move( exprs ) ); 140 } 141 } 142 if ( dynamic_cast< const ast::ReferenceType * >( expr->result.get() ) ) { 143 return expr; 144 } else { 145 castAdded = true; 146 return new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } }; 147 } 148 } 149 150 const ast::Expr * postmutate( const ast::UniqueExpr * node ) { 151 // move cast into unique expr so that the unique expr has type T& rather than 152 // type T. In particular, this transformation helps with generating the 153 // correct code for reference-cast member tuple expressions, since the result 154 // should now be a tuple of references rather than a reference to a tuple. 155 // Still, this code is a bit awkward, and could use some improvement. 156 const ast::UniqueExpr * newNode = new ast::UniqueExpr( node->location, 157 applyCast( node->expr ), node->id ); 158 if ( castAdded ) { 159 // if a cast was added by applyCast, then unique expr now has one more layer of reference 160 // than it had coming into this function. To ensure types still match correctly, need to cast 161 // to reference base so that outer expressions are still correct. 162 castAdded = false; 163 const ast::Type * newType = getReferenceBase( newNode->result ); 164 return new ast::CastExpr{ newNode->location, node, newType }; 165 } 166 return newNode; 167 } 168 169 const ast::Expr * postmutate( const ast::TupleIndexExpr * tupleExpr ) { 170 // tuple index expr needs to be rebuilt to ensure that the type of the 171 // field is consistent with the type of the tuple expr, since the field 172 // may have changed from type T to T&. 173 return new ast::TupleIndexExpr( tupleExpr->location, tupleExpr->tuple, tupleExpr->index ); 174 } 175 }; 176 177 } // namespace 178 179 const ast::Expr * distributeReference( const ast::Expr * expr ) { 180 ast::Pass<CastExploderCore> exploder; 181 expr = expr->accept( exploder ); 182 if ( ! exploder.pass.foundUniqueExpr ) { 183 expr = new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } }; 184 } 185 return expr; 186 } 187 108 188 } // namespace Tuples 109 189 -
src/Tuples/Explode.h
r7951100 rb067d9b 9 9 // Author : Rob Schluntz 10 10 // Created On : Wed Nov 9 13:12:24 2016 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:55:16 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 17 14:36:00 2019 13 // Update Count : 4 14 14 // 15 15 … … 19 19 #include <utility> // for forward 20 20 21 #include "AST/Expr.hpp" 21 22 #include "ResolvExpr/Alternative.h" // for Alternative, AltList 23 #include "ResolvExpr/Candidate.hpp" // for Candidate, CandidateList 22 24 #include "ResolvExpr/ExplodedActual.h" // for ExplodedActual 25 #include "ResolvExpr/ExplodedArg.hpp" // for ExplodedArg 23 26 #include "SynTree/Expression.h" // for Expression, UniqueExpr, AddressExpr 24 27 #include "SynTree/Type.h" // for TupleType, Type 25 28 #include "Tuples.h" // for maybeImpure 29 30 namespace ast { 31 class SymbolTable; 32 } 26 33 27 34 namespace SymTab { … … 44 51 template<typename OutputIterator> 45 52 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 53 const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 46 54 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 47 *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };55 *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost }; 48 56 } 49 57 50 58 /// Append alternative to an ExplodedActual 51 59 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 52 const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 60 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 61 const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 53 62 ea.exprs.emplace_back( expr ); 54 /// xxx -- merge environment, cost?63 /// xxx -- merge environment, openVars, need, cost? 55 64 } 56 65 … … 68 77 // distribute reference cast over all components 69 78 append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 70 alt.env, alt. cost, alt.cvtCost );79 alt.env, alt.openVars, alt.need, alt.cost, alt.cvtCost ); 71 80 } 72 81 // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives) … … 102 111 } else { 103 112 // atomic (non-tuple) type - output a clone of the expression in a new alternative 104 append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost ); 113 append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 114 alt.cost, alt.cvtCost ); 105 115 } 106 116 } … … 127 137 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign ); 128 138 } 139 140 const ast::Expr * distributeReference( const ast::Expr * ); 141 142 /// Append candidate to an OutputIterator of Candidates. 143 template<typename OutputIterator> 144 void append( OutputIterator out, const ast::Expr * expr, const ast::TypeEnvironment & env, 145 const ast::OpenVarSet & open, const ast::AssertionList & need, 146 const ResolvExpr::Cost & cost, const ResolvExpr::Cost & cvtCost ) { 147 ast::TypeEnvironment copyEnv = env; 148 ast::OpenVarSet copyOpen = open; 149 ast::AssertionSet set; 150 mergeAssertionSet( set, need ); 151 *out++ = std::make_shared<ResolvExpr::Candidate>( expr, std::move( copyEnv ), 152 std::move( copyOpen ), std::move( set ), cost, cvtCost ); 153 } 154 155 /// Append candidate to an ExplodedArg. 156 static inline void append( ResolvExpr::ExplodedArg& ea, const ast::Expr * expr, 157 const ast::TypeEnvironment&, const ast::OpenVarSet&, 158 const ast::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 159 // I'm not sure why most of the arguments are unused. But they were in the old version. 160 ea.exprs.emplace_back( expr ); 161 } 162 163 /// Check if the expression is a cast to a reference type, return it if it is. 164 static inline const ast::CastExpr * isReferenceCast( const ast::Expr * expr ) { 165 if ( const ast::CastExpr * cast = dynamic_cast< const ast::CastExpr * >( expr ) ) { 166 if ( dynamic_cast< const ast::ReferenceType * >( cast->result.get() ) ) { 167 return cast; 168 } 169 } 170 return nullptr; 171 } 172 173 /// helper function (indirectely) used by explode 174 template< typename Output > 175 void explodeRecursive( 176 const ast::CastExpr *, const ResolvExpr::Candidate &, 177 const ast::SymbolTable &, Output && 178 ) { 179 } 180 181 /// helper function used by explode 182 template< typename Output > 183 void explodeUnique( 184 const ast::ptr< ast::Expr > & expr, const ResolvExpr::Candidate & arg, 185 const ast::SymbolTable & symtab, Output && out, bool isTupleAssign 186 ) { 187 // Tuple assignment can use a faster method if it is cast. Uses recursive exploding. 188 if ( isTupleAssign ) if ( const ast::CastExpr * castExpr = isReferenceCast( expr ) ) { 189 ResolvExpr::CandidateList candidates; 190 explodeUnique( castExpr->arg, arg, symtab, back_inserter( candidates ), true ); 191 for ( ResolvExpr::CandidateRef & cand : candidates ) { 192 // Distribute the reference cast over all components of the candidate. 193 append( std::forward<Output>(out), distributeReference( cand->expr ), cand->env, 194 cand->open, cand->need, cand->cost, cand->cvtCost ); 195 } 196 return; 197 } 198 const ast::Type * res = expr->result->stripReferences(); 199 if ( const ast::TupleType * tupleType = dynamic_cast< const ast::TupleType * >( res ) ) { 200 if ( const ast::ptr< ast::TupleExpr > & tupleExpr = expr.as< ast::TupleExpr >() ) { 201 // Open the tuple expr and continue on its components. 202 for ( const ast::Expr * expr : tupleExpr->exprs ) { 203 explodeUnique( expr, arg, symtab, std::forward<Output>(out), isTupleAssign ); 204 } 205 } else { 206 ast::ptr< ast::Expr > local = expr; 207 // Expressions which may have side effects require a single unique instance. 208 if ( Tuples::maybeImpureIgnoreUnique( local ) ) { 209 local = new ast::UniqueExpr( local->location, local ); 210 } 211 // Cast a reference away to a value-type to allow further explosion. 212 if ( dynamic_cast< const ast::ReferenceType *>( local->result.get() ) ) { 213 local = new ast::CastExpr{ local, tupleType }; 214 } 215 // Now we have to go across the tuple via indexing. 216 for ( unsigned int i = 0 ; i < tupleType->size() ; ++i ) { 217 ast::TupleIndexExpr * idx = new ast::TupleIndexExpr( local->location, local, i ); 218 explodeUnique( idx, arg, symtab, std::forward<Output>(out), isTupleAssign ); 219 // TODO: We need more input to figure out the exact lifetimes of these types. 220 // delete idx; 221 } 222 // delete local; 223 } 224 } else { 225 // For atomic/non-tuple types, no explosion is used. 226 append( std::forward<Output>(out), expr, arg.env, arg.open, arg.need, arg.cost, 227 arg.cvtCost ); 228 } 229 } 230 231 /// expands a tuple-valued candidate into multiple candidates, each with a non-tuple type 232 template< typename Output > 233 void explode( 234 const ResolvExpr::Candidate & arg, const ast::SymbolTable & symtab, Output && out, 235 bool isTupleAssign = false 236 ) { 237 explodeUnique( arg.expr, arg, symtab, std::forward< Output >( out ), isTupleAssign ); 238 } 239 240 /// explode list of candidates into flattened list of candidates 241 template< typename Output > 242 void explode( 243 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 244 bool isTupleAssign = false 245 ) { 246 for ( const ResolvExpr::CandidateRef & cand : cands ) { 247 explode( *cand, symtab, std::forward< Output >( out ), isTupleAssign ); 248 } 249 } 250 129 251 } // namespace Tuples 130 252 -
src/Tuples/TupleAssignment.cc
r7951100 rb067d9b 22 22 #include <vector> 23 23 24 #include "AST/Decl.hpp" 25 #include "AST/Init.hpp" 26 #include "AST/Pass.hpp" 27 #include "AST/Stmt.hpp" 28 #include "AST/TypeEnvironment.hpp" 24 29 #include "CodeGen/OperatorTable.h" 25 30 #include "Common/PassVisitor.h" 26 31 #include "Common/UniqueName.h" // for UniqueName 27 #include "Common/utility.h" // for zipWith32 #include "Common/utility.h" // for splice, zipWith 28 33 #include "Explode.h" // for explode 29 34 #include "InitTweak/GenInit.h" // for genCtorInit … … 51 56 52 57 namespace Tuples { 53 class TupleAssignSpotter {58 class TupleAssignSpotter_old { 54 59 public: 55 60 // dispatcher for Tuple (multiple and mass) assignment operations 56 TupleAssignSpotter ( ResolvExpr::AlternativeFinder & );61 TupleAssignSpotter_old( ResolvExpr::AlternativeFinder & ); 57 62 void spot( UntypedExpr * expr, std::vector<ResolvExpr::AlternativeFinder> &args ); 58 63 … … 62 67 struct Matcher { 63 68 public: 64 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const65 ResolvExpr::AltList& rhs );69 Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 70 const ResolvExpr::AltList& rhs ); 66 71 virtual ~Matcher() {} 72 67 73 virtual void match( std::list< Expression * > &out ) = 0; 68 74 ObjectDecl * newObject( UniqueName & namer, Expression * expr ); 75 76 void combineState( const ResolvExpr::Alternative& alt ) { 77 compositeEnv.simpleCombine( alt.env ); 78 ResolvExpr::mergeOpenVars( openVars, alt.openVars ); 79 cloneAll( alt.need, need ); 80 } 81 82 void combineState( const ResolvExpr::AltList& alts ) { 83 for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); } 84 } 85 69 86 ResolvExpr::AltList lhs, rhs; 70 TupleAssignSpotter &spotter;87 TupleAssignSpotter_old &spotter; 71 88 ResolvExpr::Cost baseCost; 72 89 std::list< ObjectDecl * > tmpDecls; 73 90 ResolvExpr::TypeEnvironment compositeEnv; 91 ResolvExpr::OpenVarSet openVars; 92 ResolvExpr::AssertionSet need; 74 93 }; 75 94 76 95 struct MassAssignMatcher : public Matcher { 77 96 public: 78 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,97 MassAssignMatcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 79 98 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 80 99 virtual void match( std::list< Expression * > &out ); … … 83 102 struct MultipleAssignMatcher : public Matcher { 84 103 public: 85 MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,104 MultipleAssignMatcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 86 105 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 87 106 virtual void match( std::list< Expression * > &out ); … … 122 141 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, 123 142 std::vector<ResolvExpr::AlternativeFinder> &args ) { 124 TupleAssignSpotter spotter( currentFinder );143 TupleAssignSpotter_old spotter( currentFinder ); 125 144 spotter.spot( expr, args ); 126 145 } 127 146 128 TupleAssignSpotter ::TupleAssignSpotter( ResolvExpr::AlternativeFinder &f )147 TupleAssignSpotter_old::TupleAssignSpotter_old( ResolvExpr::AlternativeFinder &f ) 129 148 : currentFinder(f) {} 130 149 131 void TupleAssignSpotter ::spot( UntypedExpr * expr,150 void TupleAssignSpotter_old::spot( UntypedExpr * expr, 132 151 std::vector<ResolvExpr::AlternativeFinder> &args ) { 133 152 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { … … 210 229 } 211 230 212 void TupleAssignSpotter ::match() {231 void TupleAssignSpotter_old::match() { 213 232 assert ( matcher != 0 ); 214 233 … … 245 264 } 246 265 247 // extract expressions from the assignment alternatives to produce a list of assignments that248 // t ogether form a single alternative266 // extract expressions from the assignment alternatives to produce a list of assignments 267 // that together form a single alternative 249 268 std::list< Expression *> solved_assigns; 250 269 for ( ResolvExpr::Alternative & alt : current ) { 251 270 solved_assigns.push_back( alt.expr->clone() ); 252 }253 // combine assignment environments into combined expression environment254 simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv ); 271 matcher->combineState( alt ); 272 } 273 255 274 // xxx -- was push_front 256 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative( 257 new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 258 ResolvExpr::sumCost( current ) + matcher->baseCost ) ); 259 } 260 261 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, 275 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{ 276 new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 277 matcher->openVars, 278 ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 279 ResolvExpr::sumCost( current ) + matcher->baseCost } ); 280 } 281 282 TupleAssignSpotter_old::Matcher::Matcher( TupleAssignSpotter_old &spotter, 262 283 const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs ) 263 284 : lhs(lhs), rhs(rhs), spotter(spotter), 264 285 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 265 simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv);266 simpleCombineEnvironments( rhs.begin(), rhs.end(), compositeEnv);286 combineState( lhs ); 287 combineState( rhs ); 267 288 } 268 289 … … 297 318 }; 298 319 299 ObjectDecl * TupleAssignSpotter ::Matcher::newObject( UniqueName & namer, Expression * expr ) {320 ObjectDecl * TupleAssignSpotter_old::Matcher::newObject( UniqueName & namer, Expression * expr ) { 300 321 assert( expr->result && ! expr->get_result()->isVoid() ); 301 322 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->result->clone(), new SingleInit( expr->clone() ) ); … … 313 334 } 314 335 315 void TupleAssignSpotter ::MassAssignMatcher::match( std::list< Expression * > &out ) {336 void TupleAssignSpotter_old::MassAssignMatcher::match( std::list< Expression * > &out ) { 316 337 static UniqueName lhsNamer( "__massassign_L" ); 317 338 static UniqueName rhsNamer( "__massassign_R" ); … … 331 352 } 332 353 333 void TupleAssignSpotter ::MultipleAssignMatcher::match( std::list< Expression * > &out ) {354 void TupleAssignSpotter_old::MultipleAssignMatcher::match( std::list< Expression * > &out ) { 334 355 static UniqueName lhsNamer( "__multassign_L" ); 335 356 static UniqueName rhsNamer( "__multassign_R" ); … … 361 382 } 362 383 } 384 385 namespace { 386 /// true if `expr` is of tuple type 387 bool isTuple( const ast::Expr * expr ) { 388 if ( ! expr ) return false; 389 assert( expr->result ); 390 return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() ); 391 } 392 393 /// true if `expr` is of tuple type or a reference to one 394 bool refToTuple( const ast::Expr * expr ) { 395 assert( expr->result ); 396 // check for function returning tuple of reference types 397 if ( auto castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) { 398 return refToTuple( castExpr->arg ); 399 } else { 400 return isTuple( expr ); 401 } 402 } 403 404 /// Dispatcher for tuple (multiple and mass) assignment operations 405 class TupleAssignSpotter_new final { 406 /// Actually finds tuple assignment operations, by subclass 407 struct Matcher { 408 ResolvExpr::CandidateList lhs, rhs; 409 TupleAssignSpotter_new & spotter; 410 CodeLocation location; 411 ResolvExpr::Cost baseCost; 412 std::vector< ast::ptr< ast::ObjectDecl > > tmpDecls; 413 ast::TypeEnvironment env; 414 ast::OpenVarSet open; 415 ast::AssertionSet need; 416 417 void combineState( const ResolvExpr::Candidate & cand ) { 418 env.simpleCombine( cand.env ); 419 ast::mergeOpenVars( open, cand.open ); 420 need.insert( cand.need.begin(), cand.need.end() ); 421 } 422 423 Matcher( 424 TupleAssignSpotter_new & s, const CodeLocation & loc, 425 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 426 : lhs( l ), rhs( r ), spotter( s ), location( loc ), 427 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 428 env(), open(), need() { 429 for ( auto & cand : lhs ) combineState( *cand ); 430 for ( auto & cand : rhs ) combineState( *cand ); 431 } 432 virtual ~Matcher() = default; 433 434 virtual std::vector< ast::ptr< ast::Expr > > match() = 0; 435 436 /// removes environments from subexpressions within statement expressions, which could 437 /// throw off later passes like those in Box which rely on PolyMutator, and adds the 438 /// bindings to the env 439 struct EnvRemover { 440 /// environment to hoist ExprStmt environments to 441 ast::TypeEnvironment & tenv; 442 443 EnvRemover( ast::TypeEnvironment & e ) : tenv( e ) {} 444 445 const ast::ExprStmt * previsit( const ast::ExprStmt * stmt ) { 446 if ( stmt->expr->env ) { 447 tenv.add( *stmt->expr->env ); 448 ast::ExprStmt * mut = mutate( stmt ); 449 mut->expr.get_and_mutate()->env = nullptr; 450 return mut; 451 } 452 return stmt; 453 } 454 }; 455 456 ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) { 457 assert( expr->result && ! expr->result->isVoid() ); 458 459 ast::ObjectDecl * ret = new ast::ObjectDecl{ 460 location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 461 ast::Storage::Classes{}, ast::Linkage::Cforall }; 462 463 // if expression type is a reference, just need an initializer, otherwise construct 464 if ( ! expr->result.as< ast::ReferenceType >() ) { 465 // resolve ctor/dtor for the new object 466 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 467 InitTweak::genCtorInit( location, ret ), spotter.crntFinder.symtab ); 468 // remove environments from subexpressions of stmtExpr 469 ast::Pass< EnvRemover > rm{ env }; 470 ret->init = ctorInit->accept( rm ); 471 } 472 473 PRINT( std::cerr << "new object: " << ret << std::endl; ) 474 return ret; 475 } 476 477 ast::UntypedExpr * createFunc( 478 const std::string & fname, const ast::ObjectDecl * left, 479 const ast::ObjectDecl * right 480 ) { 481 assert( left ); 482 std::vector< ast::ptr< ast::Expr > > args; 483 args.emplace_back( new ast::VariableExpr{ location, left } ); 484 if ( right ) { args.emplace_back( new ast::VariableExpr{ location, right } ); } 485 486 if ( left->type->referenceDepth() > 1 && CodeGen::isConstructor( fname ) ) { 487 args.front() = new ast::AddressExpr{ location, args.front() }; 488 if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; } 489 return new ast::UntypedExpr{ 490 location, new ast::NameExpr{ location, "?=?" }, std::move(args) }; 491 } else { 492 return new ast::UntypedExpr{ 493 location, new ast::NameExpr{ location, fname }, std::move(args) }; 494 } 495 } 496 }; 497 498 /// Finds mass-assignment operations 499 struct MassAssignMatcher final : public Matcher { 500 MassAssignMatcher( 501 TupleAssignSpotter_new & s, const CodeLocation & loc, 502 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 503 : Matcher( s, loc, l, r ) {} 504 505 std::vector< ast::ptr< ast::Expr > > match() override { 506 static UniqueName lhsNamer( "__massassign_L" ); 507 static UniqueName rhsNamer( "__massassign_R" ); 508 // empty tuple case falls into this matcher 509 assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 ); 510 511 ast::ptr< ast::ObjectDecl > rtmp = 512 rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr; 513 514 std::vector< ast::ptr< ast::Expr > > out; 515 for ( ResolvExpr::CandidateRef & lhsCand : lhs ) { 516 // create a temporary object for each value in the LHS and create a call 517 // involving the RHS 518 ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr ); 519 out.emplace_back( createFunc( spotter.fname, ltmp, rtmp ) ); 520 tmpDecls.emplace_back( std::move( ltmp ) ); 521 } 522 if ( rtmp ) tmpDecls.emplace_back( std::move( rtmp ) ); 523 524 return out; 525 } 526 }; 527 528 /// Finds multiple-assignment operations 529 struct MultipleAssignMatcher final : public Matcher { 530 MultipleAssignMatcher( 531 TupleAssignSpotter_new & s, const CodeLocation & loc, 532 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 533 : Matcher( s, loc, l, r ) {} 534 535 std::vector< ast::ptr< ast::Expr > > match() override { 536 static UniqueName lhsNamer( "__multassign_L" ); 537 static UniqueName rhsNamer( "__multassign_R" ); 538 539 if ( lhs.size() != rhs.size() ) return {}; 540 541 // produce a new temporary object for each value in the LHS and RHS and pairwise 542 // create the calls 543 std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp; 544 545 std::vector< ast::ptr< ast::Expr > > out; 546 for ( unsigned i = 0; i < lhs.size(); ++i ) { 547 ResolvExpr::CandidateRef & lhsCand = lhs[i]; 548 ResolvExpr::CandidateRef & rhsCand = rhs[i]; 549 550 // convert RHS to LHS type minus one reference -- important for case where LHS 551 // is && and RHS is lvalue 552 auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >(); 553 rhsCand->expr = new ast::CastExpr{ rhsCand->expr, lhsType->base }; 554 ast::ptr< ast::ObjectDecl > lobj = newObject( lhsNamer, lhsCand->expr ); 555 ast::ptr< ast::ObjectDecl > robj = newObject( rhsNamer, rhsCand->expr ); 556 out.emplace_back( createFunc( spotter.fname, lobj, robj ) ); 557 ltmp.emplace_back( std::move( lobj ) ); 558 rtmp.emplace_back( std::move( robj ) ); 559 560 // resolve the cast expression so that rhsCand return type is bound by the cast 561 // type as needed, and transfer the resulting environment 562 ResolvExpr::CandidateFinder finder{ spotter.crntFinder.symtab, env }; 563 finder.find( rhsCand->expr, ResolvExpr::ResolvMode::withAdjustment() ); 564 assert( finder.candidates.size() == 1 ); 565 env = std::move( finder.candidates.front()->env ); 566 } 567 568 splice( tmpDecls, ltmp ); 569 splice( tmpDecls, rtmp ); 570 571 return out; 572 } 573 }; 574 575 ResolvExpr::CandidateFinder & crntFinder; 576 std::string fname; 577 std::unique_ptr< Matcher > matcher; 578 579 public: 580 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 581 : crntFinder( f ), fname(), matcher() {} 582 583 // find left- and right-hand-sides for mass or multiple assignment 584 void spot( 585 const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 586 ) { 587 if ( auto op = expr->func.as< ast::NameExpr >() ) { 588 // skip non-assignment functions 589 if ( ! CodeGen::isCtorDtorAssign( op->name ) ) return; 590 fname = op->name; 591 592 // handled by CandidateFinder if applicable (both odd cases) 593 if ( args.empty() || ( args.size() == 1 && CodeGen::isAssignment( fname ) ) ) { 594 return; 595 } 596 597 // look over all possible left-hand-side 598 for ( ResolvExpr::CandidateRef & lhsCand : args[0] ) { 599 // skip non-tuple LHS 600 if ( ! refToTuple( lhsCand->expr ) ) continue; 601 602 // explode is aware of casts - ensure every LHS is sent into explode with a 603 // reference cast 604 if ( ! lhsCand->expr.as< ast::CastExpr >() ) { 605 lhsCand->expr = new ast::CastExpr{ 606 lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } }; 607 } 608 609 // explode the LHS so that each field of a tuple-valued expr is assigned 610 ResolvExpr::CandidateList lhs; 611 explode( *lhsCand, crntFinder.symtab, back_inserter(lhs), true ); 612 for ( ResolvExpr::CandidateRef & cand : lhs ) { 613 // each LHS value must be a reference - some come in with a cast, if not 614 // just cast to reference here 615 if ( ! cand->expr->result.as< ast::ReferenceType >() ) { 616 cand->expr = new ast::CastExpr{ 617 cand->expr, new ast::ReferenceType{ cand->expr->result } }; 618 } 619 } 620 621 if ( args.size() == 1 ) { 622 // mass default-initialization/destruction 623 ResolvExpr::CandidateList rhs{}; 624 matcher.reset( new MassAssignMatcher{ *this, expr->location, lhs, rhs } ); 625 match(); 626 } else if ( args.size() == 2 ) { 627 for ( const ResolvExpr::CandidateRef & rhsCand : args[1] ) { 628 ResolvExpr::CandidateList rhs; 629 if ( isTuple( rhsCand->expr ) ) { 630 // multiple assignment 631 explode( *rhsCand, crntFinder.symtab, back_inserter(rhs), true ); 632 matcher.reset( 633 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 634 } else { 635 // mass assignment 636 rhs.emplace_back( rhsCand ); 637 matcher.reset( 638 new MassAssignMatcher{ *this, expr->location, lhs, rhs } ); 639 } 640 match(); 641 } 642 } else { 643 // expand all possible RHS possibilities 644 std::vector< ResolvExpr::CandidateList > rhsCands; 645 combos( 646 std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) ); 647 for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) { 648 // multiple assignment 649 ResolvExpr::CandidateList rhs; 650 explode( rhsCand, crntFinder.symtab, back_inserter(rhs), true ); 651 matcher.reset( 652 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 653 match(); 654 } 655 } 656 } 657 } 658 } 659 660 void match() { 661 assert( matcher ); 662 663 std::vector< ast::ptr< ast::Expr > > newAssigns = matcher->match(); 664 665 if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) { 666 // if both LHS and RHS are empty than this is the empty tuple case, wherein it's 667 // okay for newAssigns to be empty. Otherwise, return early so that no new 668 // candidates are generated 669 if ( newAssigns.empty() ) return; 670 } 671 672 ResolvExpr::CandidateList crnt; 673 // now resolve new assignments 674 for ( const ast::Expr * expr : newAssigns ) { 675 PRINT( 676 std::cerr << "== resolving tuple assign ==" << std::endl; 677 std::cerr << expr << std::endl; 678 ) 679 680 ResolvExpr::CandidateFinder finder{ crntFinder.symtab, matcher->env }; 681 682 try { 683 finder.find( expr, ResolvExpr::ResolvMode::withAdjustment() ); 684 } catch (...) { 685 // no match is not failure, just that this tuple assignment is invalid 686 return; 687 } 688 689 ResolvExpr::CandidateList & cands = finder.candidates; 690 assert( cands.size() == 1 ); 691 assert( cands.front()->expr ); 692 crnt.emplace_back( std::move( cands.front() ) ); 693 } 694 695 // extract expressions from the assignment candidates to produce a list of assignments 696 // that together form a sigle candidate 697 std::vector< ast::ptr< ast::Expr > > solved; 698 for ( ResolvExpr::CandidateRef & cand : crnt ) { 699 solved.emplace_back( cand->expr ); 700 matcher->combineState( *cand ); 701 } 702 703 crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >( 704 new ast::TupleAssignExpr{ 705 matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 706 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 707 ResolvExpr::sumCost( crnt ) + matcher->baseCost ) ); 708 } 709 }; 710 } // anonymous namespace 711 712 void handleTupleAssignment( 713 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 714 std::vector< ResolvExpr::CandidateFinder > & args 715 ) { 716 TupleAssignSpotter_new spotter{ finder }; 717 spotter.spot( assign, args ); 718 } 719 363 720 } // namespace Tuples 364 721 -
src/Tuples/TupleExpansion.cc
r7951100 rb067d9b 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jun 21 17:35:04 201713 // Update Count : 1911 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 19 14:39:00 2019 13 // Update Count : 22 14 14 // 15 15 … … 17 17 #include <cassert> // for assert 18 18 #include <list> // for list 19 19 #include <vector> 20 21 #include "AST/CVQualifiers.hpp" 22 #include "AST/Expr.hpp" 23 #include "AST/Node.hpp" 24 #include "AST/Type.hpp" 20 25 #include "Common/PassVisitor.h" // for PassVisitor, WithDeclsToAdd, WithGu... 21 26 #include "Common/ScopedMap.h" // for ScopedMap … … 58 63 }; 59 64 60 struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public With TypeSubstitution {65 struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public WithConstTypeSubstitution { 61 66 Type * postmutate( TupleType * tupleType ); 62 67 … … 299 304 // produce the TupleType which aggregates the types of the exprs 300 305 std::list< Type * > types; 301 Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type:: Lvalue | Type::Atomic | Type::Mutex );306 Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic | Type::Mutex ); 302 307 for ( Expression * expr : exprs ) { 303 308 assert( expr->get_result() ); … … 314 319 return new TupleType( qualifiers, types ); 315 320 } 321 const ast::Type * makeTupleType( const std::vector<ast::ptr<ast::Expr>> & exprs ) { 322 // produce the TupleType which aggregates the types of the exprs 323 std::vector<ast::ptr<ast::Type>> types; 324 ast::CV::Qualifiers quals{ 325 ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Lvalue | 326 ast::CV::Atomic | ast::CV::Mutex }; 327 328 for ( const ast::Expr * expr : exprs ) { 329 assert( expr->result ); 330 // if the type of any expr is void, the type of the entire tuple is void 331 if ( expr->result->isVoid() ) return new ast::VoidType{}; 332 333 // qualifiers on the tuple type are the qualifiers that exist on all components 334 quals &= expr->result->qualifiers; 335 336 types.emplace_back( expr->result ); 337 } 338 339 if ( exprs.empty() ) { quals = ast::CV::Qualifiers{}; } 340 return new ast::TupleType{ std::move(types), quals }; 341 } 316 342 317 343 TypeInstType * isTtype( Type * type ) { … … 324 350 } 325 351 352 const TypeInstType * isTtype( const Type * type ) { 353 if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type ) ) { 354 if ( inst->baseType && inst->baseType->kind == TypeDecl::Ttype ) { 355 return inst; 356 } 357 } 358 return nullptr; 359 } 360 361 const ast::TypeInstType * isTtype( const ast::Type * type ) { 362 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 363 if ( inst->base && inst->base->kind == ast::TypeVar::Ttype ) { 364 return inst; 365 } 366 } 367 return nullptr; 368 } 369 326 370 namespace { 327 371 /// determines if impurity (read: side-effects) may exist in a piece of code. Currently gives a very crude approximation, wherein any function call expression means the code may be impure … … 329 373 ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {} 330 374 331 void previsit( ApplicationExpr * appExpr ) {375 void previsit( const ApplicationExpr * appExpr ) { 332 376 visit_children = false; 333 if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {334 if ( function-> get_linkage()== LinkageSpec::Intrinsic ) {335 if ( function-> get_name() == "*?" || function->get_name()== "?[?]" ) {377 if ( const DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) { 378 if ( function->linkage == LinkageSpec::Intrinsic ) { 379 if ( function->name == "*?" || function->name == "?[?]" ) { 336 380 // intrinsic dereference, subscript are pure, but need to recursively look for impurity 337 381 visit_children = true; … … 342 386 maybeImpure = true; 343 387 } 344 void previsit( UntypedExpr * ) { maybeImpure = true; visit_children = false; }345 void previsit( UniqueExpr * ) {388 void previsit( const UntypedExpr * ) { maybeImpure = true; visit_children = false; } 389 void previsit( const UniqueExpr * ) { 346 390 if ( ignoreUnique ) { 347 391 // bottom out at unique expression. … … 358 402 } // namespace 359 403 360 bool maybeImpure( Expression * expr ) {404 bool maybeImpure( const Expression * expr ) { 361 405 PassVisitor<ImpurityDetector> detector( false ); 362 406 expr->accept( detector ); … … 364 408 } 365 409 366 bool maybeImpureIgnoreUnique( Expression * expr ) {410 bool maybeImpureIgnoreUnique( const Expression * expr ) { 367 411 PassVisitor<ImpurityDetector> detector( true ); 368 412 expr->accept( detector ); -
src/Tuples/Tuples.h
r7951100 rb067d9b 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:55:00 201713 // Update Count : 1 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Jun 18 09:36:00 2019 13 // Update Count : 18 14 14 // 15 15 … … 19 19 #include <vector> 20 20 21 #include "AST/Fwd.hpp" 22 #include "AST/Node.hpp" 21 23 #include "SynTree/Expression.h" 22 24 #include "SynTree/Declaration.h" … … 24 26 25 27 #include "ResolvExpr/AlternativeFinder.h" 28 #include "ResolvExpr/CandidateFinder.hpp" 26 29 27 30 namespace Tuples { 28 31 // TupleAssignment.cc 29 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 32 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 30 33 std::vector< ResolvExpr::AlternativeFinder >& args ); 31 34 void handleTupleAssignment( 35 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 36 std::vector< ResolvExpr::CandidateFinder > & args ); 37 32 38 // TupleExpansion.cc 33 39 /// expands z.[a, b.[x, y], c] into [z.a, z.b.x, z.b.y, z.c], inserting UniqueExprs as appropriate … … 42 48 /// returns VoidType if any of the expressions have Voidtype, otherwise TupleType of the Expression result types 43 49 Type * makeTupleType( const std::list< Expression * > & exprs ); 50 const ast::Type * makeTupleType( const std::vector<ast::ptr<ast::Expr>> & exprs ); 44 51 45 52 /// returns a TypeInstType if `type` is a ttype, nullptr otherwise 46 53 TypeInstType * isTtype( Type * type ); 54 const TypeInstType * isTtype( const Type * type ); 55 const ast::TypeInstType * isTtype( const ast::Type * type ); 47 56 48 57 /// returns true if the expression may contain side-effects. 49 bool maybeImpure( Expression * expr ); 58 bool maybeImpure( const Expression * expr ); 59 bool maybeImpure( const ast::Expr * expr ); 50 60 51 /// returns true if the expression may contain side-effect, ignoring the presence of unique expressions. 52 bool maybeImpureIgnoreUnique( Expression * expr ); 61 /// Returns true if the expression may contain side-effect, 62 /// ignoring the presence of unique expressions. 63 bool maybeImpureIgnoreUnique( const Expression * expr ); 64 bool maybeImpureIgnoreUnique( const ast::Expr * expr ); 53 65 } // namespace Tuples 54 66 -
src/Tuples/module.mk
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 SRC += Tuples/TupleAssignment.cc \ 18 Tuples/TupleExpansion.cc \ 19 Tuples/Explode.cc 17 SRC += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc \ 18 Tuples/Tuples.cc 19 SRCDEMANGLE += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc \ 20 Tuples/Tuples.cc -
src/Virtual/ExpandCasts.cc
r7951100 rb067d9b 147 147 // ) 148 148 // ), 149 new UntypedExpr( new NameExpr( "__cfa__virtual_cast"), {149 new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), { 150 150 new CastExpr( 151 151 new AddressExpr( new VariableExpr( table ) ), 152 152 pointer_to_pvt(1) 153 ),153 ), 154 154 new CastExpr( 155 155 castExpr->get_arg(), 156 156 pointer_to_pvt(2) 157 )158 } ),157 ) 158 } ), 159 159 castExpr->get_result()->clone() 160 );160 ); 161 161 162 162 castExpr->set_arg( nullptr ); -
src/include/cassert
r7951100 rb067d9b 9 9 // Author : Peter A. Buhr 10 10 // Created On : Thu Aug 18 13:19:26 2016 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue Aug 1 11:56:01201713 // Update Count : 1 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 3 13:11:00 2017 13 // Update Count : 18 14 14 // 15 15 … … 19 19 20 20 #include_next <cassert> 21 22 #include <string> 23 24 template < typename ... Params > 25 std::string toString( const Params & ... params ); 21 26 22 27 #ifdef NDEBUG … … 40 45 template<typename T, typename U> 41 46 static inline T strict_dynamic_cast( const U & src ) { 47 assert(src); 42 48 T ret = dynamic_cast<T>(src); 43 49 assertf(ret, "%s", toString(src).c_str()); … … 45 51 } 46 52 53 template<typename T, decltype(nullptr) null, typename U> 54 static inline T strict_dynamic_cast( const U & src ) { 55 return src ? strict_dynamic_cast<T, U>( src ) : nullptr; 56 } 57 58 extern void abort(const char *fmt, ... ) noexcept __attribute__((noreturn, format(printf, 1, 2))); 47 59 // Local Variables: // 48 60 // tab-width: 4 // -
src/main.cc
r7951100 rb067d9b 7 7 // main.cc -- 8 8 // 9 // Author : Richard C. Bilson9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 6 15:51:47 201813 // Update Count : 49812 // Last Modified On : Fri Aug 23 06:50:08 2019 13 // Update Count : 607 14 14 // 15 15 … … 17 17 #include <execinfo.h> // for backtrace, backtrace_symbols 18 18 #include <getopt.h> // for no_argument, optind, geto... 19 #include <signal.h> // for signal, SIGABRT, SIGSEGV20 19 #include <cassert> // for assertf 21 20 #include <cstdio> // for fopen, FILE, fclose, stdin 22 21 #include <cstdlib> // for exit, free, abort, EXIT_F... 22 #include <csignal> // for signal, SIGABRT, SIGSEGV 23 23 #include <cstring> // for index 24 24 #include <fstream> // for ofstream 25 25 #include <iostream> // for operator<<, basic_ostream 26 #include <iomanip> 26 27 #include <iterator> // for back_inserter 27 28 #include <list> // for list 28 29 #include <string> // for char_traits, operator<< 29 30 31 #include "CompilationState.h" 30 32 #include "../config.h" // for CFA_LIBDIR 31 33 #include "CodeGen/FixMain.h" // for FixMain … … 33 35 #include "CodeGen/Generate.h" // for generate 34 36 #include "CodeTools/DeclStats.h" // for printDeclStats 37 #include "CodeTools/ResolvProtoDump.h" // for dumpAsResolvProto 35 38 #include "CodeTools/TrackLoc.h" // for fillLocations 36 39 #include "Common/CompilerError.h" // for CompilerError 37 #include "Common/ Heap.h"40 #include "Common/Stats.h" 38 41 #include "Common/PassVisitor.h" 39 42 #include "Common/SemanticError.h" // for SemanticError … … 61 64 #include "Virtual/ExpandCasts.h" // for expandCasts 62 65 66 63 67 using namespace std; 64 68 65 #define PASS(name, pass) \ 69 static void NewPass( const char * const name ) { 70 Stats::Heap::newPass( name ); 71 using namespace Stats::Counters; 72 { 73 static auto group = build<CounterGroup>( "Pass Visitor" ); 74 auto pass = build<CounterGroup>( name, group ); 75 pass_visitor_stats.depth = 0; 76 pass_visitor_stats.avg = build<AverageCounter<double>>( "Average Depth", pass ); 77 pass_visitor_stats.max = build<MaxCounter<double>>( "Max Depth", pass ); 78 } 79 { 80 static auto group = build<CounterGroup>( "Syntax Node" ); 81 auto pass = build<CounterGroup>( name, group ); 82 BaseSyntaxNode::new_nodes = build<SimpleCounter>( "Allocs", pass ); 83 } 84 } 85 86 #define PASS( name, pass ) \ 66 87 if ( errorp ) { cerr << name << endl; } \ 67 HeapStats::newPass(name); \ 68 pass; 88 NewPass(name); \ 89 Stats::Time::StartBlock(name); \ 90 pass; \ 91 Stats::Time::StopBlock(); 69 92 70 93 LinkageSpec::Spec linkage = LinkageSpec::Cforall; … … 72 95 DeclarationNode * parseTree = nullptr; // program parse tree 73 96 74 extern int yydebug; // set for -g flag (Grammar) 75 bool 76 astp = false, 77 bresolvep = false, 78 bboxp = false, 79 bcodegenp = false, 80 ctorinitp = false, 81 declstatsp = false, 82 exprp = false, 83 expraltp = false, 84 genericsp = false, 85 libcfap = false, 86 nopreludep = false, 87 noprotop = false, 88 nomainp = false, 89 parsep = false, 90 resolvep = false, // used in AlternativeFinder 91 symtabp = false, 92 treep = false, 93 tuplep = false, 94 validp = false, 95 errorp = false, 96 codegenp = false, 97 prettycodegenp = false, 98 linemarks = false; 99 100 static void parse_cmdline( int argc, char *argv[], const char *& filename ); 97 static bool waiting_for_gdb = false; // flag to set cfa-cpp to wait for gdb on start 98 99 static std::string PreludeDirector = ""; 100 101 static void parse_cmdline( int argc, char *argv[] ); 101 102 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false ); 102 103 static void dump( list< Declaration * > & translationUnit, ostream & out = cout ); … … 152 153 } // backtrace 153 154 154 void sigSegvBusHandler( int sig_num ) {155 static void sigSegvBusHandler( int sig_num ) { 155 156 cerr << "*CFA runtime error* program cfa-cpp terminated with " 156 157 << (sig_num == SIGSEGV ? "segment fault" : "bus error") … … 158 159 backtrace( 2 ); // skip first 2 stack frames 159 160 //_exit( EXIT_FAILURE ); 160 abort(); 161 abort(); // cause core dump for debugging 161 162 } // sigSegvBusHandler 162 163 163 void sigAbortHandler( __attribute__((unused)) int sig_num ) {164 static void sigAbortHandler( __attribute__((unused)) int sig_num ) { 164 165 backtrace( 6 ); // skip first 6 stack frames 165 166 signal( SIGABRT, SIG_DFL); // reset default signal handler 166 raise( SIGABRT ); // reraise SIGABRT167 raise( SIGABRT ); // reraise SIGABRT 167 168 } // sigAbortHandler 168 169 169 170 170 int main( int argc, char * argv[] ) { 171 171 FILE * input; // use FILE rather than istream because yyin is FILE 172 ostream *output = & cout; 173 const char *filename = nullptr; 172 ostream * output = & cout; 174 173 list< Declaration * > translationUnit; 175 174 … … 183 182 // } // for 184 183 185 parse_cmdline( argc, argv , filename );// process command-line arguments184 parse_cmdline( argc, argv ); // process command-line arguments 186 185 CodeGen::FixMain::setReplaceMain( !nomainp ); 186 187 if ( waiting_for_gdb ) { 188 std::cerr << "Waiting for gdb" << std::endl; 189 std::cerr << "run :" << std::endl; 190 std::cerr << " gdb attach " << getpid() << std::endl; 191 raise(SIGSTOP); 192 } // if 187 193 188 194 try { … … 190 196 if ( optind < argc ) { // any commands after the flags ? => input file name 191 197 input = fopen( argv[ optind ], "r" ); 192 assertf( input, "cannot open %s\n", argv[ optind ] ); 193 // if running cfa-cpp directly, might forget to pass -F option (and really shouldn't have to) 194 if ( filename == nullptr ) filename = argv[ optind ]; 195 // prelude filename comes in differently 196 if ( libcfap ) filename = "prelude.cf"; 198 assertf( input, "cannot open %s because %s\n", argv[ optind ], strerror( errno ) ); 197 199 optind += 1; 198 200 } else { // no input file name 199 201 input = stdin; 200 // if running cfa-cpp directly, might forget to pass -F option. Since this takes from stdin, pass 201 // a fake name along 202 if ( filename == nullptr ) filename = "stdin"; 203 } // if 202 } // if 203 204 Stats::Time::StartGlobal(); 205 NewPass("Parse"); 206 Stats::Time::StartBlock("Parse"); 204 207 205 208 // read in the builtins, extras, and the prelude … … 207 210 // -l is for initial build ONLY and builtins.cf is not in the lib directory so access it here. 208 211 212 assertf( !PreludeDirector.empty(), "Can't find prelude without option --prelude-dir must be used." ); 213 209 214 // Read to gcc builtins, if not generating the cfa library 210 FILE * gcc_builtins = fopen( libcfap | treep ? "../prelude/gcc-builtins.cf" : CFA_LIBDIR "/gcc-builtins.cf", "r" );215 FILE * gcc_builtins = fopen( (PreludeDirector + "/gcc-builtins.cf").c_str(), "r" ); 211 216 assertf( gcc_builtins, "cannot open gcc-builtins.cf\n" ); 212 217 parse( gcc_builtins, LinkageSpec::Compiler ); 213 218 214 219 // read the extra prelude in, if not generating the cfa library 215 FILE * extras = fopen( libcfap | treep ? "../prelude/extras.cf" : CFA_LIBDIR "/extras.cf", "r" );220 FILE * extras = fopen( (PreludeDirector + "/extras.cf").c_str(), "r" ); 216 221 assertf( extras, "cannot open extras.cf\n" ); 217 222 parse( extras, LinkageSpec::BuiltinC ); … … 219 224 if ( ! libcfap ) { 220 225 // read the prelude in, if not generating the cfa library 221 FILE * prelude = fopen( treep ? "../prelude/prelude.cf" : CFA_LIBDIR "/prelude.cf", "r" );222 assertf( prelude, "cannot open prelude.cf \n" );226 FILE * prelude = fopen( (PreludeDirector + "/prelude.cfa").c_str(), "r" ); 227 assertf( prelude, "cannot open prelude.cfa\n" ); 223 228 parse( prelude, LinkageSpec::Intrinsic ); 224 229 225 230 // Read to cfa builtins, if not generating the cfa library 226 FILE * builtins = fopen( libcfap | treep ? "../prelude/builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" );231 FILE * builtins = fopen( (PreludeDirector + "/builtins.cf").c_str(), "r" ); 227 232 assertf( builtins, "cannot open builtins.cf\n" ); 228 233 parse( builtins, LinkageSpec::BuiltinCFA ); … … 235 240 parseTree->printList( cout ); 236 241 delete parseTree; 237 return 0;242 return EXIT_SUCCESS; 238 243 } // if 239 244 … … 244 249 if ( astp ) { 245 250 dump( translationUnit ); 246 return 0; 247 } // if 251 return EXIT_SUCCESS; 252 } // if 253 254 // Temporary: fill locations after parsing so that every node has a location, for early error messages. 255 // Eventually we should pass the locations from the parser to every node, but this quick and dirty solution 256 // works okay for now. 257 CodeTools::fillLocations( translationUnit ); 258 Stats::Time::StopBlock(); 248 259 249 260 // add the assignment statement after the initialization of a type parameter 250 PASS( " validate", SymTab::validate( translationUnit, symtabp ) );261 PASS( "Validate", SymTab::validate( translationUnit, symtabp ) ); 251 262 if ( symtabp ) { 252 263 deleteAll( translationUnit ); 253 return 0;264 return EXIT_SUCCESS; 254 265 } // if 255 266 … … 257 268 PassVisitor<ResolvExpr::AlternativePrinter> printer( cout ); 258 269 acceptAll( translationUnit, printer ); 259 return 0;270 return EXIT_SUCCESS; 260 271 } // if 261 272 262 273 if ( validp ) { 263 274 dump( translationUnit ); 264 return 0;265 } // if 266 267 PASS( " fixLabels", ControlStruct::fixLabels( translationUnit ) );268 PASS( " fixNames", CodeGen::fixNames( translationUnit ) );269 PASS( " genInit", InitTweak::genInit( translationUnit ) );270 PASS( " expandMemberTuples" , Tuples::expandMemberTuples( translationUnit ) );275 return EXIT_SUCCESS; 276 } // if 277 278 PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) ); 279 PASS( "Fix Names", CodeGen::fixNames( translationUnit ) ); 280 PASS( "Gen Init", InitTweak::genInit( translationUnit ) ); 281 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) ); 271 282 if ( libcfap ) { 272 283 // generate the bodies of cfa library functions … … 277 288 CodeTools::printDeclStats( translationUnit ); 278 289 deleteAll( translationUnit ); 279 return 0;280 } 290 return EXIT_SUCCESS; 291 } // if 281 292 282 293 if ( bresolvep ) { 283 294 dump( translationUnit ); 284 return 0;295 return EXIT_SUCCESS; 285 296 } // if 286 297 287 298 CodeTools::fillLocations( translationUnit ); 288 299 289 PASS( "resolve", ResolvExpr::resolve( translationUnit ) ); 300 if ( resolvprotop ) { 301 CodeTools::dumpAsResolvProto( translationUnit ); 302 return EXIT_SUCCESS; 303 } // if 304 305 PASS( "Resolve", ResolvExpr::resolve( translationUnit ) ); 290 306 if ( exprp ) { 291 307 dump( translationUnit ); 292 return 0;308 return EXIT_SUCCESS; 293 309 } // if 294 310 295 311 // fix ObjectDecl - replaces ConstructorInit nodes 296 PASS( " fixInit", InitTweak::fix( translationUnit, filename, libcfap || treep) );312 PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) ); 297 313 if ( ctorinitp ) { 298 314 dump ( translationUnit ); 299 return 0;300 } // if 301 302 PASS( " expandUniqueExpr", Tuples::expandUniqueExpr( translationUnit ) ); // 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 reused303 304 PASS( " translateEHM" , ControlStruct::translateEHM( translationUnit ) );305 306 PASS( " generateWaitfor" , Concurrency::generateWaitFor( translationUnit ) );307 308 PASS( " convertSpecializations", GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded309 310 PASS( " expandTuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?315 return EXIT_SUCCESS; 316 } // if 317 318 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // 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 319 320 PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) ); 321 322 PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) ); 323 324 PASS( "Convert Specializations", GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded 325 326 PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this? 311 327 312 328 if ( tuplep ) { 313 329 dump( translationUnit ); 314 return 0;315 } 316 317 PASS( " virtual expandCasts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM318 319 PASS( " instantiateGenerics", GenPoly::instantiateGeneric( translationUnit ) );330 return EXIT_SUCCESS; 331 } // if 332 333 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM 334 335 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) ); 320 336 if ( genericsp ) { 321 337 dump( translationUnit ); 322 return 0;323 } 324 PASS( "convertLvalue", GenPoly::convertLvalue( translationUnit ) ); 325 338 return EXIT_SUCCESS; 339 } // if 340 341 PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) ); 326 342 327 343 if ( bboxp ) { 328 344 dump( translationUnit ); 329 return 0;330 } // if 331 PASS( " box", GenPoly::box( translationUnit ) );345 return EXIT_SUCCESS; 346 } // if 347 PASS( "Box", GenPoly::box( translationUnit ) ); 332 348 333 349 if ( bcodegenp ) { 334 350 dump( translationUnit ); 335 return 0;336 } 351 return EXIT_SUCCESS; 352 } // if 337 353 338 354 if ( optind < argc ) { // any commands after the flags and input file ? => output file name … … 341 357 342 358 CodeTools::fillLocations( translationUnit ); 343 PASS( " codegen", CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true, linemarks ) );344 345 CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c");359 PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) ); 360 361 CodeGen::FixMain::fix( *output, (PreludeDirector + "/bootloader.c").c_str() ); 346 362 if ( output != &cout ) { 347 363 delete output; … … 357 373 delete output; 358 374 } // if 359 return 1;375 return EXIT_FAILURE; 360 376 } catch ( UnimplementedError &e ) { 361 377 cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl; … … 363 379 delete output; 364 380 } // if 365 return 1;381 return EXIT_FAILURE; 366 382 } catch ( CompilerError &e ) { 367 383 cerr << "Compiler Error: " << e.get_what() << endl; … … 370 386 delete output; 371 387 } // if 372 return 1;373 } catch (...) {388 return EXIT_FAILURE; 389 } catch ( ... ) { 374 390 std::exception_ptr eptr = std::current_exception(); 375 391 try { 376 392 if (eptr) { 377 393 std::rethrow_exception(eptr); 378 } 379 else { 380 std::cerr << "Exception Uncaught and Unkown" << std::endl; 381 } 394 } else { 395 std::cerr << "Exception Uncaught and Unknown" << std::endl; 396 } // if 382 397 } catch(const std::exception& e) { 383 std::cerr << "Un aught Exception \"" << e.what() << "\"\n";384 } 385 return 1;386 } // try398 std::cerr << "Uncaught Exception \"" << e.what() << "\"\n"; 399 } // try 400 return EXIT_FAILURE; 401 } // try 387 402 388 403 deleteAll( translationUnit ); 389 if(!libcfap && !treep) HeapStats::printStats();390 return 0;404 Stats::print(); 405 return EXIT_SUCCESS; 391 406 } // main 392 407 393 void parse_cmdline( int argc, char * argv[], const char *& filename ) { 394 enum { Ast, Bbox, Bresolver, CtorInitFix, DeclStats, Expr, ExprAlt, Grammar, LibCFA, Linemarks, Nolinemarks, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, TupleExpansion, Validate, }; 395 396 static struct option long_opts[] = { 397 { "ast", no_argument, 0, Ast }, 398 { "before-box", no_argument, 0, Bbox }, 399 { "before-resolver", no_argument, 0, Bresolver }, 400 { "ctorinitfix", no_argument, 0, CtorInitFix }, 401 { "decl-stats", no_argument, 0, DeclStats }, 402 { "expr", no_argument, 0, Expr }, 403 { "expralt", no_argument, 0, ExprAlt }, 404 { "grammar", no_argument, 0, Grammar }, 405 { "libcfa", no_argument, 0, LibCFA }, 406 { "line-marks", no_argument, 0, Linemarks }, 407 { "no-line-marks", no_argument, 0, Nolinemarks }, 408 { "no-preamble", no_argument, 0, Nopreamble }, 409 { "parse", no_argument, 0, Parse }, 410 { "no-prototypes", no_argument, 0, Prototypes }, 411 { "resolver", no_argument, 0, Resolver }, 412 { "symbol", no_argument, 0, Symbol }, 413 { "tree", no_argument, 0, Tree }, 414 { "tuple-expansion", no_argument, 0, TupleExpansion }, 415 { "validate", no_argument, 0, Validate }, 416 { 0, 0, 0, 0 } 417 }; // long_opts 418 int long_index; 419 408 409 static const char optstring[] = ":hlLmNnpP:S:twW:D:"; 410 411 enum { PreludeDir = 128 }; 412 static struct option long_opts[] = { 413 { "help", no_argument, nullptr, 'h' }, 414 { "libcfa", no_argument, nullptr, 'l' }, 415 { "linemarks", no_argument, nullptr, 'L' }, 416 { "no-main", no_argument, 0, 'm' }, 417 { "no-linemarks", no_argument, nullptr, 'N' }, 418 { "no-prelude", no_argument, nullptr, 'n' }, 419 { "prototypes", no_argument, nullptr, 'p' }, 420 { "print", required_argument, nullptr, 'P' }, 421 { "prelude-dir", required_argument, nullptr, PreludeDir }, 422 { "statistics", required_argument, nullptr, 'S' }, 423 { "tree", no_argument, nullptr, 't' }, 424 { "gdb", no_argument, nullptr, 'g' }, 425 { "", no_argument, nullptr, 0 }, // -w 426 { "", no_argument, nullptr, 0 }, // -W 427 { "", no_argument, nullptr, 0 }, // -D 428 { nullptr, 0, nullptr, 0 } 429 }; // long_opts 430 431 static const char * description[] = { 432 "print help message", // -h 433 "generate libcfa.c", // -l 434 "generate line marks", // -L 435 "do not replace main", // -m 436 "do not generate line marks", // -N 437 "do not read prelude", // -n 438 "generate prototypes for prelude functions", // -p 439 "print", // -P 440 "<directory> prelude directory for debug/nodebug", // no flag 441 "<option-list> enable profiling information:\n counters,heap,time,all,none", // -S 442 "building cfa standard lib", // -t 443 "wait for gdb to attach", // -g 444 "", // -w 445 "", // -W 446 "", // -D 447 }; // description 448 449 static_assert( sizeof( long_opts ) / sizeof( long_opts[0] ) - 1 == sizeof( description ) / sizeof( description[0] ), "Long opts and description must match" ); 450 451 static struct Printopts { 452 const char * name; 453 int & flag; 454 int val; 455 const char * descript; 456 } printopts[] = { 457 { "ascodegen", codegenp, true, "print AST as codegen rather than AST" }, 458 { "asterr", errorp, true, "print AST on error" }, 459 { "declstats", declstatsp, true, "code property statistics" }, 460 { "parse", yydebug, true, "yacc (parsing) debug information" }, 461 { "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" }, 462 { "rproto", resolvprotop, true, "resolver-proto instance" }, 463 { "rsteps", resolvep, true, "print resolver steps" }, 464 { "tree", parsep, true, "print parse tree" }, 465 // code dumps 466 { "ast", astp, true, "print AST after parsing" }, 467 { "symevt", symtabp, true, "print AST after symbol table events" }, 468 { "altexpr", expraltp, true, "print alternatives for expressions" }, 469 { "astdecl", validp, true, "print AST after declaration validation pass" }, 470 { "resolver", bresolvep, true, "print AST before resolver step" }, 471 { "astexpr", exprp, true, "print AST after expression analysis" }, 472 { "ctordtor", ctorinitp, true, "print AST after ctor/dtor are replaced" }, 473 { "tuple", tuplep, true, "print AST after tuple expansion" }, 474 { "astgen", genericsp, true, "print AST after instantiate generics" }, 475 { "box", bboxp, true, "print AST before box step" }, 476 { "codegen", bcodegenp, true, "print AST before code generation" }, 477 }; 478 enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) }; 479 480 static void usage( char *argv[] ) { 481 cout << "Usage: " << argv[0] << " [options] [input-file (default stdin)] [output-file (default stdout)], where options are:" << endl; 482 int i = 0, j = 1; // j skips starting colon 483 for ( ; long_opts[i].name != 0 && optstring[j] != '\0'; i += 1, j += 1 ) { 484 if ( long_opts[i].name[0] != '\0' ) { // hidden option, internal usage only 485 if ( strcmp( long_opts[i].name, "prelude-dir" ) != 0 ) { // flag 486 cout << " -" << optstring[j] << ","; 487 } else { // no flag 488 j -= 1; // compensate 489 cout << " "; 490 } // if 491 cout << " --" << left << setw(12) << long_opts[i].name << " "; 492 if ( strcmp( long_opts[i].name, "print" ) == 0 ) { 493 cout << "one of: " << endl; 494 for ( int i = 0; i < printoptsSize; i += 1 ) { 495 cout << setw(10) << " " << left << setw(10) << printopts[i].name << " " << printopts[i].descript << endl; 496 } // for 497 } else { 498 cout << description[i] << endl; 499 } // if 500 } // if 501 if ( optstring[j + 1] == ':' ) j += 1; 502 } // for 503 if ( long_opts[i].name != 0 || optstring[j] != '\0' ) assertf( false, "internal error, mismatch of option flags and names\n" ); 504 exit( EXIT_FAILURE ); 505 } // usage 506 507 static void parse_cmdline( int argc, char * argv[] ) { 420 508 opterr = 0; // (global) prevent getopt from printing error messages 421 509 422 510 bool Wsuppress = false, Werror = false; 423 511 int c; 424 while ( (c = getopt_long( argc, argv, "abBcCdefgGlLmnNpqrstTvwW:yzZD:F:", long_opts, &long_index)) != -1 ) {512 while ( (c = getopt_long( argc, argv, optstring, long_opts, nullptr )) != -1 ) { 425 513 switch ( c ) { 426 case Ast: 427 case 'a': // dump AST 428 astp = true; 429 break; 430 case Bresolver: 431 case 'b': // print before resolver steps 432 bresolvep = true; 433 break; 434 case 'B': // print before box steps 435 bboxp = true; 436 break; 437 case CtorInitFix: 438 case 'c': // print after constructors and destructors are replaced 439 ctorinitp = true; 440 break; 441 case 'C': // print before code generation 442 bcodegenp = true; 443 break; 444 case DeclStats: 445 case 'd': 446 declstatsp = true; 447 break; 448 case Expr: 449 case 'e': // dump AST after expression analysis 450 exprp = true; 451 break; 452 case ExprAlt: 453 case 'f': // print alternatives for expressions 454 expraltp = true; 455 break; 456 case Grammar: 457 case 'g': // bison debugging info (grammar rules) 458 yydebug = true; 459 break; 460 case 'G': // dump AST after instantiate generics 461 genericsp = true; 462 break; 463 case LibCFA: 514 case 'h': // help message 515 usage( argv ); // no return 516 break; 464 517 case 'l': // generate libcfa.c 465 518 libcfap = true; 466 519 break; 467 case Linemarks: 468 case 'L': // print lines marks 520 case 'L': // generate line marks 469 521 linemarks = true; 470 522 break; 471 case Nopreamble: 472 case 'n': // do not read preamble 523 case 'm': // do not replace main 524 nomainp = true; 525 break; 526 case 'N': // do not generate line marks 527 linemarks = false; 528 break; 529 case 'n': // do not read prelude 473 530 nopreludep = true; 474 531 break; 475 case Nolinemarks: 476 case 'N': // suppress line marks 477 linemarks = false; 478 break; 479 case Prototypes: 480 case 'p': // generate prototypes for preamble functions 481 noprotop = true; 482 break; 483 case 'm': // don't replace the main 484 nomainp = true; 485 break; 486 case Parse: 487 case 'q': // dump parse tree 488 parsep = true; 489 break; 490 case Resolver: 491 case 'r': // print resolver steps 492 resolvep = true; 493 break; 494 case Symbol: 495 case 's': // print symbol table events 496 symtabp = true; 497 break; 498 case Tree: 499 case 't': // build in tree 532 case 'p': // generate prototypes for prelude functions 533 genproto = true; 534 break; 535 case 'P': // print options 536 for ( int i = 0;; i += 1 ) { 537 if ( i == printoptsSize ) { 538 cout << "Unknown --print option " << optarg << endl; 539 goto Default; 540 } // if 541 if ( strcmp( optarg, printopts[i].name ) == 0 ) { 542 printopts[i].flag = printopts[i].val; 543 break; 544 } // if 545 } // for 546 break; 547 case PreludeDir: // prelude directory for debug/nodebug, hidden 548 PreludeDirector = optarg; 549 break; 550 case 'S': // enable profiling information, argument comma separated list of names 551 Stats::parse_params( optarg ); 552 break; 553 case 't': // building cfa stdlib 500 554 treep = true; 501 555 break; 502 case TupleExpansion: 503 case 'T': // print after tuple expansion 504 tuplep = true; 505 break; 506 case 'v': // dump AST after decl validation pass 507 validp = true; 508 break; 509 case 'w': 556 case 'g': // wait for gdb 557 waiting_for_gdb = true; 558 break; 559 case 'w': // suppress all warnings, hidden 510 560 Wsuppress = true; 511 561 break; 512 case 'W': 562 case 'W': // coordinate gcc -W with CFA, hidden 513 563 if ( strcmp( optarg, "all" ) == 0 ) { 514 564 SemanticWarning_EnableAll(); … … 527 577 } // if 528 578 break; 529 case 'y': // dump AST on error 530 errorp = true; 531 break; 532 case 'z': // dump as codegen rather than AST 533 codegenp = true; 534 break; 535 case 'Z': // prettyprint during codegen (i.e. print unmangled names, etc.) 536 prettycodegenp = true; 537 break; 538 case 'D': // ignore -Dxxx 539 break; 540 case 'F': // source file-name without suffix 541 filename = optarg; 542 break; 543 case '?': 579 case 'D': // ignore -Dxxx, forwarded by cpp, hidden 580 break; 581 case '?': // unknown option 544 582 if ( optopt ) { // short option ? 545 assertf( false, "Unknown option: -%c\n", (char)optopt );583 cout << "Unknown option -" << (char)optopt << endl; 546 584 } else { 547 assertf( false, "Unknown option: %s\n", argv[optind - 1] ); 548 } // if 549 #if defined(__GNUC__) && __GNUC__ >= 7 550 __attribute__((fallthrough)); 551 #endif 585 cout << "Unknown option " << argv[optind - 1] << endl; 586 } // if 587 goto Default; 588 case ':': // missing option 589 if ( optopt ) { // short option ? 590 cout << "Missing option for -" << (char)optopt << endl; 591 } else { 592 cout << "Missing option for " << argv[optind - 1] << endl; 593 } // if 594 goto Default; 595 Default: 552 596 default: 553 abort();597 usage( argv ); // no return 554 598 } // switch 555 599 } // while … … 589 633 list< Declaration * > decls; 590 634 591 if ( noprotop) {635 if ( genproto ) { 592 636 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), notPrelude ); 593 637 } else { … … 597 641 // depending on commandline options, either generate code or dump the AST 598 642 if ( codegenp ) { 599 CodeGen::generate( decls, out, ! noprotop, prettycodegenp );643 CodeGen::generate( decls, out, ! genproto, prettycodegenp ); 600 644 } else { 601 645 printAll( decls, out ); 602 } 646 } // if 603 647 deleteAll( translationUnit ); 604 648 } // dump -
tools/Makefile.am
r7951100 rb067d9b 15 15 ############################################################################### 16 16 17 CC = @BACKEND_CC@ 18 CFLAGS = -Wall -Wextra -O2 -g 17 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 18 ACLOCAL_AMFLAGS = -I automake 19 19 20 noinst_PROGRAMS = busy catchsig repeat 20 AM_CFLAGS = -Wall -Wextra -O2 -g 21 22 noinst_PROGRAMS = busy catchsig repeat watchdog 21 23 22 24 busy_SOURCES = busy.c … … 24 26 catchsig_SOURCES = catchsig.c 25 27 repeat_SOURCES = repeat.c 28 watchdog_SOURCES = watchdog.c -
tools/Makefile.in
r7951100 rb067d9b 92 92 build_triplet = @build@ 93 93 host_triplet = @host@ 94 noinst_PROGRAMS = busy$(EXEEXT) catchsig$(EXEEXT) repeat$(EXEEXT) 94 noinst_PROGRAMS = busy$(EXEEXT) catchsig$(EXEEXT) repeat$(EXEEXT) \ 95 watchdog$(EXEEXT) 95 96 subdir = tools 96 97 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 97 am__aclocal_m4_deps = $(top_srcdir)/configure.ac 98 am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \ 99 $(top_srcdir)/automake/ltoptions.m4 \ 100 $(top_srcdir)/automake/ltsugar.m4 \ 101 $(top_srcdir)/automake/ltversion.m4 \ 102 $(top_srcdir)/automake/lt~obsolete.m4 \ 103 $(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac 98 104 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 99 105 $(ACLOCAL_M4) … … 107 113 busy_OBJECTS = $(am_busy_OBJECTS) 108 114 busy_LDADD = $(LDADD) 109 busy_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(busy_LDFLAGS) $(LDFLAGS) \ 110 -o $@ 115 AM_V_lt = $(am__v_lt_@AM_V@) 116 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 117 am__v_lt_0 = --silent 118 am__v_lt_1 = 119 busy_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 120 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 121 $(busy_LDFLAGS) $(LDFLAGS) -o $@ 111 122 am_catchsig_OBJECTS = catchsig.$(OBJEXT) 112 123 catchsig_OBJECTS = $(am_catchsig_OBJECTS) … … 115 126 repeat_OBJECTS = $(am_repeat_OBJECTS) 116 127 repeat_LDADD = $(LDADD) 128 am_watchdog_OBJECTS = watchdog.$(OBJEXT) 129 watchdog_OBJECTS = $(am_watchdog_OBJECTS) 130 watchdog_LDADD = $(LDADD) 117 131 AM_V_P = $(am__v_P_@AM_V@) 118 132 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) … … 133 147 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 134 148 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 149 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 150 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ 151 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 152 $(AM_CFLAGS) $(CFLAGS) 135 153 AM_V_CC = $(am__v_CC_@AM_V@) 136 154 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) … … 138 156 am__v_CC_1 = 139 157 CCLD = $(CC) 140 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 158 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 159 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 160 $(AM_LDFLAGS) $(LDFLAGS) -o $@ 141 161 AM_V_CCLD = $(am__v_CCLD_@AM_V@) 142 162 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) 143 163 am__v_CCLD_0 = @echo " CCLD " $@; 144 164 am__v_CCLD_1 = 145 SOURCES = $(busy_SOURCES) $(catchsig_SOURCES) $(repeat_SOURCES) 146 DIST_SOURCES = $(busy_SOURCES) $(catchsig_SOURCES) $(repeat_SOURCES) 165 SOURCES = $(busy_SOURCES) $(catchsig_SOURCES) $(repeat_SOURCES) \ 166 $(watchdog_SOURCES) 167 DIST_SOURCES = $(busy_SOURCES) $(catchsig_SOURCES) $(repeat_SOURCES) \ 168 $(watchdog_SOURCES) 147 169 am__can_run_installinfo = \ 148 170 case $$AM_UPDATE_INFO_DIR in \ … … 172 194 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 173 195 ACLOCAL = @ACLOCAL@ 174 ALLOCA = @ALLOCA@175 196 AMTAR = @AMTAR@ 176 197 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 198 AR = @AR@ 177 199 AUTOCONF = @AUTOCONF@ 178 200 AUTOHEADER = @AUTOHEADER@ 179 201 AUTOMAKE = @AUTOMAKE@ 180 202 AWK = @AWK@ 181 B ACKEND_CC = @BACKEND_CC@182 CC = @ BACKEND_CC@203 BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@ 204 CC = @CC@ 183 205 CCAS = @CCAS@ 184 206 CCASDEPMODE = @CCASDEPMODE@ 185 207 CCASFLAGS = @CCASFLAGS@ 186 208 CCDEPMODE = @CCDEPMODE@ 209 CFACC = @CFACC@ 210 CFACC_INSTALL = @CFACC_INSTALL@ 211 CFACPP = @CFACPP@ 187 212 CFA_BACKEND_CC = @CFA_BACKEND_CC@ 188 213 CFA_BINDIR = @CFA_BINDIR@ … … 192 217 CFA_NAME = @CFA_NAME@ 193 218 CFA_PREFIX = @CFA_PREFIX@ 194 CFLAGS = -Wall -Wextra -O2 -g219 CFLAGS = @CFLAGS@ 195 220 CPP = @CPP@ 196 221 CPPFLAGS = @CPPFLAGS@ 197 222 CXX = @CXX@ 223 CXXCPP = @CXXCPP@ 198 224 CXXDEPMODE = @CXXDEPMODE@ 199 225 CXXFLAGS = @CXXFLAGS@ 200 226 CYGPATH_W = @CYGPATH_W@ 201 227 DEFS = @DEFS@ 228 DEMANGLER = @DEMANGLER@ 202 229 DEPDIR = @DEPDIR@ 230 DLLTOOL = @DLLTOOL@ 231 DRIVER_DIR = @DRIVER_DIR@ 232 DSYMUTIL = @DSYMUTIL@ 233 DUMPBIN = @DUMPBIN@ 203 234 ECHO_C = @ECHO_C@ 204 235 ECHO_N = @ECHO_N@ … … 206 237 EGREP = @EGREP@ 207 238 EXEEXT = @EXEEXT@ 239 FGREP = @FGREP@ 208 240 GREP = @GREP@ 241 HAS_DISTCC = @HAS_DISTCC@ 242 HOST_FLAGS = @HOST_FLAGS@ 209 243 INSTALL = @INSTALL@ 210 244 INSTALL_DATA = @INSTALL_DATA@ … … 212 246 INSTALL_SCRIPT = @INSTALL_SCRIPT@ 213 247 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 248 LD = @LD@ 214 249 LDFLAGS = @LDFLAGS@ 215 250 LEX = @LEX@ 216 251 LEXLIB = @LEXLIB@ 217 252 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ 253 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 254 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 255 LIBDEMANGLE = @LIBDEMANGLE@ 218 256 LIBOBJS = @LIBOBJS@ 219 257 LIBS = @LIBS@ 258 LIBTOOL = @LIBTOOL@ 259 LIPO = @LIPO@ 260 LN_S = @LN_S@ 220 261 LTLIBOBJS = @LTLIBOBJS@ 221 MACHINE_TYPE = @MACHINE_TYPE@ 222 MAINT = @MAINT@ 262 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ 223 263 MAKEINFO = @MAKEINFO@ 264 MANIFEST_TOOL = @MANIFEST_TOOL@ 224 265 MKDIR_P = @MKDIR_P@ 266 NM = @NM@ 267 NMEDIT = @NMEDIT@ 268 OBJDUMP = @OBJDUMP@ 225 269 OBJEXT = @OBJEXT@ 270 OTOOL = @OTOOL@ 271 OTOOL64 = @OTOOL64@ 226 272 PACKAGE = @PACKAGE@ 227 273 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ … … 233 279 PATH_SEPARATOR = @PATH_SEPARATOR@ 234 280 RANLIB = @RANLIB@ 281 SED = @SED@ 235 282 SET_MAKE = @SET_MAKE@ 236 283 SHELL = @SHELL@ 237 284 STRIP = @STRIP@ 285 TARGET_HOSTS = @TARGET_HOSTS@ 238 286 VERSION = @VERSION@ 239 287 YACC = @YACC@ … … 243 291 abs_top_builddir = @abs_top_builddir@ 244 292 abs_top_srcdir = @abs_top_srcdir@ 293 ac_ct_AR = @ac_ct_AR@ 245 294 ac_ct_CC = @ac_ct_CC@ 246 295 ac_ct_CXX = @ac_ct_CXX@ 296 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 247 297 am__include = @am__include@ 248 298 am__leading_dot = @am__leading_dot@ … … 291 341 top_builddir = @top_builddir@ 292 342 top_srcdir = @top_srcdir@ 343 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 344 ACLOCAL_AMFLAGS = -I automake 345 AM_CFLAGS = -Wall -Wextra -O2 -g 293 346 busy_SOURCES = busy.c 294 347 busy_LDFLAGS = -pthread 295 348 catchsig_SOURCES = catchsig.c 296 349 repeat_SOURCES = repeat.c 350 watchdog_SOURCES = watchdog.c 297 351 all: all-am 298 352 299 353 .SUFFIXES: 300 .SUFFIXES: .c . o .obj301 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@$(srcdir)/Makefile.am $(am__configure_deps)354 .SUFFIXES: .c .lo .o .obj 355 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 302 356 @for dep in $?; do \ 303 357 case '$(am__configure_deps)' in \ … … 323 377 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 324 378 325 $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@$(am__configure_deps)379 $(top_srcdir)/configure: $(am__configure_deps) 326 380 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 327 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@$(am__aclocal_m4_deps)381 $(ACLOCAL_M4): $(am__aclocal_m4_deps) 328 382 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 329 383 $(am__aclocal_m4_deps): 330 384 331 385 clean-noinstPROGRAMS: 332 -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) 386 @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ 387 echo " rm -f" $$list; \ 388 rm -f $$list || exit $$?; \ 389 test -n "$(EXEEXT)" || exit 0; \ 390 list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ 391 echo " rm -f" $$list; \ 392 rm -f $$list 333 393 334 394 busy$(EXEEXT): $(busy_OBJECTS) $(busy_DEPENDENCIES) $(EXTRA_busy_DEPENDENCIES) … … 344 404 $(AM_V_CCLD)$(LINK) $(repeat_OBJECTS) $(repeat_LDADD) $(LIBS) 345 405 406 watchdog$(EXEEXT): $(watchdog_OBJECTS) $(watchdog_DEPENDENCIES) $(EXTRA_watchdog_DEPENDENCIES) 407 @rm -f watchdog$(EXEEXT) 408 $(AM_V_CCLD)$(LINK) $(watchdog_OBJECTS) $(watchdog_LDADD) $(LIBS) 409 346 410 mostlyclean-compile: 347 411 -rm -f *.$(OBJEXT) … … 353 417 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/catchsig.Po@am__quote@ 354 418 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repeat.Po@am__quote@ 419 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watchdog.Po@am__quote@ 355 420 356 421 .c.o: … … 369 434 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 370 435 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 436 437 .c.lo: 438 @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ 439 @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 440 @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo 441 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ 442 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 443 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< 444 445 mostlyclean-libtool: 446 -rm -f *.lo 447 448 clean-libtool: 449 -rm -rf .libs _libs 371 450 372 451 ID: $(am__tagged_files) … … 488 567 clean: clean-am 489 568 490 clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am 569 clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ 570 mostlyclean-am 491 571 492 572 distclean: distclean-am … … 543 623 mostlyclean: mostlyclean-am 544 624 545 mostlyclean-am: mostlyclean-compile mostlyclean-generic 625 mostlyclean-am: mostlyclean-compile mostlyclean-generic \ 626 mostlyclean-libtool 546 627 547 628 pdf: pdf-am … … 558 639 559 640 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ 560 clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ 561 distclean-compile distclean-generic distclean-tags distdir dvi \ 562 dvi-am html html-am info info-am install install-am \ 563 install-data install-data-am install-dvi install-dvi-am \ 564 install-exec install-exec-am install-html install-html-am \ 565 install-info install-info-am install-man install-pdf \ 566 install-pdf-am install-ps install-ps-am install-strip \ 567 installcheck installcheck-am installdirs maintainer-clean \ 641 clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ 642 ctags-am distclean distclean-compile distclean-generic \ 643 distclean-libtool distclean-tags distdir dvi dvi-am html \ 644 html-am info info-am install install-am install-data \ 645 install-data-am install-dvi install-dvi-am install-exec \ 646 install-exec-am install-html install-html-am install-info \ 647 install-info-am install-man install-pdf install-pdf-am \ 648 install-ps install-ps-am install-strip installcheck \ 649 installcheck-am installdirs maintainer-clean \ 568 650 maintainer-clean-generic mostlyclean mostlyclean-compile \ 569 mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall\570 uninstall-am651 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ 652 tags tags-am uninstall uninstall-am 571 653 572 654 .PRECIOUS: Makefile -
tools/cfa.nanorc
r7951100 rb067d9b 2 2 ## WIP 3 3 4 syntax "cfa" "\. cfa"4 syntax "cfa" "\.(c|h)fa" 5 5 6 6 # Macros … … 9 9 # Types 10 10 color green "\<(forall|trait|(o|d|f|t)type|mutex|_Bool|volatile|virtual)\>" 11 color green "\<(float|double|bool|char|int|short|long| sizeof|enum|void|auto)\>"12 color green "\<(static|const| struct|union|typedef|extern|(un)?signed|inline)\>"11 color green "\<(float|double|bool|char|int|short|long|enum|void|auto)\>" 12 color green "\<(static|const|extern|(un)?signed|inline)\>" "\<(sizeof)\>" 13 13 color green "\<((s?size)|one|zero|((u_?)?int(8|16|32|64|ptr)))_t\>" 14 14 … … 19 19 # Control Flow Structures 20 20 color brightyellow "\<(if|else|while|do|for|switch|choose|case|default)\>" 21 color brightyellow "\<(disable|enable|waitfor|when|timeout)\>" 21 22 color brightyellow "\<(try|catch(Resume)?|finally)\>" 22 23 23 24 # Control Flow Statements 24 25 color magenta "\<(goto|return|break|continue|fallthr(u|ough)|throw(Resume)?)\>" 26 27 # Escaped Keywords, now Identifiers. 28 color white "`\w+`" 25 29 26 30 # Operator Names -
tools/prettyprinter/Makefile.am
r7951100 rb067d9b 1 1 ######################## -*- Mode: Makefile-Automake -*- ###################### 2 ## 2 ## 3 3 ## Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo 4 4 ## 5 5 ## The contents of this file are covered under the licence agreement in the 6 6 ## file "LICENCE" distributed with Cforall. 7 ## 8 ## Makefile.am -- 9 ## 7 ## 8 ## Makefile.am -- 9 ## 10 10 ## Author : Peter A. Buhr 11 11 ## Created On : Wed Jun 28 12:07:10 2017 … … 14 14 ## Update Count : 20 15 15 ############################################################################### 16 17 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 18 ACLOCAL_AMFLAGS = -I automake 16 19 17 20 BUILT_SOURCES = parser.hh -
tools/prettyprinter/Makefile.in
r7951100 rb067d9b 95 95 subdir = tools/prettyprinter 96 96 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 97 am__aclocal_m4_deps = $(top_srcdir)/configure.ac 97 am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \ 98 $(top_srcdir)/automake/ltoptions.m4 \ 99 $(top_srcdir)/automake/ltsugar.m4 \ 100 $(top_srcdir)/automake/ltversion.m4 \ 101 $(top_srcdir)/automake/lt~obsolete.m4 \ 102 $(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac 98 103 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 99 104 $(ACLOCAL_M4) … … 112 117 am__DEPENDENCIES_1 = 113 118 pretty_DEPENDENCIES = $(am__DEPENDENCIES_1) 114 pretty_LINK = $(CXXLD) $(pretty_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ 115 $(LDFLAGS) -o $@ 119 AM_V_lt = $(am__v_lt_@AM_V@) 120 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 121 am__v_lt_0 = --silent 122 am__v_lt_1 = 123 pretty_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 124 $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(pretty_CXXFLAGS) \ 125 $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 116 126 AM_V_P = $(am__v_P_@AM_V@) 117 127 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) … … 130 140 am__depfiles_maybe = depfiles 131 141 am__mv = mv -f 132 AM_V_lt = $(am__v_lt_@AM_V@)133 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)134 am__v_lt_0 = --silent135 am__v_lt_1 =136 142 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ 137 143 $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 144 LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 145 $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ 146 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 147 $(AM_CXXFLAGS) $(CXXFLAGS) 138 148 AM_V_CXX = $(am__v_CXX_@AM_V@) 139 149 am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) … … 141 151 am__v_CXX_1 = 142 152 CXXLD = $(CXX) 143 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ 144 -o $@ 153 CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 154 $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ 155 $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 145 156 AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) 146 157 am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) 147 158 am__v_CXXLD_0 = @echo " CXXLD " $@; 148 159 am__v_CXXLD_1 = 149 @MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ ||150 160 LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) 161 LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 162 $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) 151 163 AM_V_LEX = $(am__v_LEX_@AM_V@) 152 164 am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) … … 154 166 am__v_LEX_1 = 155 167 YLWRAP = $(top_srcdir)/automake/ylwrap 156 @MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ ||157 168 am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ 158 169 -e s/c++$$/h++/ -e s/c$$/h/ 159 170 YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) 171 LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 172 $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) 160 173 AM_V_YACC = $(am__v_YACC_@AM_V@) 161 174 am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) … … 164 177 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 165 178 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 179 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 180 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ 181 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 182 $(AM_CFLAGS) $(CFLAGS) 166 183 AM_V_CC = $(am__v_CC_@AM_V@) 167 184 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) … … 169 186 am__v_CC_1 = 170 187 CCLD = $(CC) 171 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 188 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 189 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 190 $(AM_LDFLAGS) $(LDFLAGS) -o $@ 172 191 AM_V_CCLD = $(am__v_CCLD_@AM_V@) 173 192 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) … … 204 223 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 205 224 ACLOCAL = @ACLOCAL@ 206 ALLOCA = @ALLOCA@207 225 AMTAR = @AMTAR@ 208 226 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 227 AR = @AR@ 209 228 AUTOCONF = @AUTOCONF@ 210 229 AUTOHEADER = @AUTOHEADER@ 211 230 AUTOMAKE = @AUTOMAKE@ 212 231 AWK = @AWK@ 213 B ACKEND_CC = @BACKEND_CC@232 BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@ 214 233 CC = @CC@ 215 234 CCAS = @CCAS@ … … 217 236 CCASFLAGS = @CCASFLAGS@ 218 237 CCDEPMODE = @CCDEPMODE@ 238 CFACC = @CFACC@ 239 CFACC_INSTALL = @CFACC_INSTALL@ 240 CFACPP = @CFACPP@ 219 241 CFA_BACKEND_CC = @CFA_BACKEND_CC@ 220 242 CFA_BINDIR = @CFA_BINDIR@ … … 228 250 CPPFLAGS = @CPPFLAGS@ 229 251 CXX = @CXX@ 252 CXXCPP = @CXXCPP@ 230 253 CXXDEPMODE = @CXXDEPMODE@ 231 254 CXXFLAGS = @CXXFLAGS@ 232 255 CYGPATH_W = @CYGPATH_W@ 233 256 DEFS = @DEFS@ 257 DEMANGLER = @DEMANGLER@ 234 258 DEPDIR = @DEPDIR@ 259 DLLTOOL = @DLLTOOL@ 260 DRIVER_DIR = @DRIVER_DIR@ 261 DSYMUTIL = @DSYMUTIL@ 262 DUMPBIN = @DUMPBIN@ 235 263 ECHO_C = @ECHO_C@ 236 264 ECHO_N = @ECHO_N@ … … 238 266 EGREP = @EGREP@ 239 267 EXEEXT = @EXEEXT@ 268 FGREP = @FGREP@ 240 269 GREP = @GREP@ 270 HAS_DISTCC = @HAS_DISTCC@ 271 HOST_FLAGS = @HOST_FLAGS@ 241 272 INSTALL = @INSTALL@ 242 273 INSTALL_DATA = @INSTALL_DATA@ … … 244 275 INSTALL_SCRIPT = @INSTALL_SCRIPT@ 245 276 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 277 LD = @LD@ 246 278 LDFLAGS = @LDFLAGS@ 247 279 LEX = @LEX@ 248 280 LEXLIB = @LEXLIB@ 249 281 LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ 282 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 283 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 284 LIBDEMANGLE = @LIBDEMANGLE@ 250 285 LIBOBJS = @LIBOBJS@ 251 286 LIBS = @LIBS@ 287 LIBTOOL = @LIBTOOL@ 288 LIPO = @LIPO@ 289 LN_S = @LN_S@ 252 290 LTLIBOBJS = @LTLIBOBJS@ 253 MACHINE_TYPE = @MACHINE_TYPE@ 254 MAINT = @MAINT@ 291 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ 255 292 MAKEINFO = @MAKEINFO@ 293 MANIFEST_TOOL = @MANIFEST_TOOL@ 256 294 MKDIR_P = @MKDIR_P@ 295 NM = @NM@ 296 NMEDIT = @NMEDIT@ 297 OBJDUMP = @OBJDUMP@ 257 298 OBJEXT = @OBJEXT@ 299 OTOOL = @OTOOL@ 300 OTOOL64 = @OTOOL64@ 258 301 PACKAGE = @PACKAGE@ 259 302 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ … … 265 308 PATH_SEPARATOR = @PATH_SEPARATOR@ 266 309 RANLIB = @RANLIB@ 310 SED = @SED@ 267 311 SET_MAKE = @SET_MAKE@ 268 312 SHELL = @SHELL@ 269 313 STRIP = @STRIP@ 314 TARGET_HOSTS = @TARGET_HOSTS@ 270 315 VERSION = @VERSION@ 271 316 YACC = @YACC@ … … 275 320 abs_top_builddir = @abs_top_builddir@ 276 321 abs_top_srcdir = @abs_top_srcdir@ 322 ac_ct_AR = @ac_ct_AR@ 277 323 ac_ct_CC = @ac_ct_CC@ 278 324 ac_ct_CXX = @ac_ct_CXX@ 325 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 279 326 am__include = @am__include@ 280 327 am__leading_dot = @am__leading_dot@ … … 323 370 top_builddir = @top_builddir@ 324 371 top_srcdir = @top_srcdir@ 372 AUTOMAKE_OPTIONS = foreign # do not require all the GNU file names 373 ACLOCAL_AMFLAGS = -I automake 325 374 BUILT_SOURCES = parser.hh 326 375 AM_YFLAGS = -d -t -v … … 340 389 341 390 .SUFFIXES: 342 .SUFFIXES: .cc .ll . o .obj .yy343 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@$(srcdir)/Makefile.am $(am__configure_deps)391 .SUFFIXES: .cc .ll .lo .o .obj .yy 392 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 344 393 @for dep in $?; do \ 345 394 case '$(am__configure_deps)' in \ … … 365 414 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 366 415 367 $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@$(am__configure_deps)416 $(top_srcdir)/configure: $(am__configure_deps) 368 417 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 369 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@$(am__aclocal_m4_deps)418 $(ACLOCAL_M4): $(am__aclocal_m4_deps) 370 419 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 371 420 $(am__aclocal_m4_deps): … … 380 429 sed 's/$(EXEEXT)$$//' | \ 381 430 while read p p1; do if test -f $$p \ 431 || test -f $$p1 \ 382 432 ; then echo "$$p"; echo "$$p"; else :; fi; \ 383 433 done | \ … … 394 444 if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ 395 445 test -z "$$files" || { \ 396 echo " $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files '$(DESTDIR)$(tools_prettyprinterdir)$$dir'"; \397 $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files "$(DESTDIR)$(tools_prettyprinterdir)$$dir" || exit $$?; \446 echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(tools_prettyprinterdir)$$dir'"; \ 447 $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(tools_prettyprinterdir)$$dir" || exit $$?; \ 398 448 } \ 399 449 ; done … … 411 461 412 462 clean-tools_prettyprinterPROGRAMS: 413 -test -z "$(tools_prettyprinter_PROGRAMS)" || rm -f $(tools_prettyprinter_PROGRAMS) 463 @list='$(tools_prettyprinter_PROGRAMS)'; test -n "$$list" || exit 0; \ 464 echo " rm -f" $$list; \ 465 rm -f $$list || exit $$?; \ 466 test -n "$(EXEEXT)" || exit 0; \ 467 list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ 468 echo " rm -f" $$list; \ 469 rm -f $$list 414 470 parser.hh: parser.cc 415 471 @if test ! -f $@; then rm -f parser.cc; else :; fi … … 448 504 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 449 505 506 .cc.lo: 507 @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ 508 @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 509 @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo 510 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ 511 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 512 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< 513 450 514 pretty-lex.o: lex.cc 451 515 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pretty_CXXFLAGS) $(CXXFLAGS) -MT pretty-lex.o -MD -MP -MF $(DEPDIR)/pretty-lex.Tpo -c -o pretty-lex.o `test -f 'lex.cc' || echo '$(srcdir)/'`lex.cc … … 523 587 .yy.cc: 524 588 $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) 589 590 mostlyclean-libtool: 591 -rm -f *.lo 592 593 clean-libtool: 594 -rm -rf .libs _libs 525 595 526 596 ID: $(am__tagged_files) … … 652 722 clean: clean-am 653 723 654 clean-am: clean-generic clean- tools_prettyprinterPROGRAMS\655 mostlyclean-am724 clean-am: clean-generic clean-libtool \ 725 clean-tools_prettyprinterPROGRAMS mostlyclean-am 656 726 657 727 distclean: distclean-am … … 708 778 mostlyclean: mostlyclean-am 709 779 710 mostlyclean-am: mostlyclean-compile mostlyclean-generic 780 mostlyclean-am: mostlyclean-compile mostlyclean-generic \ 781 mostlyclean-libtool 711 782 712 783 pdf: pdf-am … … 723 794 724 795 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ 725 clean-tools_prettyprinterPROGRAMS cscopelist-am ctags ctags-am \ 726 distclean distclean-compile distclean-generic distclean-tags \ 727 distdir dvi dvi-am html html-am info info-am install \ 728 install-am install-data install-data-am install-dvi \ 729 install-dvi-am install-exec install-exec-am install-html \ 730 install-html-am install-info install-info-am install-man \ 731 install-pdf install-pdf-am install-ps install-ps-am \ 732 install-strip install-tools_prettyprinterPROGRAMS installcheck \ 796 clean-libtool clean-tools_prettyprinterPROGRAMS cscopelist-am \ 797 ctags ctags-am distclean distclean-compile distclean-generic \ 798 distclean-libtool distclean-tags distdir dvi dvi-am html \ 799 html-am info info-am install install-am install-data \ 800 install-data-am install-dvi install-dvi-am install-exec \ 801 install-exec-am install-html install-html-am install-info \ 802 install-info-am install-man install-pdf install-pdf-am \ 803 install-ps install-ps-am install-strip \ 804 install-tools_prettyprinterPROGRAMS installcheck \ 733 805 installcheck-am installdirs maintainer-clean \ 734 806 maintainer-clean-generic mostlyclean mostlyclean-compile \ 735 mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ 736 uninstall-am uninstall-tools_prettyprinterPROGRAMS 807 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ 808 tags tags-am uninstall uninstall-am \ 809 uninstall-tools_prettyprinterPROGRAMS 737 810 738 811 .PRECIOUS: Makefile -
tools/stat.py
r7951100 rb067d9b 11 11 content = f.readlines() 12 12 content = [x.strip() for x in content] 13 content = [ int(x) for x in content]14 content.remove(max(content)) 15 content.remove(min(content)) 16 med = numpy. around( numpy.median(content), decimals=1)17 avg = numpy. around( numpy.mean (content), decimals=2)18 std = numpy. around( numpy.std (content), decimals=2)19 print "median {0 } avg {1} stddev {2}".format( med, avg, std )13 content = [float(x) for x in content] # expect floating-point strings 14 content.remove(max(content)) # need at least 4 data values because 15 content.remove(min(content)) # the max and min values are removed 16 med = numpy.median(content) 17 avg = numpy.mean (content) 18 std = numpy.std (content) 19 print "median {0:.1f} avg {1:.1f} stddev {2:.2f}".format( med, avg, std ) 20 20 21 21
Note:
See TracChangeset
for help on using the changeset viewer.