Changes in / [6840e7c:b96ec83]
- Files:
-
- 8 added
- 30 deleted
- 148 edited
-
doc/LaTeXmacros/lstlang.sty (modified) (2 diffs)
-
doc/proposals/concurrency/Makefile (modified) (2 diffs)
-
doc/proposals/concurrency/annex/glossary.tex (modified) (2 diffs)
-
doc/proposals/concurrency/figures/dependency.fig (deleted)
-
doc/proposals/concurrency/figures/ext_monitor.fig (modified) (5 diffs)
-
doc/proposals/concurrency/figures/int_monitor.fig.bak (added)
-
doc/proposals/concurrency/style/cfa-format.tex (modified) (4 diffs)
-
doc/proposals/concurrency/text/basics.tex (modified) (12 diffs)
-
doc/proposals/concurrency/text/cforall.tex (modified) (3 diffs)
-
doc/proposals/concurrency/text/concurrency.tex (modified) (25 diffs)
-
doc/proposals/concurrency/text/future.tex (deleted)
-
doc/proposals/concurrency/text/internals.tex (deleted)
-
doc/proposals/concurrency/text/intro.tex (modified) (1 diff)
-
doc/proposals/concurrency/text/parallelism.tex (modified) (1 diff)
-
doc/proposals/concurrency/text/together.tex (deleted)
-
doc/proposals/concurrency/thesis.tex (modified) (4 diffs)
-
doc/proposals/concurrency/version (modified) (1 diff)
-
src/CodeGen/CodeGenerator.cc (modified) (3 diffs)
-
src/CodeGen/CodeGenerator.h (modified) (1 diff)
-
src/CodeGen/FixNames.cc (modified) (1 diff)
-
src/CodeGen/GenType.cc (modified) (1 diff)
-
src/Common/Indenter.h (modified) (2 diffs)
-
src/Common/PassVisitor.h (modified) (3 diffs)
-
src/Common/PassVisitor.impl.h (modified) (111 diffs)
-
src/Common/PassVisitor.proto.h (modified) (1 diff)
-
src/Common/utility.h (modified) (4 diffs)
-
src/Concurrency/Keywords.cc (modified) (9 diffs)
-
src/Concurrency/Waitfor.cc (modified) (8 diffs)
-
src/GenPoly/Box.cc (modified) (9 diffs)
-
src/GenPoly/CopyParams.cc (added)
-
src/GenPoly/CopyParams.h (added)
-
src/GenPoly/FindFunction.cc (modified) (6 diffs)
-
src/GenPoly/GenPoly.cc (modified) (1 diff)
-
src/GenPoly/GenPoly.h (modified) (1 diff)
-
src/GenPoly/Specialize.cc (modified) (1 diff)
-
src/GenPoly/module.mk (modified) (1 diff)
-
src/InitTweak/FixInit.cc (modified) (20 diffs)
-
src/InitTweak/GenInit.cc (modified) (10 diffs)
-
src/InitTweak/GenInit.h (modified) (2 diffs)
-
src/InitTweak/InitTweak.cc (modified) (6 diffs)
-
src/InitTweak/InitTweak.h (modified) (2 diffs)
-
src/MakeLibCfa.cc (modified) (3 diffs)
-
src/Makefile.in (modified) (5 diffs)
-
src/Parser/DeclarationNode.cc (modified) (2 diffs)
-
src/Parser/ExpressionNode.cc (modified) (11 diffs)
-
src/Parser/ParseNode.h (modified) (3 diffs)
-
src/Parser/TypeData.cc (modified) (28 diffs)
-
src/Parser/lex.ll (modified) (6 diffs)
-
src/Parser/parser.yy (modified) (15 diffs)
-
src/ResolvExpr/AdjustExprType.cc (modified) (5 diffs)
-
src/ResolvExpr/Alternative.cc (modified) (1 diff)
-
src/ResolvExpr/Alternative.h (modified) (1 diff)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (7 diffs)
-
src/ResolvExpr/CastCost.cc (modified) (2 diffs)
-
src/ResolvExpr/CommonType.cc (modified) (2 diffs)
-
src/ResolvExpr/ConversionCost.cc (modified) (5 diffs)
-
src/ResolvExpr/ResolveTypeof.cc (modified) (3 diffs)
-
src/ResolvExpr/Resolver.cc (modified) (22 diffs)
-
src/ResolvExpr/Resolver.h (modified) (1 diff)
-
src/ResolvExpr/TypeEnvironment.cc (modified) (2 diffs)
-
src/ResolvExpr/TypeEnvironment.h (modified) (2 diffs)
-
src/ResolvExpr/Unify.cc (modified) (4 diffs)
-
src/SymTab/Autogen.cc (modified) (19 diffs)
-
src/SymTab/Autogen.h (modified) (10 diffs)
-
src/SymTab/FixFunction.cc (modified) (2 diffs)
-
src/SymTab/FixFunction.h (modified) (1 diff)
-
src/SymTab/Indexer.cc (modified) (3 diffs)
-
src/SymTab/Mangler.cc (modified) (2 diffs)
-
src/SymTab/Validate.cc (modified) (6 diffs)
-
src/SynTree/AddressExpr.cc (modified) (4 diffs)
-
src/SynTree/AggregateDecl.cc (modified) (1 diff)
-
src/SynTree/ApplicationExpr.cc (modified) (2 diffs)
-
src/SynTree/ArrayType.cc (modified) (1 diff)
-
src/SynTree/AttrType.cc (modified) (2 diffs)
-
src/SynTree/Attribute.cc (modified) (2 diffs)
-
src/SynTree/Attribute.h (modified) (1 diff)
-
src/SynTree/BaseSyntaxNode.h (modified) (2 diffs)
-
src/SynTree/BasicType.cc (modified) (3 diffs)
-
src/SynTree/CommaExpr.cc (modified) (2 diffs)
-
src/SynTree/CompoundStmt.cc (modified) (1 diff)
-
src/SynTree/Constant.cc (modified) (1 diff)
-
src/SynTree/Constant.h (modified) (4 diffs)
-
src/SynTree/DeclStmt.cc (modified) (1 diff)
-
src/SynTree/Declaration.cc (modified) (2 diffs)
-
src/SynTree/Declaration.h (modified) (7 diffs)
-
src/SynTree/Expression.cc (modified) (30 diffs)
-
src/SynTree/Expression.h (modified) (57 diffs)
-
src/SynTree/FunctionDecl.cc (modified) (2 diffs)
-
src/SynTree/FunctionType.cc (modified) (2 diffs)
-
src/SynTree/Initializer.cc (modified) (4 diffs)
-
src/SynTree/Initializer.h (modified) (5 diffs)
-
src/SynTree/Mutator.cc (modified) (1 diff)
-
src/SynTree/Mutator.h (modified) (1 diff)
-
src/SynTree/NamedTypeDecl.cc (modified) (2 diffs)
-
src/SynTree/ObjectDecl.cc (modified) (3 diffs)
-
src/SynTree/PointerType.cc (modified) (1 diff)
-
src/SynTree/ReferenceToType.cc (modified) (10 diffs)
-
src/SynTree/ReferenceType.cc (modified) (1 diff)
-
src/SynTree/Statement.cc (modified) (18 diffs)
-
src/SynTree/Statement.h (modified) (19 diffs)
-
src/SynTree/TupleExpr.cc (modified) (5 diffs)
-
src/SynTree/TupleType.cc (modified) (1 diff)
-
src/SynTree/Type.cc (modified) (4 diffs)
-
src/SynTree/Type.h (modified) (20 diffs)
-
src/SynTree/TypeDecl.cc (modified) (1 diff)
-
src/SynTree/TypeExpr.cc (modified) (1 diff)
-
src/SynTree/TypeSubstitution.cc (modified) (5 diffs)
-
src/SynTree/TypeSubstitution.h (modified) (2 diffs)
-
src/SynTree/TypeofType.cc (modified) (2 diffs)
-
src/SynTree/VarArgsType.cc (modified) (1 diff)
-
src/SynTree/VoidType.cc (modified) (2 diffs)
-
src/SynTree/ZeroOneType.cc (modified) (2 diffs)
-
src/Tuples/Explode.h (modified) (2 diffs)
-
src/Tuples/TupleAssignment.cc (modified) (7 diffs)
-
src/benchmark/Makefile.am (modified) (1 diff)
-
src/benchmark/Makefile.in (modified) (1 diff)
-
src/benchmark/PthrdCtxSwitch.c (deleted)
-
src/benchmark/bench.h (modified) (1 diff)
-
src/benchmark/create_cfaThrd.c (modified) (1 diff)
-
src/driver/cfa.cc (modified) (2 diffs)
-
src/include/cassert (modified) (1 diff)
-
src/libcfa/Makefile.am (modified) (1 diff)
-
src/libcfa/Makefile.in (modified) (1 diff)
-
src/libcfa/concurrency/invoke.h (modified) (2 diffs)
-
src/libcfa/concurrency/monitor (modified) (4 diffs)
-
src/libcfa/concurrency/monitor.c (modified) (18 diffs)
-
src/libcfa/iostream (modified) (2 diffs)
-
src/libcfa/iostream.c (modified) (3 diffs)
-
src/main.cc (modified) (2 diffs)
-
src/prelude/extras.c (modified) (1 diff)
-
src/prelude/extras.regx (modified) (1 diff)
-
src/prelude/prelude.cf (modified) (2 diffs)
-
src/tests/.expect/32/KRfunctions.txt (modified) (3 diffs)
-
src/tests/.expect/32/attributes.txt (modified) (21 diffs)
-
src/tests/.expect/32/declarationSpecifier.txt (modified) (50 diffs)
-
src/tests/.expect/32/extension.txt (modified) (5 diffs)
-
src/tests/.expect/32/gccExtensions.txt (modified) (7 diffs)
-
src/tests/.expect/32/literals.txt (modified) (48 diffs)
-
src/tests/.expect/64/KRfunctions.txt (modified) (3 diffs)
-
src/tests/.expect/64/attributes.txt (modified) (21 diffs)
-
src/tests/.expect/64/declarationSpecifier.txt (modified) (50 diffs)
-
src/tests/.expect/64/extension.txt (modified) (5 diffs)
-
src/tests/.expect/64/gccExtensions.txt (modified) (7 diffs)
-
src/tests/.expect/64/literals.txt (modified) (48 diffs)
-
src/tests/.expect/castError.txt (modified) (1 diff)
-
src/tests/.expect/concurrent/boundedBuffer.txt (deleted)
-
src/tests/.expect/concurrent/fmtLines.txt (deleted)
-
src/tests/.expect/concurrent/matrixSum.txt (deleted)
-
src/tests/.expect/concurrent/pingpong.txt (deleted)
-
src/tests/.expect/concurrent/prodcons.txt (deleted)
-
src/tests/.expect/concurrent/sched-ext-barge.txt (deleted)
-
src/tests/.expect/concurrent/sched-ext-dtor.txt (deleted)
-
src/tests/.expect/concurrent/sched-ext-else.txt (deleted)
-
src/tests/.expect/concurrent/sched-ext-recurse.txt (deleted)
-
src/tests/.expect/concurrent/sched-ext-statment.txt (deleted)
-
src/tests/.expect/concurrent/sched-ext-when.txt (deleted)
-
src/tests/.expect/ctor-autogen-ERR1.txt (deleted)
-
src/tests/.expect/ctor-autogen.txt (deleted)
-
src/tests/.expect/fmtLines.txt (added)
-
src/tests/.expect/pingpong.txt (added)
-
src/tests/.expect/polymorphism.txt (deleted)
-
src/tests/.expect/prodcons.txt (added)
-
src/tests/.expect/references.txt (deleted)
-
src/tests/.expect/sched-ext-else.txt (added)
-
src/tests/.expect/sched-ext-parse.txt (added)
-
src/tests/.expect/scopeErrors.txt (modified) (1 diff)
-
src/tests/Makefile.am (modified) (3 diffs)
-
src/tests/Makefile.in (modified) (2 diffs)
-
src/tests/boundedBuffer.c (deleted)
-
src/tests/coroutine.c (modified) (4 diffs)
-
src/tests/ctor-autogen.c (deleted)
-
src/tests/fmtLines.c (modified) (3 diffs)
-
src/tests/gmp.c (modified) (2 diffs)
-
src/tests/literals.c (modified) (6 diffs)
-
src/tests/matrixSum.c (deleted)
-
src/tests/polymorphism.c (deleted)
-
src/tests/references.c (deleted)
-
src/tests/sched-ext-barge.c (deleted)
-
src/tests/sched-ext-dtor.c (deleted)
-
src/tests/sched-ext-parse.c (modified) (1 diff)
-
src/tests/sched-ext-recurse.c (deleted)
-
src/tests/sched-ext-statment.c (deleted)
-
src/tests/sched-ext-when.c (deleted)
-
src/tests/sched-int-barge.c (modified) (1 diff)
-
src/tests/sched-int-block.c (modified) (1 diff)
-
src/tests/sched-int-wait.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/lstlang.sty
r6840e7c rb96ec83 2 2 %% 3 3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 %% 5 %% lstlang.sty -- 6 %% 4 %% 5 %% lstlang.sty -- 6 %% 7 7 %% Author : Peter A. Buhr 8 8 %% Created On : Sat May 13 16:34:42 2017 … … 110 110 __attribute__, auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, 111 111 __const, __const__, disable, dtype, enable, __extension__, fallthrough, fallthru, 112 finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t, 113 otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 114 __typeof__, virtual, w ith, zero_t},112 finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t, 113 otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 114 __typeof__, virtual, waitfor, when, with, zero_t}, 115 115 morekeywords=[2]{ 116 _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, or,117 resume, suspend, thread, _Thread_local, waitfor, when,yield},116 _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, 117 resume, suspend, thread, _Thread_local, yield}, 118 118 moredirectives={defined,include_next}% 119 119 } -
doc/proposals/concurrency/Makefile
r6840e7c rb96ec83 16 16 text/basics \ 17 17 text/concurrency \ 18 text/internals \19 18 text/parallelism \ 20 text/together \21 text/future \22 19 } 23 20 … … 26 23 ext_monitor \ 27 24 int_monitor \ 28 dependency \29 25 }} 30 26 -
doc/proposals/concurrency/annex/glossary.tex
r6840e7c rb96ec83 13 13 } 14 14 15 \longnewglossaryentry{ bulk-acq}16 {name={bulk -acquiring}}15 \longnewglossaryentry{group-acquire} 16 {name={bulk acquiring}} 17 17 { 18 18 Implicitly acquiring several monitors when entering a monitor. 19 }20 21 \longnewglossaryentry{multi-acq}22 {name={multiple-acquisition}}23 {24 Any locking technique which allow any single thread to acquire a lock multiple times.25 19 } 26 20 … … 107 101 \newacronym{api}{API}{Application Program Interface} 108 102 \newacronym{raii}{RAII}{Ressource Acquisition Is Initialization} 109 \newacronym{numa}{NUMA}{Non-Uniform Memory Access} -
doc/proposals/concurrency/figures/ext_monitor.fig
r6840e7c rb96ec83 14 14 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 2160 d\001 15 15 -6 16 6 5 100 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 5850 1650 6150 1950 17 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 1800 105 105 6000 1800 6105 1905 18 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 1860 b\001 19 19 -6 20 20 6 5100 1800 5400 2100 … … 22 22 4 1 -1 0 0 0 10 0.0000 2 105 120 5250 2010 Y\001 23 23 -6 24 6 5 850 1650 6150 195025 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 6000 1800 105 105 6000 1800 6105 190526 4 1 -1 0 0 0 10 0.0000 2 105 90 6000 1860 b\00124 6 5100 2100 5400 2400 25 1 3 0 1 -1 -1 1 0 4 0.000 1 0.0000 5250 2250 105 105 5250 2250 5355 2250 26 4 1 -1 0 0 0 10 0.0000 2 105 120 5250 2295 X\001 27 27 -6 28 6 30 70 5445 7275 565528 6 3000 5400 7200 5700 29 29 1 3 0 1 -1 -1 0 0 20 0.000 1 0.0000 3150 5550 80 80 3150 5550 3230 5630 30 30 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 4500 5550 105 105 4500 5550 4605 5655 … … 32 32 4 0 -1 0 0 0 12 0.0000 2 135 1035 4725 5625 blocked task\001 33 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 1 35 1050 6225 5625 routine mask\00134 4 0 -1 0 0 0 12 0.0000 2 180 930 6225 5625 routine ptrs\001 35 35 -6 36 36 1 3 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3300 3600 105 105 3300 3600 3405 3705 … … 43 43 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 44 44 4050 2925 5475 2925 5475 3225 4050 3225 4050 2925 45 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 2 46 5850 2850 6075 3000 45 47 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 46 48 3150 3750 3750 3750 3750 4050 3150 4050 … … 64 66 2 2 1 1 -1 -1 0 0 -1 4.000 0 0 0 0 0 5 65 67 5850 4200 5850 3300 4350 3300 4350 4200 5850 4200 68 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 3 69 5250 2850 5850 2850 5850 1650 70 2 1 0 1 -1 -1 0 0 -1 0.000 0 0 -1 0 0 4 71 3150 3150 3750 3150 3750 2850 5325 2850 66 72 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 67 73 1 1 1.00 60.00 120.00 68 74 7 1 1.00 60.00 120.00 69 75 5250 3150 5250 2400 70 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 571 3150 3150 3750 3150 3750 2850 5850 2850 5850 165072 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 273 5850 2850 6150 300074 76 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 75 77 5100 1800 5400 1800 5400 2400 5100 2400 5100 1800 -
doc/proposals/concurrency/style/cfa-format.tex
r6840e7c rb96ec83 108 108 belowskip=3pt, 109 109 keepspaces=true, 110 tabsize=4,111 110 % frame=lines, 112 111 literate=, … … 134 133 belowskip=3pt, 135 134 keepspaces=true, 136 tabsize=4,137 135 % frame=lines, 138 136 literate=, … … 152 150 keywordstyle=\bfseries\color{blue}, 153 151 keywordstyle=[2]\bfseries\color{Plum}, 154 commentstyle=\ sf\itshape\color{OliveGreen},% green and italic comments152 commentstyle=\itshape\color{OliveGreen}, % green and italic comments 155 153 identifierstyle=\color{identifierCol}, 156 154 stringstyle=\sf\color{Mahogany}, % use sanserif font … … 160 158 belowskip=3pt, 161 159 keepspaces=true, 162 tabsize=4,163 160 % frame=lines, 164 161 literate=, -
doc/proposals/concurrency/text/basics.tex
r6840e7c rb96ec83 1 1 % ====================================================================== 2 2 % ====================================================================== 3 \chapter{ ConcurrencyBasics}\label{basics}3 \chapter{Basics}\label{basics} 4 4 % ====================================================================== 5 5 % ====================================================================== 6 Before any detailed discussion of the concurrency and parallelism in \CFA, it is important to describe the basics of concurrency and how they are expressed in \CFA user -code.6 Before any detailed discussion of the concurrency and parallelism in \CFA, it is important to describe the basics of concurrency and how they are expressed in \CFA user code. 7 7 8 8 \section{Basics of concurrency} 9 At its core, concurrency is based on having multiple call-stacks and scheduling among threads of execution executing on these stacks. Concurrency without parallelism only requires having multiple call stacks (or contexts) for a single thread of execution. 10 11 Indeed, while execution with a single thread and multiple stacks where the thread is self-scheduling deterministically across the stacks is called coroutining, execution with a single and multiple stacks but where the thread is scheduled by an oracle (non-deterministic from the thread perspective) across the stacks is called concurrency. 12 13 Therefore, a minimal concurrency system can be achieved by creating coroutines, which instead of context switching among each other, always ask an oracle where to context switch next. While coroutines can execute on the caller's stack-frame, stackfull coroutines allow full generality and are sufficient as the basis for concurrency. The aforementioned oracle is a scheduler and the whole system now follows a cooperative threading-model \cit. The oracle/scheduler can either be a stackless or stackfull entity and correspondingly require one or two context switches to run a different coroutine. In any case, a subset of concurrency related challenges start to appear. For the complete set of concurrency challenges to occur, the only feature missing is preemption. Indeed, concurrency challenges appear with non-determinism. Using mutual-exclusion or synchronisation are ways of limiting the lack of determinism in a system. A scheduler introduces order of execution uncertainty, while preemption introduces uncertainty about where context-switches occur. Now it is important to understand that uncertainty is not undesireable; uncertainty can often be used by systems to significantly increase performance and is often the basis of giving a user the illusion that tasks are running in parallel. Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows\cit. 9 At its core, concurrency is based on having call-stacks and potentially multiple threads of execution for these stacks. Concurrency without parallelism only requires having multiple call stacks (or contexts) for a single thread of execution, and switching between these call stacks on a regular basis. A minimal concurrency product can be achieved by creating coroutines, which instead of context switching between each other, always ask an oracle where to context switch next. While coroutines do not technically require a stack, stackfull coroutines are the closest abstraction to a practical "naked"" call stack. When writing concurrency in terms of coroutines, the oracle effectively becomes a scheduler and the whole system now follows a cooperative threading-model \cit. The oracle/scheduler can either be a stackless or stackfull entity and correspondingly require one or two context switches to run a different coroutine. In any case, a subset of concurrency related challenges start to appear. For the complete set of concurrency challenges to occur, the only feature missing is preemption. Indeed, concurrency challenges appear with non-determinism. Guaranteeing mutual-exclusion or synchronisation are simply ways of limiting the lack of determinism in a system. A scheduler introduces order of execution uncertainty, while preemption introduces incertainty about where context-switches occur. Now it is important to understand that uncertainty is not necessarily undesireable; uncertainty can often be used by systems to significantly increase performance and is often the basis of giving a user the illusion that tasks are running in parallel. Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows\cit. 14 10 15 11 \section{\protect\CFA 's Thread Building Blocks} 16 One of the important features that is missing in C is threading. On modern architectures, a lack of threading is unacceptable\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write performant concurrent and/or parallel programs. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar withimperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay.12 One of the important features that is missing in C is threading. On modern architectures, a lack of threading is becoming less and less forgivable\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write performant concurrent and/or parallel programs. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers used to imperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay. 17 13 18 14 \section{Coroutines: A stepping stone}\label{coroutine} 19 While the main focus of this proposal is concurrency and parallelism, it is important to address coroutines, which are actually a significant building block of a concurrency system. Coroutines need to deal with context-switchs and other context-management operations. Therefore, this proposal includes coroutines both as an intermediate step for the implementation of threads, and a first class feature of \CFA. Furthermore, many design challenges of threads are at least partially present in designing coroutines, which makes the design effort that much more relevant. The core \acrshort{api} of coroutines revolve around two features: independent call stacks and \code{suspend}/\code{resume}. 20 21 A good example of a problem made easier with coroutines is genereting the fibonacci sequence. This problem comes with the challenge of decoupling how a sequence is generated and how it is used. Figure \ref{fig:fibonacci-c} shows conventional approaches to writing generators in C. All three of these approach suffer from strong coupling. The left and center approaches require that the generator have knowledge of how the sequence will be used, while the rightmost approach requires to user to hold internal state between calls on behalf of th sequence generator and makes it much harder to handle corner cases like the Fibonacci seed. 22 \begin{figure} 23 \label{fig:fibonacci-c} 24 \begin{center} 25 \begin{tabular}{c @{\hskip 0.025in}|@{\hskip 0.025in} c @{\hskip 0.025in}|@{\hskip 0.025in} c} 26 \begin{ccode}[tabsize=2] 27 //Using callbacks 28 void fibonacci_func( 29 int n, 30 void (*callback)(int) 31 ) { 32 int first = 0; 33 int second = 1; 34 int next, i; 35 for(i = 0; i < n; i++) 36 { 37 if(i <= 1) 38 next = i; 39 else { 40 next = f1 + f2; 41 f1 = f2; 42 f2 = next; 43 } 44 callback(next); 45 } 46 } 47 \end{ccode}&\begin{ccode}[tabsize=2] 48 //Using output array 49 void fibonacci_array( 50 int n, 51 int * array 52 ) { 53 int f1 = 0; int f2 = 1; 54 int next, i; 55 for(i = 0; i < n; i++) 56 { 57 if(i <= 1) 58 next = i; 59 else { 60 next = f1 + f2; 61 f1 = f2; 62 f2 = next; 63 } 64 *array = next; 65 array++; 66 } 67 } 68 \end{ccode}&\begin{ccode}[tabsize=2] 69 //Using external state 70 typedef struct { 71 int f1, f2; 72 } iterator_t; 73 74 int fibonacci_state( 75 iterator_t * it 76 ) { 77 int f; 78 f = it->f1 + it->f2; 79 it->f2 = it->f1; 80 it->f1 = f; 81 return f; 82 } 83 84 85 86 87 88 89 \end{ccode} 90 \end{tabular} 91 \end{center} 92 \caption{Different implementations of a fibonacci sequence generator in C.} 93 \end{figure} 94 95 96 Figure \ref{fig:fibonacci-cfa} is an example of a solution to the fibonnaci problem using \CFA coroutines, using the coroutine stack to hold sufficient state for the generation. This solution has the advantage of having very strong decoupling between how the sequence is generated and how it is used. Indeed, this version is a easy to use as the \code{fibonacci_state} solution, while the imlpementation is very similar to the \code{fibonacci_func} example. 97 98 \begin{figure} 99 \label{fig:fibonacci-cfa} 100 \begin{cfacode} 101 coroutine Fibonacci { 102 int fn; //used for communication 103 }; 104 105 void ?{}(Fibonacci & this) { //constructor 106 this.fn = 0; 107 } 108 109 //main automacically called on first resume 110 void main(Fibonacci & this) { 111 int fn1, fn2; //retained between resumes 112 this.fn = 0; 113 fn1 = this.fn; 114 suspend(this); //return to last resume 115 116 this.fn = 1; 117 fn2 = fn1; 118 fn1 = this.fn; 119 suspend(this); //return to last resume 120 121 for ( ;; ) { 122 this.fn = fn1 + fn2; 15 While the main focus of this proposal is concurrency and parallelism, as mentionned above it is important to adress coroutines, which are actually a significant underlying aspect of a concurrency system. Indeed, while having nothing to do with parallelism and arguably little to do with concurrency, coroutines need to deal with context-switchs and other context-management operations. Therefore, this proposal includes coroutines both as an intermediate step for the implementation of threads, and a first class feature of \CFA. Furthermore, many design challenges of threads are at least partially present in designing coroutines, which makes the design effort that much more relevant. The core API of coroutines revolve around two features: independent call stacks and \code{suspend}/\code{resume}. 16 17 Here is an example of a solution to the fibonnaci problem using \CFA coroutines: 18 \begin{cfacode} 19 coroutine Fibonacci { 20 int fn; // used for communication 21 }; 22 23 void ?{}(Fibonacci & this) { // constructor 24 this.fn = 0; 25 } 26 27 // main automacically called on first resume 28 void main(Fibonacci & this) { 29 int fn1, fn2; // retained between resumes 30 this.fn = 0; 31 fn1 = this.fn; 32 suspend(this); // return to last resume 33 34 this.fn = 1; 123 35 fn2 = fn1; 124 36 fn1 = this.fn; 125 suspend(this); //return to last resume 126 } 127 } 128 129 int next(Fibonacci & this) { 130 resume(this); //transfer to last suspend 131 return this.fn; 132 } 133 134 void main() { //regular program main 135 Fibonacci f1, f2; 136 for ( int i = 1; i <= 10; i += 1 ) { 137 sout | next( f1 ) | next( f2 ) | endl; 138 } 139 } 140 \end{cfacode} 141 \caption{Implementation of fibonacci using coroutines} 142 \end{figure} 37 suspend(this); // return to last resume 38 39 for ( ;; ) { 40 this.fn = fn1 + fn2; 41 fn2 = fn1; 42 fn1 = this.fn; 43 suspend(this); // return to last resume 44 } 45 } 46 47 int next(Fibonacci & this) { 48 resume(this); // transfer to last suspend 49 return this.fn; 50 } 51 52 void main() { // regular program main 53 Fibonacci f1, f2; 54 for ( int i = 1; i <= 10; i += 1 ) { 55 sout | next( f1 ) | next( f2 ) | endl; 56 } 57 } 58 \end{cfacode} 143 59 144 60 \subsection{Construction} 145 One important design challenge for coroutines and threads (shown in section \ref{threads}) is that the runtime system needs to run code after the user-constructor runs to connect the object into the system. In the case of coroutines, this challenge is simpler since there is no non-determinism from preemption or scheduling. However, the underlying challenge remains the same for coroutines and threads.146 147 The runtime system needs to create the coroutine's stack and more importantly prepare it for the first resumption. The timing of the creation is non-trivial since users both expect to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor. As regular objects, constructors canleak coroutines before they are ready. There are several solutions to this problem but the chosen options effectively forces the design of the coroutine.61 One important design challenge for coroutines and threads (shown in section \ref{threads}) is that the runtime system needs to run code after the user-constructor runs. In the case of coroutines, this challenge is simpler since there is no non-determinism from preemption or scheduling. However, the underlying challenge remains the same for coroutines and threads. 62 63 The runtime system needs to create the coroutine's stack and more importantly prepare it for the first resumption. The timing of the creation is non-trivial since users both expect to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor. Like for regular objects, constructors can still leak coroutines before they are ready. There are several solutions to this problem but the chosen options effectively forces the design of the coroutine. 148 64 149 65 Furthermore, \CFA faces an extra challenge as polymorphic routines create invisible thunks when casted to non-polymorphic routines and these thunks have function scope. For example, the following code, while looking benign, can run into undefined behaviour because of thunks: … … 162 78 } 163 79 \end{cfacode} 164 165 80 The generated C code\footnote{Code trimmed down for brevity} creates a local thunk to hold type information: 166 81 … … 180 95 } 181 96 \end{ccode} 182 The problem in this example is a storage management issue, the function pointer \code{_thunk0} is only valid until the end of the block. This extra challenge limits which solutions are viable because storing the function pointer for too long causesundefined behavior; i.e. the stack based thunk being destroyed before it was used. This challenge is an extension of challenges that come with second-class routines. Indeed, GCC nested routines also have the limitation that the routines cannot be passed outside of the scope of the functions these were declared in. The case of coroutines and threads is simply an extension of this problem to multiple call-stacks.97 The problem in this example is a race condition between the start of the execution of \code{noop} on the other thread and the stack frame of \code{bar} being destroyed. This extra challenge limits which solutions are viable because storing the function pointer for too long only increases the chances that the race will end in undefined behavior; i.e. the stack based thunk being destroyed before it was used. This challenge is an extension of challenges that come with second-class routines. Indeed, GCC nested routines also have the limitation that the routines cannot be passed outside of the scope of the functions these were declared in. The case of coroutines and threads is simply an extension of this problem to multiple call-stacks. 183 98 184 99 \subsection{Alternative: Composition} 185 One solution to this challenge is to use composition/containement, where uses add insert a coroutine field which contains the necessary information to manage the coroutine. 186 187 \begin{cfacode} 188 struct Fibonacci { 189 int fn; //used for communication 190 coroutine c; //composition 191 }; 192 193 void ?{}(Fibonacci & this) { 194 this.fn = 0; 195 (this.c){}; //Call constructor to initialize coroutine 196 } 197 \end{cfacode} 198 There are two downsides to this approach. The first, which is relatively minor, made aware of the main routine pointer. This information must either be store in the coroutine runtime data or in its static type structure. When using composition, all coroutine handles have the same static type structure which means the pointer to the main needs to be part of the runtime data. This requirement means the coroutine data must be made larger to store a value that is actually a compile time constant (address of the main routine). The second problem, which is both subtle and significant, is that now users can get the initialisation order of coroutines wrong. Indeed, every field of a \CFA struct is constructed but in declaration order, unless users explicitly write otherwise. This semantics means that users who forget to initialize the coroutine handle may resume the coroutine with an uninitilized object. For coroutines, this is unlikely to be a problem, for threads however, this is a significant problem. Figure \ref{fig:fmt-line} shows the \code{Format} coroutine which rearranges text in order to group characters into blocks of fixed size. This is a good example where the control flow is made much simpler from being able to resume the coroutine from the constructor and highlights the idea that interesting control flow can occor in the constructor. 199 \begin{figure} 200 \label{fig:fmt-line} 201 \begin{cfacode}[tabsize=3] 202 //format characters into blocks of 4 and groups of 5 blocks per line 203 coroutine Format { 204 char ch; //used for communication 205 int g, b; //global because used in destructor 206 }; 207 208 void ?{}(Format & fmt) { 209 resume( fmt ); //prime (start) coroutine 210 } 211 212 void ^?{}(Format & fmt) with fmt { 213 if ( fmt.g != 0 || fmt.b != 0 ) 214 sout | endl; 215 } 216 217 void main(Format & fmt) with fmt { 218 for ( ;; ) { //for as many characters 219 for(g = 0; g < 5; g++) { //groups of 5 blocks 220 for(b = 0; b < 4; fb++) { //blocks of 4 characters 221 suspend(); 222 sout | ch; //print character 223 } 224 sout | " "; //print block separator 225 } 226 sout | endl; //print group separator 227 } 228 } 229 230 void prt(Format & fmt, char ch) { 231 fmt.ch = ch; 232 resume(fmt); 233 } 234 235 int main() { 236 Format fmt; 237 char ch; 238 Eof: for ( ;; ) { //read until end of file 239 sin | ch; //read one character 240 if(eof(sin)) break Eof; //eof ? 241 prt(fmt, ch); //push character for formatting 242 } 243 } 244 \end{cfacode} 245 \caption{Formatting text into lines of 5 blocks of 4 characters.} 246 \end{figure} 247 100 One solution to this challenge would be to use composition/containement, 101 102 \begin{cfacode} 103 struct Fibonacci { 104 int fn; // used for communication 105 coroutine c; //composition 106 }; 107 108 void ?{}(Fibonacci & this) { 109 this.fn = 0; 110 (this.c){}; 111 } 112 \end{cfacode} 113 There are two downsides to this approach. The first, which is relatively minor, is that the base class needs to be made aware of the main routine pointer, regardless of whether a parameter or a virtual pointer is used, this means the coroutine data must be made larger to store a value that is actually a compile time constant (address of the main routine). The second problem, which is both subtle and significant, is that now users can get the initialisation order of there coroutines wrong. Indeed, every field of a \CFA struct is constructed but in declaration order, unless users explicitly write otherwise. This semantics means that users who forget to initialize a the coroutine may resume the coroutine with an uninitilized object. For coroutines, this is unlikely to be a problem, for threads however, this is a significant problem. 248 114 249 115 \subsection{Alternative: Reserved keyword} … … 251 117 252 118 \begin{cfacode} 253 coroutine Fibonacci { 254 int fn; //used for communication 255 }; 256 \end{cfacode} 257 This mean the compiler can solve problems by injecting code where needed. The downside of this approach is that it makes coroutine a special case in the language. Users who would want to extend coroutines or build their own for various reasons can only do so in ways offered by the language. Furthermore, implementing coroutines without language supports also displays the power of the programming language used. While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can both be constructed by users without using the language support. The reserved keywords are only present to improve ease of use for the common cases. 119 coroutine Fibonacci { 120 int fn; // used for communication 121 }; 122 \end{cfacode} 123 This mean the compiler can solve problems by injecting code where needed. The downside of this approach is that it makes coroutine a special case in the language. Users who would want to extend coroutines or build their own for various reasons can only do so in ways offered by the language. Furthermore, implementing coroutines without language supports also displays the power of \CFA. 124 While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can both be constructed by users without using the language support. The reserved keywords are only present to improve ease of use for the common cases. 258 125 259 126 \subsection{Alternative: Lamda Objects} … … 292 159 coroutine_desc * get_coroutine(T & this); 293 160 }; 294 295 forall( dtype T | is_coroutine(T) ) void suspend(T &); 296 forall( dtype T | is_coroutine(T) ) void resume (T &); 297 \end{cfacode} 298 This ensures an object is not a coroutine until \code{resume} is called on the object. Correspondingly, any object that is passed to \code{resume} is a coroutine since it must satisfy the \code{is_coroutine} trait to compile. 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 \code{get_coroutine} routine. The \CFA keyword \code{coroutine} only has the effect of implementing the getter and forward declarations required for users to only have to implement the main routine. 161 \end{cfacode} 162 This ensures an object is not a coroutine until \code{resume} (or \code{prime}) is called on the object. Correspondingly, any object that is passed to \code{resume} is a coroutine since it must satisfy the \code{is_coroutine} trait to compile. The advantage of this approach is that users can easily create different types of coroutines, for example, changing the memory foot print of a coroutine is trivial when implementing the \code{get_coroutine} routine. The \CFA keyword \code{coroutine} only has the effect of implementing the getter and forward declarations required for users to only have to implement the main routine. 299 163 300 164 \begin{center} … … 322 186 \end{center} 323 187 324 The combination of these two approaches allows users new to co routinning and concurrency to have an easy and concise specification, while more advanced users havetighter control on memory layout and initialization.188 The combination of these two approaches allows users new to concurrency to have a easy and concise method while more advanced users can expose themselves to otherwise hidden pitfalls at the benefit of tighter control on memory layout and initialization. 325 189 326 190 \section{Thread Interface}\label{threads} … … 328 192 329 193 \begin{cfacode} 330 thread foo {};194 thread foo {}; 331 195 \end{cfacode} 332 196 … … 341 205 \end{cfacode} 342 206 343 Obviously, for this thread implementation to be usefull it must run some user code. Several other threading interfaces use a function-pointer representation as the interface of threads (for example \Csharp~\cite{Csharp} and Scala~\cite{Scala}). However, this proposal considers that statically tying a \code{main} routine to a thread superseeds this approach. Since the \code{main} routine is already a special routine in \CFA (where the program begins), it is a natural extension of the semantics using overloading to declare mains for different threads (the normal main being the main of the initial thread). As such the \code{main} routine of a thread can be defined as 344 \begin{cfacode} 345 thread foo {}; 346 347 void main(foo & this) { 348 sout | "Hello World!" | endl; 349 } 350 \end{cfacode} 351 352 In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!"}. While this thesis encourages this approach to enforce strongly-typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity. With these semantics it is trivial to write a thread type that takes a function pointer as a parameter and executes it on its stack asynchronously 353 \begin{cfacode} 354 typedef void (*voidFunc)(int); 355 356 thread FuncRunner { 357 voidFunc func; 358 int arg; 359 }; 360 361 void ?{}(FuncRunner & this, voidFunc inFunc, int arg) { 362 this.func = inFunc; 363 } 364 365 void main(FuncRunner & this) { 366 this.func( this.arg ); 367 } 368 \end{cfacode} 369 370 An 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 \acrshort{api}. 371 372 Of course for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution. While using an \acrshort{api} such as \code{fork} and \code{join} is relatively common in the literature, such an interface is unnecessary. Indeed, the simplest approach is to use \acrshort{raii} principles and have threads \code{fork} after the constructor has completed and \code{join} before the destructor runs. 207 Obviously, for this thread implementation to be usefull it must run some user code. Several other threading interfaces use a function-pointer representation as the interface of threads (for example \Csharp~\cite{Csharp} and Scala~\cite{Scala}). However, this proposal considers that statically tying a \code{main} routine to a thread superseeds this approach. Since the \code{main} routine is already a special routine in \CFA (where the program begins), it is possible naturally extend the semantics using overloading to declare mains for different threads (the normal main being the main of the initial thread). As such the \code{main} routine of a thread can be defined as 208 \begin{cfacode} 209 thread foo {}; 210 211 void main(foo & this) { 212 sout | "Hello World!" | endl; 213 } 214 \end{cfacode} 215 216 In this example, threads of type \code{foo} start execution in the \code{void main(foo*)} routine which prints \code{"Hello World!"}. While this proposoal encourages this approach to enforce strongly-typed programming, users may prefer to use the routine based thread semantics for the sake of simplicity. With these semantics it is trivial to write a thread type that takes a function pointer as parameter and executes it on its stack asynchronously 217 \begin{cfacode} 218 typedef void (*voidFunc)(void); 219 220 thread FuncRunner { 221 voidFunc func; 222 }; 223 224 //ctor 225 void ?{}(FuncRunner & this, voidFunc inFunc) { 226 this.func = inFunc; 227 } 228 229 //main 230 void main(FuncRunner & this) { 231 this.func(); 232 } 233 \end{cfacode} 234 235 An advantage of the overloading approach to main is to clearly highlight where and what memory is required to pass parameters and return values to/from a thread. 236 237 Of course for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution. While using an \acrshort{api} such as \code{fork} and \code{join} is relatively common in the literature, such an interface is unnecessary. Indeed, the simplest approach is to use \acrshort{raii} principles and have threads \code{fork} once the constructor has completed and \code{join} before the destructor runs. 373 238 \begin{cfacode} 374 239 thread World; … … 389 254 \end{cfacode} 390 255 391 This semantic has several advantages over explicit semantics : a thread is always started and stopped exaclty once and users cannot make any progamming errors and it naturally scalesto multiple threads meaning basic synchronisation is very simple256 This semantic has several advantages over explicit semantics typesafety is guaranteed, a thread is always started and stopped exaclty once and users cannot make any progamming errors. Another advantage of this semantic is that it naturally scale to multiple threads meaning basic synchronisation is very simple 392 257 393 258 \begin{cfacode} … … 411 276 \end{cfacode} 412 277 413 However, one of the drawbacks of this approach is that threads now always form a lattice, that is they are always destroyed in opposite order of construction because of block structure. This restriction is relaxed 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 created278 However, one of the apparent drawbacks of this system is that threads now always form a lattice, that is they are always destroyed in opposite order of construction because of block structure. However, storage allocation is not limited to blocks; dynamic allocation can create threads that outlive the scope in which the thread is created much like dynamically allocating memory lets objects outlive the scope in which they are created 414 279 415 280 \begin{cfacode} … … 418 283 }; 419 284 285 //main 420 286 void main(MyThread & this) { 421 287 //... … … 425 291 MyThread * long_lived; 426 292 { 293 MyThread short_lived; 427 294 //Start a thread at the beginning of the scope 428 MyThread short_lived; 295 296 DoStuff(); 429 297 430 298 //create another thread that will outlive the thread in this scope 431 299 long_lived = new MyThread; 432 300 433 DoStuff();434 435 301 //Wait for the thread short_lived to finish 436 302 } 437 303 DoMoreStuff(); 438 304 439 //Now wait for the long_lived to finish305 //Now wait for the short_lived to finish 440 306 delete long_lived; 441 307 } -
doc/proposals/concurrency/text/cforall.tex
r6840e7c rb96ec83 5 5 % ====================================================================== 6 6 7 This thesis presents the design for a set of concurrency features in \CFA. Since it is a new dialect of C, the following is a quick introduction to the language,specifically tailored to the features needed to support concurrency.7 As mentionned in the introduction, the document presents the design for the concurrency features in \CFA. Since it is a new language here is a quick review of the language specifically tailored to the features needed to support concurrency. 8 8 9 \CFA is a extension of ISO -C and therefore supports all of the same paradigms as C. It is a non-object oriented system language, meaning most of the major abstractions have either no runtime overhead or can be opt-out easily. Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over machine code. The vast majority of the code produced by the \CFA translator respects memory-layouts and calling-conventions laid out by C. Interestingly, while \CFA is not an object-oriented language, lacking the concept of a received (e.g.: this), it does have some notion of objects\footnote{C defines the term objects as : [Where to I get the C11 reference manual?]}, most importantly construction and destruction of objects. Most of the following pieces of code can be found on the \CFA website\cite{www-cfa}9 \CFA is a extension of ISO C and therefore supports much of the same paradigms as C. It is a non-object oriented system level language, meaning it has very most of the major abstractions have either no runtime cost or can be opt-out easily. Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over assembly. The vast majority of the code produced by a \CFA compiler respects memory-layouts and calling-conventions laid out by C. However, while \CFA is not an object-oriented language according to a strict definition. It does have some notion of objects, most importantly construction and destruction of objects. Most of the following pieces of code can be found as is on the \CFA website : \cite{www-cfa} 10 10 11 11 \section{References} 12 12 13 Like \CC, \CFA introduces references as an alternative to pointers. In regards to concurrency, the semantics difference between pointers and references are not particularly relevant but since this document uses mostly references here is a quick overview of the semantics :13 Like \CC, \CFA introduces references as an alternative to pointers. In regards to concurrency, the semantics difference between pointers and references aren't particularly relevant but since this document uses mostly references here is a quick overview of the semantics : 14 14 \begin{cfacode} 15 15 int x, *p1 = &x, **p2 = &p1, ***p3 = &p2, 16 16 &r1 = x, &&r2 = r1, &&&r3 = r2; 17 ***p3 = 3; //change x 18 r3 = 3; //change x, ***r3 19 **p3 = ...; //change p1 20 *p3 = ...; //change p2 21 int y, z, & ar[3] = {x, y, z}; //initialize array of references 22 typeof( ar[1]) p; //is int, i.e., the type of referenced object 23 typeof(&ar[1]) q; //is int &, i.e., the type of reference 24 sizeof( ar[1]) == sizeof(int); //is true, i.e., the size of referenced object 25 sizeof(&ar[1]) == sizeof(int *); //is true, i.e., the size of a reference 17 ***p3 = 3; // change x 18 r3 = 3; // change x, ***r3 19 **p3 = ...; // change p1 20 &r3 = ...; // change r1, (&*)**r3 21 *p3 = ...; // change p2 22 &&r3 = ...; // change r2, (&(&*)*)*r3 23 &&&r3 = p3; // change r3 to p3, (&(&(&*)*)*)r3 24 int y, z, & ar[3] = { x, y, z }; // initialize array of references 25 &ar[1] = &z; // change reference array element 26 typeof( ar[1] ) p; // is int, i.e., the type of referenced object 27 typeof( &ar[1] ) q; // is int &, i.e., the type of reference 28 sizeof( ar[1] ) == sizeof( int ); // is true, i.e., the size of referenced object 29 sizeof( &ar[1] ) == sizeof( int *); // is true, i.e., the size of a reference 26 30 \end{cfacode} 27 31 The important thing to take away from this code snippet is that references offer a handle to an object much like pointers but which is automatically derefferenced when convinient. … … 29 33 \section{Overloading} 30 34 31 Another important feature of \CFA is function overloading as in Java and \CC, where routine with the same name are selected based on the numbers and type of the arguments. As well, \CFA uses the return type as part of the selection criteria, as in Ada\cite{Ada}. For routines with multiple parameters and returns, the selection is complex.35 Another important feature \CFA has in common with \CC is function overloading : 32 36 \begin{cfacode} 33 // selection based on type and number of parameters34 void f( void); //(1)35 void f( char); //(2)36 void f( int, double); //(3)37 f(); //select (1)38 f( 'a'); //select (2)39 f( 3, 5.2); //select (3)37 // selection based on type and number of parameters 38 void f( void ); // (1) 39 void f( char ); // (2) 40 void f( int, double ); // (3) 41 f(); // select (1) 42 f( 'a' ); // select (2) 43 f( 3, 5.2 ); // select (3) 40 44 41 //selection based on type and number of returns 42 char f(int); //(1) 43 double f(int); //(2) 44 char c = f(3); //select (1) 45 double d = f(4); //select (2) 45 // selection based on type and number of returns 46 char f( int ); // (1) 47 double f( int ); // (2) 48 [ int, double ] f( int ); // (3) 49 char c = f( 3 ); // select (1) 50 double d = f( 4 ); // select (2) 51 [ int, double ] t = f( 5 ); // select (3) 46 52 \end{cfacode} 47 This feature is particularly important for concurrency since the runtime system relies on creating different types to represent concurrency objects. Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions that prevent name clashes. As seen in chapter \ref{basics}, routines main is an example that benefits from overloading.53 This feature is particularly important for concurrency since the runtime system relies on creating different types do represent concurrency objects. Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions that prevent clashes. As seen in chapter \ref{basics}, the main is an example of routine that benefits from overloading when concurrency in introduced. 48 54 49 55 \section{Operators} 50 56 Overloading also extends to operators. The syntax for denoting operator-overloading is to name a routine with the symbol of the operator and question marks where the arguments of the operation would be, like so : 51 57 \begin{cfacode} 52 int ++? (int op); //unary prefix increment53 int ?++ (int op); //unary postfix increment54 int ?+? (int op1, int op2); //binary plus55 int ?<=?( int op1, int op2); //binary less than56 int ?=? (int & op1, int op2); //binary assignment57 int ?+=?( int & op1, int op2); //binary plus-assignment58 int ++?( int op ); // unary prefix increment 59 int ?++( int op ); // unary postfix increment 60 int ?+?( int op1, int op2 ); // binary plus 61 int ?<=?( int op1, int op2 ); // binary less than 62 int ?=?( int & op1, int op2 ); // binary assignment 63 int ?+=?( int & op1, int op2 ); // binary plus-assignment 58 64 59 struct S { int i, j;};60 S ?+?( S op1, S op2) { //add two structures61 return (S){ op1.i + op2.i, op1.j + op2.j};65 struct S { int i, j; }; 66 S ?+?( S op1, S op2 ) { // add two structures 67 return (S){ op1.i + op2.i, op1.j + op2.j }; 62 68 } 63 S s1 = { 1, 2}, s2 = {2, 3}, s3;64 s3 = s1 + s2; //compute sum: s3 == {2, 5}69 S s1 = { 1, 2 }, s2 = { 2, 3 }, s3; 70 s3 = s1 + s2; // compute sum: s3 == { 2, 5 } 65 71 \end{cfacode} 66 While concurrency does not use operator overloading directly, this feature is more important as an introduction for the syntax of constructors. 72 73 Since concurrency does not use operator overloading, this feature is more important as an introduction for the syntax of constructors. 67 74 68 75 \section{Constructors/Destructors} 69 Object life-time is often a challenge in concurrency. \CFA uses the approach of giving concurrent meaning to object life-time as a mean of synchronization and/or mutual exclusion. Since \CFA relies heavily on the life time of objects, constructors and destructors are a core feature required for concurrency and parallelism.\CFA uses the following syntax for constructors and destructors :76 \CFA uses the following syntax for constructors and destructors : 70 77 \begin{cfacode} 71 78 struct S { … … 73 80 int * ia; 74 81 }; 75 void ?{}( S & s, int asize) { //constructor operator76 s .size = asize; //initialize fields77 s.ia = calloc(size, sizeof(S));82 void ?{}( S & s, int asize ) with s { // constructor operator 83 size = asize; // initialize fields 84 ia = calloc( size, sizeof( S ) ); 78 85 } 79 void ^?{}( S & s) { //destructor operator80 free( ia); //de-initialization fields86 void ^?{}( S & s ) with s { // destructor operator 87 free( ia ); // de-initialization fields 81 88 } 82 89 int main() { 83 S x = { 10}, y = {100}; //implict calls: ?{}(x, 10), ?{}(y, 100)84 ... //use x and y85 ^x{}; ^y{}; // explicit calls to de-initialize86 x{ 20}; y{200}; //explicit calls to reinitialize87 ... //reuse x and y88 } //implict calls: ^?{}(y), ^?{}(x)90 S x = { 10 }, y = { 100 }; // implict calls: ?{}( x, 10 ), ?{}( y, 100 ) 91 ... // use x and y 92 ^x{}; ^y{}; // explicit calls to de-initialize 93 x{ 20 }; y{ 200 }; // explicit calls to reinitialize 94 ... // reuse x and y 95 } // implict calls: ^?{}( y ), ^?{}( x ) 89 96 \end{cfacode} 90 The language guarantees that every object and all their fields are constructed. Like \CC, construction of an object is automatically done on allocation and destruction of the object is done on deallocation. Allocation and deallocation can occur on the stack or on the heap. 91 \begin{cfacode} 92 { 93 struct S s = {10}; //allocation, call constructor 94 ... 95 } //deallocation, call destructor 96 struct S * s = new(); //allocation, call constructor 97 ... 98 delete(s); //deallocation, call destructor 99 \end{cfacode} 100 Note that like \CC, \CFA introduces \code{new} and \code{delete}, which behave like \code{malloc} and \code{free} in addition to constructing and destructing objects, after calling \code{malloc} and before calling \code{free} respectively. 97 The language guarantees that every object and all their fields are constructed. Like \CC construction is automatically done on declaration and destruction done when the declared variables reach the end of its scope. 101 98 102 \section{Parametric Polymorphism} 103 Routines in \CFA can also be reused for multiple types. This is done using the \code{forall} clause which gives \CFA it's name. \code{forall} clauses allow seperatly compiled routines to support generic usage over multiple types. For example, the following sum function will work for any type which support construction from 0 and addition : 104 \begin{cfacode} 105 //constraint type, 0 and + 106 forall(otype T | { void ?{}(T *, zero_t); T ?+?(T, T); }) 107 T sum(T a[ ], size_t size) { 108 T total = 0; //construct T from 0 109 for(size_t i = 0; i < size; i++) 110 total = total + a[i]; //select appropriate + 111 return total; 112 } 113 114 S sa[5]; 115 int i = sum(sa, 5); //use S's 0 construction and + 116 \end{cfacode} 117 118 Since writing constraints on types can become cumbersome for more constrained functions, \CFA also has the concept of traits. Traits are named collection of constraints which can be used both instead and in addition to regular constraints: 119 \begin{cfacode} 120 trait sumable( otype T ) { 121 void ?{}(T *, zero_t); //constructor from 0 literal 122 T ?+?(T, T); //assortment of additions 123 T ?+=?(T *, T); 124 T ++?(T *); 125 T ?++(T *); 126 }; 127 forall( otype T | sumable(T) ) //use trait 128 T sum(T a[], size_t size); 129 \end{cfacode} 130 131 \section{with Clause/Statement} 132 Since \CFA lacks the concept of a receiver, certain functions end-up needing to repeat variable names often, to solve this \CFA offers the \code{with} statement which opens an aggregate scope making its fields directly accessible (like Pascal). 133 \begin{cfacode} 134 struct S { int i, j; }; 135 int mem(S & this) with this //with clause 136 i = 1; //this->i 137 j = 2; //this->j 138 } 139 int foo() { 140 struct S1 { ... } s1; 141 struct S2 { ... } s2; 142 with s1 //with statement 143 { 144 //access fields of s1 145 //without qualification 146 with s2 //nesting 147 { 148 //access fields of s1 and s2 149 //without qualification 150 } 151 } 152 with s1, s2 //scopes open in parallel 153 { 154 //access fields of s1 and s2 155 //without qualification 156 } 157 } 158 \end{cfacode} 159 160 For more information on \CFA see \cite{cforall-ug,rob-thesis,www-cfa}. 99 For more information see \cite{cforall-ug,rob-thesis,www-cfa}. -
doc/proposals/concurrency/text/concurrency.tex
r6840e7c rb96ec83 4 4 % ====================================================================== 5 5 % ====================================================================== 6 Several tool can be used to solve concurrency challenges. Since many of these challenges appear with the use of mutable shared-state, some languages and libraries simply disallow mutable shared-state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}). In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (channels\cit for example). However, in languages that use routine calls as their core abstraction-mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (i.e., message passing versus routine call). This distinction in turn means that, in order to be effective, programmers need to learn two sets of designs patterns. While this distinction can be hidden away in library code, effective use of the librairy still has to take both paradigms into account.6 Several tool can be used to solve concurrency challenges. Since many of these challenges appear with the use of mutable shared-state, some languages and libraries simply disallow mutable shared-state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}). In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms that closely relate to networking concepts (channels\cit for example). However, in languages that use routine calls as their core abstraction-mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (i.e., message passing versus routine call). This distinction in turn means that, in order to be effective, programmers need to learn two sets of designs patterns. While this distinction can be hidden away in library code, effective use of the librairy still has to take both paradigms into account. 7 7 8 8 Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on basic constructs like routine calls and shared objects. At the lowest level, concurrent paradigms are implemented as atomic operations and locks. Many such mechanisms have been proposed, including semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}. However, for productivity reasons it is desireable to have a higher-level construct be the core concurrency paradigm~\cite{HPP:Study}. 9 9 10 An approach that is worth mentionning because it is gaining in popularity is transactionnal memory~\cite{Dice10}[Check citation]. While this approach is even pursued by system languages like \CC\cit, the performance and feature set is currently too restrictive to be the main concurrency paradigm for systemslanguage, which is why it was rejected as the core paradigm for concurrency in \CFA.11 12 One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared -memory systems, is the \emph{monitor}. Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}. Many programming languages---e.g., Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs. In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors. For these reasons, this project proposes monitors as the core concurrency-construct.10 An approach that is worth mentionning because it is gaining in popularity is transactionnal memory~\cite{Dice10}[Check citation]. While this approach is even pursued by system languages like \CC\cit, the performance and feature set is currently too restrictive to be the main concurrency paradigm for general purpose language, which is why it was rejected as the core paradigm for concurrency in \CFA. 11 12 One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared memory systems, is the \emph{monitor}. Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}. Many programming languages---e.g., Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs. In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors. For these reasons, this project proposes monitors as the core concurrency-construct. 13 13 14 14 \section{Basics} 15 Non-determinism requires concurrent systems to offer support for mutual-exclusion and synchronisation. Mutual-exclusion is the concept that only a fixed number of threads can access a critical section at any given time, where a critical section is a group of instructions on an associated portion of data that requires the restricted access. On the other hand, synchronization enforces relative ordering of execution and synchronization tools providenumerous mechanisms to establish timing relationships among threads.15 Non-determinism requires concurrent systems to offer support for mutual-exclusion and synchronisation. Mutual-exclusion is the concept that only a fixed number of threads can access a critical section at any given time, where a critical section is a group of instructions on an associated portion of data that requires the restricted access. On the other hand, synchronization enforces relative ordering of execution and synchronization tools numerous mechanisms to establish timing relationships among threads. 16 16 17 17 \subsection{Mutual-Exclusion} 18 As mentionned above, mutual-exclusion is the guarantee that only a fix number of threads can enter a critical section at once. However, many solution s exist for mutual exclusion, which vary in terms of performance, flexibility and ease of use. Methods range from low-level locks, which are fast and flexible but require significant attention to be correct, to higher-level mutual-exclusion methods, which sacrifice some performance in order to improve ease of use. Ease of use comes by either guaranteeing some problems cannot occur (e.g., being deadlock free) or by offering a more explicit coupling between data and corresponding critical section. For example, the \CC \code{std::atomic<T>} offers an easy way to express mutual-exclusion on a restricted set of operations (e.g.: reading/writing large types atomically). Another challenge with low-level locks is composability. Locks have restricted composabilitybecause it takes careful organising for multiple locks to be used while preventing deadlocks. Easing composability is another feature higher-level mutual-exclusion mechanisms often offer.18 As mentionned above, mutual-exclusion is the guarantee that only a fix number of threads can enter a critical section at once. However, many solution exists for mutual exclusion which vary in terms of performance, flexibility and ease of use. Methods range from low-level locks, which are fast and flexible but require significant attention to be correct, to higher-level mutual-exclusion methods, which sacrifice some performance in order to improve ease of use. Ease of use comes by either guaranteeing some problems cannot occur (e.g., being deadlock free) or by offering a more explicit coupling between data and corresponding critical section. For example, the \CC \code{std::atomic<T>} which offer an easy way to express mutual-exclusion on a restricted set of operations (.e.g: reading/writing large types atomically). Another challenge with low-level locks is composability. Locks are not composable because it takes careful organising for multiple locks to be used while preventing deadlocks. Easing composability is another feature higher-level mutual-exclusion mechanisms often offer. 19 19 20 20 \subsection{Synchronization} 21 As for mutual-exclusion, low -level synchronisation primitives often offer good performance and good flexibility at the cost of ease of use. Again, higher-level mechanism often simplify usage by adding better coupling between synchronization and data, e.g.: message passing, or offering simple solution to otherwise involved challenges. An example is barging. As mentioned above, synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}. Most of the time, synchronisation happens around a critical section, where threads must acquire critical sections in a certain order. However, it may also be desirable to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}. Not satisfying this property called barging. For example, where event \textit{X} tries to effect event \textit{Y} but another thread acquires the critical section and emits \textit{Z} before \textit{Y}. Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs. This challenge is often split into two different methods, barging avoidance and barging prevention. Algorithms that use status flags and other flag variables to detect barging threads are said to be using barging avoidance while algorithms that baton-passing locks between threads instead of releasing the locks are said to be using barging prevention.21 As for mutual-exclusion, low level synchronisation primitive often offer good performance and good flexibility at the cost of ease of use. Again, higher-level mechanism often simplify usage by adding better coupling between synchronization and data, .eg., message passing, or offering simple solution to otherwise involved challenges. An example of this is barging. As mentionned above synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}. Most of the time synchronisation happens around a critical section, where threads most acquire said critical section in a certain order. However, it may also be desired to be able to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}. This is called barging, where event \textit{X} tries to effect event \textit{Y} but anoter thread races to grab the critical section and emits \textit{Z} before \textit{Y}. Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs. 22 22 23 23 % ====================================================================== … … 28 28 A monitor is a set of routines that ensure mutual exclusion when accessing shared state. This concept is generally associated with Object-Oriented Languages like Java~\cite{Java} or \uC~\cite{uC++book} but does not strictly require OO semantics. The only requirements is the ability to declare a handle to a shared object and a set of routines that act on it : 29 29 \begin{cfacode} 30 typedef /*some monitor type*/ monitor;31 int f(monitor & m);32 33 int main() {34 monitor m; //Handle m35 f(m); //Routine using handle36 }30 typedef /*some monitor type*/ monitor; 31 int f(monitor & m); 32 33 int main() { 34 monitor m; //Handle m 35 f(m); //Routine using handle 36 } 37 37 \end{cfacode} 38 38 … … 47 47 48 48 \begin{cfacode} 49 monitor counter_t { /*...see section $\ref{data}$...*/ }; 50 51 void ?{}(counter_t & nomutex this); //constructor 52 size_t ++?(counter_t & mutex this); //increment 53 54 //need for mutex is platform dependent 55 void ?{}(size_t * this, counter_t & mutex cnt); //conversion 56 \end{cfacode} 49 monitor counter_t { /*...see section $\ref{data}$...*/ }; 50 51 void ?{}(counter_t & nomutex this); //constructor 52 size_t ++?(counter_t & mutex this); //increment 53 54 //need for mutex is platform dependent 55 void ?{}(size_t * this, counter_t & mutex cnt); //conversion 56 \end{cfacode} 57 58 Here, the constructor(\code{?\{\}}) uses the \code{nomutex} keyword to signify that it does not acquire the monitor mutual-exclusion when constructing. This semantics is because an object not yet constructed should never be shared and therefore does not require mutual exclusion. The prefix increment operator uses \code{mutex} to protect the incrementing process from race conditions. Finally, there is a conversion operator from \code{counter_t} to \code{size_t}. This conversion may or may not require the \code{mutex} keyword depending on whether or not reading an \code{size_t} is an atomic operation. 59 60 Having both \code{mutex} and \code{nomutex} keywords is redundant based on the meaning of a routine having neither of these keywords. For example, given a routine without qualifiers \code{void foo(counter_t & this)}, then it is reasonable that it should default to the safest option \code{mutex}, whereas assuming \code{nomutex} is unsafe and may cause subtle errors. In fact, \code{nomutex} is the "normal" parameter behaviour, with the \code{nomutex} keyword effectively stating explicitly that "this routine is not special". Another alternative is to make having exactly one of these keywords mandatory, which would provide the same semantics but without the ambiguity of supporting routines neither keyword. Mandatory keywords would also have the added benefit of being self-documented but at the cost of extra typing. While there are several benefits to mandatory keywords, they do bring a few challenges. Mandatory keywords in \CFA would imply that the compiler must know without a doubt wheter or not a parameter is a monitor or not. Since \CFA relies heavily on traits as an abstraction mechanism, the distinction between a type that is a monitor and a type that looks like a monitor can become blurred. For this reason, \CFA only has the \code{mutex} keyword. 61 62 63 The next semantic decision is to establish when \code{mutex} may be used as a type qualifier. Consider the following declarations: 64 \begin{cfacode} 65 int f1(monitor & mutex m); 66 int f2(const monitor & mutex m); 67 int f3(monitor ** mutex m); 68 int f4(monitor * mutex m []); 69 int f5(graph(monitor*) & mutex m); 70 \end{cfacode} 71 The problem is to indentify which object(s) should be acquired. Furthermore, each object needs to be acquired only once. In the case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entry. Adding indirections (\code{f3}) still allows the compiler and programmer to indentify which object is acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths are not necessarily known in C, and even then making sure objects are only acquired once becomes none-trivial. This can be extended to absurd limits like \code{f5}, which uses a graph of monitors. To keep everyone as sane as possible~\cite{Chicken}, this projects imposes the requirement that a routine may only acquire one monitor per parameter and it must be the type of the parameter with one level of indirection (ignoring potential qualifiers). Also note that while routine \code{f3} can be supported, meaning that monitor \code{**m} is be acquired, passing an array to this routine would be type safe and yet result in undefined behavior because only the first element of the array is acquired. This is specially true for non-copyable objects like monitors, where an array of pointers is simplest way to express a group of monitors. However, this ambiguity is part of the C type-system with respects to arrays. For this reason, \code{mutex} is disallowed in the context where arrays may be passed: 72 73 \begin{cfacode} 74 int f1(monitor & mutex m); //Okay : recommanded case 75 int f2(monitor * mutex m); //Okay : could be an array but probably not 76 int f3(monitor mutex m []); //Not Okay : Array of unkown length 77 int f4(monitor ** mutex m); //Not Okay : Could be an array 78 int f5(monitor * mutex m []); //Not Okay : Array of unkown length 79 \end{cfacode} 80 81 Unlike object-oriented monitors, where calling a mutex member \emph{implicitly} acquires mutual-exclusion, \CFA uses an explicit mechanism to acquire mutual-exclusion. A consequence of this approach is that it extends naturally to multi-monitor calls. 82 \begin{cfacode} 83 int f(MonitorA & mutex a, MonitorB & mutex b); 84 85 MonitorA a; 86 MonitorB b; 87 f(a,b); 88 \end{cfacode} 89 The capacity to acquire multiple locks before entering a critical section is called \emph{\gls{group-acquire}}. In practice, writing multi-locking routines that do not lead to deadlocks is tricky. Having language support for such a feature is therefore a significant asset for \CFA. In the case presented above, \CFA guarantees that the order of aquisition is consistent across calls to routines using the same monitors as arguments. However, since \CFA monitors use multi-acquisition locks, users can effectively force the acquiring order. For example, notice which routines use \code{mutex}/\code{nomutex} and how this affects aquiring order: 90 \begin{cfacode} 91 void foo(A & mutex a, B & mutex b) { //acquire a & b 92 ... 93 } 94 95 void bar(A & mutex a, B & /*nomutex*/ b) { //acquire a 96 ... foo(a, b); ... //acquire b 97 } 98 99 void baz(A & /*nomutex*/ a, B & mutex b) { //acquire b 100 ... foo(a, b); ... //acquire a 101 } 102 \end{cfacode} 103 The multi-acquisition monitor lock allows a monitor lock to be acquired by both \code{bar} or \code{baz} and acquired again in \code{foo}. In the calls to \code{bar} and \code{baz} the monitors are acquired in opposite order. 104 105 However, such use leads the lock acquiring order problem. In the example above, the user uses implicit ordering in the case of function \code{foo} but explicit ordering in the case of \code{bar} and \code{baz}. This subtle mistake means that calling these routines concurrently may lead to deadlock and is therefore undefined behavior. As shown on several occasion\cit, solving this problem requires: 106 \begin{enumerate} 107 \item Dynamically tracking of the monitor-call order. 108 \item Implement rollback semantics. 109 \end{enumerate} 110 While the first requirement is already a significant constraint on the system, implementing a general rollback semantics in a C-like language is prohibitively complex \cit. In \CFA, users simply need to be carefull when acquiring multiple monitors at the same time. 111 112 Finally, for convenience, monitors support multiple acquiring, that is acquiring a monitor while already holding it does not cause a deadlock. It simply increments an internal counter which is then used to release the monitor after the number of acquires and releases match up. This is particularly usefull when monitor routines use other monitor routines as helpers or for recursions. For example: 113 \begin{cfacode} 114 monitor bank { 115 int money; 116 log_t usr_log; 117 }; 118 119 void deposit( bank & mutex b, int deposit ) { 120 b.money += deposit; 121 b.usr_log | "Adding" | deposit | endl; 122 } 123 124 void transfer( bank & mutex mybank, bank & mutex yourbank, int me2you) { 125 deposit( mybank, -me2you ); 126 deposit( yourbank, me2you ); 127 } 128 \end{cfacode} 129 130 % ====================================================================== 131 % ====================================================================== 132 \subsection{Data semantics} \label{data} 133 % ====================================================================== 134 % ====================================================================== 135 Once the call semantics are established, the next step is to establish data semantics. Indeed, until now a monitor is used simply as a generic handle but in most cases monitors contain shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appropriate protection. For example, here is a complete version of the counter showed in section \ref{call}: 136 \begin{cfacode} 137 monitor counter_t { 138 int value; 139 }; 140 141 void ?{}(counter_t & this) { 142 this.cnt = 0; 143 } 144 145 int ?++(counter_t & mutex this) { 146 return ++this.value; 147 } 148 149 //need for mutex is platform dependent here 150 void ?{}(int * this, counter_t & mutex cnt) { 151 *this = (int)cnt; 152 } 153 \end{cfacode} 154 57 155 This counter is used as follows: 58 156 \begin{center} … … 73 171 Notice how the counter is used without any explicit synchronisation and yet supports thread-safe semantics for both reading and writting. 74 172 75 Here, the constructor(\code{?\{\}}) uses the \code{nomutex} keyword to signify that it does not acquire the monitor mutual-exclusion when constructing. This semantics is because an object not yet constructed should never be shared and therefore does not require mutual exclusion. The prefix increment operator uses \code{mutex} to protect the incrementing process from race conditions. Finally, there is a conversion operator from \code{counter_t} to \code{size_t}. This conversion may or may not require the \code{mutex} keyword depending on whether or not reading a \code{size_t} is an atomic operation. 76 77 For maximum usability, monitors use \gls{multi-acq} semantics, which means a single thread can acquire multiple times the same monitor without deadlock. For example, figure \ref{fig:search} uses recursion and \gls{multi-acq} to print values inside a binary tree. 78 \begin{figure} 79 \label{fig:search} 80 \begin{cfacode} 81 monitor printer { ... }; 82 struct tree { 83 tree * left, right; 84 char * value; 85 }; 86 void print(printer & mutex p, char * v); 87 88 void print(printer & mutex p, tree * t) { 89 print(p, t->value); 90 print(p, t->left ); 91 print(p, t->right); 92 } 93 \end{cfacode} 94 \caption{Recursive printing algorithm using \gls{multi-acq}.} 95 \end{figure} 96 97 Having both \code{mutex} and \code{nomutex} keywords is redundant based on the meaning of a routine having neither of these keywords. For example, given a routine without qualifiers \code{void foo(counter_t & this)}, then it is reasonable that it should default to the safest option \code{mutex}, whereas assuming \code{nomutex} is unsafe and may cause subtle errors. In fact, \code{nomutex} is the "normal" parameter behaviour, with the \code{nomutex} keyword effectively stating explicitly that "this routine is not special". Another alternative is making exactly one of these keywords mandatory, which would provide the same semantics but without the ambiguity of supporting routines with neither keyword. Mandatory keywords would also have the added benefit of being self-documented but at the cost of extra typing. While there are several benefits to mandatory keywords, they do bring a few challenges. Mandatory keywords in \CFA would imply that the compiler must know without doubt whether or not a parameter is a monitor or not. Since \CFA relies heavily on traits as an abstraction mechanism, the distinction between a type that is a monitor and a type that looks like a monitor can become blurred. For this reason, \CFA only has the \code{mutex} keyword and uses no keyword to mean \code{nomutex}. 98 99 The next semantic decision is to establish when \code{mutex} may be used as a type qualifier. Consider the following declarations: 100 \begin{cfacode} 101 int f1(monitor & mutex m); 102 int f2(const monitor & mutex m); 103 int f3(monitor ** mutex m); 104 int f4(monitor * mutex m []); 105 int f5(graph(monitor*) & mutex m); 106 \end{cfacode} 107 The problem is to indentify which object(s) should be acquired. Furthermore, each object needs to be acquired only once. In the case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entry. Adding indirections (\code{f3}) still allows the compiler and programmer to indentify which object is acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths are not necessarily known in C, and even then making sure objects are only acquired once becomes none-trivial. This problem can be extended to absurd limits like \code{f5}, which uses a graph of monitors. To make the issue tractable, this project imposes the requirement that a routine may only acquire one monitor per parameter and it must be the type of the parameter with at most one level of indirection (ignoring potential qualifiers). Also note that while routine \code{f3} can be supported, meaning that monitor \code{**m} is be acquired, passing an array to this routine would be type safe and yet result in undefined behavior because only the first element of the array is acquired. However, this ambiguity is part of the C type-system with respects to arrays. For this reason, \code{mutex} is disallowed in the context where arrays may be passed: 108 \begin{cfacode} 109 int f1(monitor & mutex m); //Okay : recommanded case 110 int f2(monitor * mutex m); //Okay : could be an array but probably not 111 int f3(monitor mutex m []); //Not Okay : Array of unkown length 112 int f4(monitor ** mutex m); //Not Okay : Could be an array 113 int f5(monitor * mutex m []); //Not Okay : Array of unkown length 114 \end{cfacode} 115 Note that not all array functions are actually distinct in the type system sense. However, even the code generation could tell the difference, the extra information is still not sufficient to extend meaningfully the monitor call semantic. 116 117 Unlike object-oriented monitors, where calling a mutex member \emph{implicitly} acquires mutual-exclusion often receives an object, \CFA uses an explicit mechanism to acquire mutual-exclusion. A consequence of this approach is that it extends naturally to multi-monitor calls. 118 \begin{cfacode} 119 int f(MonitorA & mutex a, MonitorB & mutex b); 120 121 MonitorA a; 122 MonitorB b; 123 f(a,b); 124 \end{cfacode} 125 The capacity to acquire multiple locks before entering a critical section is called \emph{\gls{bulk-acq}}. In practice, writing multi-locking routines that do not lead to deadlocks is tricky. Having language support for such a feature is therefore a significant asset for \CFA. In the case presented above, \CFA guarantees that the order of aquisition is consistent across calls to routines using the same monitors as arguments. However, since \CFA monitors use \gls{multi-acq} locks, users can effectively force the acquiring order. For example, notice which routines use \code{mutex}/\code{nomutex} and how this affects aquiring order: 126 \begin{cfacode} 127 void foo(A & mutex a, B & mutex b) { //acquire a & b 128 ... 129 } 130 131 void bar(A & mutex a, B & /*nomutex*/ b) { //acquire a 132 ... foo(a, b); ... //acquire b 133 } 134 135 void baz(A & /*nomutex*/ a, B & mutex b) { //acquire b 136 ... foo(a, b); ... //acquire a 137 } 138 \end{cfacode} 139 The \gls{multi-acq} monitor lock allows a monitor lock to be acquired by both \code{bar} or \code{baz} and acquired again in \code{foo}. In the calls to \code{bar} and \code{baz} the monitors are acquired in opposite order. 140 141 However, such use leads to the lock acquiring order problem. In the example above, the user uses implicit ordering in the case of function \code{foo} but explicit ordering in the case of \code{bar} and \code{baz}. This subtle mistake means that calling these routines concurrently may lead to deadlock and is therefore undefined behavior. As shown on several occasion\cit, solving this problem requires: 142 \begin{enumerate} 143 \item Dynamically tracking of the monitor-call order. 144 \item Implement rollback semantics. 145 \end{enumerate} 146 While the first requirement is already a significant constraint on the system, implementing a general rollback semantics in a C-like language is prohibitively complex \cit. In \CFA, users simply need to be carefull when acquiring multiple monitors at the same time or only use \gls{bulk-acq} of all the monitors. 147 148 \Gls{multi-acq} and \gls{bulk-acq} can be used together in interesting ways, for example: 149 \begin{cfacode} 150 monitor bank { ... }; 151 152 void deposit( bank & mutex b, int deposit ); 153 154 void transfer( bank & mutex mybank, bank & mutex yourbank, int me2you) { 155 deposit( mybank, -me2you ); 156 deposit( yourbank, me2you ); 157 } 158 \end{cfacode} 159 This example shows a trivial solution to the bank account transfer problem\cit. Without \gls{multi-acq} and \gls{bulk-acq}, the solution to this problem is much more involved and requires carefull engineering. 160 161 \subsubsection{\code{mutex} statement} \label{mutex-stmt} 162 163 The call semantics discussed aboved have one software engineering issue, only a named routine can acquire the mutual-exclusion of a set of monitor. \CFA offers the \code{mutex} statement to workaround the need for unnecessary names, avoiding a major software engineering problem\cit. Listing \ref{lst:mutex-stmt} shows an example of the \code{mutex} statement, which introduces a new scope in which the mutual-exclusion of a set of monitor is acquired. Beyond naming, the \code{mutex} statement has no semantic difference from a routine call with \code{mutex} parameters. 164 165 \begin{figure} 166 \begin{center} 167 \begin{tabular}{|c|c|} 168 function call & \code{mutex} statement \\ 173 % ====================================================================== 174 % ====================================================================== 175 \subsection{Implementation Details: Interaction with polymorphism} 176 % ====================================================================== 177 % ====================================================================== 178 Depending on the choice of semantics for when monitor locks are acquired, interaction between monitors and \CFA's concept of polymorphism can be complex to support. However, it is shown that entry-point locking solves most of the issues. 179 180 First of all, interaction between \code{otype} polymorphism and monitors is impossible since monitors do not support copying. Therefore, the main question is how to support \code{dtype} polymorphism. Since a monitor's main purpose is to ensure mutual exclusion when accessing shared data, this implies that mutual exclusion is only required for routines that do in fact access shared data. However, since \code{dtype} polymorphism always handles incomplete types (by definition), no \code{dtype} polymorphic routine can access shared data since the data requires knowledge about the type. Therefore, the only concern when combining \code{dtype} polymorphism and monitors is to protect access to routines. 181 182 Before looking into complex control-flow, it is important to present the difference between the two acquiring options : callsite and entry-point locking, i.e. acquiring the monitors before making a mutex routine call or as the first operation of the mutex routine-call. For example: 183 \begin{center} 184 \setlength\tabcolsep{1.5pt} 185 \begin{tabular}{|c|c|c|} 186 Code & \gls{callsite-locking} & \gls{entry-point-locking} \\ 187 \CFA & pseudo-code & pseudo-code \\ 169 188 \hline 170 189 \begin{cfacode}[tabsize=3] 171 monitor M {}; 172 void foo( M & mutex m ) { 173 //critical section 174 } 175 176 void bar( M & m ) { 177 foo( m ); 178 } 179 \end{cfacode}&\begin{cfacode}[tabsize=3] 180 monitor M {}; 181 void bar( M & m ) { 182 mutex(m) { 183 //critical section 184 } 185 } 186 187 188 \end{cfacode} 190 void foo(monitor& mutex a){ 191 192 193 194 //Do Work 195 //... 196 197 } 198 199 void main() { 200 monitor a; 201 202 203 204 foo(a); 205 206 } 207 \end{cfacode} & \begin{pseudo}[tabsize=3] 208 foo(& a) { 209 210 211 212 //Do Work 213 //... 214 215 } 216 217 main() { 218 monitor a; 219 //calling routine 220 //handles concurrency 221 acquire(a); 222 foo(a); 223 release(a); 224 } 225 \end{pseudo} & \begin{pseudo}[tabsize=3] 226 foo(& a) { 227 //called routine 228 //handles concurrency 229 acquire(a); 230 //Do Work 231 //... 232 release(a); 233 } 234 235 main() { 236 monitor a; 237 238 239 240 foo(a); 241 242 } 243 \end{pseudo} 189 244 \end{tabular} 190 245 \end{center} 191 \caption{Regular call semantics vs. \code{mutex} statement} 192 \label{lst:mutex-stmt} 193 \end{figure} 194 195 % ====================================================================== 196 % ====================================================================== 197 \subsection{Data semantics} \label{data} 198 % ====================================================================== 199 % ====================================================================== 200 Once the call semantics are established, the next step is to establish data semantics. Indeed, until now a monitor is used simply as a generic handle but in most cases monitors contain shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appropriate protection. For example, here is a complete version of the counter showed in section \ref{call}: 201 \begin{cfacode} 202 monitor counter_t { 203 int value; 204 }; 205 206 void ?{}(counter_t & this) { 207 this.cnt = 0; 208 } 209 210 int ?++(counter_t & mutex this) { 211 return ++this.value; 212 } 213 214 //need for mutex is platform dependent here 215 void ?{}(int * this, counter_t & mutex cnt) { 216 *this = (int)cnt; 217 } 246 247 \Gls{callsite-locking} is inefficient, since any \code{dtype} routine may have to obtain some lock before calling a routine, depending on whether or not the type passed is a monitor. However, with \gls{entry-point-locking} calling a monitor routine becomes exactly the same as calling it from anywhere else. 248 249 Note the \code{mutex} keyword relies on the resolver, which means that in cases where a generic monitor routine is actually desired, writing a mutex routine is possible with the proper trait. This is possible because monitors are designed in terms a trait. For example: 250 \begin{cfacode} 251 //Incorrect 252 //T is not a monitor 253 forall(dtype T) 254 void foo(T * mutex t); 255 256 //Correct 257 //this function only works on monitors 258 //(any monitor) 259 forall(dtype T | is_monitor(T)) 260 void bar(T * mutex t)); 218 261 \end{cfacode} 219 262 … … 224 267 % ====================================================================== 225 268 % ====================================================================== 226 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronisation. With monitors, this capability is generally achieved with internal or external scheduling as in\cit. Since internal scheduling within a single monitor is mostly a solved problem, this thesis concentrates on extending internal scheduling to multiple monitors. Indeed, like the \gls{bulk-acq} semantics, internal scheduling extends to multiple monitorsin a way that is natural to the user but requires additional complexity on the implementation side.269 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronisation. With monitors, this is generally achieved with internal or external scheduling as in\cit. Since internal scheduling of single monitors is mostly a solved problem, this proposal concentraits on extending internal scheduling to multiple monitors at once. Indeed, like the \gls{group-acquire} semantics, internal scheduling extends to multiple monitors at once in a way that is natural to the user but requires additional complexity on the implementation side. 227 270 228 271 First, here is a simple example of such a technique: 229 272 230 273 \begin{cfacode} 231 monitor A {232 condition e;233 }234 235 void foo(A & mutex a) {236 ...237 //Wait for cooperation from bar()238 wait(a.e);239 ...240 }241 242 void bar(A & mutex a) {243 //Provide cooperation for foo()244 ...245 //Unblock foo246 signal(a.e);247 }248 \end{cfacode} 249 250 There are two details to note here. First, the \code{signal} is a delayed operation, it only unblocks the waiting thread when it reaches the end of the critical section. This semantic is needed to respect mutual-exclusion. Second, in \CFA, a \code{condition} variable can be stored/created independently of a monitor. Here routine \code{foo} waits for the \code{signal} from \code{bar} before making further progress, effectively ensuring a basic ordering.251 252 An important aspect of the implementationis that \CFA does not allow barging, which means that once function \code{bar} releases the monitor, foo is guaranteed to resume immediately after (unless some other thread waited on the same condition). This guarantees offers the benefit of not having to loop arount waits in order to guarantee that a condition is still met. The main reason \CFA offers this guarantee is that users can easily introduce barging if it becomes a necessity but adding barging prevention or barging avoidance is more involved without language support. Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design of \CFA concurrency.274 monitor A { 275 condition e; 276 } 277 278 void foo(A & mutex a) { 279 ... 280 // Wait for cooperation from bar() 281 wait(a.e); 282 ... 283 } 284 285 void bar(A & mutex a) { 286 // Provide cooperation for foo() 287 ... 288 // Unblock foo at scope exit 289 signal(a.e); 290 } 291 \end{cfacode} 292 293 There are two details to note here. First, there \code{signal} is a delayed operation, it only unblocks the waiting thread when it reaches the end of the critical section. This is needed to respect mutual-exclusion. Second, in \CFA, \code{condition} have no particular need to be stored inside a monitor, beyond any software engineering reasons. Here routine \code{foo} waits for the \code{signal} from \code{bar} before making further progress, effectively ensuring a basic ordering. 294 295 An important aspect to take into account here is that \CFA does not allow barging, which means that once function \code{bar} releases the monitor, foo is guaranteed to resume immediately after (unless some other thread waited on the same condition). This guarantees offers the benefit of not having to loop arount waits in order to guarantee that a condition is still met. The main reason \CFA offers this guarantee is that users can easily introduce barging if it becomes a necessity but adding barging prevention or barging avoidance is more involved without language support. Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design of \CFA concurrency. 253 296 254 297 % ====================================================================== … … 257 300 % ====================================================================== 258 301 % ====================================================================== 259 It is easier to understand the problem of multi-monitor scheduling using a series of pseudo-code. Note that for simplicity in the following snippets of pseudo-code, waiting and signalling is done using an implicit condition variable, like Java built-in monitors. Indeed, \code{wait} statements always use a single condition as paremeter and waits on the monitors associated with the condition.302 It is easier to understand the problem of multi-monitor scheduling using a series of pseudo-code. Note that for simplicity in the following snippets of pseudo-code, waiting and signalling is done using an implicit condition variable, like Java built-in monitors. 260 303 261 304 \begin{multicols}{2} … … 276 319 \end{pseudo} 277 320 \end{multicols} 278 The example shows the simple case of having two threads (one for each column) and a single monitor A. One thread acquires before waiting (atomically blocking and releasing A) and the other acquires before signalling. It is important to note here that both \code{wait} and \code{signal} must be called with the proper monitor(s) already acquired. This semanticis a logical requirement for barging prevention.279 280 A direct extension of the previous example is a \gls{bulk-acq} version:321 The example shows the simple case of having two threads (one for each column) and a single monitor A. One thread acquires before waiting (atomically blocking and releasing A) and the other acquires before signalling. There is an important thing to note here, both \code{wait} and \code{signal} must be called with the proper monitor(s) already acquired. This restriction is hidden on the user side in \uC, as it is a logical requirement for barging prevention. 322 323 A direct extension of the previous example is the \gls{group-acquire} version: 281 324 282 325 \begin{multicols}{2} … … 295 338 \end{pseudo} 296 339 \end{multicols} 297 This version uses \gls{bulk-acq} (denoted using the \& symbol), but the presence of multiple monitors does not add a particularly new meaning. Synchronization happens between the two threads in exactly the same way and order. The only difference is that mutual exclusion covers more monitors. On the implementation side, handling multiple monitors does add a degree of complexity as the next few examples demonstrate. 298 299 While deadlock issues can occur when nesting monitors, these issues are only a symptom of the fact that locks, and by extension monitors, are not perfectly composable. For monitors, a well known deadlock problem is the Nested Monitor Problem\cit, which occurs when a \code{wait} is made on a thread that holds more than one monitor. For example, the following pseudo-code will run into the nested monitor problem : 340 This version uses \gls{group-acquire} (denoted using the \& symbol), but the presence of multiple monitors does not add a particularly new meaning. Synchronization happens between the two threads in exactly the same way and order. The only difference is that mutual exclusion covers more monitors. On the implementation side, handling multiple monitors does add a degree of complexity as the next few examples demonstrate. 341 342 While deadlock issues can occur when nesting monitors, these issues are only a symptom of the fact that locks, and by extension monitors, are not perfectly composable. However, for monitors as for locks, it is possible to write a program using nesting without encountering any problems if nested is done correctly. For example, the next pseudo-code snippet acquires monitors A then B before waiting while only acquiring B when signalling, effectively avoiding the nested monitor problem. 343 300 344 \begin{multicols}{2} 301 345 \begin{pseudo} … … 310 354 311 355 \begin{pseudo} 312 acquire A313 acquire B314 signal B315 release B316 release A317 \end{pseudo}318 \end{multicols}319 However, for monitors as for locks, it is possible to write a program using nesting without encountering any problems if nesting is done correctly. For example, the next pseudo-code snippet acquires monitors {\sf A} then {\sf B} before waiting, while only acquiring {\sf B} when signalling, effectively avoiding the nested monitor problem.320 321 \begin{multicols}{2}322 \begin{pseudo}323 acquire A324 acquire B325 wait B326 release B327 release A328 \end{pseudo}329 330 \columnbreak331 332 \begin{pseudo}333 356 334 357 acquire B … … 339 362 \end{multicols} 340 363 341 Listing \ref{lst:int-bulk-pseudo} shows an example where \gls{bulk-acq} adds a significant layer of complexity to the internal signalling semantics. Listing \ref{lst:int-bulk-cfa} shows the corresponding \CFA code which implements the pseudo-code in listing \ref{lst:int-bulk-pseudo}. Note that listing \ref{lst:int-bulk-cfa} uses non-\code{mutex} parameter to introduce monitor \code{b} into context. However, for the purpose of translating the given pseudo-code into \CFA-code any method of introducing new monitors into context, other than a \code{mutex} parameter, is acceptable, e.g. global variables, pointer parameters or using locals with the \code{mutex}-statement. 342 343 \begin{figure}[!b] 364 The next example is where \gls{group-acquire} adds a significant layer of complexity to the internal signalling semantics. 365 344 366 \begin{multicols}{2} 345 367 Waiting thread 346 368 \begin{pseudo}[numbers=left] 347 369 acquire A 348 // Code Section 1370 // Code Section 1 349 371 acquire A & B 350 // Code Section 2372 // Code Section 2 351 373 wait A & B 352 // Code Section 3374 // Code Section 3 353 375 release A & B 354 // Code Section 4376 // Code Section 4 355 377 release A 356 378 \end{pseudo} … … 361 383 \begin{pseudo}[numbers=left, firstnumber=10] 362 384 acquire A 363 // Code Section 5385 // Code Section 5 364 386 acquire A & B 365 // Code Section 6387 // Code Section 6 366 388 signal A & B 367 // Code Section 7389 // Code Section 7 368 390 release A & B 369 // Code Section 8391 // Code Section 8 370 392 release A 371 393 \end{pseudo} 372 394 \end{multicols} 373 \caption{Internal scheduling with \gls{bulk-acq}} 374 \label{lst:int-bulk-pseudo} 375 \end{figure} 376 377 \begin{figure}[!b] 378 \begin{multicols}{2} 379 Waiting thread 380 \begin{cfacode} 381 monitor A; 382 monitor B; 383 extern condition c; 384 void foo(A & mutex a, B & b) { 385 //Code Section 1 386 mutex(a, b) { 387 //Code Section 2 388 wait(c); 389 //Code Section 3 390 } 391 //Code Section 4 392 } 393 \end{cfacode} 394 395 \columnbreak 396 397 Signalling thread 398 \begin{cfacode} 399 monitor A; 400 monitor B; 401 extern condition c; 402 void foo(A & mutex a, B & b) { 403 //Code Section 5 404 mutex(a, b) { 405 //Code Section 6 406 signal(c); 407 //Code Section 7 408 } 409 //Code Section 8 410 } 411 \end{cfacode} 412 \end{multicols} 413 \caption{Equivalent \CFA code for listing \ref{lst:int-bulk-pseudo}} 414 \label{lst:int-bulk-cfa} 415 \end{figure} 416 417 It is particularly important to pay attention to code sections 4 and 8, which are where the existing semantics of internal scheduling need to be extended for multiple monitors. The root of the problem is that \gls{bulk-acq} is used in a context where one of the monitors is already acquired and is why it is important to define the behaviour of the previous pseudo-code. When the signaller thread reaches the location where it should "release A \& B" (line 16), it must actually transfer ownership of monitor B to the waiting thread. This ownership trasnfer is required in order to prevent barging. Since the signalling thread still needs monitor A, simply waking up the waiting thread is not an option because it would violate mutual exclusion. There are three options. 395 \begin{center} 396 Listing 1 397 \end{center} 398 399 It is particularly important to pay attention to code sections 8 and 4, which are where the existing semantics of internal scheduling need to be extended for multiple monitors. The root of the problem is that \gls{group-acquire} is used in a context where one of the monitors is already acquired and is why it is important to define the behaviour of the previous pseudo-code. When the signaller thread reaches the location where it should "release A \& B" (line 16), it must actually transfer ownership of monitor B to the waiting thread. This ownership trasnfer is required in order to prevent barging. Since the signalling thread still needs the monitor A, simply waking up the waiting thread is not an option because it would violate mutual exclusion. There are three options: 418 400 419 401 \subsubsection{Delaying signals} 420 The first more obvious solution to solve the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred. It can be argued that that moment is the correct time to transfer ownership when the last lock is no longer needed because this semantics fits most closely to the behaviour of single monitor scheduling. This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from mutiple objects to a single group of object s, effectively making the existing single monitor semantic viable by simply changing monitors to monitor groups.402 The first more obvious solution to solve the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred. It can be argued that that moment is the correct time to transfer ownership when the last lock is no longer needed because this semantics fits most closely to the behaviour of single monitor scheduling. This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from mutiple objects to a single group of object, effectively making the existing single monitor semantic viable by simply changing monitors to monitor collections. 421 403 \begin{multicols}{2} 422 404 Waiter … … 442 424 \end{pseudo} 443 425 \end{multicols} 444 However, this solution can become much more complicated depending on what is executed while secretly holding B (at line 10). Indeed, nothing prevents signalling monitor A on a different condition variable: 426 However, this solution can become much more complicated depending on what is executed while secretly holding B (at line 10). Indeed, nothing prevents a user from signalling monitor A on a different condition variable: 427 \newpage 445 428 \begin{multicols}{2} 446 429 Thread 1 … … 463 446 464 447 Thread 3 465 \begin{pseudo}[numbers=left, firstnumber= 9]448 \begin{pseudo}[numbers=left, firstnumber=10] 466 449 acquire A 467 450 acquire A & B … … 484 467 Note that ordering is not determined by a race condition but by whether signalled threads are enqueued in FIFO or FILO order. However, regardless of the answer, users can move line 15 before line 11 and get the reverse effect. 485 468 486 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 monitors cannot be handled as a single homogenous group and therefore invalidates the main benefit of this approach.469 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 monitors cannot be handled as a single homogenous group. 487 470 488 471 \subsubsection{Dependency graphs} 489 In the Listing 1 pseudo-code, there is a solution which statisfies both barging prevention and mutual exclusion. If ownership of both monitors is transferred to the waiter when the signaller releases A and then the waiter transfers back ownership of A when it releases it ,then the problem is solved. Dynamically finding the correct order is therefore the second possible solution. The problem it encounters is that it effectively boils down to resolving a dependency graph of ownership requirements. Here even the simplest of code snippets requires two transfers and it seems to increase in a manner closer to polynomial. For example, the following code, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions:472 In the Listing 1 pseudo-code, there is a solution which statisfies both barging prevention and mutual exclusion. If ownership of both monitors is transferred to the waiter when the signaller releases A and then the waiter transfers back ownership of A when it releases it then the problem is solved. Dynamically finding the correct order is therefore the second possible solution. The problem it encounters is that it effectively boils down to resolving a dependency graph of ownership requirements. Here even the simplest of code snippets requires two transfers and it seems to increase in a manner closer to polynomial. For example, the following code, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions: 490 473 491 474 \begin{multicols}{2} … … 512 495 \end{pseudo} 513 496 \end{multicols} 514 515 \begin{figure} 516 \begin{multicols}{3} 517 Thread $\alpha$ 518 \begin{pseudo}[numbers=left, firstnumber=1] 497 Resolving dependency graph being a complex and expensive endeavour, this solution is not the preffered one. 498 499 \subsubsection{Partial signalling} \label{partial-sig} 500 Finally, the solution that is chosen for \CFA is to use partial signalling. Consider the following case: 501 502 \begin{multicols}{2} 503 \begin{pseudo}[numbers=left] 519 504 acquire A 520 505 acquire A & B … … 526 511 \columnbreak 527 512 528 Thread $\gamma$ 529 \begin{pseudo}[numbers=left, firstnumber=1] 513 \begin{pseudo}[numbers=left, firstnumber=6] 530 514 acquire A 531 515 acquire A & B 532 516 signal A & B 533 517 release A & B 534 signal A 535 release A 536 \end{pseudo} 537 538 \columnbreak 539 540 Thread $\beta$ 541 \begin{pseudo}[numbers=left, firstnumber=1] 542 acquire A 543 wait A 544 release A 545 \end{pseudo} 546 518 // ... More code 519 release A 520 \end{pseudo} 547 521 \end{multicols} 548 \caption{Dependency graph} 549 \label{lst:dependency} 550 \end{figure} 551 552 \begin{figure} 553 \begin{center} 554 \input{dependency} 555 \end{center} 556 \label{fig:dependency} 557 \caption{Dependency graph of the statements in listing \ref{lst:dependency}} 558 \end{figure} 559 560 Listing \ref{lst:dependency} is the three thread example rewritten for dependency graphs as well as the corresponding dependency graph. 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. The extra challenge is that this dependency graph is effectively post-mortem, but the run time system needs to be able to build and solve these graphs as the dependency unfolds. Resolving dependency graph being a complex and expensive endeavour, this solution is not the preffered one. 561 562 \subsubsection{Partial signalling} \label{partial-sig} 563 Finally, the solution that is chosen for \CFA is to use partial signalling. Consider the following case: 564 565 \begin{multicols}{2} 566 \begin{pseudo}[numbers=left] 567 acquire A 568 acquire A & B 569 wait A & B 570 release A & B 571 release A 572 \end{pseudo} 573 574 \columnbreak 575 576 \begin{pseudo}[numbers=left, firstnumber=6] 577 acquire A 578 acquire A & B 579 signal A & B 580 release A & B 581 //... More code 582 release A 583 \end{pseudo} 584 \end{multicols} 585 The partial signalling solution transfers ownership of monitor B at lines 10 but does not wake the waiting thread since it is still using monitor A. Only when it reaches line 11 does it actually wakeup the waiting thread. This solution has the benefit that complexity is encapsulated into only two actions, passing monitors to the next owner when they should be release and conditionally waking threads if all conditions are met. This solution has a much simpler implementation than a dependency graph solving algorithm which is why it was chosen. 522 The partial signalling solution transfers ownership of monitor B at lines 10 but does not wake the waiting thread since it is still using monitor A. Only when it reaches line 11 does it actually wakeup the waiting thread. This solution has the benefit that complexity is encapsulated into only two actions, passing monitors to the next owner when they should be release and conditionnaly waking threads if all conditions are met. Contrary to the other solutions, this solution quickly hits an upper bound on complexity of implementation. 586 523 587 524 % ====================================================================== … … 592 529 An important note is that, until now, signalling a monitor was a delayed operation. The ownership of the monitor is transferred only when the monitor would have otherwise been released, not at the point of the \code{signal} statement. 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 \code{signal_block} routine\footnote{name to be discussed}. 593 530 594 The example in listing \ref{lst:datingservice} highlights the difference in behaviour. As mentioned, \code{signal} only transfers ownership once the current critical section exits, this behaviour cause the need for additional synchronisation when a two-way handshake is needed. To avoid this extraneous synchronisation, the \code{condition} type offers the \code{signal_block} routine which handle two-way handshakes as shown in the example. This removes the need for a second condition variables and simplifies programming. Like every other monitor semantic, \code{signal_block} uses barging prevention which means mutual-exclusion is baton-passed both on the frond-end and the back-end of the call to \code{signal_block}, meaning no other thread can acquire the monitor neither before nor after the call. 595 \begin{ figure}531 For example here is an example highlighting the difference in behaviour: 532 \begin{center} 596 533 \begin{tabular}{|c|c|} 597 534 \code{signal} & \code{signal_block} \\ 598 535 \hline 599 \begin{cfacode}[tabsize=3] 600 monitor DatingService 601 { 602 //compatibility codes 603 enum{ CCodes = 20 }; 604 605 int girlPhoneNo 606 int boyPhoneNo; 607 }; 608 609 condition girls[CCodes]; 610 condition boys [CCodes]; 611 condition exchange; 612 613 int girl(int phoneNo, int ccode) 614 { 615 //no compatible boy ? 616 if(empty(boys[ccode])) 617 { 618 //wait for boy 619 wait(girls[ccode]); 620 621 //make phone number available 622 girlPhoneNo = phoneNo; 623 624 //wake boy fron chair 625 signal(exchange); 626 } 627 else 628 { 629 //make phone number available 630 girlPhoneNo = phoneNo; 631 632 //wake boy 633 signal(boys[ccode]); 634 635 //sit in chair 636 wait(exchange); 637 } 638 return boyPhoneNo; 639 } 640 641 int boy(int phoneNo, int ccode) 642 { 643 //same as above 644 //with boy/girl interchanged 645 } 646 \end{cfacode}&\begin{cfacode}[tabsize=3] 647 monitor DatingService 648 { 649 //compatibility codes 650 enum{ CCodes = 20 }; 651 652 int girlPhoneNo; 653 int boyPhoneNo; 654 }; 655 656 condition girls[CCodes]; 657 condition boys [CCodes]; 658 //exchange is not needed 659 660 int girl(int phoneNo, int ccode) 661 { 662 //no compatible boy ? 663 if(empty(boys[ccode])) 664 { 665 //wait for boy 666 wait(girls[ccode]); 667 668 //make phone number available 669 girlPhoneNo = phoneNo; 670 671 //wake boy fron chair 672 signal(exchange); 673 } 674 else 675 { 676 //make phone number available 677 girlPhoneNo = phoneNo; 678 679 //wake boy 680 signal_block(boys[ccode]); 681 682 //second handshake unnecessary 683 684 } 685 return boyPhoneNo; 686 } 687 688 int boy(int phoneNo, int ccode) 689 { 690 //same as above 691 //with boy/girl interchanged 536 \begin{cfacode} 537 monitor M { int val; }; 538 539 void foo(M & mutex m ) { 540 m.val++; 541 sout| "Foo:" | m.val |endl; 542 543 wait( c ); 544 545 m.val++; 546 sout| "Foo:" | m.val |endl; 547 } 548 549 void bar(M & mutex m ) { 550 m.val++; 551 sout| "Bar:" | m.val |endl; 552 553 signal( c ); 554 555 m.val++; 556 sout| "Bar:" | m.val |endl; 557 } 558 \end{cfacode}&\begin{cfacode} 559 monitor M { int val; }; 560 561 void foo(M & mutex m ) { 562 m.val++; 563 sout| "Foo:" | m.val |endl; 564 565 wait( c ); 566 567 m.val++; 568 sout| "Foo:" | m.val |endl; 569 } 570 571 void bar(M & mutex m ) { 572 m.val++; 573 sout| "Bar:" | m.val |endl; 574 575 signal_block( c ); 576 577 m.val++; 578 sout| "Bar:" | m.val |endl; 692 579 } 693 580 \end{cfacode} 694 581 \end{tabular} 695 \caption{Dating service example using \code{signal} and \code{signal_block}. } 696 \label{lst:datingservice} 697 \end{figure} 582 \end{center} 583 Assuming that \code{val} is initialized at 0, that each routine are called from seperate thread and that \code{foo} is always called first. The previous code would yield the following output: 584 585 \begin{center} 586 \begin{tabular}{|c|c|} 587 \code{signal} & \code{signal_block} \\ 588 \hline 589 \begin{pseudo} 590 Foo: 0 591 Bar: 1 592 Bar: 2 593 Foo: 3 594 \end{pseudo}&\begin{pseudo} 595 Foo: 0 596 Bar: 1 597 Foo: 2 598 Bar: 3 599 \end{pseudo} 600 \end{tabular} 601 \end{center} 602 603 As mentionned, \code{signal} only transfers ownership once the current critical section exits, resulting in the second "Bar" line to be printed before the second "Foo" line. On the other hand, \code{signal_block} immediately transfers ownership to \code{bar}, causing an inversion of output. Obviously this means that \code{signal_block} is a blocking call, which will only be resumed once the signalled function exits the critical section. 604 605 % ====================================================================== 606 % ====================================================================== 607 \subsection{Internal scheduling: Implementation} \label{inschedimpl} 608 % ====================================================================== 609 % ====================================================================== 610 There are several challenges specific to \CFA when implementing internal scheduling. These challenges are direct results of \gls{group-acquire} and loose object definitions. These two constraints are to root cause of most design decisions in the implementation of internal scheduling. Furthermore, to avoid the head-aches of dynamically allocating memory in a concurrent environment, the internal-scheduling design is entirely free of mallocs and other dynamic memory allocation scheme. This is to avoid the chicken and egg problem of having a memory allocator that relies on the threading system and a threading system that relies on the runtime. This extra goal, means that memory management is a constant concern in the design of the system. 611 612 The main memory concern for concurrency is queues. All blocking operations are made by parking threads onto queues. These queues need to be intrinsic\cit to avoid the need memory allocation. This entails that all the fields needed to keep track of all needed information. Since internal scheduling can use an unbound amount of memory (depending on \gls{group-acquire}) statically defining information information in the intrusive fields of threads is insufficient. The only variable sized container that does not require memory allocation is the callstack, which is heavily used in the implementation of internal scheduling. Particularly the GCC extension variable length arrays which is used extensively. 613 614 Since stack allocation is based around scope, 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. In the case of external scheduling, the threads and the condition both allow a fixed amount of memory to be stored, while mutex-routines and the actual blocking call allow for an unbound amount (though adding too much to the mutex routine stack size can become expansive faster). 615 616 The following figure is the traditionnal illustration of a monitor : 617 618 \begin{center} 619 {\resizebox{0.4\textwidth}{!}{\input{monitor}}} 620 \end{center} 621 622 For \CFA, the previous picture does not have support for blocking multiple monitors on a single condition. To support \gls{group-acquire} two changes to this picture are required. First, it doesn't make sense to tie the condition to a single monitor since blocking two monitors as one would require arbitrarily picking a monitor to hold the condition. Secondly, the object waiting on the conditions and AS-stack cannot simply contain the waiting thread since a single thread can potentially wait on multiple monitors. As mentionned in section \ref{inschedimpl}, the handling in multiple monitors is done by partially passing, which entails that each concerned monitor needs to have a node object. However, for waiting on the condition, since all threads need to wait together, a single object needs to be queued in the condition. Moving out the condition and updating the node types yields : 623 624 \begin{center} 625 {\resizebox{0.8\textwidth}{!}{\input{int_monitor}}} 626 \end{center} 627 628 \newpage 629 630 This picture and the proper entry and leave algorithms is the fundamental implementation of internal scheduling. 631 632 \begin{multicols}{2} 633 Entry 634 \begin{pseudo}[numbers=left] 635 if monitor is free 636 enter 637 elif I already own the monitor 638 continue 639 else 640 block 641 increment recursion 642 643 \end{pseudo} 644 \columnbreak 645 Exit 646 \begin{pseudo}[numbers=left, firstnumber=8] 647 decrement recursion 648 if recursion == 0 649 if signal_stack not empty 650 set_owner to thread 651 if all monitors ready 652 wake-up thread 653 654 if entry queue not empty 655 wake-up thread 656 \end{pseudo} 657 \end{multicols} 658 659 Some important things to notice about the exit routine. The solution discussed in \ref{inschedimpl} can be seen on line 11 of the previous pseudo code. Basically, the solution boils down to having a seperate 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 trasnferred ownership. This solution is safe as well as preventing any potential barging. 698 660 699 661 % ====================================================================== … … 738 700 \end{tabular} 739 701 \end{center} 740 This method is more constrained and explicit, which helps users tone down the undeterministic nature of concurrency. Indeed, as the following examples demonstrates, external scheduling allows users to wait for events from other threads without the concern of unrelated events occuring. External scheduling can generally be done either in terms of control flow (e.g., \uC with \code{_Accept}) or in terms of data (e.g. Go with channels). Of course, both of these paradigms have their own strenghts and weaknesses but for this project control-flow semantics were chosen to stay consistent with the rest of the languages semantics. Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multi-monitor routines. The previous example shows a simple use \code{_Accept} versus \code{wait}/\code{signal} and its advantages. Note that while other languages often use \code{accept}/\code{select} as the core external scheduling keyword, \CFA uses \code{waitfor} to prevent name collisions with existing socket \acrshort{api}s.741 742 In the case of internal scheduling, the call to \code{wait} only guarantees that \code{V} is the last routine to access the monitor. This entails that a third routine, say \code{isInUse()},may have acquired mutual exclusion several times while routine \code{P} was waiting. On the other hand, external scheduling guarantees that while routine \code{P} was waiting, no routine other than \code{V} could acquire the monitor.702 This method is more constrained and explicit, which may help users tone down the undeterministic nature of concurrency. Indeed, as the following examples demonstrates, external scheduling allows users to wait for events from other threads without the concern of unrelated events occuring. External scheduling can generally be done either in terms of control flow (e.g., \uC) or in terms of data (e.g. Go). Of course, both of these paradigms have their own strenghts and weaknesses but for this project control-flow semantics were chosen to stay consistent with the rest of the languages semantics. Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multi-monitor routines. The previous example shows a simple use \code{_Accept} versus \code{wait}/\code{signal} and its advantages. Note that while other languages often use \code{accept} as the core external scheduling keyword, \CFA uses \code{waitfor} to prevent name collisions with existing socket APIs. 703 704 In the case of internal scheduling, the call to \code{wait} only guarantees that \code{V} is the last routine to access the monitor. This entails that the routine \code{V} may have acquired mutual exclusion several times while routine \code{P} was waiting. On the other hand, external scheduling guarantees that while routine \code{P} was waiting, no routine other than \code{V} could acquire the monitor. 743 705 744 706 % ====================================================================== … … 750 712 751 713 \begin{cfacode} 752 monitor A {}; 753 754 void f(A & mutex a); 755 void g(A & mutex a) { 756 waitfor(f); //Obvious which f() to wait for 757 } 758 759 void f(A & mutex a, int); //New different F added in scope 760 void h(A & mutex a) { 761 waitfor(f); //Less obvious which f() to wait for 762 } 714 monitor A {}; 715 716 void f(A & mutex a); 717 void f(int a, float b); 718 void g(A & mutex a) { 719 waitfor(f); // Less obvious which f() to wait for 720 } 763 721 \end{cfacode} 764 722 … … 770 728 if monitor is free 771 729 enter 772 elif already own the monitor730 elif I already own the monitor 773 731 continue 774 732 elif monitor accepts me … … 780 738 \end{center} 781 739 782 For the fi rst two conditions, it is easy to implement a check that can evaluate the condition in a few instruction. However, a fast check for \pscode{monitor accepts me} is much harder to implement depending on the constraints put on the monitors. Indeed, monitors are often expressed as an entry queue and some acceptor queue as in the following figure:740 For the fist two conditions, it is easy to implement a check that can evaluate the condition in a few instruction. However, a fast check for \pscode{monitor accepts me} is much harder to implement depending on the constraints put on the monitors. Indeed, monitors are often expressed as an entry queue and some acceptor queue as in the following figure: 783 741 784 742 \begin{center} … … 786 744 \end{center} 787 745 788 There are other alternatives to these pictures , but in the case of this picture,implementing a fast accept check is relatively easy. Indeed simply updating a bitmask when the acceptor queue changes is enough to have a check that executes in a single instruction, even with a fairly large number (e.g. 128) of mutex members. This technique cannot be used in \CFA because it relies on the fact that the monitor type declares all the acceptable routines. For OO languages this does not compromise much since monitors already have an exhaustive list of member routines. However, for \CFA this is not the case; routines can be added to a type anywhere after its declaration. Its important to note that the bitmask approach does not actually require an exhaustive list of routines, but it requires a dense unique ordering of routines with an upper-bound and that ordering must be consistent across translation units.789 The alternative is to have a picture like this one:746 There are other alternatives to these pictures but in the case of this picture implementing a fast accept check is relatively easy. Indeed simply updating a bitmask when the acceptor queue changes is enough to have a check that executes in a single instruction, even with a fairly large number (e.g. 128) of mutex members. This technique cannot be used in \CFA because it relies on the fact that the monitor type declares all the acceptable routines. For OO languages this does not compromise much since monitors already have an exhaustive list of member routines. However, for \CFA this is not the case; routines can be added to a type anywhere after its declaration. Its important to note that the bitmask approach does not actually require an exhaustive list of routines, but it requires a dense unique ordering of routines with an upper-bound and that ordering must be consistent across translation units. 747 The alternative would be to have a picture more like this one: 790 748 791 749 \begin{center} … … 793 751 \end{center} 794 752 795 Not storing the mask inside the monitor means that the storage for the mask information can vary between calls to \code{waitfor}, allowing for more flexibility and extensions. Storing an array of function-pointers would solve the issue of uniquely identifying acceptable routines. However, the single instruction bitmask compare has been replaced by dereferencing a pointer followed by a linear search. Furthermore, supporting nested external scheduling may now require additionnal searches on calls to waitfor to check if a routine is already queued in.796 797 Note that in the second picture, tasks need to always keep track of through which routine they are attempting to acquire the monitor and the routine mask needs to have both a function pointer and a set of monitors, as will be discussed in the next section. These details where omitted from the picture for the sake of simplifying the representation.798 799 A t this point we must make a decision between flexibility and performance. 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. Here however, the cost of flexibility cannot be trivially removed. In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be prohibitively hard to write. This decision is based on the assumption that writing fast but inflexible locks is closer to a solved problems than writing locks that are as flexible as external scheduling in \CFA.753 Not storing the queues inside the monitor means that the storage can vary between routines, allowing for more flexibility and extensions. Storing an array of function-pointers would solve the issue of uniquely identifying acceptable routines. However, the single instruction bitmask compare has been replaced by dereferencing a pointer followed by a linear search. Furthermore, supporting nested external scheduling may now require additionnal searches on calls to waitfor to check if a routine is already queued in. 754 755 At this point we must make a decision between flexibility and performance. 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. Here however, the cost of flexibility cannot be trivially removed. In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be prohibitively hard to write. This is based on the assumption that writing fast but inflexible locks is closer to a solved problems than writing locks that are as flexible as external scheduling in \CFA. 756 757 Another aspect to consider is what happens if multiple overloads of the same routine are used. For the time being it is assumed that multiple overloads of the same routine are considered as distinct routines. However, this could easily be extended in the future. 800 758 801 759 % ====================================================================== … … 805 763 % ====================================================================== 806 764 807 External scheduling, like internal scheduling, becomes significantly more complex when introducing multi-monitor syntax. Even in the simplest possible case,some new semantics need to be established:808 \begin{cfacode} 809 monitor M{};810 811 void f(M & mutex a);812 813 void g(M & mutex a, M& mutex b) {814 waitfor(f); //ambiguous, keep a pass b or other way around?815 }765 External scheduling, like internal scheduling, becomes orders of magnitude more complex when we start introducing multi-monitor syntax. Even in the simplest possible case some new semantics need to be established: 766 \begin{cfacode} 767 mutex struct A {}; 768 769 mutex struct B {}; 770 771 void g(A & mutex a, B & mutex b) { 772 waitfor(f); //ambiguous, which monitor 773 } 816 774 \end{cfacode} 817 775 … … 819 777 820 778 \begin{cfacode} 821 monitor M {}; 822 823 void f(M & mutex a); 824 825 void g(M & mutex a, M & mutex b) { 826 waitfor( f, b ); 827 } 828 \end{cfacode} 829 830 This syntax is unambiguous. Both locks are acquired and kept. When routine \code{f} is called, the lock for monitor \code{b} is temporarily transferred from \code{g} to \code{f} (while \code{g} still holds lock \code{a}). This behavior can be extended to multi-monitor waitfor statement as follows. 831 832 \begin{cfacode} 833 monitor M {}; 834 835 void f(M & mutex a, M & mutex b); 836 837 void g(M & mutex a, M & mutex b) { 838 waitfor( f, a, b); 839 } 840 \end{cfacode} 841 842 Note that the set of monitors passed to the \code{waitfor} statement must be entirely contained in the set of monitors already acquired in the routine. \code{waitfor} used in any other context is Undefined Behaviour. 843 844 An important behavior to note is that what happens when a set of monitors only match partially : 845 846 \begin{cfacode} 847 mutex struct A {}; 848 849 mutex struct B {}; 850 851 void g(A & mutex a, B & mutex b) { 852 waitfor(f, a, b); 853 } 854 855 A a1, a2; 856 B b; 857 858 void foo() { 859 g(a1, b); //block on accept 860 } 861 862 void bar() { 863 f(a2, b); //fufill cooperation 864 } 865 \end{cfacode} 866 867 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. In both cases, partially matching monitor sets does not wake-up the waiting thread. It is also important to note that in the case of external scheduling, as for routine calls, the order of parameters is important; \code{waitfor(f,a,b)} and \code{waitfor(f,b,a)} are to distinct waiting condition. 868 869 % ====================================================================== 870 % ====================================================================== 871 \subsection{\code{waitfor} semantics} 872 % ====================================================================== 873 % ====================================================================== 874 875 Syntactically, the \code{waitfor} statement takes a function identifier and a set of monitors. While the set of monitors can be any list of expression, the function name is more restricted. This is because the compiler validates at compile time the validity of the waitfor statement. It checks that the set of monitor passed in matches the requirements for a function call. Listing \ref{lst:waitfor} shows various usage of the waitfor statement and which are acceptable. The choice of the function type is made ignoring any non-\code{mutex} parameter. One limitation of the current implementation is that it does not handle overloading. 876 \begin{figure} 877 \begin{cfacode} 878 monitor A{}; 879 monitor B{}; 880 881 void f1( A & mutex ); 882 void f2( A & mutex, B & mutex ); 883 void f3( A & mutex, int ); 884 void f4( A & mutex, int ); 885 void f4( A & mutex, double ); 886 887 void foo( A & mutex a1, A & mutex a2, B & mutex b1, B & b2 ) { 888 A * ap = & a1; 889 void (*fp)( A & mutex ) = f1; 890 891 waitfor(f1, a1); //Correct : 1 monitor case 892 waitfor(f2, a1, b1); //Correct : 2 monitor case 893 waitfor(f3, a1); //Correct : non-mutex arguments are ignored 894 waitfor(f1, *ap); //Correct : expression as argument 895 896 waitfor(f1, a1, b1); //Incorrect : Too many mutex arguments 897 waitfor(f2, a1); //Incorrect : Too few mutex arguments 898 waitfor(f2, a1, a2); //Incorrect : Mutex arguments don't match 899 waitfor(f1, 1); //Incorrect : 1 not a mutex argument 900 waitfor(f4, a1); //Incorrect : f9 not a function 901 waitfor(*fp, a1 ); //Incorrect : fp not a identifier 902 waitfor(f4, a1); //Incorrect : f4 ambiguous 903 904 waitfor(f2, a1, b2); //Undefined Behaviour : b2 may not acquired 905 } 906 \end{cfacode} 907 \caption{Various correct and incorrect uses of the waitfor statement} 908 \label{lst:waitfor} 909 \end{figure} 910 911 Finally, for added flexibility, \CFA supports constructing complex waitfor mask using the \code{or}, \code{timeout} and \code{else}. Indeed, multiple \code{waitfor} can be chained together using \code{or}; this chain will form a single statement which will baton-pass to any one function that fits one of the function+monitor set which was passed in. To eanble users to tell which was the accepted function, \code{waitfor}s are followed by a statement (including the null statement \code{;}) or a compound statement. When multiple \code{waitfor} are chained together, only the statement corresponding to the accepted function is executed. A \code{waitfor} chain can also be followed by a \code{timeout}, to signify an upper bound on the wait, or an \code{else}, to signify that the call should be non-blocking, that is only check of a matching function already arrived and return immediately otherwise. Any and all of these clauses can be preceded by a \code{when} condition to dynamically construct the mask based on some current state. Listing \ref{lst:waitfor2}, demonstrates several complex masks and some incorrect ones. 912 913 \begin{figure} 914 \begin{cfacode} 915 monitor A{}; 916 917 void f1( A & mutex ); 918 void f2( A & mutex ); 919 920 void foo( A & mutex a, bool b, int t ) { 921 //Correct : blocking case 922 waitfor(f1, a); 923 924 //Correct : block with statement 925 waitfor(f1, a) { 926 sout | "f1" | endl; 927 } 928 929 //Correct : block waiting for f1 or f2 930 waitfor(f1, a) { 931 sout | "f1" | endl; 932 } or waitfor(f2, a) { 933 sout | "f2" | endl; 934 } 935 936 //Correct : non-blocking case 937 waitfor(f1, a); or else; 938 939 //Correct : non-blocking case 940 waitfor(f1, a) { 941 sout | "blocked" | endl; 942 } or else { 943 sout | "didn't block" | endl; 944 } 945 946 //Correct : block at most 10 seconds 947 waitfor(f1, a) { 948 sout | "blocked" | endl; 949 } or timeout( 10`s) { 950 sout | "didn't block" | endl; 951 } 952 953 //Correct : block only if b == true 954 //if b == false, don't even make the call 955 when(b) waitfor(f1, a); 956 957 //Correct : block only if b == true 958 //if b == false, make non-blocking call 959 waitfor(f1, a); or when(!b) else; 960 961 //Correct : block only of t > 1 962 waitfor(f1, a); or when(t > 1) timeout(t); or else; 963 964 //Incorrect : timeout clause is dead code 965 waitfor(f1, a); or timeout(t); or else; 966 967 //Incorrect : order must be 968 //waitfor [or waitfor... [or timeout] [or else]] 969 timeout(t); or waitfor(f1, a); or else; 970 } 971 \end{cfacode} 972 \caption{Various correct and incorrect uses of the or, else, and timeout clause around a waitfor statement} 973 \label{lst:waitfor2} 974 \end{figure} 779 mutex struct A {}; 780 781 mutex struct B {}; 782 783 void g(A & mutex a, B & mutex b) { 784 waitfor( f, b ); 785 } 786 \end{cfacode} 787 788 This is unambiguous. Both locks will be acquired and kept, when routine \code{f} is called the lock for monitor \code{b} will be temporarily transferred from \code{g} to \code{f} (while \code{g} still holds lock \code{a}). This behavior can be extended to multi-monitor waitfor statment as follows. 789 790 \begin{cfacode} 791 mutex struct A {}; 792 793 mutex struct B {}; 794 795 void g(A & mutex a, B & mutex b) { 796 waitfor( f, a, b); 797 } 798 \end{cfacode} 799 800 Note that the set of monitors passed to the \code{waitfor} statement must be entirely contained in the set of monitor already acquired in the routine. \code{waitfor} used in any other context is Undefined Behaviour. 801 802 An important behavior to note is that what happens when set of monitors only match partially : 803 804 \begin{cfacode} 805 mutex struct A {}; 806 807 mutex struct B {}; 808 809 void g(A & mutex a, B & mutex b) { 810 waitfor(f, a, b); 811 } 812 813 A a1, a2; 814 B b; 815 816 void foo() { 817 g(a1, b); 818 } 819 820 void bar() { 821 f(a2, b); 822 } 823 \end{cfacode} 824 825 While the equivalent can happen when using internal scheduling, the fact that conditions are branded on first use means that users have to use two different condition variables. In both cases, partially matching monitor sets will not wake-up the waiting thread. It is also important to note that in the case of external scheduling, as for routine calls, the order of parameters is important; \code{waitfor(f,a,b)} and \code{waitfor(f,b,a)} are to distinct waiting condition. 826 827 % ====================================================================== 828 % ====================================================================== 829 \subsection{Implementation Details: External scheduling queues} 830 % ====================================================================== 831 % ====================================================================== 832 To support multi-monitor external scheduling means that some kind of entry-queues must be used that is aware of both monitors. However, acceptable routines must be aware of the entry queues which means they must be stored inside at least one of the monitors that will be acquired. This in turn adds the requirement a systematic algorithm of disambiguating which queue is relavant regardless of user ordering. The proposed algorithm is to fall back on monitors lock ordering and specify that the monitor that is acquired first is the lock with the relevant entry queue. This assumes that the lock acquiring order is static for the lifetime of all concerned objects but that is a reasonable constraint. This algorithm choice has two consequences, the entry queue of the highest priority monitor is no longer a true FIFO queue and the queue of the lowest priority monitor is both required and probably unused. The queue can no longer be a FIFO queue because instead of simply containing the waiting threads in order arrival, they also contain the second mutex. Therefore, another thread with the same highest priority monitor but a different lowest priority monitor may arrive first but enter the critical section after a thread with the correct pairing. Secondly, since it may not be known at compile time which monitor will be the lowest priority monitor, every monitor needs to have the correct queues even though it is probable that half the multi-monitor queues will go unused for the entire duration of the program. 833 834 % ====================================================================== 835 % ====================================================================== 836 \section{Other concurrency tools} 837 % ====================================================================== 838 % ====================================================================== 839 % \TODO -
doc/proposals/concurrency/text/intro.tex
r6840e7c rb96ec83 3 3 % ====================================================================== 4 4 5 This thesis provides a minimal concurrency \acrshort{api} that is simple, efficient and can be reused to build higher-level features. The simplest possible concurrency system is a thread and a lock but this low-level approach is hard to master. An easier approach for users is to support higher-level constructs as the basis of concurrency. Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{HPP:Study}. Examples are task based, message passing and implicit threading. The high-level approach and its minimal \acrshort{api} are tested in a dialect of C, call \CFA. [Is there value to say that this thesis is also an early definition of the \CFA language and library in regards to concurrency?]5 This proposal provides a minimal concurrency API that is simple, efficient and can be reused to build higher-level features. The simplest possible concurrency system is a thread and a lock but this low-level approach is hard to master. An easier approach for users is to support higher-level constructs as the basis of the concurrency, in \CFA. Indeed, for highly productive parallel programming, high-level approaches are much more popular~\cite{HPP:Study}. Examples are task based, message passing and implicit threading. Therefore a high-level approach is adapted in \CFA 6 6 7 There are actually two problems that need to be solved in the design of concurrency for a programming language: which concurrency and which parallelism tools are available to the programmer. While these two concepts are often combined, they are in fact distinct, requiringdifferent tools~\cite{Buhr05a}. Concurrency tools need to handle mutual exclusion and synchronization, while parallelism tools are about performance, cost and resource utilization.7 There are actually two problems that need to be solved in the design of concurrency for a programming language: which concurrency and which parallelism tools are available to the users. While these two concepts are often combined, they are in fact distinct concepts that require different tools~\cite{Buhr05a}. Concurrency tools need to handle mutual exclusion and synchronization, while parallelism tools are about performance, cost and resource utilization. -
doc/proposals/concurrency/text/parallelism.tex
r6840e7c rb96ec83 11 11 \section{Paradigm} 12 12 \subsection{User-level threads} 13 A direct improvement on the \gls{kthread} approach is to use \glspl{uthread}. These threads offer most of the same features that the operating system already provide but can be used on a much larger scale. This approach is the most powerfull solution as it allows all the features of multi-threading, while removing several of the more expensive costs of kernel threads. The down side is that almost none of the low-level threading problems are hidden;users still have to think about data races, deadlocks and synchronization issues. These issues can be somewhat alleviated by a concurrency toolkit with strong garantees but the parallelism toolkit offers very little to reduce complexity in itself.13 A direct improvement on the \gls{kthread} approach is to use \glspl{uthread}. These threads offer most of the same features that the operating system already provide but can be used on a much larger scale. This approach is the most powerfull solution as it allows all the features of multi-threading, while removing several of the more expensives costs of using kernel threads. The down side is that almost none of the low-level threading problems are hidden, users still have to think about data races, deadlocks and synchronization issues. These issues can be somewhat alleviated by a concurrency toolkit with strong garantees but the parallelism toolkit offers very little to reduce complexity in itself. 14 14 15 15 Examples of languages that support \glspl{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}. 16 16 17 17 \subsection{Fibers : user-level threads without preemption} 18 A popular varient of \glspl{uthread} is what is often ref ered to as \glspl{fiber}. However, \glspl{fiber} do not present meaningful semantical differences with \glspl{uthread}. Advocates of \glspl{fiber} list their high performance and ease of implementation as majors strenghts of \glspl{fiber} but the performance difference between \glspl{uthread} and \glspl{fiber} is controversial,and the ease of implementation, while true, is a weak argument in the context of language design. Therefore this proposal largely ignore fibers.18 A popular varient of \glspl{uthread} is what is often reffered to as \glspl{fiber}. However, \glspl{fiber} do not present meaningful semantical differences with \glspl{uthread}. Advocates of \glspl{fiber} list their high performance and ease of implementation as majors strenghts of \glspl{fiber} but the performance difference between \glspl{uthread} and \glspl{fiber} is controversial and the ease of implementation, while true, is a weak argument in the context of language design. Therefore this proposal largely ignore fibers. 19 19 20 20 An example of a language that uses fibers is Go~\cite{Go} 21 21 22 22 \subsection{Jobs and thread pools} 23 An approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work, called jobs, and a dependency graph (either explicit or implicit) that tie them together. This approach means users need not worry about concurrency but significantly limitthe interaction that can occur among jobs. Indeed, any \gls{job} that blocks also blocks the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. It can be argued that a solution to this problem is to use more workers than available cores. However, unless the number of jobs and the number of workers are comparable, having a significant amount of blocked jobs always results in idles cores.23 The approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work and a dependency graph (either explicit or implicit) that tie them together. This approach means users need not worry about concurrency but significantly limits the interaction that can occur among jobs. Indeed, any \gls{job} that blocks also blocks the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. It can be argued that a solution to this problem is to use more workers than available cores. However, unless the number of jobs and the number of workers are comparable, having a significant amount of blocked jobs always results in idles cores. 24 24 25 25 The gold standard of this implementation is Intel's TBB library~\cite{TBB}. 26 26 27 27 \subsection{Paradigm performance} 28 While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pindown the performance implications of chosing a model at the language level. Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. Having a large amount of mostly independent units of work to execute almost guarantess that the \gls{pool} based system has the best performance thanks to the lower memory overhead (i.e., not thread stack per job). However, interactions among jobs can easily exacerbate contention. User-level threads allow fine-grain context switching, which results in better resource utilisation, but a context switch is more expensive and the extra control means users need to tweak more variables to get the desired performance. Finally, if the units of uninterrupted work are large enough the paradigm choice is largely amortised by the actual work done.28 While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pindown the performance implications of chosing a model at the language level. Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. Having a large amount of mostly independent units of work to execute almost guarantess that the \gls{pool} based system has the best performance thanks to the lower memory overhead. However, interactions between jobs can easily exacerbate contention. User-level threads allow fine-grain context switching, which results in better resource utilisation, but context switches will be more expansive and the extra control means users need to tweak more variables to get the desired performance. Furthermore, if the units of uninterrupted work are large enough the paradigm choice is largely amorticised by the actual work done. 29 29 30 \newpage 30 31 \TODO 31 32 \section{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel} 32 \subsection{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel} 33 33 34 34 35 \subsection{ Future Work: Machine setup}\label{machine}36 While this was not done in the context of this thesis, another important aspect of clusters is affinity. While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heteregenous setups. For example, system using \acrshort{numa} configurations may benefit from users being able to tie clusters and/or kernel threads to certains CPU cores. OS support for CPU affinity is now common \cit, which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity.35 \subsection{Paradigms}\label{cfaparadigms} 36 Given these building blocks we can then reproduce the all three of the popular paradigms. Indeed, we get \glspl{uthread} as the default paradigm in \CFA. However, disabling \glspl{preemption} on the \gls{cfacluster} means \glspl{cfathread} effectively become \glspl{fiber}. Since several \glspl{cfacluster} with different scheduling policy can coexist in the same application, this allows \glspl{fiber} and \glspl{uthread} to coexist in the runtime of an application. 37 37 38 \subsection{Paradigms}\label{cfaparadigms} 39 Given these building blocks, it is possible to reproduce all three of the popular paradigms. Indeed, \glspl{uthread} is the default paradigm in \CFA. However, disabling \glspl{preemption} on the \gls{cfacluster} means \glspl{cfathread} effectively become \glspl{fiber}. Since several \glspl{cfacluster} with different scheduling policy can coexist in the same application, this allows \glspl{fiber} and \glspl{uthread} to coexist in the runtime of an application. Finally, it is possible to build executors for thread pools from \glspl{uthread} or \glspl{fiber}. 38 % \subsection{High-level options}\label{tasks} 39 % 40 % \subsubsection{Thread interface} 41 % constructors destructors 42 % initializer lists 43 % monitors 44 % 45 % \subsubsection{Futures} 46 % 47 % \subsubsection{Implicit threading} 48 % Finally, simpler applications can benefit greatly from having implicit parallelism. That is, parallelism that does not rely on the user to write concurrency. This type of parallelism can be achieved both at the language level and at the system level. 49 % 50 % \begin{center} 51 % \begin{tabular}[t]{|c|c|c|} 52 % Sequential & System Parallel & Language Parallel \\ 53 % \begin{lstlisting} 54 % void big_sum(int* a, int* b, 55 % int* out, 56 % size_t length) 57 % { 58 % for(int i = 0; i < length; ++i ) { 59 % out[i] = a[i] + b[i]; 60 % } 61 % } 62 % 63 % 64 % 65 % 66 % 67 % int* a[10000]; 68 % int* b[10000]; 69 % int* c[10000]; 70 % //... fill in a and b ... 71 % big_sum(a, b, c, 10000); 72 % \end{lstlisting} &\begin{lstlisting} 73 % void big_sum(int* a, int* b, 74 % int* out, 75 % size_t length) 76 % { 77 % range ar(a, a + length); 78 % range br(b, b + length); 79 % range or(out, out + length); 80 % parfor( ai, bi, oi, 81 % [](int* ai, int* bi, int* oi) { 82 % oi = ai + bi; 83 % }); 84 % } 85 % 86 % int* a[10000]; 87 % int* b[10000]; 88 % int* c[10000]; 89 % //... fill in a and b ... 90 % big_sum(a, b, c, 10000); 91 % \end{lstlisting}&\begin{lstlisting} 92 % void big_sum(int* a, int* b, 93 % int* out, 94 % size_t length) 95 % { 96 % for (ai, bi, oi) in (a, b, out) { 97 % oi = ai + bi; 98 % } 99 % } 100 % 101 % 102 % 103 % 104 % 105 % int* a[10000]; 106 % int* b[10000]; 107 % int* c[10000]; 108 % //... fill in a and b ... 109 % big_sum(a, b, c, 10000); 110 % \end{lstlisting} 111 % \end{tabular} 112 % \end{center} 113 % 114 % \subsection{Machine setup}\label{machine} 115 % Threads are all good and well but wee still some OS support to fully utilize available hardware. 116 % 117 % \textbf{\large{Work in progress...}} Do wee need something beyond specifying the number of kernel threads? -
doc/proposals/concurrency/thesis.tex
r6840e7c rb96ec83 1 1 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 2 2 3 % inline code �...�(copyright symbol) emacs: C-q M-)4 % red highlighting �...�(registered trademark symbol) emacs: C-q M-.5 % blue highlighting �...�(sharp s symbol) emacs: C-q M-_6 % green highlighting �...�(cent symbol) emacs: C-q M-"7 % LaTex escape �...�(section symbol) emacs: C-q M-'8 % keyword escape �...�(pilcrow symbol) emacs: C-q M-^3 % inline code ©...© (copyright symbol) emacs: C-q M-) 4 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 5 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ 6 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-" 7 % LaTex escape §...§ (section symbol) emacs: C-q M-' 8 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 9 9 % math escape $...$ (dollar symbol) 10 10 … … 27 27 \usepackage{multicol} 28 28 \usepackage[acronym]{glossaries} 29 \usepackage{varioref} 29 \usepackage{varioref} 30 30 \usepackage{listings} % format program code 31 31 \usepackage[flushmargin]{footmisc} % support label/reference in footnote … … 70 70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71 71 72 \setcounter{secnumdepth}{ 2} % number subsubsections73 \setcounter{tocdepth}{ 2} % subsubsections in table of contents72 \setcounter{secnumdepth}{3} % number subsubsections 73 \setcounter{tocdepth}{3} % subsubsections in table of contents 74 74 % \linenumbers % comment out to turn off line numbering 75 75 \makeindex … … 103 103 \input{parallelism} 104 104 105 \input{internals} 106 107 \input{together} 108 109 \input{future} 105 \chapter{Putting it all together} 110 106 111 107 \chapter{Conclusion} 108 109 \chapter{Future work} 110 Concurrency and parallelism is still a very active field that strongly benefits from hardware advances. As such certain features that aren't necessarily mature enough in their current state could become relevant in the lifetime of \CFA. 111 \subsection{Transactions} 112 112 113 113 \section*{Acknowledgements} -
doc/proposals/concurrency/version
r6840e7c rb96ec83 1 0. 10.2121 0.9.180 -
src/CodeGen/CodeGenerator.cc
r6840e7c rb96ec83 287 287 void CodeGenerator::postvisit( TypeDecl * typeDecl ) { 288 288 assertf( ! genC, "TypeDecls should not reach code generation." ); 289 output << typeDecl->genTypeString() << " " << typeDecl-> name;290 if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl-> sized) {291 output << " | sized(" << typeDecl-> name<< ")";292 } 293 if ( ! typeDecl-> assertions.empty() ) {289 output << typeDecl->genTypeString() << " " << typeDecl->get_name(); 290 if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->get_sized() ) { 291 output << " | sized(" << typeDecl->get_name() << ")"; 292 } 293 if ( ! typeDecl->get_assertions().empty() ) { 294 294 output << " | { "; 295 for ( DeclarationWithType * assert : typeDecl->assertions ) { 296 assert->accept( *visitor ); 297 output << "; "; 298 } 295 genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() ); 299 296 output << " }"; 300 297 } … … 949 946 output << ";"; 950 947 } 951 void CodeGenerator::postvisit( CatchStmt * stmt ) {952 assertf( ! genC, "Catch statements should not reach code generation." );953 954 output << ((stmt->get_kind() == CatchStmt::Terminate) ?955 "catch" : "catchResume");956 output << "( ";957 stmt->decl->accept( *visitor );958 output << " ) ";959 960 if( stmt->cond ) {961 output << "if/when(?) (";962 stmt->cond->accept( *visitor );963 output << ") ";964 }965 stmt->body->accept( *visitor );966 }967 968 void CodeGenerator::postvisit( WaitForStmt * stmt ) {969 assertf( ! genC, "Waitfor statements should not reach code generation." );970 971 bool first = true;972 for( auto & clause : stmt->clauses ) {973 if(first) { output << "or "; first = false; }974 if( clause.condition ) {975 output << "when(";976 stmt->timeout.condition->accept( *visitor );977 output << ") ";978 }979 output << "waitfor(";980 clause.target.function->accept( *visitor );981 for( Expression * expr : clause.target.arguments ) {982 output << ",";983 expr->accept( *visitor );984 }985 output << ") ";986 clause.statement->accept( *visitor );987 }988 989 if( stmt->timeout.statement ) {990 output << "or ";991 if( stmt->timeout.condition ) {992 output << "when(";993 stmt->timeout.condition->accept( *visitor );994 output << ") ";995 }996 output << "timeout(";997 stmt->timeout.time->accept( *visitor );998 output << ") ";999 stmt->timeout.statement->accept( *visitor );1000 }1001 1002 if( stmt->orelse.statement ) {1003 output << "or ";1004 if( stmt->orelse.condition ) {1005 output << "when(";1006 stmt->orelse.condition->accept( *visitor );1007 output << ")";1008 }1009 output << "else ";1010 stmt->orelse.statement->accept( *visitor );1011 }1012 }1013 1014 948 1015 949 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { … … 1090 1024 } 1091 1025 } // namespace CodeGen 1092 1093 1094 unsigned Indenter::tabsize = 2;1095 1026 1096 1027 std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) { -
src/CodeGen/CodeGenerator.h
r6840e7c rb96ec83 100 100 void postvisit( ReturnStmt * ); 101 101 void postvisit( ThrowStmt * ); 102 void postvisit( CatchStmt * );103 void postvisit( WaitForStmt * );104 102 void postvisit( WhileStmt * ); 105 103 void postvisit( ForStmt * ); -
src/CodeGen/FixNames.cc
r6840e7c rb96ec83 66 66 ); 67 67 68 main _type->get_parameters().push_back(68 mainDecl->get_functionType()->get_parameters().push_back( 69 69 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) 70 70 ); 71 71 72 main _type->get_parameters().push_back(72 mainDecl->get_functionType()->get_parameters().push_back( 73 73 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 74 74 new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ), -
src/CodeGen/GenType.cc
r6840e7c rb96ec83 210 210 211 211 std::string GenType::handleGeneric( ReferenceToType * refType ) { 212 if ( ! refType-> parameters.empty() ) {212 if ( ! refType->get_parameters().empty() ) { 213 213 std::ostringstream os; 214 214 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 215 215 os << "("; 216 cg.pass.genCommaList( refType-> parameters.begin(), refType->parameters.end() );216 cg.pass.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() ); 217 217 os << ") "; 218 218 return os.str(); -
src/Common/Indenter.h
r6840e7c rb96ec83 18 18 19 19 struct Indenter { 20 static unsigned tabsize; 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; 20 Indenter( unsigned int amt = 2 ) : amt( amt ) {} 21 unsigned int amt = 2; // amount 1 level increases indent by (i.e. how much to increase by in operator++) 22 unsigned int indent = 0; 25 23 26 24 Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; } … … 32 30 }; 33 31 34 inline std::ostream & operator<<( std::ostream & out, constIndenter & indent ) {32 inline std::ostream & operator<<( std::ostream & out, Indenter & indent ) { 35 33 return out << std::string(indent.indent, ' '); 36 34 } -
src/Common/PassVisitor.h
r6840e7c rb96ec83 4 4 5 5 #include <stack> 6 7 #include "Common/utility.h"8 6 9 7 #include "SynTree/Mutator.h" … … 238 236 virtual Attribute * mutate( Attribute * attribute ) override final; 239 237 240 virtual TypeSubstitution * mutate( TypeSubstitution * sub ) final;241 242 238 private: 243 239 template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 244 240 template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 245 template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor );246 template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator );247 template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor );248 template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator );249 241 250 242 template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); } … … 281 273 std::list< Declaration* > * get_afterDecls () { return declsToAddAfter_impl ( pass, 0); } 282 274 283 bool get_visit_children () { bool_ref * ptr = visit_children_impl(pass, 0); return ptr ? *ptr : true; } 284 bool_ref * get_visit_children_ptr() { return visit_children_impl(pass, 0); } 275 void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); } 285 276 286 277 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); } -
src/Common/PassVisitor.impl.h
r6840e7c rb96ec83 2 2 // IWYU pragma: private, include "PassVisitor.h" 3 3 4 #define VISIT_START( node ) \ 5 __attribute__((unused)) \ 6 ChildrenGuard children_guard( get_visit_children_ptr() ); \ 7 __attribute__((unused)) \ 4 #define VISIT_START( node ) \ 5 __attribute__((unused)) \ 8 6 guard_value_impl guard( at_cleanup_impl(pass, 0) ); \ 9 call_previsit( node ); \ 7 bool visit_children = true; \ 8 set_visit_children( visit_children ); \ 9 call_previsit( node ); \ 10 if( visit_children ) { \ 10 11 11 12 #define VISIT_END( node ) \ 13 } \ 12 14 call_postvisit( node ); \ 13 15 14 #define MUTATE_START( node ) \ 15 __attribute__((unused)) \ 16 ChildrenGuard children_guard( get_visit_children_ptr() ); \ 17 __attribute__((unused)) \ 16 #define MUTATE_START( node ) \ 17 __attribute__((unused)) \ 18 18 guard_value_impl guard( at_cleanup_impl(pass, 0) ); \ 19 call_premutate( node ); \ 19 bool visit_children = true; \ 20 set_visit_children( visit_children ); \ 21 call_premutate( node ); \ 22 if( visit_children ) { \ 20 23 21 24 #define MUTATE_END( type, node ) \ 25 } \ 22 26 return call_postmutate< type * >( node ); \ 23 27 24 28 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 ); \ 29 #define VISIT_BODY( node ) \ 30 VISIT_START( node ); \ 31 Visitor::visit( node ); \ 32 VISIT_END( node ); \ 33 34 35 #define MUTATE_BODY( type, node ) \ 36 MUTATE_START( node ); \ 37 Mutator::mutate( node ); \ 38 MUTATE_END( type, node ); \ 39 39 40 40 … … 63 63 template< typename pass_type > 64 64 static inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) { 65 65 66 DeclList_t* beforeDecls = visitor.get_beforeDecls(); 66 67 DeclList_t* afterDecls = visitor.get_afterDecls(); … … 75 76 try { 76 77 // run visitor on declaration 77 maybeAccept _impl( *i, visitor );78 maybeAccept( *i, visitor ); 78 79 } catch( SemanticError &e ) { 79 80 e.set_location( (*i)->location ); … … 91 92 template< typename pass_type > 92 93 static inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) { 94 93 95 DeclList_t* beforeDecls = mutator.get_beforeDecls(); 94 96 DeclList_t* afterDecls = mutator.get_afterDecls(); … … 102 104 try { 103 105 // run mutator on declaration 104 maybeMutate_impl( *i, mutator );106 *i = maybeMutate( *i, mutator ); 105 107 } catch( SemanticError &e ) { 106 108 e.set_location( (*i)->location ); … … 116 118 } 117 119 118 template< typename TreeType, typename pass_type > 119 inline void maybeAccept_impl( TreeType * tree, PassVisitor< pass_type > & visitor ) { 120 if ( ! visitor.get_visit_children() ) return; 121 if ( tree ) { 122 tree->accept( visitor ); 123 } 124 } 125 126 template< typename Container, typename pass_type > 127 inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) { 128 if ( ! visitor.get_visit_children() ) return; 120 template< typename Container, typename VisitorType > 121 inline void maybeAccept( Container &container, VisitorType &visitor ) { 129 122 SemanticError errors; 130 123 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { … … 143 136 } 144 137 145 template< typename TreeType, typename pass_type > 146 inline void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_type > & mutator ) { 147 if ( ! mutator.get_visit_children() ) return; 148 149 if ( tree ) { 150 tree = strict_dynamic_cast< TreeType * >( tree->acceptMutator( mutator ) ); 151 } 152 } 153 154 template< typename Container, typename pass_type > 155 inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) { 156 if ( ! mutator.get_visit_children() ) return; 138 template< typename Container, typename MutatorType > 139 inline void maybeMutateRef( Container &container, MutatorType &mutator ) { 157 140 SemanticError errors; 158 141 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { 159 142 try { 160 143 if ( *i ) { 144 /// *i = (*i)->acceptMutator( mutator ); 161 145 *i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) ); 162 146 assert( *i ); … … 175 159 template< typename func_t > 176 160 void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) { 177 if ( ! get_visit_children() ) return;178 161 SemanticError errors; 179 162 … … 216 199 void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) { 217 200 handleStatementList( statements, [this]( Statement * stmt) { 218 maybeAccept_impl( stmt,*this );201 stmt->accept( *this ); 219 202 }); 220 203 } … … 223 206 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) { 224 207 handleStatementList( statements, [this]( Statement *& stmt) { 225 maybeMutate_impl( stmt,*this );208 stmt = stmt->acceptMutator( *this ); 226 209 }); 227 210 } … … 231 214 template< typename func_t > 232 215 Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) { 233 if ( ! get_visit_children() ) return stmt;234 235 216 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 236 217 ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr () ); … … 263 244 Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) { 264 245 return handleStatement( stmt, [this]( Statement * stmt ) { 265 maybeAccept _impl( stmt, *this );246 maybeAccept( stmt, *this ); 266 247 return stmt; 267 248 }); … … 271 252 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) { 272 253 return handleStatement( stmt, [this]( Statement * stmt ) { 273 maybeMutate_impl( stmt, *this ); 274 return stmt; 254 return maybeMutate( stmt, *this ); 275 255 }); 276 256 } … … 279 259 template< typename func_t > 280 260 Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) { 281 if ( ! get_visit_children() ) return expr;282 261 if( !expr ) return nullptr; 283 262 … … 287 266 } 288 267 289 // should env be movedonto the result of the mutate?268 // should env be cloned (or moved) onto the result of the mutate? 290 269 return func( expr ); 291 270 } … … 294 273 Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) { 295 274 return handleExpression(expr, [this]( Expression * expr ) { 296 maybeAccept_impl( expr,*this );275 expr->accept( *this ); 297 276 return expr; 298 277 }); … … 302 281 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) { 303 282 return handleExpression(expr, [this]( Expression * expr ) { 304 maybeMutate_impl( expr, *this ); 305 return expr; 283 return expr->acceptMutator( *this ); 306 284 }); 307 }308 309 template< typename TreeType, typename VisitorType >310 inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {311 if ( ! visitor.get_visit_children() ) return;312 auto guard = makeFuncGuard(313 [&visitor]() { visitor.indexerScopeEnter(); },314 [&visitor]() { visitor.indexerScopeLeave(); }315 );316 maybeAccept_impl( tree, visitor );317 }318 319 template< typename TreeType, typename MutatorType >320 inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) {321 if ( ! mutator.get_visit_children() ) return;322 auto guard = makeFuncGuard(323 [&mutator]() { mutator.indexerScopeEnter(); },324 [&mutator]() { mutator.indexerScopeLeave(); }325 );326 maybeMutate_impl( tree, mutator );327 285 } 328 286 … … 361 319 362 320 indexerScopedAccept( node->type , *this ); 363 maybeAccept _impl( node->init , *this );364 maybeAccept _impl( node->bitfieldWidth, *this );365 maybeAccept _impl( node->attributes , *this );321 maybeAccept ( node->init , *this ); 322 maybeAccept ( node->bitfieldWidth, *this ); 323 maybeAccept ( node->attributes , *this ); 366 324 367 325 if ( node->name != "" ) { … … 377 335 378 336 indexerScopedMutate( node->type , *this ); 379 maybeMutate _impl( node->init , *this );380 maybeMutate _impl( node->bitfieldWidth, *this );381 maybeMutate _impl( node->attributes , *this );337 maybeMutateRef ( node->init , *this ); 338 maybeMutateRef ( node->bitfieldWidth, *this ); 339 maybeMutateRef ( node->attributes , *this ); 382 340 383 341 if ( node->name != "" ) { … … 400 358 { 401 359 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 402 maybeAccept _impl( node->type, *this );403 maybeAccept _impl( node->statements, *this );404 maybeAccept _impl( node->attributes, *this );360 maybeAccept( node->type, *this ); 361 maybeAccept( node->statements, *this ); 362 maybeAccept( node->attributes, *this ); 405 363 } 406 364 … … 418 376 { 419 377 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 420 maybeMutate _impl( node->type, *this );421 maybeMutate _impl( node->statements, *this );422 maybeMutate _impl( node->attributes, *this );378 maybeMutateRef( node->type, *this ); 379 maybeMutateRef( node->statements, *this ); 380 maybeMutateRef( node->attributes, *this ); 423 381 } 424 382 … … 438 396 { 439 397 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 440 maybeAccept _impl( node->parameters, *this );441 maybeAccept _impl( node->members , *this );398 maybeAccept( node->parameters, *this ); 399 maybeAccept( node->members , *this ); 442 400 } 443 401 … … 458 416 { 459 417 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 460 maybeMutate _impl( node->parameters, *this );461 maybeMutate _impl( node->members , *this );418 maybeMutateRef( node->parameters, *this ); 419 maybeMutateRef( node->members , *this ); 462 420 } 463 421 … … 479 437 { 480 438 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 481 maybeAccept _impl( node->parameters, *this );482 maybeAccept _impl( node->members , *this );439 maybeAccept( node->parameters, *this ); 440 maybeAccept( node->members , *this ); 483 441 } 484 442 … … 497 455 { 498 456 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 499 maybeMutate _impl( node->parameters, *this );500 maybeMutate _impl( node->members , *this );457 maybeMutateRef( node->parameters, *this ); 458 maybeMutateRef( node->members , *this ); 501 459 } 502 460 … … 515 473 516 474 // unlike structs, traits, and unions, enums inject their members into the global scope 517 maybeAccept _impl( node->parameters, *this );518 maybeAccept _impl( node->members , *this );475 maybeAccept( node->parameters, *this ); 476 maybeAccept( node->members , *this ); 519 477 520 478 VISIT_END( node ); … … 528 486 529 487 // unlike structs, traits, and unions, enums inject their members into the global scope 530 maybeMutate _impl( node->parameters, *this );531 maybeMutate _impl( node->members , *this );488 maybeMutateRef( node->parameters, *this ); 489 maybeMutateRef( node->members , *this ); 532 490 533 491 MUTATE_END( Declaration, node ); … … 542 500 { 543 501 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 544 maybeAccept _impl( node->parameters, *this );545 maybeAccept _impl( node->members , *this );502 maybeAccept( node->parameters, *this ); 503 maybeAccept( node->members , *this ); 546 504 } 547 505 … … 557 515 { 558 516 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 559 maybeMutate _impl( node->parameters, *this );560 maybeMutate _impl( node->members , *this );517 maybeMutateRef( node->parameters, *this ); 518 maybeMutateRef( node->members , *this ); 561 519 } 562 520 … … 574 532 { 575 533 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 576 maybeAccept _impl( node->parameters, *this );577 maybeAccept _impl( node->base , *this );534 maybeAccept( node->parameters, *this ); 535 maybeAccept( node->base , *this ); 578 536 } 579 537 … … 583 541 indexerAddType( node ); 584 542 585 maybeAccept _impl( node->assertions, *this );543 maybeAccept( node->assertions, *this ); 586 544 587 545 indexerScopedAccept( node->init, *this ); … … 596 554 { 597 555 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 598 maybeMutate _impl( node->parameters, *this );599 maybeMutate _impl( node->base , *this );556 maybeMutateRef( node->parameters, *this ); 557 maybeMutateRef( node->base , *this ); 600 558 } 601 559 … … 605 563 indexerAddType( node ); 606 564 607 maybeMutate _impl( node->assertions, *this );565 maybeMutateRef( node->assertions, *this ); 608 566 609 567 indexerScopedMutate( node->init, *this ); … … 620 578 { 621 579 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 622 maybeAccept _impl( node->parameters, *this );623 maybeAccept _impl( node->base , *this );580 maybeAccept( node->parameters, *this ); 581 maybeAccept( node->base , *this ); 624 582 } 625 583 626 584 indexerAddType( node ); 627 585 628 maybeAccept _impl( node->assertions, *this );586 maybeAccept( node->assertions, *this ); 629 587 630 588 VISIT_END( node ); … … 637 595 { 638 596 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 639 maybeMutate _impl( node->parameters, *this );640 maybeMutate _impl( node->base , *this );597 maybeMutateRef ( node->parameters, *this ); 598 maybeMutateRef( node->base , *this ); 641 599 } 642 600 643 601 indexerAddType( node ); 644 602 645 maybeMutate _impl( node->assertions, *this );603 maybeMutateRef( node->assertions, *this ); 646 604 647 605 MUTATE_END( Declaration, node ); … … 654 612 VISIT_START( node ); 655 613 656 maybeAccept _impl( node->stmt, *this );614 maybeAccept( node->stmt, *this ); 657 615 658 616 VISIT_END( node ); … … 663 621 MUTATE_START( node ); 664 622 665 maybeMutate _impl( node->stmt, *this );623 maybeMutateRef( node->stmt, *this ); 666 624 667 625 MUTATE_END( AsmDecl, node ); … … 732 690 // if statements introduce a level of scope (for the initialization) 733 691 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 734 maybeAccept_impl( node->get_initialization(), *this );735 visitExpression ( node->condition );692 acceptAll( node->get_initialization(), *this ); 693 visitExpression( node->condition ); 736 694 node->thenPart = visitStatement( node->thenPart ); 737 695 node->elsePart = visitStatement( node->elsePart ); … … 746 704 // if statements introduce a level of scope (for the initialization) 747 705 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 748 maybeMutate _impl( node->get_initialization(), *this );706 maybeMutateRef( node->get_initialization(), *this ); 749 707 node->condition = mutateExpression( node->condition ); 750 708 node->thenPart = mutateStatement ( node->thenPart ); … … 784 742 // for statements introduce a level of scope (for the initialization) 785 743 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 786 maybeAccept _impl( node->initialization, *this );744 maybeAccept( node->initialization, *this ); 787 745 visitExpression( node->condition ); 788 746 visitExpression( node->increment ); … … 798 756 // for statements introduce a level of scope (for the initialization) 799 757 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 800 maybeMutate _impl( node->initialization, *this );758 maybeMutateRef( node->initialization, *this ); 801 759 node->condition = mutateExpression( node->condition ); 802 760 node->increment = mutateExpression( node->increment ); … … 901 859 VISIT_START( node ); 902 860 903 maybeAccept _impl( node->block , *this );904 maybeAccept _impl( node->handlers , *this );905 maybeAccept _impl( node->finallyBlock, *this );861 maybeAccept( node->block , *this ); 862 maybeAccept( node->handlers , *this ); 863 maybeAccept( node->finallyBlock, *this ); 906 864 907 865 VISIT_END( node ); … … 912 870 MUTATE_START( node ); 913 871 914 maybeMutate _impl( node->block , *this );915 maybeMutate _impl( node->handlers , *this );916 maybeMutate _impl( node->finallyBlock, *this );872 maybeMutateRef( node->block , *this ); 873 maybeMutateRef( node->handlers , *this ); 874 maybeMutateRef( node->finallyBlock, *this ); 917 875 918 876 MUTATE_END( Statement, node ); … … 927 885 // catch statements introduce a level of scope (for the caught exception) 928 886 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 929 maybeAccept _impl( node->decl, *this );887 maybeAccept( node->decl, *this ); 930 888 node->cond = visitExpression( node->cond ); 931 889 node->body = visitStatement ( node->body ); … … 940 898 // catch statements introduce a level of scope (for the caught exception) 941 899 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 942 maybeMutate _impl( node->decl, *this );900 maybeMutateRef( node->decl, *this ); 943 901 node->cond = mutateExpression( node->cond ); 944 902 node->body = mutateStatement ( node->body ); … … 1014 972 1015 973 indexerScopedAccept( node->result , *this ); 1016 maybeAccept _impl( node->function, *this );1017 maybeAccept _impl( node->args , *this );974 maybeAccept ( node->function, *this ); 975 maybeAccept ( node->args , *this ); 1018 976 1019 977 VISIT_END( node ); … … 1026 984 indexerScopedMutate( node->env , *this ); 1027 985 indexerScopedMutate( node->result , *this ); 1028 maybeMutate _impl( node->function, *this );1029 maybeMutate _impl( node->args , *this );986 maybeMutateRef ( node->function, *this ); 987 maybeMutateRef ( node->args , *this ); 1030 988 1031 989 MUTATE_END( Expression, node ); … … 1038 996 VISIT_START( node ); 1039 997 1040 // maybeAccept _impl( node->get_env(), *this );998 // maybeAccept( node->get_env(), *this ); 1041 999 indexerScopedAccept( node->result, *this ); 1042 1000 … … 1090 1048 1091 1049 indexerScopedAccept( node->result, *this ); 1092 maybeAccept _impl( node->arg , *this );1050 maybeAccept ( node->arg , *this ); 1093 1051 1094 1052 VISIT_END( node ); … … 1101 1059 indexerScopedMutate( node->env , *this ); 1102 1060 indexerScopedMutate( node->result, *this ); 1103 maybeMutate _impl( node->arg , *this );1061 maybeMutateRef ( node->arg , *this ); 1104 1062 1105 1063 MUTATE_END( Expression, node ); … … 1113 1071 1114 1072 indexerScopedAccept( node->result, *this ); 1115 maybeAccept _impl( node->arg, *this );1073 maybeAccept( node->arg, *this ); 1116 1074 1117 1075 VISIT_END( node ); … … 1124 1082 indexerScopedMutate( node->env , *this ); 1125 1083 indexerScopedMutate( node->result, *this ); 1126 maybeMutate _impl( node->arg , *this );1084 maybeMutateRef ( node->arg , *this ); 1127 1085 1128 1086 MUTATE_END( Expression, node ); … … 1136 1094 1137 1095 indexerScopedAccept( node->result, *this ); 1138 maybeAccept _impl( node->arg , *this );1096 maybeAccept ( node->arg , *this ); 1139 1097 1140 1098 VISIT_END( node ); … … 1147 1105 indexerScopedMutate( node->env , *this ); 1148 1106 indexerScopedMutate( node->result, *this ); 1149 maybeMutate _impl( node->arg , *this );1107 maybeMutateRef ( node->arg , *this ); 1150 1108 1151 1109 MUTATE_END( Expression, node ); … … 1180 1138 1181 1139 indexerScopedAccept( node->result , *this ); 1182 maybeAccept _impl( node->aggregate, *this );1183 maybeAccept _impl( node->member , *this );1140 maybeAccept ( node->aggregate, *this ); 1141 maybeAccept ( node->member , *this ); 1184 1142 1185 1143 VISIT_END( node ); … … 1192 1150 indexerScopedMutate( node->env , *this ); 1193 1151 indexerScopedMutate( node->result , *this ); 1194 maybeMutate _impl( node->aggregate, *this );1195 maybeMutate _impl( node->member , *this );1152 maybeMutateRef ( node->aggregate, *this ); 1153 maybeMutateRef ( node->member , *this ); 1196 1154 1197 1155 MUTATE_END( Expression, node ); … … 1205 1163 1206 1164 indexerScopedAccept( node->result , *this ); 1207 maybeAccept _impl( node->aggregate, *this );1165 maybeAccept ( node->aggregate, *this ); 1208 1166 1209 1167 VISIT_END( node ); … … 1216 1174 indexerScopedMutate( node->env , *this ); 1217 1175 indexerScopedMutate( node->result , *this ); 1218 maybeMutate _impl( node->aggregate, *this );1176 maybeMutateRef ( node->aggregate, *this ); 1219 1177 1220 1178 MUTATE_END( Expression, node ); … … 1249 1207 1250 1208 indexerScopedAccept( node->result , *this ); 1251 maybeAccept _impl( &node->constant, *this );1209 maybeAccept ( &node->constant, *this ); 1252 1210 1253 1211 VISIT_END( node ); … … 1260 1218 indexerScopedMutate( node->env , *this ); 1261 1219 indexerScopedMutate( node->result, *this ); 1262 Constant * ptr = &node->constant; 1263 maybeMutate_impl( ptr, *this ); 1264 node->constant = *ptr; 1220 node->constant = *maybeMutate( &node->constant, *this ); 1265 1221 1266 1222 MUTATE_END( Expression, node ); … … 1275 1231 indexerScopedAccept( node->result, *this ); 1276 1232 if ( node->get_isType() ) { 1277 maybeAccept _impl( node->type, *this );1233 maybeAccept( node->type, *this ); 1278 1234 } else { 1279 maybeAccept _impl( node->expr, *this );1235 maybeAccept( node->expr, *this ); 1280 1236 } 1281 1237 … … 1290 1246 indexerScopedMutate( node->result, *this ); 1291 1247 if ( node->get_isType() ) { 1292 maybeMutate _impl( node->type, *this );1248 maybeMutateRef( node->type, *this ); 1293 1249 } else { 1294 maybeMutate _impl( node->expr, *this );1250 maybeMutateRef( node->expr, *this ); 1295 1251 } 1296 1252 … … 1306 1262 indexerScopedAccept( node->result, *this ); 1307 1263 if ( node->get_isType() ) { 1308 maybeAccept _impl( node->type, *this );1264 maybeAccept( node->type, *this ); 1309 1265 } else { 1310 maybeAccept _impl( node->expr, *this );1266 maybeAccept( node->expr, *this ); 1311 1267 } 1312 1268 … … 1321 1277 indexerScopedMutate( node->result, *this ); 1322 1278 if ( node->get_isType() ) { 1323 maybeMutate _impl( node->type, *this );1279 maybeMutateRef( node->type, *this ); 1324 1280 } else { 1325 maybeMutate _impl( node->expr, *this );1281 maybeMutateRef( node->expr, *this ); 1326 1282 } 1327 1283 … … 1336 1292 1337 1293 indexerScopedAccept( node->result, *this ); 1338 maybeAccept _impl( node->type , *this );1294 maybeAccept ( node->type , *this ); 1339 1295 1340 1296 VISIT_END( node ); … … 1347 1303 indexerScopedMutate( node->env , *this ); 1348 1304 indexerScopedMutate( node->result, *this ); 1349 maybeMutate _impl( node->type , *this );1305 maybeMutateRef ( node->type , *this ); 1350 1306 1351 1307 MUTATE_END( Expression, node ); … … 1359 1315 1360 1316 indexerScopedAccept( node->result, *this ); 1361 maybeAccept _impl( node->type , *this );1362 maybeAccept _impl( node->member, *this );1317 maybeAccept ( node->type , *this ); 1318 maybeAccept ( node->member, *this ); 1363 1319 1364 1320 VISIT_END( node ); … … 1371 1327 indexerScopedMutate( node->env , *this ); 1372 1328 indexerScopedMutate( node->result, *this ); 1373 maybeMutate _impl( node->type , *this );1374 maybeMutate _impl( node->member, *this );1329 maybeMutateRef ( node->type , *this ); 1330 maybeMutateRef ( node->member, *this ); 1375 1331 1376 1332 MUTATE_END( Expression, node ); … … 1384 1340 1385 1341 indexerScopedAccept( node->result, *this ); 1386 maybeAccept _impl( node->type , *this );1342 maybeAccept ( node->type , *this ); 1387 1343 1388 1344 VISIT_END( node ); … … 1395 1351 indexerScopedMutate( node->env , *this ); 1396 1352 indexerScopedMutate( node->result, *this ); 1397 maybeMutate _impl( node->type , *this );1353 maybeMutateRef ( node->type , *this ); 1398 1354 1399 1355 MUTATE_END( Expression, node ); … … 1408 1364 indexerScopedAccept( node->result, *this ); 1409 1365 if ( node->get_isType() ) { 1410 maybeAccept _impl( node->type, *this );1366 maybeAccept( node->type, *this ); 1411 1367 } else { 1412 maybeAccept _impl( node->expr, *this );1368 maybeAccept( node->expr, *this ); 1413 1369 } 1414 1370 … … 1423 1379 indexerScopedMutate( node->result, *this ); 1424 1380 if ( node->get_isType() ) { 1425 maybeMutate _impl( node->type, *this );1381 maybeMutateRef( node->type, *this ); 1426 1382 } else { 1427 maybeMutate _impl( node->expr, *this );1383 maybeMutateRef( node->expr, *this ); 1428 1384 } 1429 1385 … … 1438 1394 1439 1395 indexerScopedAccept( node->result, *this ); 1440 maybeAccept _impl( node->arg1 , *this );1441 maybeAccept _impl( node->arg2 , *this );1396 maybeAccept ( node->arg1 , *this ); 1397 maybeAccept ( node->arg2 , *this ); 1442 1398 1443 1399 VISIT_END( node ); … … 1450 1406 indexerScopedMutate( node->env , *this ); 1451 1407 indexerScopedMutate( node->result, *this ); 1452 maybeMutate _impl( node->arg1 , *this );1453 maybeMutate _impl( node->arg2 , *this );1408 maybeMutateRef ( node->arg1 , *this ); 1409 maybeMutateRef ( node->arg2 , *this ); 1454 1410 1455 1411 MUTATE_END( Expression, node ); … … 1463 1419 1464 1420 indexerScopedAccept( node->result, *this ); 1465 maybeAccept _impl( node->arg1 , *this );1466 maybeAccept _impl( node->arg2 , *this );1467 maybeAccept _impl( node->arg3 , *this );1421 maybeAccept ( node->arg1 , *this ); 1422 maybeAccept ( node->arg2 , *this ); 1423 maybeAccept ( node->arg3 , *this ); 1468 1424 1469 1425 VISIT_END( node ); … … 1476 1432 indexerScopedMutate( node->env , *this ); 1477 1433 indexerScopedMutate( node->result, *this ); 1478 maybeMutate _impl( node->arg1 , *this );1479 maybeMutate _impl( node->arg2 , *this );1480 maybeMutate _impl( node->arg3 , *this );1434 maybeMutateRef ( node->arg1 , *this ); 1435 maybeMutateRef ( node->arg2 , *this ); 1436 maybeMutateRef ( node->arg3 , *this ); 1481 1437 1482 1438 MUTATE_END( Expression, node ); … … 1490 1446 1491 1447 indexerScopedAccept( node->result, *this ); 1492 maybeAccept _impl( node->arg1 , *this );1493 maybeAccept _impl( node->arg2 , *this );1448 maybeAccept ( node->arg1 , *this ); 1449 maybeAccept ( node->arg2 , *this ); 1494 1450 1495 1451 VISIT_END( node ); … … 1502 1458 indexerScopedMutate( node->env , *this ); 1503 1459 indexerScopedMutate( node->result, *this ); 1504 maybeMutate _impl( node->arg1 , *this );1505 maybeMutate _impl( node->arg2 , *this );1460 maybeMutateRef ( node->arg1 , *this ); 1461 maybeMutateRef ( node->arg2 , *this ); 1506 1462 1507 1463 MUTATE_END( Expression, node ); … … 1515 1471 1516 1472 indexerScopedAccept( node->result, *this ); 1517 maybeAccept _impl( node->type, *this );1473 maybeAccept ( node->type, *this ); 1518 1474 1519 1475 VISIT_END( node ); … … 1526 1482 indexerScopedMutate( node->env , *this ); 1527 1483 indexerScopedMutate( node->result, *this ); 1528 maybeMutate _impl( node->type , *this );1484 maybeMutateRef ( node->type , *this ); 1529 1485 1530 1486 MUTATE_END( Expression, node ); … … 1538 1494 1539 1495 indexerScopedAccept( node->result , *this ); 1540 maybeAccept _impl( node->inout , *this );1541 maybeAccept _impl( node->constraint, *this );1542 maybeAccept _impl( node->operand , *this );1496 maybeAccept ( node->inout , *this ); 1497 maybeAccept ( node->constraint, *this ); 1498 maybeAccept ( node->operand , *this ); 1543 1499 1544 1500 VISIT_END( node ); … … 1551 1507 indexerScopedMutate( node->env , *this ); 1552 1508 indexerScopedMutate( node->result , *this ); 1553 maybeMutate _impl( node->inout , *this );1554 maybeMutate _impl( node->constraint, *this );1555 maybeMutate _impl( node->operand , *this );1509 maybeMutateRef ( node->inout , *this ); 1510 maybeMutateRef ( node->constraint, *this ); 1511 maybeMutateRef ( node->operand , *this ); 1556 1512 1557 1513 MUTATE_END( Expression, node ); … … 1565 1521 1566 1522 indexerScopedAccept( node->result , *this ); 1567 maybeAccept _impl( node->callExpr , *this );1568 maybeAccept _impl( node->tempDecls , *this );1569 maybeAccept _impl( node->returnDecls, *this );1570 maybeAccept _impl( node->dtors , *this );1523 maybeAccept ( node->callExpr , *this ); 1524 maybeAccept ( node->tempDecls , *this ); 1525 maybeAccept ( node->returnDecls, *this ); 1526 maybeAccept ( node->dtors , *this ); 1571 1527 1572 1528 VISIT_END( node ); … … 1579 1535 indexerScopedMutate( node->env , *this ); 1580 1536 indexerScopedMutate( node->result , *this ); 1581 maybeMutate _impl( node->callExpr , *this );1582 maybeMutate _impl( node->tempDecls , *this );1583 maybeMutate _impl( node->returnDecls, *this );1584 maybeMutate _impl( node->dtors , *this );1537 maybeMutateRef ( node->callExpr , *this ); 1538 maybeMutateRef ( node->tempDecls , *this ); 1539 maybeMutateRef ( node->returnDecls, *this ); 1540 maybeMutateRef ( node->dtors , *this ); 1585 1541 1586 1542 MUTATE_END( Expression, node ); … … 1594 1550 1595 1551 indexerScopedAccept( node->result , *this ); 1596 maybeAccept _impl( node->callExpr, *this );1552 maybeAccept ( node->callExpr, *this ); 1597 1553 1598 1554 VISIT_END( node ); … … 1605 1561 indexerScopedMutate( node->env , *this ); 1606 1562 indexerScopedMutate( node->result , *this ); 1607 maybeMutate _impl( node->callExpr, *this );1563 maybeMutateRef ( node->callExpr, *this ); 1608 1564 1609 1565 MUTATE_END( Expression, node ); … … 1617 1573 1618 1574 indexerScopedAccept( node->result , *this ); 1619 maybeAccept _impl( node->initializer, *this );1575 maybeAccept ( node->initializer, *this ); 1620 1576 1621 1577 VISIT_END( node ); … … 1628 1584 indexerScopedMutate( node->env , *this ); 1629 1585 indexerScopedMutate( node->result , *this ); 1630 maybeMutate _impl( node->initializer, *this );1586 maybeMutateRef ( node->initializer, *this ); 1631 1587 1632 1588 MUTATE_END( Expression, node ); … … 1640 1596 1641 1597 indexerScopedAccept( node->result, *this ); 1642 maybeAccept _impl( node->low , *this );1643 maybeAccept _impl( node->high , *this );1598 maybeAccept ( node->low , *this ); 1599 maybeAccept ( node->high , *this ); 1644 1600 1645 1601 VISIT_END( node ); … … 1652 1608 indexerScopedMutate( node->env , *this ); 1653 1609 indexerScopedMutate( node->result, *this ); 1654 maybeMutate _impl( node->low , *this );1655 maybeMutate _impl( node->high , *this );1610 maybeMutateRef ( node->low , *this ); 1611 maybeMutateRef ( node->high , *this ); 1656 1612 1657 1613 MUTATE_END( Expression, node ); … … 1665 1621 1666 1622 indexerScopedAccept( node->result, *this ); 1667 maybeAccept _impl( node->exprs , *this );1623 maybeAccept ( node->exprs , *this ); 1668 1624 1669 1625 VISIT_END( node ); … … 1676 1632 indexerScopedMutate( node->env , *this ); 1677 1633 indexerScopedMutate( node->result, *this ); 1678 maybeMutate _impl( node->exprs , *this );1634 maybeMutateRef ( node->exprs , *this ); 1679 1635 1680 1636 MUTATE_END( Expression, node ); … … 1688 1644 1689 1645 indexerScopedAccept( node->result, *this ); 1690 maybeAccept _impl( node->exprs , *this );1646 maybeAccept ( node->exprs , *this ); 1691 1647 1692 1648 VISIT_END( node ); … … 1699 1655 indexerScopedMutate( node->env , *this ); 1700 1656 indexerScopedMutate( node->result, *this ); 1701 maybeMutate _impl( node->exprs , *this );1657 maybeMutateRef ( node->exprs , *this ); 1702 1658 1703 1659 MUTATE_END( Expression, node ); … … 1711 1667 1712 1668 indexerScopedAccept( node->result, *this ); 1713 maybeAccept _impl( node->tuple , *this );1669 maybeAccept ( node->tuple , *this ); 1714 1670 1715 1671 VISIT_END( node ); … … 1722 1678 indexerScopedMutate( node->env , *this ); 1723 1679 indexerScopedMutate( node->result, *this ); 1724 maybeMutate _impl( node->tuple , *this );1680 maybeMutateRef ( node->tuple , *this ); 1725 1681 1726 1682 MUTATE_END( Expression, node ); … … 1734 1690 1735 1691 indexerScopedAccept( node->result , *this ); 1736 maybeAccept _impl( node->stmtExpr, *this );1692 maybeAccept ( node->stmtExpr, *this ); 1737 1693 1738 1694 VISIT_END( node ); … … 1745 1701 indexerScopedMutate( node->env , *this ); 1746 1702 indexerScopedMutate( node->result , *this ); 1747 maybeMutate _impl( node->stmtExpr, *this );1703 maybeMutateRef ( node->stmtExpr, *this ); 1748 1704 1749 1705 MUTATE_END( Expression, node ); … … 1762 1718 1763 1719 indexerScopedAccept( node->result , *this ); 1764 maybeAccept _impl( node->statements , *this );1765 maybeAccept _impl( node->returnDecls, *this );1766 maybeAccept _impl( node->dtors , *this );1720 maybeAccept ( node->statements , *this ); 1721 maybeAccept ( node->returnDecls, *this ); 1722 maybeAccept ( node->dtors , *this ); 1767 1723 1768 1724 VISIT_END( node ); … … 1779 1735 1780 1736 indexerScopedMutate( node->result , *this ); 1781 maybeMutate _impl( node->statements , *this );1782 maybeMutate _impl( node->returnDecls, *this );1783 maybeMutate _impl( node->dtors , *this );1737 maybeMutateRef ( node->statements , *this ); 1738 maybeMutateRef ( node->returnDecls, *this ); 1739 maybeMutateRef ( node->dtors , *this ); 1784 1740 1785 1741 MUTATE_END( Expression, node ); … … 1793 1749 1794 1750 indexerScopedAccept( node->result, *this ); 1795 maybeAccept _impl( node->expr , *this );1751 maybeAccept ( node->expr , *this ); 1796 1752 1797 1753 VISIT_END( node ); … … 1804 1760 indexerScopedMutate( node->env , *this ); 1805 1761 indexerScopedMutate( node->result, *this ); 1806 maybeMutate _impl( node->expr , *this );1762 maybeMutateRef ( node->expr , *this ); 1807 1763 1808 1764 MUTATE_END( Expression, node ); … … 1849 1805 { 1850 1806 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1851 maybeAccept _impl( node->forall , *this );1852 maybeAccept _impl( node->parameters, *this );1807 maybeAccept( node->forall , *this ); 1808 maybeAccept( node->parameters, *this ); 1853 1809 } 1854 1810 … … 1864 1820 { 1865 1821 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1866 maybeMutate _impl( node->forall , *this );1867 maybeMutate _impl( node->parameters, *this );1822 maybeMutateRef( node->forall , *this ); 1823 maybeMutateRef( node->parameters, *this ); 1868 1824 } 1869 1825 … … 1881 1837 { 1882 1838 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1883 maybeAccept _impl( node->forall , *this );1884 maybeAccept _impl( node->parameters, *this );1839 maybeAccept( node->forall , *this ); 1840 maybeAccept( node->parameters, *this ); 1885 1841 } 1886 1842 … … 1896 1852 { 1897 1853 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1898 maybeMutate _impl( node->forall , *this );1899 maybeMutate _impl( node->parameters, *this );1854 maybeMutateRef( node->forall , *this ); 1855 maybeMutateRef( node->parameters, *this ); 1900 1856 } 1901 1857 … … 1921 1877 VISIT_START( node ); 1922 1878 1923 maybeAccept _impl( node->forall , *this );1924 maybeAccept _impl( node->parameters, *this );1879 maybeAccept( node->forall , *this ); 1880 maybeAccept( node->parameters, *this ); 1925 1881 1926 1882 VISIT_END( node ); … … 1931 1887 MUTATE_START( node ); 1932 1888 1933 maybeMutate _impl( node->forall , *this );1934 maybeMutate _impl( node->parameters, *this );1889 maybeMutateRef( node->forall , *this ); 1890 maybeMutateRef( node->parameters, *this ); 1935 1891 1936 1892 MUTATE_END( Type, node ); … … 1978 1934 VISIT_START( node ); 1979 1935 1980 maybeAccept _impl( node->get_designators(), *this );1936 maybeAccept( node->get_designators(), *this ); 1981 1937 1982 1938 VISIT_END( node ); … … 1987 1943 MUTATE_START( node ); 1988 1944 1989 maybeMutate _impl( node->get_designators(), *this );1945 maybeMutateRef( node->get_designators(), *this ); 1990 1946 1991 1947 MUTATE_END( Designation, node ); … … 2127 2083 MUTATE_BODY( Attribute, node ); 2128 2084 } 2129 2130 template< typename pass_type >2131 TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {2132 MUTATE_START( node );2133 2134 for ( auto & p : node->typeEnv ) {2135 indexerScopedMutate( p.second, *this );2136 }2137 for ( auto & p : node->varEnv ) {2138 indexerScopedMutate( p.second, *this );2139 }2140 2141 MUTATE_END( TypeSubstitution, node );2142 } -
src/Common/PassVisitor.proto.h
r6840e7c rb96ec83 46 46 ~bool_ref() = default; 47 47 48 operator bool() { return m_ref ? *m_ref : true; }48 operator bool() { return *m_ref; } 49 49 bool operator=( bool val ) { return *m_ref = val; } 50 50 51 51 private: 52 52 53 friend class ChildrenGuard; 54 55 bool * set( bool & val ) { 56 bool * prev = m_ref; 57 m_ref = &val; 58 return prev; 59 } 60 61 bool * m_ref = nullptr; 53 template<typename pass> 54 friend class PassVisitor; 55 56 void set( bool & val ) { m_ref = &val; }; 57 58 bool * m_ref; 62 59 }; 63 60 64 class ChildrenGuard { 65 public: 66 67 ChildrenGuard( bool_ref * ref )68 : m_val ( true )69 , m_prev( ref ? ref->set( m_val ) : nullptr )70 , m_ref ( ref )71 {}72 73 ~ChildrenGuard() { 74 if( m_ref) {75 m_ref->set( *m_prev );76 }77 }78 79 operator bool() { return m_val; }80 81 private: 82 bool m_val; 83 bool * m_prev; 84 bool_ref * m_ref;85 } ;61 template< typename TreeType, typename VisitorType > 62 inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) { 63 auto guard = makeFuncGuard( 64 [&visitor]() { visitor.indexerScopeEnter(); }, 65 [&visitor]() { visitor.indexerScopeLeave(); } 66 ); 67 maybeAccept( tree, visitor ); 68 } 69 70 template< typename TreeType, typename MutatorType > 71 inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) { 72 auto guard = makeFuncGuard( 73 [&mutator]() { mutator.indexerScopeEnter(); }, 74 [&mutator]() { mutator.indexerScopeLeave(); } 75 ); 76 tree = maybeMutate( tree, mutator ); 77 } 78 79 template< typename TreeType, typename MutatorType > 80 inline void maybeMutateRef( TreeType *& tree, MutatorType & mutator ) { 81 tree = maybeMutate( tree, mutator ); 82 } 86 83 87 84 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -
src/Common/utility.h
r6840e7c rb96ec83 28 28 #include <cassert> 29 29 30 #include "Common/Indenter.h"31 32 30 template< typename T > 33 31 static inline T * maybeClone( const T *orig ) { … … 77 75 78 76 template< typename Container > 79 void printAll( const Container &container, std::ostream &os, Indenter indent = {}) {77 void printAll( const Container &container, std::ostream &os, int indent = 0 ) { 80 78 for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) { 81 79 if ( *i ) { 82 os << indent;83 (*i)->print( os, indent );80 os << std::string( indent, ' ' ); 81 (*i)->print( os, indent + 2 ); 84 82 // need an endl after each element because it's not easy to know when each individual item should end 85 83 os << std::endl; … … 353 351 template< typename T1, typename T2 > 354 352 struct group_iterate_t { 355 private:356 std::tuple<T1, T2> args;357 public:358 353 group_iterate_t( bool skipBoundsCheck, const T1 & v1, const T2 & v2 ) : args(v1, v2) { 359 354 assertf(skipBoundsCheck || v1.size() == v2.size(), "group iteration requires containers of the same size: <%zd, %zd>.", v1.size(), v2.size()); 360 355 }; 361 356 362 typedef std::tuple<decltype(*std::get<0>(args).begin()), decltype(*std::get<1>(args).begin())> value_type;363 typedef decltype(std::get<0>(args).begin()) T1Iter;364 typedef decltype(std::get<1>(args).begin()) T2Iter;365 366 357 struct iterator { 358 typedef typename std::remove_reference<T1>::type T1val; 359 typedef typename std::remove_reference<T2>::type T2val; 360 typedef std::tuple<typename T1val::value_type &, typename T2val::value_type &> value_type; 361 typedef typename T1val::iterator T1Iter; 362 typedef typename T2val::iterator T2Iter; 367 363 typedef std::tuple<T1Iter, T2Iter> IterTuple; 368 364 IterTuple it; … … 374 370 value_type operator*() const { return std::tie( *std::get<0>(it), *std::get<1>(it) ); } 375 371 }; 376 377 372 iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); } 378 373 iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); } 374 375 private: 376 std::tuple<T1, T2> args; 379 377 }; 380 378 -
src/Concurrency/Keywords.cc
r6840e7c rb96ec83 196 196 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* ); 197 197 void validate( DeclarationWithType * ); 198 void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);199 198 void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 200 199 … … 207 206 StructDecl* monitor_decl = nullptr; 208 207 StructDecl* guard_decl = nullptr; 209 StructDecl* dtor_guard_decl = nullptr;210 208 211 209 static std::unique_ptr< Type > generic_func; … … 231 229 232 230 void postvisit( FunctionDecl * decl ); 233 void previsit ( StructDecl * decl );234 231 235 232 void addStartStatement( FunctionDecl * decl, DeclarationWithType * param ); … … 239 236 acceptAll( translationUnit, impl ); 240 237 } 241 242 private :243 bool thread_ctor_seen = false;244 StructDecl * thread_decl = nullptr;245 238 }; 246 239 … … 410 403 if( mutexArgs.empty() ) return; 411 404 412 if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl );413 414 bool isDtor = CodeGen::isDestructor( decl->name );415 416 if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl );417 418 405 for(auto arg : mutexArgs) { 419 406 validate( arg ); … … 425 412 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 426 413 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 427 if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 428 429 if( isDtor ) { 430 addDtorStatments( decl, body, mutexArgs ); 431 } 432 else { 433 addStatments( decl, body, mutexArgs ); 434 } 414 415 addStatments( decl, body, mutexArgs ); 435 416 } 436 417 … … 444 425 assert( !guard_decl ); 445 426 guard_decl = decl; 446 }447 else if( decl->name == "monitor_dtor_guard_t" ) {448 assert( !dtor_guard_decl );449 dtor_guard_decl = decl;450 427 } 451 428 } … … 480 457 //Make sure that typed isn't mutex 481 458 if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg ); 482 }483 484 void MutexKeyword::addDtorStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {485 Type * arg_type = args.front()->get_type()->clone();486 arg_type->set_mutex( false );487 488 ObjectDecl * monitors = new ObjectDecl(489 "__monitor",490 noStorage,491 LinkageSpec::Cforall,492 nullptr,493 new PointerType(494 noQualifiers,495 new StructInstType(496 noQualifiers,497 monitor_decl498 )499 ),500 new SingleInit( new UntypedExpr(501 new NameExpr( "get_monitor" ),502 { new CastExpr( new VariableExpr( args.front() ), arg_type ) }503 ))504 );505 506 assert(generic_func);507 508 //in reverse order :509 // monitor_guard_t __guard = { __monitors, #, func };510 body->push_front(511 new DeclStmt( noLabels, new ObjectDecl(512 "__guard",513 noStorage,514 LinkageSpec::Cforall,515 nullptr,516 new StructInstType(517 noQualifiers,518 dtor_guard_decl519 ),520 new ListInit(521 {522 new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ),523 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )524 },525 noDesignators,526 true527 )528 ))529 );530 531 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };532 body->push_front( new DeclStmt( noLabels, monitors) );533 459 } 534 460 … … 597 523 // General entry routine 598 524 //============================================================================================= 599 void ThreadStarter::previsit( StructDecl * decl ) {600 if( decl->name == "thread_desc" && decl->body ) {601 assert( !thread_decl );602 thread_decl = decl;603 }604 }605 606 525 void ThreadStarter::postvisit(FunctionDecl * decl) { 607 526 if( ! CodeGen::isConstructor(decl->name) ) return; 608 609 Type * typeof_this = InitTweak::getTypeofThis(decl->type);610 StructInstType * ctored_type = dynamic_cast< StructInstType * >( typeof_this );611 if( ctored_type && ctored_type->baseStruct == thread_decl ) {612 thread_ctor_seen = true;613 }614 527 615 528 DeclarationWithType * param = decl->get_functionType()->get_parameters().front(); 616 529 auto type = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) ); 617 530 if( type && type->get_baseStruct()->is_thread() ) { 618 if( !thread_decl || !thread_ctor_seen ) {619 throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>");620 }621 622 531 addStartStatement( decl, param ); 623 532 } -
src/Concurrency/Waitfor.cc
r6840e7c rb96ec83 190 190 191 191 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) { 192 Expression * expr =makeOpAssign(192 std::unique_ptr< Expression > expr( makeOpAssign( 193 193 makeOpMember( 194 194 makeOpIndex( … … 199 199 ), 200 200 value 201 ); 202 203 ResolvExpr::findVoidExpression( expr, indexer ); 204 205 return new ExprStmt( noLabels, expr ); 201 ) ); 202 203 return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) ); 206 204 } 207 205 … … 315 313 stmt->push_back( new DeclStmt( noLabels, acceptables) ); 316 314 317 Expression* set = new UntypedExpr(315 UntypedExpr * set = new UntypedExpr( 318 316 new NameExpr( "__builtin_memset" ), 319 317 { … … 324 322 ); 325 323 326 ResolvExpr::findVoidExpression( set, indexer ); 327 328 stmt->push_back( new ExprStmt( noLabels, set ) ); 324 Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer ); 325 delete set; 326 327 stmt->push_back( new ExprStmt( noLabels, resolved_set ) ); 329 328 330 329 return acceptables; … … 347 346 348 347 Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) { 349 Expression * expr= new UntypedExpr(348 Expression * untyped = new UntypedExpr( 350 349 new NameExpr( "?=?" ), 351 350 { … … 355 354 ); 356 355 357 ResolvExpr::findVoidExpression( expr, indexer ); 356 Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer ); 357 delete untyped; 358 358 359 359 return new ExprStmt( noLabels, expr ); … … 379 379 new ListInit( 380 380 map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){ 381 Expression * init= new CastExpr(381 Expression * untyped = new CastExpr( 382 382 new UntypedExpr( 383 383 new NameExpr( "get_monitor" ), … … 393 393 ); 394 394 395 ResolvExpr::findSingleExpression( init, indexer ); 395 Expression * init = ResolvExpr::findSingleExpression( untyped, indexer ); 396 delete untyped; 396 397 return new SingleInit( init ); 397 398 }) -
src/GenPoly/Box.cc
r6840e7c rb96ec83 600 600 601 601 // add size/align for generic types to parameter list 602 if ( ! appExpr->get_function()-> result) return;602 if ( ! appExpr->get_function()->has_result() ) return; 603 603 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() ); 604 604 assert( funcType ); … … 714 714 715 715 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 716 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 717 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 718 719 if ( arg->result->get_lvalue() ) { 720 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 721 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 722 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 723 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 724 // return; 725 // } 726 // } 727 arg = generalizedLvalue( new AddressExpr( arg ) ); 728 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 729 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 730 arg = new CastExpr( arg, param->clone() ); 731 } 732 } else { 733 // use type computed in unification to declare boxed variables 734 Type * newType = param->clone(); 716 assertf( arg->has_result(), "arg does not have result: %s", toString( arg ).c_str() ); 717 if ( isPolyType( param, exprTyVars ) ) { 718 Type * newType = arg->get_result()->clone(); 735 719 if ( env ) env->apply( newType ); 736 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 737 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 738 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 739 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 740 assign->get_args().push_back( new VariableExpr( newObj ) ); 741 assign->get_args().push_back( arg ); 742 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 743 arg = new AddressExpr( new VariableExpr( newObj ) ); 720 std::unique_ptr<Type> manager( newType ); 721 if ( isPolyType( newType ) ) { 722 // if the argument's type is polymorphic, we don't need to box again! 723 return; 724 } else if ( arg->get_result()->get_lvalue() ) { 725 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 726 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 727 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 728 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 729 // return; 730 // } 731 // } 732 arg = generalizedLvalue( new AddressExpr( arg ) ); 733 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 734 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 735 arg = new CastExpr( arg, param->clone() ); 736 } 737 } else { 738 // use type computed in unification to declare boxed variables 739 Type * newType = param->clone(); 740 if ( env ) env->apply( newType ); 741 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 742 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 743 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 744 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 745 assign->get_args().push_back( new VariableExpr( newObj ) ); 746 assign->get_args().push_back( arg ); 747 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 748 arg = new AddressExpr( new VariableExpr( newObj ) ); 749 } // if 744 750 } // if 745 751 } … … 959 965 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) { 960 966 if ( varExpr->get_var()->get_name() == "?[?]" ) { 961 assert( appExpr-> result);967 assert( appExpr->has_result() ); 962 968 assert( appExpr->get_args().size() == 2 ); 963 969 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); … … 993 999 } // if 994 1000 } else if ( varExpr->get_var()->get_name() == "*?" ) { 995 assert( appExpr-> result);1001 assert( appExpr->has_result() ); 996 1002 assert( ! appExpr->get_args().empty() ); 997 1003 if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) { … … 1010 1016 } // if 1011 1017 } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) { 1012 assert( appExpr-> result);1018 assert( appExpr->has_result() ); 1013 1019 assert( appExpr->get_args().size() == 1 ); 1014 1020 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { … … 1030 1036 } // if 1031 1037 } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) { 1032 assert( appExpr-> result);1038 assert( appExpr->has_result() ); 1033 1039 assert( appExpr->get_args().size() == 1 ); 1034 1040 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { … … 1036 1042 } // if 1037 1043 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 1038 assert( appExpr-> result);1044 assert( appExpr->has_result() ); 1039 1045 assert( appExpr->get_args().size() == 2 ); 1040 1046 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); … … 1062 1068 } // if 1063 1069 } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) { 1064 assert( appExpr-> result);1070 assert( appExpr->has_result() ); 1065 1071 assert( appExpr->get_args().size() == 2 ); 1066 1072 Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ); … … 1156 1162 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1157 1163 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1158 assert( addrExpr->get_arg()-> result&& ! addrExpr->get_arg()->get_result()->isVoid() );1164 assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() ); 1159 1165 1160 1166 bool needs = false; 1161 1167 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 1162 if ( expr-> result&& isPolyType( expr->get_result(), scopeTyVars, env ) ) {1168 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1163 1169 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1164 1170 if ( name->get_name() == "*?" ) { 1165 1171 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 1166 assert( appExpr->get_function()-> result);1172 assert( appExpr->get_function()->has_result() ); 1167 1173 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() ); 1168 1174 assert( function ); -
src/GenPoly/FindFunction.cc
r6840e7c rb96ec83 18 18 #include <utility> // for pair 19 19 20 #include "Common/PassVisitor.h" // for PassVisitor21 20 #include "Common/SemanticError.h" // for SemanticError 22 21 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::iterator … … 28 27 29 28 namespace GenPoly { 30 class FindFunction : public WithGuards, public WithVisitorRef<FindFunction>, public WithShortCircuiting{29 class FindFunction : public Mutator { 31 30 public: 32 31 FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ); 33 32 34 void premutate( FunctionType * functionType ); 35 Type * postmutate( FunctionType * functionType ); 36 void premutate( PointerType * pointerType ); 33 virtual Type *mutate( FunctionType *functionType ); 34 virtual Type *mutate( PointerType *pointerType ); 37 35 private: 38 36 void handleForall( const Type::ForallList &forall ); … … 45 43 46 44 void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 47 PassVisitor<FindFunction>finder( functions, tyVars, false, predicate );45 FindFunction finder( functions, tyVars, false, predicate ); 48 46 type->acceptMutator( finder ); 49 47 } 50 48 51 49 void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 52 PassVisitor<FindFunction>finder( functions, tyVars, true, predicate );50 FindFunction finder( functions, tyVars, true, predicate ); 53 51 type = type->acceptMutator( finder ); 54 52 } … … 59 57 60 58 void FindFunction::handleForall( const Type::ForallList &forall ) { 61 for ( const Declaration * td : forall) {62 TyVarMap::iterator var = tyVars.find( td->name);59 for ( Type::ForallList::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 60 TyVarMap::iterator var = tyVars.find( (*i)->get_name() ); 63 61 if ( var != tyVars.end() ) { 64 62 tyVars.erase( var->first ); … … 67 65 } 68 66 69 void FindFunction::premutate( FunctionType * functionType ) { 70 visit_children = false; 71 GuardScope( tyVars ); 67 Type * FindFunction::mutate( FunctionType *functionType ) { 68 tyVars.beginScope(); 72 69 handleForall( functionType->get_forall() ); 73 mutateAll( functionType->get_returnVals(), *visitor ); 74 } 75 76 Type * FindFunction::postmutate( FunctionType * functionType ) { 70 mutateAll( functionType->get_returnVals(), *this ); 77 71 Type *ret = functionType; 78 72 if ( predicate( functionType, tyVars ) ) { … … 83 77 } // if 84 78 } // if 79 tyVars.endScope(); 85 80 return ret; 86 81 } 87 82 88 void FindFunction::premutate( PointerType *pointerType ) {89 GuardScope( tyVars);83 Type * FindFunction::mutate( PointerType *pointerType ) { 84 tyVars.beginScope(); 90 85 handleForall( pointerType->get_forall() ); 86 Type *ret = Mutator::mutate( pointerType ); 87 tyVars.endScope(); 88 return ret; 91 89 } 92 90 } // namespace GenPoly -
src/GenPoly/GenPoly.cc
r6840e7c rb96ec83 432 432 } 433 433 434 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {435 // is parameter is not polymorphic, don't need to box436 if ( ! isPolyType( param, exprTyVars ) ) return false;437 Type * newType = arg->clone();438 if ( env ) env->apply( newType );439 std::unique_ptr<Type> manager( newType );440 // if the argument's type is polymorphic, we don't need to box again!441 return ! isPolyType( newType );442 }443 444 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {445 FunctionType * function = getFunctionType( appExpr->function->result );446 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );447 TyVarMap exprTyVars( TypeDecl::Data{} );448 makeTyVarMap( function, exprTyVars );449 return needsBoxing( param, arg, exprTyVars, env );450 }451 452 434 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 453 435 // xxx - should this actually be insert? -
src/GenPoly/GenPoly.h
r6840e7c rb96ec83 80 80 bool typesPolyCompatible( Type *aty, Type *bty ); 81 81 82 /// true if arg requires boxing given exprTyVars83 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );84 85 /// true if arg requires boxing in the call to appExpr86 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );87 88 82 /// Adds the type variable `tyVar` to `tyVarMap` 89 83 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ); -
src/GenPoly/Specialize.cc
r6840e7c rb96ec83 147 147 148 148 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 149 assertf( actual-> result, "attempting to specialize an untyped expression" );149 assertf( actual->has_result(), "attempting to specialize an untyped expression" ); 150 150 if ( needsSpecialization( formalType, actual->get_result(), env ) ) { 151 151 if ( FunctionType *funType = getFunctionType( formalType ) ) { -
src/GenPoly/module.mk
r6840e7c rb96ec83 20 20 GenPoly/Lvalue.cc \ 21 21 GenPoly/Specialize.cc \ 22 GenPoly/CopyParams.cc \ 22 23 GenPoly/FindFunction.cc \ 23 24 GenPoly/InstantiateGeneric.cc -
src/InitTweak/FixInit.cc
r6840e7c rb96ec83 94 94 /// true if type does not need to be copy constructed to ensure correctness 95 95 bool skipCopyConstruct( Type * type ); 96 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr , Type * formal);96 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 97 97 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 98 98 … … 259 259 260 260 GenStructMemberCalls::generate( translationUnit ); 261 262 261 // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a 263 262 // hack in the way untyped assignments are generated, where the first argument cannot have … … 289 288 for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 290 289 try { 291 maybeMutate( *i, fixer );290 *i = maybeMutate( *i, fixer ); 292 291 translationUnit.splice( i, fixer.pass.staticDtorDecls ); 293 292 } catch( SemanticError &e ) { … … 323 322 324 323 Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) { 324 assert( appExpr ); 325 325 326 if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) { 326 if ( function->var->linkage.is_builtin) {327 if ( LinkageSpec::isBuiltin( function->get_var()->get_linkage() ) ) { 327 328 // optimization: don't need to copy construct in order to call intrinsic functions 328 329 return appExpr; … … 330 331 FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) ); 331 332 assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() ); 332 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype-> parameters.size() == 2 ) {333 Type * t1 = getPointerBase( ftype-> parameters.front()->get_type() );334 Type * t2 = ftype-> parameters.back()->get_type();333 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) { 334 Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() ); 335 Type * t2 = ftype->get_parameters().back()->get_type(); 335 336 assert( t1 ); 336 337 … … 365 366 ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg ); 366 367 ExprStmt * exprStmt = strict_dynamic_cast< ExprStmt * >( stmt->get_callStmt() ); 367 Expression * resolved = exprStmt->expr; 368 exprStmt->expr = nullptr; // take ownership of expr 368 Expression * untyped = exprStmt->get_expr(); 369 369 370 370 // resolve copy constructor 371 371 // should only be one alternative for copy ctor and dtor expressions, since all arguments are fixed 372 372 // (VariableExpr and already resolved expression) 373 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << resolved << std::endl; )374 ResolvExpr::findVoidExpression( resolved, indexer );373 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; ) 374 Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer ); 375 375 assert( resolved ); 376 376 if ( resolved->get_env() ) { … … 380 380 resolved->set_env( nullptr ); 381 381 } // if 382 382 383 delete stmt; 383 384 return resolved; 384 385 } 385 386 386 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr , Type * formal) {387 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) { 387 388 static UniqueName tempNamer("_tmp_cp"); 388 389 assert( env ); 389 390 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; ) 390 assert( arg-> result);391 Type * result = arg-> result;391 assert( arg->has_result() ); 392 Type * result = arg->get_result(); 392 393 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 393 394 394 // type may involve type variables, so apply type substitution to get temporary variable's actual type. 395 // Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T). 395 // type may involve type variables, so apply type substitution to get temporary variable's actual type 396 396 result = result->clone(); 397 env->apply Free( result );397 env->apply( result ); 398 398 ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr ); 399 399 tmp->get_type()->set_const( false ); … … 406 406 // if the chosen constructor is intrinsic, the copy is unnecessary, so 407 407 // don't create the temporary and don't call the copy constructor 408 VariableExpr * function = strict_dynamic_cast< VariableExpr * >( appExpr->function ); 409 if ( function->var->linkage == LinkageSpec::Intrinsic ) { 410 // arguments that need to be boxed need a temporary regardless of whether the copy constructor is intrinsic, 411 // so that the object isn't changed inside of the polymorphic function 412 if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return; 413 } 408 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ); 409 assert( function ); 410 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return; 414 411 } 415 412 … … 419 416 // replace argument to function call with temporary 420 417 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 421 impCpCtorExpr-> tempDecls.push_back( tmp );422 impCpCtorExpr-> dtors.push_front( makeCtorDtor( "^?{}", tmp ) );418 impCpCtorExpr->get_tempDecls().push_back( tmp ); 419 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) ); 423 420 } 424 421 … … 430 427 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 431 428 432 ApplicationExpr * appExpr = impCpCtorExpr-> callExpr;429 ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr(); 433 430 434 431 // take each argument and attempt to copy construct it. 435 FunctionType * ftype = GenPoly::getFunctionType( appExpr->function->result ); 436 assert( ftype ); 437 auto & params = ftype->parameters; 438 auto iter = params.begin(); 439 for ( Expression * & arg : appExpr->args ) { 440 Type * formal = nullptr; 441 if ( iter != params.end() ) { 442 DeclarationWithType * param = *iter++; 443 formal = param->get_type(); 444 } 445 446 copyConstructArg( arg, impCpCtorExpr, formal ); 432 for ( Expression * & arg : appExpr->get_args() ) { 433 copyConstructArg( arg, impCpCtorExpr ); 447 434 } // for 448 435 … … 450 437 // initialized with the return value and is destructed later 451 438 // xxx - handle named return values? 452 Type * result = appExpr-> result;439 Type * result = appExpr->get_result(); 453 440 if ( ! result->isVoid() ) { 454 441 static UniqueName retNamer("_tmp_cp_ret"); … … 456 443 env->apply( result ); 457 444 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr ); 458 ret-> type->set_const( false );459 impCpCtorExpr-> returnDecls.push_back( ret );445 ret->get_type()->set_const( false ); 446 impCpCtorExpr->get_returnDecls().push_back( ret ); 460 447 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 461 448 if ( ! dynamic_cast< ReferenceType * >( result ) ) { … … 564 551 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 565 552 // move env from callExpr to retExpr 566 std::swap( retExpr->env, callExpr->env ); 553 retExpr->set_env( callExpr->get_env() ); 554 callExpr->set_env( nullptr ); 567 555 return retExpr; 568 556 } else { … … 766 754 if ( ctorStmt && (ctorCall = isIntrinsicCallExpr( ctorStmt->expr )) && ctorCall->get_args().size() == 2 ) { 767 755 // clean up intrinsic copy constructor calls by making them into SingleInits 768 Expression * ctorArg = ctorCall->args.back(); 769 std::swap( ctorArg->env, ctorCall->env ); 770 objDecl->init = new SingleInit( ctorArg ); 771 756 objDecl->init = new SingleInit( ctorCall->args.back() ); 772 757 ctorCall->args.pop_back(); 773 758 } else { … … 837 822 GuardValue( labelVars ); 838 823 labelVars.clear(); 839 // LabelFinder does not recurse into FunctionDecl, so need to visit840 // its children manually.841 824 maybeAccept( funcDecl->type, finder ); 842 825 maybeAccept( funcDecl->statements, finder ); … … 1096 1079 } 1097 1080 1098 DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) {1081 DeclarationWithType * MutatingResolver::mutate( ObjectDecl *objectDecl ) { 1099 1082 // add object to the indexer assumes that there will be no name collisions 1100 1083 // in generated code. If this changes, add mutate methods for entities with … … 1104 1087 } 1105 1088 1106 Expression * MutatingResolver::mutate( UntypedExpr * untypedExpr ) { 1107 Expression * newExpr = untypedExpr; 1108 ResolvExpr::findVoidExpression( newExpr, indexer ); 1109 return newExpr; 1089 Expression* MutatingResolver::mutate( UntypedExpr *untypedExpr ) { 1090 return strict_dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untypedExpr, indexer ) ); 1110 1091 } 1111 1092 … … 1113 1094 static UniqueName tempNamer( "_tmp_ctor_expr" ); 1114 1095 // xxx - is the size check necessary? 1115 assert( ctorExpr-> result&& ctorExpr->get_result()->size() == 1 );1096 assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 ); 1116 1097 1117 1098 // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary. … … 1132 1113 1133 1114 // resolve assignment and dispose of new env 1134 ResolvExpr::findVoidExpression( assign, indexer ); 1135 delete assign->env; 1136 assign->env = nullptr; 1115 Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer ); 1116 delete resolvedAssign->env; 1117 resolvedAssign->env = nullptr; 1118 delete assign; 1137 1119 1138 1120 // for constructor expr: … … 1143 1125 // T & tmp; 1144 1126 // &tmp = &x, ?{}(tmp), tmp 1145 CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );1127 CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) ); 1146 1128 commaExpr->set_env( env ); 1147 1129 return commaExpr; -
src/InitTweak/GenInit.cc
r6840e7c rb96ec83 85 85 // should not have a ConstructorInit generated. 86 86 87 ManagedTypes managedTypes; 87 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed 88 bool isManaged( Type * type ) const; // determine if type is managed 89 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor 90 GenPoly::ScopedSet< std::string > managedTypes; 88 91 bool inFunction = false; 89 92 }; … … 126 129 // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address 127 130 // is being returned 128 if ( returnStmt-> expr&& returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {131 if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) { 129 132 // explicitly construct the return value using the return expression and the retVal object 130 assertf( returnVals.front()->name != "", "Function %s has unnamed return value\n", funcName.c_str() ); 131 132 ObjectDecl * retVal = strict_dynamic_cast< ObjectDecl * >( returnVals.front() ); 133 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( returnStmt->expr ) ) { 134 // return statement has already been mutated - don't need to do it again 135 if ( varExpr->var == retVal ) return; 136 } 137 stmtsToAddBefore.push_back( genCtorDtor( "?{}", retVal, returnStmt->get_expr() ) ); 133 assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() ); 134 135 stmtsToAddBefore.push_back( genCtorDtor( "?{}", dynamic_cast< ObjectDecl *>( returnVals.front() ), returnStmt->get_expr() ) ); 138 136 139 137 // return the retVal object 140 returnStmt-> expr = new VariableExpr( returnVals.front() );138 returnStmt->set_expr( new VariableExpr( returnVals.front() ) ); 141 139 } // if 142 140 } … … 201 199 } 202 200 203 bool ManagedTypes::isManaged( Type * type ) const {201 bool CtorDtor::isManaged( Type * type ) const { 204 202 // references are never constructed 205 203 if ( dynamic_cast< ReferenceType * >( type ) ) return false; … … 217 215 } 218 216 219 bool ManagedTypes::isManaged( ObjectDecl * objDecl ) const {217 bool CtorDtor::isManaged( ObjectDecl * objDecl ) const { 220 218 Type * type = objDecl->get_type(); 221 219 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { … … 225 223 } 226 224 227 void ManagedTypes::handleDWT( DeclarationWithType * dwt ) {225 void CtorDtor::handleDWT( DeclarationWithType * dwt ) { 228 226 // if this function is a user-defined constructor or destructor, mark down the type as "managed" 229 227 if ( ! LinkageSpec::isOverridable( dwt->get_linkage() ) && CodeGen::isCtorDtor( dwt->get_name() ) ) { … … 235 233 } 236 234 } 237 238 void ManagedTypes::handleStruct( StructDecl * aggregateDecl ) {239 // don't construct members, but need to take note if there is a managed member,240 // because that means that this type is also managed241 for ( Declaration * member : aggregateDecl->get_members() ) {242 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {243 if ( isManaged( field ) ) {244 StructInstType inst( Type::Qualifiers(), aggregateDecl );245 managedTypes.insert( SymTab::Mangler::mangle( &inst ) );246 break;247 }248 }249 }250 }251 252 void ManagedTypes::beginScope() { managedTypes.beginScope(); }253 void ManagedTypes::endScope() { managedTypes.endScope(); }254 235 255 236 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) { … … 296 277 297 278 void CtorDtor::previsit( ObjectDecl * objDecl ) { 298 managedTypes.handleDWT( objDecl );279 handleDWT( objDecl ); 299 280 // hands off if @=, extern, builtin, etc. 300 281 // even if unmanaged, try to construct global or static if initializer is not constexpr, since this is not legal C 301 if ( tryConstruct( objDecl ) && ( managedTypes.isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {282 if ( tryConstruct( objDecl ) && ( isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) { 302 283 // constructed objects cannot be designated 303 284 if ( isDesignated( objDecl->get_init() ) ) throw SemanticError( "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n", objDecl ); … … 314 295 inFunction = true; 315 296 316 managedTypes.handleDWT( functionDecl );297 handleDWT( functionDecl ); 317 298 318 299 GuardScope( managedTypes ); … … 320 301 for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) { 321 302 for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) { 322 managedTypes.handleDWT( assertion );303 handleDWT( assertion ); 323 304 } 324 305 } … … 330 311 visit_children = false; // do not try to construct and destruct aggregate members 331 312 332 managedTypes.handleStruct( aggregateDecl ); 313 // don't construct members, but need to take note if there is a managed member, 314 // because that means that this type is also managed 315 for ( Declaration * member : aggregateDecl->get_members() ) { 316 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) { 317 if ( isManaged( field ) ) { 318 StructInstType inst( Type::Qualifiers(), aggregateDecl ); 319 managedTypes.insert( SymTab::Mangler::mangle( &inst ) ); 320 break; 321 } 322 } 323 } 333 324 } 334 325 -
src/InitTweak/GenInit.h
r6840e7c rb96ec83 16 16 #pragma once 17 17 18 #include <list> // for list19 #include <string> // for string18 #include <list> // for list 19 #include <string> // for string 20 20 21 #include "SynTree/SynTree.h" // for Visitor Nodes 22 23 #include "GenPoly/ScopedSet.h" // for ScopedSet 21 #include "SynTree/SynTree.h" // for Visitor Nodes 24 22 25 23 namespace InitTweak { … … 35 33 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer 36 34 ConstructorInit * genCtorInit( ObjectDecl * objDecl ); 37 38 class ManagedTypes {39 public:40 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed41 bool isManaged( Type * type ) const; // determine if type is managed42 43 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor44 void handleStruct( StructDecl * aggregateDecl ); // add type to managed if child is managed45 46 void beginScope();47 void endScope();48 private:49 GenPoly::ScopedSet< std::string > managedTypes;50 };51 35 } // namespace 52 36 -
src/InitTweak/InitTweak.cc
r6840e7c rb96ec83 168 168 deleteAll( indices ); 169 169 indices.clear(); 170 }171 172 bool InitExpander::addReference() {173 bool added = false;174 for ( Expression *& expr : cur ) {175 expr = new AddressExpr( expr );176 added = true;177 }178 return added;179 170 } 180 171 … … 279 270 } 280 271 281 Type * getT ypeofThis( FunctionType * ftype ) {282 assertf( ftype, "getT ypeofThis: nullptr ftype" );283 ObjectDecl * thisParam = get ParamThis( ftype );272 Type * getThisType( FunctionType * ftype ) { 273 assertf( ftype, "getThisType: nullptr ftype" ); 274 ObjectDecl * thisParam = getThisParam( ftype ); 284 275 ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( thisParam->type ); 285 276 return refType->base; 286 277 } 287 278 288 ObjectDecl * get ParamThis( FunctionType * ftype ) {289 assertf( ftype, "get ParamThis: nullptr ftype" );279 ObjectDecl * getThisParam( FunctionType * ftype ) { 280 assertf( ftype, "getThisParam: nullptr ftype" ); 290 281 auto & params = ftype->parameters; 291 assertf( ! params.empty(), "get ParamThis: ftype with 0 parameters: %s", toString( ftype ).c_str() );282 assertf( ! params.empty(), "getThisParam: ftype with 0 parameters: %s", toString( ftype ).c_str() ); 292 283 return strict_dynamic_cast< ObjectDecl * >( params.front() ); 293 284 } … … 362 353 assert( expr ); 363 354 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) { 364 return varExpr-> var;355 return varExpr->get_var(); 365 356 } else if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( expr ) ) { 366 return memberExpr-> member;357 return memberExpr->get_member(); 367 358 } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 368 return getCalledFunction( castExpr-> arg);359 return getCalledFunction( castExpr->get_arg() ); 369 360 } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( expr ) ) { 370 361 return handleDerefCalledFunction( untypedExpr ); … … 372 363 return handleDerefCalledFunction( appExpr ); 373 364 } else if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) { 374 return getCalledFunction( addrExpr->arg ); 375 } else if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( expr ) ) { 376 return getCalledFunction( commaExpr->arg2 ); 365 return getCalledFunction( addrExpr->get_arg() ); 377 366 } 378 367 return nullptr; … … 589 578 FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ) { 590 579 FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ); 591 if ( ! function ) return nullptr;592 if ( function-> name != fname ) return nullptr;593 FunctionType * ftype = function-> type;594 if ( ftype-> parameters.size() != 2 ) return nullptr;580 if ( ! function ) return 0; 581 if ( function->get_name() != fname ) return 0; 582 FunctionType * ftype = function->get_functionType(); 583 if ( ftype->get_parameters().size() != 2 ) return 0; 595 584 596 585 Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() ); 597 Type * t2 = ftype-> parameters.back()->get_type();586 Type * t2 = ftype->get_parameters().back()->get_type(); 598 587 assert( t1 ); 599 588 … … 615 604 } 616 605 FunctionDecl * isDefaultConstructor( Declaration * decl ) { 617 if ( isConstructor( decl-> name) ) {606 if ( isConstructor( decl->get_name() ) ) { 618 607 if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) { 619 if ( func-> type->parameters.size() == 1 ) {608 if ( func->get_functionType()->get_parameters().size() == 1 ) { 620 609 return func; 621 610 } -
src/InitTweak/InitTweak.h
r6840e7c rb96ec83 31 31 32 32 /// returns the base type of the first parameter to a constructor/destructor/assignment function 33 Type * getT ypeofThis( FunctionType * ftype );33 Type * getThisType( FunctionType * ftype ); 34 34 35 35 /// returns the first parameter of a constructor/destructor/assignment function 36 ObjectDecl * get ParamThis( FunctionType * ftype );36 ObjectDecl * getThisParam( FunctionType * ftype ); 37 37 38 38 /// transform Initializer into an argument list that can be passed to a call expression … … 105 105 void addArrayIndex( Expression * index, Expression * dimension ); 106 106 void clearArrayIndices(); 107 bool addReference();108 107 109 108 class ExpanderImpl; -
src/MakeLibCfa.cc
r6840e7c rb96ec83 119 119 newDecls.push_back( funcDecl ); 120 120 121 Statement * stmt = nullptr;122 121 switch ( opInfo.type ) { 123 122 case CodeGen::OT_INDEX: … … 129 128 case CodeGen::OT_POSTFIXASSIGN: 130 129 case CodeGen::OT_INFIXASSIGN: 131 // return the recursive call132 stmt = new ReturnStmt( noLabels, newExpr );133 break;134 130 case CodeGen::OT_CTOR: 135 131 case CodeGen::OT_DTOR: 136 // executethe recursive call137 stmt = new ExprStmt( noLabels, newExpr);132 // return the recursive call 133 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) ); 138 134 break; 139 135 case CodeGen::OT_CONSTANT: … … 142 138 assert( false ); 143 139 } // switch 144 funcDecl->get_statements()->push_back( stmt );145 140 } 146 141 } // namespace -
src/Makefile.in
r6840e7c rb96ec83 175 175 GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \ 176 176 GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT) \ 177 GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \ 177 178 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \ 178 179 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \ … … 494 495 ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \ 495 496 GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \ 496 GenPoly/Specialize.cc GenPoly/FindFunction.cc \ 497 GenPoly/InstantiateGeneric.cc InitTweak/GenInit.cc \ 498 InitTweak/FixInit.cc InitTweak/FixGlobalInit.cc \ 499 InitTweak/InitTweak.cc Parser/parser.yy Parser/lex.ll \ 500 Parser/TypedefTable.cc Parser/ParseNode.cc \ 501 Parser/DeclarationNode.cc Parser/ExpressionNode.cc \ 502 Parser/StatementNode.cc Parser/InitializerNode.cc \ 503 Parser/TypeData.cc Parser/LinkageSpec.cc \ 504 Parser/parserutility.cc ResolvExpr/AlternativeFinder.cc \ 505 ResolvExpr/Alternative.cc ResolvExpr/Unify.cc \ 506 ResolvExpr/PtrsAssignable.cc ResolvExpr/CommonType.cc \ 507 ResolvExpr/ConversionCost.cc ResolvExpr/CastCost.cc \ 508 ResolvExpr/PtrsCastable.cc ResolvExpr/AdjustExprType.cc \ 509 ResolvExpr/AlternativePrinter.cc ResolvExpr/Resolver.cc \ 510 ResolvExpr/ResolveTypeof.cc ResolvExpr/RenameVars.cc \ 511 ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \ 512 ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \ 513 ResolvExpr/CurrentObject.cc SymTab/Indexer.cc \ 514 SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \ 515 SymTab/ImplementationType.cc SymTab/TypeEquality.cc \ 516 SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \ 517 SynTree/BasicType.cc SynTree/PointerType.cc \ 518 SynTree/ArrayType.cc SynTree/ReferenceType.cc \ 519 SynTree/FunctionType.cc SynTree/ReferenceToType.cc \ 520 SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \ 497 GenPoly/Specialize.cc GenPoly/CopyParams.cc \ 498 GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \ 499 InitTweak/GenInit.cc InitTweak/FixInit.cc \ 500 InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \ 501 Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \ 502 Parser/ParseNode.cc Parser/DeclarationNode.cc \ 503 Parser/ExpressionNode.cc Parser/StatementNode.cc \ 504 Parser/InitializerNode.cc Parser/TypeData.cc \ 505 Parser/LinkageSpec.cc Parser/parserutility.cc \ 506 ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \ 507 ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \ 508 ResolvExpr/CommonType.cc ResolvExpr/ConversionCost.cc \ 509 ResolvExpr/CastCost.cc ResolvExpr/PtrsCastable.cc \ 510 ResolvExpr/AdjustExprType.cc ResolvExpr/AlternativePrinter.cc \ 511 ResolvExpr/Resolver.cc ResolvExpr/ResolveTypeof.cc \ 512 ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \ 513 ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \ 514 ResolvExpr/TypeEnvironment.cc ResolvExpr/CurrentObject.cc \ 515 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \ 516 SymTab/FixFunction.cc SymTab/ImplementationType.cc \ 517 SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \ 518 SynTree/VoidType.cc SynTree/BasicType.cc \ 519 SynTree/PointerType.cc SynTree/ArrayType.cc \ 520 SynTree/ReferenceType.cc SynTree/FunctionType.cc \ 521 SynTree/ReferenceToType.cc SynTree/TupleType.cc \ 522 SynTree/TypeofType.cc SynTree/AttrType.cc \ 521 523 SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \ 522 524 SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 716 718 GenPoly/$(DEPDIR)/$(am__dirstamp) 717 719 GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT): GenPoly/$(am__dirstamp) \ 720 GenPoly/$(DEPDIR)/$(am__dirstamp) 721 GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT): GenPoly/$(am__dirstamp) \ 718 722 GenPoly/$(DEPDIR)/$(am__dirstamp) 719 723 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT): \ … … 993 997 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@ 994 998 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@ 999 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po@am__quote@ 995 1000 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@ 996 1001 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@ … … 1474 1479 @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` 1475 1480 1481 GenPoly/driver_cfa_cpp-CopyParams.o: GenPoly/CopyParams.cc 1482 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-CopyParams.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo -c -o GenPoly/driver_cfa_cpp-CopyParams.o `test -f 'GenPoly/CopyParams.cc' || echo '$(srcdir)/'`GenPoly/CopyParams.cc 1483 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po 1484 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/CopyParams.cc' object='GenPoly/driver_cfa_cpp-CopyParams.o' libtool=no @AMDEPBACKSLASH@ 1485 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1486 @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-CopyParams.o `test -f 'GenPoly/CopyParams.cc' || echo '$(srcdir)/'`GenPoly/CopyParams.cc 1487 1488 GenPoly/driver_cfa_cpp-CopyParams.obj: GenPoly/CopyParams.cc 1489 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-CopyParams.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo -c -o GenPoly/driver_cfa_cpp-CopyParams.obj `if test -f 'GenPoly/CopyParams.cc'; then $(CYGPATH_W) 'GenPoly/CopyParams.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/CopyParams.cc'; fi` 1490 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po 1491 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/CopyParams.cc' object='GenPoly/driver_cfa_cpp-CopyParams.obj' libtool=no @AMDEPBACKSLASH@ 1492 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1493 @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-CopyParams.obj `if test -f 'GenPoly/CopyParams.cc'; then $(CYGPATH_W) 'GenPoly/CopyParams.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/CopyParams.cc'; fi` 1494 1476 1495 GenPoly/driver_cfa_cpp-FindFunction.o: GenPoly/FindFunction.cc 1477 1496 @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 -
src/Parser/DeclarationNode.cc
r6840e7c rb96ec83 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 12:34:05 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Sep 23 18:16:48201713 // Update Count : 102 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 10 17:02:00 2017 13 // Update Count : 1021 14 14 // 15 15 … … 40 40 using namespace std; 41 41 42 // These must harmonize withthe corresponding DeclarationNode enumerations.43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", " int128", "float80", "float128", "NoBasicTypeNames" };42 // These must remain in the same order as the corresponding DeclarationNode enumerations. 43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "NoBasicTypeNames" }; 44 44 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "_Imaginary", "NoComplexTypeNames" }; 45 45 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" }; -
src/Parser/ExpressionNode.cc
r6840e7c rb96ec83 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Sep 27 22:51:55201713 // Update Count : 78112 // Last Modified On : Thu Sep 14 23:09:34 2017 13 // Update Count : 690 14 14 // 15 15 … … 60 60 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 61 61 62 static const char * lnthsInt[2][6] = {63 { "int8_t", "int16_t", "int32_t", "int64_t", "size_t", },64 { "uint8_t", "uint16_t", "uint32_t", "uint64_t", "size_t", }65 }; // lnthsInt66 67 static inline void checkLNInt( string & str, int & lnth, int & size ) {68 string::size_type posn = str.find_first_of( "lL" ), start = posn;69 if ( posn == string::npos ) return;70 size = 4; // assume largest size71 posn += 1; // advance to size72 if ( str[posn] == '8' ) { // 873 lnth = 0;74 } else if ( str[posn] == '1' ) {75 posn += 1;76 if ( str[posn] == '6' ) { // 1677 lnth = 1;78 } else { // 12879 posn += 1;80 lnth = 5;81 } // if82 } else {83 if ( str[posn] == '3' ) { // 3284 lnth = 2;85 } else if ( str[posn] == '6' ) { // 6486 lnth = 3;87 } else {88 assertf( false, "internal error, bad integral length %s", str.c_str() );89 } // if90 posn += 1;91 } // if92 str.erase( start, posn - start + 1 ); // remove length suffix93 } // checkLNInt94 95 62 static void sepNumeric( string & str, string & units ) { 96 63 string::size_type posn = str.find_first_of( "`" ); … … 102 69 103 70 Expression * build_constantInteger( string & str ) { 104 static const BasicType::Kind kind[2][ 6] = {71 static const BasicType::Kind kind[2][5] = { 105 72 // short (h) must be before char (hh) 106 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt , BasicType::SignedInt128,},107 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt , BasicType::UnsignedInt128,},73 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt }, 74 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt }, 108 75 }; 109 76 110 string units; 77 string units; // units 111 78 sepNumeric( str, units ); // separate constant from units 112 79 113 80 bool dec = true, Unsigned = false; // decimal, unsigned constant 114 int size; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 115 int lnth = -1; // literal length 116 81 int size; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => size_t 117 82 unsigned long long int v; // converted integral value 118 83 size_t last = str.length() - 1; // last character of constant … … 175 140 } // if 176 141 str.erase( last - size - 1, size + 1 ); // remove 'h'/"hh" 177 } else { // suffix "ln" ?178 checkLNInt( str, lnth, size );179 142 } // if 180 143 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ? … … 200 163 str.erase( last - size, size + 1 ); // remove 'h'/"hh" 201 164 } else if ( checkZ( str[last] ) ) { // suffix 'z' ? 202 lnth = 4;165 size = 5; 203 166 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. 167 } // if 168 210 169 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 unfortunatelyeliminates warnings for large values.170 if ( Unsigned && size < 2 ) { // less than int ? 171 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which eliminates warnings for large values. 213 172 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) ); 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] ) ); 218 } else { 219 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ) ); 220 } // if 173 } else if ( size == 5 ) { // explicit cast to size_t 174 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), "size_t", false ) ); 221 175 } // if 222 176 CLEANUP: … … 228 182 return ret; 229 183 } // build_constantInteger 230 231 232 static inline void checkLNFloat( string & str, int & lnth, int & size ) {233 string::size_type posn = str.find_first_of( "lL" ), start = posn;234 if ( posn == string::npos ) return;235 size = 2; // assume largest size236 lnth = 0;237 posn += 1; // advance to size238 if ( str[posn] == '3' ) { // 32239 size = 0;240 } else if ( str[posn] == '6' ) { // 64241 size = 1;242 } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128243 size = 2;244 if ( str[posn] == '1' ) posn += 1;245 } else {246 assertf( false, "internal error, bad floating point length %s", str.c_str() );247 } // if248 posn += 1;249 str.erase( start, posn - start + 1 ); // remove length suffix250 } // checkLNFloat251 252 184 253 185 Expression * build_constantFloat( string & str ) { … … 257 189 }; 258 190 259 string units; 191 string units; // units 260 192 sepNumeric( str, units ); // separate constant from units 261 193 262 194 bool complx = false; // real, complex 263 int size = 1; // 0 => float, 1 => double, 2 => long double 264 int lnth = -1; // literal length 195 int size = 1; // 0 => float, 1 => double (default), 2 => long double 265 196 // floating-point constant has minimum of 2 characters: 1. or .1 266 197 size_t last = str.length() - 1; … … 280 211 } else if ( checkL( str[last] ) ) { // long double ? 281 212 size = 2; 282 } else {283 size = 1; // double (default)284 checkLNFloat( str, lnth, size );285 213 } // if 286 214 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ? … … 288 216 } // if 289 217 290 assert( 0 <= size && size < 3 );291 218 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) ); 292 if ( lnth != -1 ) { // explicit length ?293 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ) );294 } // if295 219 if ( units.length() != 0 ) { 296 220 ret = new UntypedExpr( new NameExpr( units ), { ret } ); … … 397 321 398 322 NameExpr * build_varref( const string * name ) { 399 NameExpr * expr = new NameExpr( *name );323 NameExpr * expr = new NameExpr( *name, nullptr ); 400 324 delete name; 401 325 return expr; … … 488 412 list< Expression * > args; 489 413 buildMoveList( expr_node, args ); 490 return new UntypedExpr( maybeMoveBuild< Expression >(function), args );414 return new UntypedExpr( maybeMoveBuild< Expression >(function), args, nullptr ); 491 415 } // build_func 492 416 -
src/Parser/ParseNode.h
r6840e7c rb96ec83 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Sep 23 18:11:22201713 // Update Count : 8 2112 // Last Modified On : Thu Sep 14 23:09:39 2017 13 // Update Count : 815 14 14 // 15 15 … … 47 47 #define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */ 48 48 49 extern char * yyfilename; 50 extern int yylineno; 49 51 extern YYLTYPE yylloc; 50 52 … … 195 197 class DeclarationNode : public ParseNode { 196 198 public: 197 // These enumerations must harmonize with their names. 198 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType }; 199 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType }; 200 enum ComplexType { Complex, Imaginary, NoComplexType }; 201 enum Signedness { Signed, Unsigned, NoSignedness }; 202 enum Length { Short, Long, LongLong, NoLength }; 203 enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate }; 204 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass }; 205 enum BuiltinType { Valist, Zero, One, NoBuiltinType }; 206 199 207 static const char * basicTypeNames[]; 200 enum ComplexType { Complex, Imaginary, NoComplexType };201 208 static const char * complexTypeNames[]; 202 enum Signedness { Signed, Unsigned, NoSignedness };203 209 static const char * signednessNames[]; 204 enum Length { Short, Long, LongLong, NoLength };205 210 static const char * lengthNames[]; 206 enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };207 211 static const char * aggregateNames[]; 208 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };209 212 static const char * typeClassNames[]; 210 enum BuiltinType { Valist, Zero, One, NoBuiltinType };211 213 static const char * builtinTypeNames[]; 212 214 -
src/Parser/TypeData.cc
r6840e7c rb96ec83 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 18:33:41201713 // Update Count : 5 8712 // Last Modified On : Fri Sep 1 23:13:38 2017 13 // Update Count : 569 14 14 // 15 15 … … 98 98 } // TypeData::TypeData 99 99 100 101 100 TypeData::~TypeData() { 102 101 delete base; … … 162 161 } // switch 163 162 } // TypeData::~TypeData 164 165 163 166 164 TypeData * TypeData::clone() const { … … 237 235 } // TypeData::clone 238 236 239 240 237 void TypeData::print( ostream &os, int indent ) const { 241 238 for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) { … … 401 398 } // switch 402 399 } // TypeData::print 403 404 400 405 401 template< typename ForallList > … … 434 430 } // if 435 431 } // for 436 } // buildForall 437 432 } 438 433 439 434 Type * typebuild( const TypeData * td ) { … … 482 477 } // typebuild 483 478 484 485 479 TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) { 486 480 TypeData * ret = nullptr; … … 510 504 } // typeextractAggregate 511 505 512 513 506 Type::Qualifiers buildQualifiers( const TypeData * td ) { 514 507 return td->qualifiers; 515 508 } // buildQualifiers 516 509 517 518 static string genTSError( string msg, DeclarationNode::BasicType basictype ) {519 throw SemanticError( string( "invalid type specifier \"" ) + msg + "\" for type \"" + DeclarationNode::basicTypeNames[basictype] + "\"." );520 } // genTSError521 522 510 Type * buildBasicType( const TypeData * td ) { 523 511 BasicType::Kind ret; … … 525 513 switch ( td->basictype ) { 526 514 case DeclarationNode::Void: 527 if ( td->signedness != DeclarationNode::NoSignedness ) { 528 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); 529 } // if 530 if ( td->length != DeclarationNode::NoLength ) { 531 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 532 } // if 515 if ( td->signedness != DeclarationNode::NoSignedness && td->length != DeclarationNode::NoLength ) { 516 throw SemanticError( "invalid type specifier \"void\" in type: ", td ); 517 } // if 518 533 519 return new VoidType( buildQualifiers( td ) ); 534 520 break; … … 536 522 case DeclarationNode::Bool: 537 523 if ( td->signedness != DeclarationNode::NoSignedness ) { 538 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype);524 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessNames[ td->signedness ] + " in type: ", td ); 539 525 } // if 540 526 if ( td->length != DeclarationNode::NoLength ) { 541 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype);527 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td ); 542 528 } // if 543 529 … … 552 538 553 539 if ( td->length != DeclarationNode::NoLength ) { 554 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype);540 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td ); 555 541 } // if 556 542 … … 571 557 break; 572 558 573 case DeclarationNode::Int128:574 ret = td->signedness == 1 ? BasicType::UnsignedInt128 : BasicType::SignedInt128;575 if ( td->length != DeclarationNode::NoLength ) {576 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );577 } // if578 break;579 580 559 case DeclarationNode::Float: 581 case DeclarationNode::Float80:582 case DeclarationNode::Float128:583 560 case DeclarationNode::Double: 584 561 case DeclarationNode::LongDouble: // not set until below … … 591 568 FloatingPoint: ; 592 569 if ( td->signedness != DeclarationNode::NoSignedness ) { 593 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype);570 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessNames[ td->signedness ] + " in type: ", td ); 594 571 } // if 595 572 if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) { 596 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype);573 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthNames[ td->length ] + " in type: ", td ); 597 574 } // if 598 575 if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) { 599 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype);576 throw SemanticError( "invalid type specifier \"long\" in type: ", td ); 600 577 } // if 601 578 if ( td->length == DeclarationNode::Long ) { … … 616 593 goto Integral; 617 594 default: 618 assert f( false, "unknown basic type");595 assert(false); 619 596 return nullptr; 620 597 } // switch … … 624 601 return bt; 625 602 } // buildBasicType 626 627 603 628 604 PointerType * buildPointer( const TypeData * td ) { … … 636 612 return pt; 637 613 } // buildPointer 638 639 614 640 615 ArrayType * buildArray( const TypeData * td ) { … … 651 626 } // buildArray 652 627 653 654 628 ReferenceType * buildReference( const TypeData * td ) { 655 629 ReferenceType * rt; … … 663 637 } // buildReference 664 638 665 666 639 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 667 640 assert( td->kind == TypeData::Aggregate ); … … 692 665 return at; 693 666 } // buildAggregate 694 695 667 696 668 ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { … … 750 722 } // buildAggInst 751 723 752 753 724 ReferenceToType * buildAggInst( const TypeData * td ) { 754 725 assert( td->kind == TypeData::AggregateInst ); … … 790 761 } // buildAggInst 791 762 792 793 763 NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) { 794 764 assert( td->kind == TypeData::Symbolic ); … … 805 775 } // buildSymbolic 806 776 807 808 777 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 809 778 assert( td->kind == TypeData::Enum ); … … 821 790 } // buildEnum 822 791 823 824 792 TypeInstType * buildSymbolicInst( const TypeData * td ) { 825 793 assert( td->kind == TypeData::SymbolicInst ); … … 829 797 return ret; 830 798 } // buildSymbolicInst 831 832 799 833 800 TupleType * buildTuple( const TypeData * td ) { … … 840 807 } // buildTuple 841 808 842 843 809 TypeofType * buildTypeof( const TypeData * td ) { 844 810 assert( td->kind == TypeData::Typeof ); … … 847 813 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() ); 848 814 } // buildTypeof 849 850 815 851 816 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) { … … 871 836 return nullptr; 872 837 } // buildDecl 873 874 838 875 839 FunctionType * buildFunction( const TypeData * td ) { … … 893 857 return ft; 894 858 } // buildFunction 895 896 859 897 860 // Transform KR routine declarations into C99 routine declarations: -
src/Parser/lex.ll
r6840e7c rb96ec83 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : S at Sep 23 17:29:28201713 * Update Count : 6 3212 * Last Modified On : Sun Sep 10 22:29:15 2017 13 * Update Count : 620 14 14 */ 15 15 … … 93 93 // numeric constants, CFA: '_' in constant 94 94 hex_quad {hex}("_"?{hex}){3} 95 size_opt (8|16|32|64|128)? 96 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hH]) 95 length ("ll"|"LL"|[lL])|("hh"|"HH"|[hH]) 97 96 integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?{user_suffix_opt} 98 97 … … 110 109 // GCC: D (double) and iI (imaginary) suffixes, and DL (long double) 111 110 exponent "_"?[eE]"_"?[+-]?{decimal_digits} 112 floating_size 32|64|80|128 113 floating_length ([fFdDlL]|[lL]{floating_size}) 114 floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length}) 111 floating_suffix ([fFdDlL]?[iI]?)|([iI][lLfFdD]) 115 112 floating_suffix_opt ("_"?({floating_suffix}|"DL"))?{user_suffix_opt} 116 113 decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal}) … … 237 234 finally { KEYWORD_RETURN(FINALLY); } // CFA 238 235 float { KEYWORD_RETURN(FLOAT); } 239 __float80 { KEYWORD_RETURN(FLOAT80); } // GCC 240 float80 { KEYWORD_RETURN(FLOAT80); } // GCC 241 __float128 { KEYWORD_RETURN(FLOAT128); } // GCC 242 float128 { KEYWORD_RETURN(FLOAT128); } // GCC 236 __float128 { KEYWORD_RETURN(FLOAT); } // GCC 243 237 for { KEYWORD_RETURN(FOR); } 244 238 forall { KEYWORD_RETURN(FORALL); } // CFA … … 255 249 __inline__ { KEYWORD_RETURN(INLINE); } // GCC 256 250 int { KEYWORD_RETURN(INT); } 257 __int128 { KEYWORD_RETURN(INT 128); } // GCC258 int128 { KEYWORD_RETURN(INT128); } // GCC251 __int128 { KEYWORD_RETURN(INT); } // GCC 252 __int128_t { KEYWORD_RETURN(INT); } // GCC 259 253 __label__ { KEYWORD_RETURN(LABEL); } // GCC 260 254 long { KEYWORD_RETURN(LONG); } … … 291 285 __typeof { KEYWORD_RETURN(TYPEOF); } // GCC 292 286 __typeof__ { KEYWORD_RETURN(TYPEOF); } // GCC 287 __uint128_t { KEYWORD_RETURN(INT); } // GCC 293 288 union { KEYWORD_RETURN(UNION); } 294 289 unsigned { KEYWORD_RETURN(UNSIGNED); } -
src/Parser/parser.yy
r6840e7c rb96ec83 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Oct 16 11:07:29201713 // Update Count : 28 9212 // Last Modified On : Thu Sep 14 23:07:12 2017 13 // Update Count : 2815 14 14 // 15 15 … … 43 43 #define YYDEBUG_LEXER_TEXT (yylval) // lexer loads this up each time 44 44 #define YYDEBUG 1 // get the pretty debugging code to compile 45 #define YYERROR_VERBOSE // more information in syntax errors45 #define YYERROR_VERBOSE 46 46 47 47 #undef __GNUC_MINOR__ … … 117 117 bool forall = false; // aggregate have one or more forall qualifiers ? 118 118 119 // https://www.gnu.org/software/bison/manual/bison.html#Location-Type 120 #define YYLLOC_DEFAULT(Cur, Rhs, N) \ 121 if ( N ) { \ 122 (Cur).first_line = YYRHSLOC( Rhs, 1 ).first_line; \ 123 (Cur).first_column = YYRHSLOC( Rhs, 1 ).first_column; \ 124 (Cur).last_line = YYRHSLOC( Rhs, N ).last_line; \ 125 (Cur).last_column = YYRHSLOC( Rhs, N ).last_column; \ 126 (Cur).filename = YYRHSLOC( Rhs, 1 ).filename; \ 127 } else { \ 128 (Cur).first_line = (Cur).last_line = YYRHSLOC( Rhs, 0 ).last_line; \ 129 (Cur).first_column = (Cur).last_column = YYRHSLOC( Rhs, 0 ).last_column; \ 130 (Cur).filename = YYRHSLOC( Rhs, 0 ).filename; \ 131 } 119 # define YYLLOC_DEFAULT(Cur, Rhs, N) \ 120 do \ 121 if (N) { \ 122 (Cur).first_line = YYRHSLOC(Rhs, 1).first_line; \ 123 (Cur).first_column = YYRHSLOC(Rhs, 1).first_column; \ 124 (Cur).last_line = YYRHSLOC(Rhs, N).last_line; \ 125 (Cur).last_column = YYRHSLOC(Rhs, N).last_column; \ 126 (Cur).filename = YYRHSLOC(Rhs, 1).filename; \ 127 } else { \ 128 (Cur).first_line = (Cur).last_line = \ 129 YYRHSLOC(Rhs, 0).last_line; \ 130 (Cur).first_column = (Cur).last_column = \ 131 YYRHSLOC(Rhs, 0).last_column; \ 132 (Cur).filename = YYRHSLOC(Rhs, 0).filename; \ 133 } \ 134 while (0) 132 135 %} 133 136 134 137 %define parse.error verbose 135 138 136 // Types declaration for productions139 // Types declaration 137 140 %union 138 141 { … … 170 173 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 171 174 %token BOOL COMPLEX IMAGINARY // C99 172 %token INT128 FLOAT80 FLOAT128 // GCC173 175 %token ZERO_T ONE_T // CFA 174 176 %token VALIST // GCC … … 250 252 %type<sn> exception_statement handler_clause finally_clause 251 253 %type<catch_kind> handler_key 252 %type<sn> mutex_statement253 254 %type<en> when_clause when_clause_opt waitfor timeout 254 255 %type<sn> waitfor_statement … … 457 458 | '(' compound_statement ')' // GCC, lambda expression 458 459 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >($2) ) ) ); } 460 | primary_expression '{' argument_expression_list '}' // CFA, constructor call 461 { 462 Token fn; 463 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 464 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 465 } 459 466 | type_name '.' no_attr_identifier // CFA, nested type 460 467 { $$ = nullptr; } // FIX ME … … 471 478 // equivalent to the old x[i,j]. 472 479 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $4 ) ); } 473 | postfix_expression '{' argument_expression_list '}' // CFA, constructor call474 {475 Token fn;476 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'?477 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );478 }479 480 | postfix_expression '(' argument_expression_list ')' 480 481 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } … … 808 809 | jump_statement 809 810 | with_statement 810 | mutex_statement811 811 | waitfor_statement 812 812 | exception_statement … … 1033 1033 ; 1034 1034 1035 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex".1036 mutex_statement:1037 MUTEX '(' argument_expression_list ')' statement1038 { $$ = nullptr; } // FIX ME1039 ;1040 1041 1035 when_clause: 1042 1036 WHEN '(' comma_expression ')' … … 1557 1551 | VOLATILE 1558 1552 { $$ = DeclarationNode::newTypeQualifier( Type::Volatile ); } 1553 | MUTEX 1554 { $$ = DeclarationNode::newTypeQualifier( Type::Mutex ); } 1559 1555 | ATOMIC 1560 1556 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } … … 1610 1606 1611 1607 basic_type_name: 1612 VOID 1608 CHAR 1609 { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); } 1610 | DOUBLE 1611 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); } 1612 | FLOAT 1613 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); } 1614 | INT 1615 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); } 1616 | LONG 1617 { $$ = DeclarationNode::newLength( DeclarationNode::Long ); } 1618 | SHORT 1619 { $$ = DeclarationNode::newLength( DeclarationNode::Short ); } 1620 | SIGNED 1621 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Signed ); } 1622 | UNSIGNED 1623 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); } 1624 | VOID 1613 1625 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 1614 1626 | BOOL // C99 1615 1627 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 1616 | CHAR1617 { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }1618 | INT1619 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); }1620 | INT1281621 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 ); }1622 | FLOAT1623 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }1624 | FLOAT801625 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float80 ); }1626 | FLOAT1281627 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float128 ); }1628 | DOUBLE1629 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }1630 1628 | COMPLEX // C99 1631 1629 { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); } 1632 1630 | IMAGINARY // C99 1633 1631 { $$ = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); } 1634 | SIGNED1635 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Signed ); }1636 | UNSIGNED1637 { $$ = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); }1638 | SHORT1639 { $$ = DeclarationNode::newLength( DeclarationNode::Short ); }1640 | LONG1641 { $$ = DeclarationNode::newLength( DeclarationNode::Long ); }1642 1632 | ZERO_T 1643 1633 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); } … … 2709 2699 paren_identifier attribute_list_opt 2710 2700 { $$ = $1->addQualifiers( $2 ); } 2711 | '&' MUTEX paren_identifier attribute_list_opt2712 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); }2713 2701 | identifier_parameter_ptr 2714 2702 | identifier_parameter_array attribute_list_opt … … 2751 2739 // 2752 2740 // typedef int foo; 2753 // forall( otype T ) foo( T );2754 2741 // int f( int foo ); // redefine typedef name in new scope 2755 2742 // … … 2759 2746 typedef attribute_list_opt 2760 2747 { $$ = $1->addQualifiers( $2 ); } 2761 | '&' MUTEX typedef attribute_list_opt2762 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); }2763 2748 | type_parameter_ptr 2764 2749 | type_parameter_array attribute_list_opt … … 2907 2892 abstract_parameter_declarator: 2908 2893 abstract_parameter_ptr 2909 | '&' MUTEX attribute_list_opt2910 { $$ = DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf )->addQualifiers( $3 ); }2911 2894 | abstract_parameter_array attribute_list_opt 2912 2895 { $$ = $1->addQualifiers( $2 ); } -
src/ResolvExpr/AdjustExprType.cc
r6840e7c rb96ec83 14 14 // 15 15 16 #include "Common/PassVisitor.h"17 16 #include "SymTab/Indexer.h" // for Indexer 18 17 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Kind::Ftype … … 22 21 23 22 namespace ResolvExpr { 24 class AdjustExprType : public WithShortCircuiting { 23 class AdjustExprType : public Mutator { 24 typedef Mutator Parent; 25 using Parent::mutate; 25 26 public: 26 27 AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer ); 27 void premutate( VoidType * ) { visit_children = false; } 28 void premutate( BasicType * ) { visit_children = false; } 29 void premutate( PointerType * ) { visit_children = false; } 30 void premutate( FunctionType * ) { visit_children = false; } 31 void premutate( StructInstType * ) { visit_children = false; } 32 void premutate( UnionInstType * ) { visit_children = false; } 33 void premutate( EnumInstType * ) { visit_children = false; } 34 void premutate( TraitInstType * ) { visit_children = false; } 35 void premutate( TypeInstType * ) { visit_children = false; } 36 void premutate( TupleType * ) { visit_children = false; } 37 void premutate( VarArgsType * ) { visit_children = false; } 38 void premutate( ZeroType * ) { visit_children = false; } 39 void premutate( OneType * ) { visit_children = false; } 28 private: 29 virtual Type* mutate( VoidType *voidType ); 30 virtual Type* mutate( BasicType *basicType ); 31 virtual Type* mutate( PointerType *pointerType ); 32 virtual Type* mutate( ArrayType *arrayType ); 33 virtual Type* mutate( FunctionType *functionType ); 34 virtual Type* mutate( StructInstType *aggregateUseType ); 35 virtual Type* mutate( UnionInstType *aggregateUseType ); 36 virtual Type* mutate( EnumInstType *aggregateUseType ); 37 virtual Type* mutate( TraitInstType *aggregateUseType ); 38 virtual Type* mutate( TypeInstType *aggregateUseType ); 39 virtual Type* mutate( TupleType *tupleType ); 40 virtual Type* mutate( VarArgsType *varArgsType ); 41 virtual Type* mutate( ZeroType *zeroType ); 42 virtual Type* mutate( OneType *oneType ); 40 43 41 Type * postmutate( ArrayType *arrayType );42 Type * postmutate( FunctionType *functionType );43 Type * postmutate( TypeInstType *aggregateUseType );44 45 private:46 44 const TypeEnvironment &env; 47 45 const SymTab::Indexer &indexer; … … 49 47 50 48 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 51 PassVisitor<AdjustExprType>adjuster( env, indexer );49 AdjustExprType adjuster( env, indexer ); 52 50 Type *newType = type->acceptMutator( adjuster ); 53 51 type = newType; … … 58 56 } 59 57 60 Type * AdjustExprType::postmutate( ArrayType * arrayType ) { 58 Type *AdjustExprType::mutate( VoidType *voidType ) { 59 return voidType; 60 } 61 62 Type *AdjustExprType::mutate( BasicType *basicType ) { 63 return basicType; 64 } 65 66 Type *AdjustExprType::mutate( PointerType *pointerType ) { 67 return pointerType; 68 } 69 70 Type *AdjustExprType::mutate( ArrayType *arrayType ) { 61 71 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 62 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base ); 63 arrayType->base = nullptr; 72 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ) ); 64 73 delete arrayType; 65 74 return pointerType; 66 75 } 67 76 68 Type * AdjustExprType::postmutate( FunctionType * functionType ) { 69 return new PointerType( Type::Qualifiers(), functionType ); 77 Type *AdjustExprType::mutate( FunctionType *functionType ) { 78 PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType ); 79 return pointerType; 70 80 } 71 81 72 Type * AdjustExprType::postmutate( TypeInstType * typeInst ) { 82 Type *AdjustExprType::mutate( StructInstType *aggregateUseType ) { 83 return aggregateUseType; 84 } 85 86 Type *AdjustExprType::mutate( UnionInstType *aggregateUseType ) { 87 return aggregateUseType; 88 } 89 90 Type *AdjustExprType::mutate( EnumInstType *aggregateUseType ) { 91 return aggregateUseType; 92 } 93 94 Type *AdjustExprType::mutate( TraitInstType *aggregateUseType ) { 95 return aggregateUseType; 96 } 97 98 Type *AdjustExprType::mutate( TypeInstType *typeInst ) { 73 99 EqvClass eqvClass; 74 100 if ( env.lookup( typeInst->get_name(), eqvClass ) ) { … … 87 113 return typeInst; 88 114 } 115 116 Type *AdjustExprType::mutate( TupleType *tupleType ) { 117 return tupleType; 118 } 119 120 Type *AdjustExprType::mutate( VarArgsType *varArgsType ) { 121 return varArgsType; 122 } 123 124 Type *AdjustExprType::mutate( ZeroType *zeroType ) { 125 return zeroType; 126 } 127 128 Type *AdjustExprType::mutate( OneType *oneType ) { 129 return oneType; 130 } 89 131 } // namespace ResolvExpr 90 132 -
src/ResolvExpr/Alternative.cc
r6840e7c rb96ec83 66 66 } 67 67 68 void Alternative::print( std::ostream &os, Indenterindent ) const {69 os << "Cost " << cost << ": ";68 void Alternative::print( std::ostream &os, int indent ) const { 69 os << std::string( indent, ' ' ) << "Cost " << cost << ": "; 70 70 if ( expr ) { 71 expr->print( os, indent +1);72 os << std::endl << indent <<"(types:" << std::endl;73 os << indent+1;74 expr-> result->print( os, indent+1);75 os << std::endl << indent <<")" << std::endl;71 expr->print( os, indent ); 72 os << "(types:" << std::endl; 73 os << std::string( indent+4, ' ' ); 74 expr->get_result()->print( os, indent + 4 ); 75 os << std::endl << ")" << std::endl; 76 76 } else { 77 77 os << "Null expression!" << std::endl; 78 78 } // if 79 os << indent<< "Environment: ";80 env.print( os, indent+ 1);79 os << std::string( indent, ' ' ) << "Environment: "; 80 env.print( os, indent+2 ); 81 81 os << std::endl; 82 82 } -
src/ResolvExpr/Alternative.h
r6840e7c rb96ec83 39 39 ~Alternative(); 40 40 41 void print( std::ostream &os, Indenter indent = {}) const;41 void print( std::ostream &os, int indent = 0 ) const; 42 42 43 43 Cost cost; -
src/ResolvExpr/AlternativeFinder.cc
r6840e7c rb96ec83 75 75 76 76 namespace { 77 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) { 78 Indenter indent = { Indenter::tabsize, indentAmt }; 77 void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) { 79 78 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 80 79 i->print( os, indent ); … … 196 195 AltList winners; 197 196 findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) ); 198 stream << "Cannot choose between " << winners.size() << " alternatives for expression \n";197 stream << "Cannot choose between " << winners.size() << " alternatives for expression "; 199 198 expr->print( stream ); 200 stream << "Alternatives are: \n";201 printAlts( winners, stream, 1);199 stream << "Alternatives are:"; 200 printAlts( winners, stream, 8 ); 202 201 throw SemanticError( stream.str() ); 203 202 } … … 605 604 Alternative newerAlt( newAlt ); 606 605 newerAlt.env = newEnv; 607 assert f( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() );606 assert( (*candidate)->get_uniqueId() ); 608 607 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 609 608 … … 729 728 PRINT( 730 729 std::cerr << "known function ops:" << std::endl; 731 printAlts( funcOpFinder.alternatives, std::cerr, 1);730 printAlts( funcOpFinder.alternatives, std::cerr, 8 ); 732 731 ) 733 732 … … 839 838 bool isLvalue( Expression *expr ) { 840 839 // xxx - recurse into tuples? 841 return expr-> result&& ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );840 return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) ); 842 841 } 843 842 … … 973 972 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 974 973 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 975 VariableExpr newExpr( *i );974 VariableExpr newExpr( *i, nameExpr->get_argName() ); 976 975 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 977 976 PRINT( … … 1268 1267 // O(N^2) checks of d-types with e-types 1269 1268 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { 1270 Type * toType = resolveTypeof( initAlt.type ->clone(), indexer );1269 Type * toType = resolveTypeof( initAlt.type, indexer ); 1271 1270 SymTab::validateType( toType, &indexer ); 1272 1271 adjustExprType( toType, env, indexer ); -
src/ResolvExpr/CastCost.cc
r6840e7c rb96ec83 24 24 #include "typeops.h" // for typesCompatibleIgnoreQualifiers 25 25 26 #if 027 #define PRINT(x) x28 #else29 #define PRINT(x)30 #endif31 26 32 27 namespace ResolvExpr { … … 57 52 } // if 58 53 } // if 59 60 PRINT(61 std::cerr << "castCost ::: src is ";62 src->print( std::cerr );63 std::cerr << std::endl << "dest is ";64 dest->print( std::cerr );65 std::cerr << std::endl << "env is" << std::endl;66 env.print( std::cerr, 8 );67 )68 69 54 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 70 PRINT( std::cerr << "compatible!" << std::endl; )71 55 return Cost::zero; 72 56 } else if ( dynamic_cast< VoidType* >( dest ) ) { 73 57 return Cost::safe; 74 58 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 75 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )76 59 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer & indexer) { 77 60 return ptrsCastable( t1, t2, env, indexer ); -
src/ResolvExpr/CommonType.cc
r6840e7c rb96ec83 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:17201713 // Update Count : 912 // Last Modified On : Thu Mar 16 16:24:31 2017 13 // Update Count : 7 14 14 // 15 15 … … 150 150 static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = 151 151 { 152 /* Bool Char SignedChar UnsignedChar ShortSignedInt ShortUnsignedInt SignedInt UnsignedInt LongSignedInt LongUnsignedInt LongLongSignedInt LongLongUnsignedInt Float Double LongDouble FloatComplex DoubleComplex LongDoubleComplex FloatImaginary DoubleImaginary LongDoubleImaginary SignedInt128 UnsignedInt128 */ 153 /* 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, }, 154 /* 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, }, 155 /* 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, }, 156 /* 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, }, 157 /* 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, }, 158 /* 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, }, 159 /* 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, }, 160 /* 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, }, 161 /* 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, }, 162 /* 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, }, 163 /* 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, }, 164 /* 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, }, 165 /* 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, }, 166 /* 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, }, 167 /* 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, }, 168 /* 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, }, 169 /* 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, }, 170 /* 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, }, 171 /* 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, }, 172 /* 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, }, 173 /* 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 }, 174 /* 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, }, 175 /* 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, }, 152 /* Bool Char SignedChar UnsignedChar ShortSignedInt ShortUnsignedInt SignedInt UnsignedInt LongSignedInt LongUnsignedInt LongLongSignedInt LongLongUnsignedInt Float Double LongDouble FloatComplex DoubleComplex LongDoubleComplex FloatImaginary DoubleImaginary LongDoubleImaginary */ 153 /* 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 }, 154 /* 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 }, 155 /* 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 }, 156 /* 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 }, 157 /* 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 }, 158 /* 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 }, 159 /* 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 }, 160 /* 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 }, 161 /* 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 }, 162 /* 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 }, 163 /* 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 }, 164 /* 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 }, 165 /* 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 }, 166 /* 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 }, 167 /* 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 }, 168 /* 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 }, 169 /* 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 }, 170 /* 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 }, 171 /* 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 }, 172 /* 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 }, 173 /* 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 } 176 174 }; 177 175 -
src/ResolvExpr/ConversionCost.cc
r6840e7c rb96ec83 10 10 // Created On : Sun May 17 07:06:19 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 15:43:34 201713 // Update Count : 1012 // Last Modified On : Wed Mar 2 17:35:46 2016 13 // Update Count : 6 14 14 // 15 15 … … 219 219 */ 220 220 221 static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = { 222 /* 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 */ 223 /* Bool */ { 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 12, 13, 14, 12, 13, 14, -1, -1, -1, 10, 11, }, 224 /* Char */ { -1, 0, -1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, }, 225 /* SChar */ { -1, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, }, 226 /* UChar */ { -1, -1, -1, 0, 1, 2, 3, 4, 4, 5, 6, 7, 10, 11, 12, 10, 11, 12, -1, -1, -1, 8, 9, }, 227 /* Short */ { -1, -1, -1, -1, 0, 1, 2, 3, 3, 4, 5, 6, 9, 10, 11, 9, 10, 11, -1, -1, -1, 7, 8, }, 228 /* UShort */{ -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 4, 5, 8, 9, 10, 8, 9, 10, -1, -1, -1, 6, 7, }, 229 /* Int */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 7, 8, 9, 7, 8, 9, -1, -1, -1, 5, 6, }, 230 /* UInt */ { -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, }, 231 /* Long */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, }, 232 /* ULong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 5, 6, 7, 5, 6, 7, -1, -1, -1, 3, 4, }, 233 /* LLong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 4, 5, 6, 4, 5, 6, -1, -1, -1, 2, 3, }, 234 /* ULLong */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 4, 5, 3, 4, 5, -1, -1, -1, 1, 2, }, 235 236 /* Float */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 3, -1, -1, -1, -1, -1, }, 237 /* Double */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 2, -1, -1, -1, -1, -1, }, 238 /* LDbl */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1, -1, -1, }, 239 /* FCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, -1, -1, -1, -1, }, 240 /* DCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, }, 241 /* LDCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, }, 242 /* FImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 0, 1, 2, -1, -1, }, 243 /* DImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, 0, 1, -1, -1, }, 244 /* LDImag */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, -1, }, 245 246 /* I128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 3, 4, 5, -1, -1, -1, 0, 1, }, 247 /* U128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 2, 3, 4, -1, -1, -1, -1, 0, }, 221 static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = 222 { 223 /* Src \ Dest: Bool Char SChar UChar Short UShort Int UInt Long ULong LLong ULLong Float Double LDbl FCplex DCplex LDCplex FImag DImag LDImag */ 224 /* Bool */ { 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 11, 12, 13, -1, -1, -1 }, 225 /* Char */ { -1, 0, -1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 10, 11, 12, -1, -1, -1 }, 226 /* SChar */ { -1, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 10, 11, 12, -1, -1, -1 }, 227 /* UChar */ { -1, -1, -1, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 9, 10, 11, -1, -1, -1 }, 228 /* Short */ { -1, -1, -1, -1, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 8, 9, 10, -1, -1, -1 }, 229 /* UShort */{ -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 7, 8, 9, -1, -1, -1 }, 230 /* Int */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 5, 6, 7, 6, 7, 8, -1, -1, -1 }, 231 /* UInt */ { -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, 4, 5, 6, 5, 6, 7, -1, -1, -1 }, 232 /* Long */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 5, 6, 7, -1, -1, -1 }, 233 /* ULong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 4, 5, 6, -1, -1, -1 }, 234 /* LLong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 3, 4, 5, -1, -1, -1 }, 235 /* ULLong */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 2, 3, 4, -1, -1, -1 }, 236 /* Float */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 3, -1, -1, -1 }, 237 /* Double */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 2, -1, -1, -1 }, 238 /* LDbl */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1 }, 239 /* FCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, -1, -1 }, 240 /* DCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1 }, 241 /* LDCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1 }, 242 /* FImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 0, 1, 2 }, 243 /* DImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, 0, 1 }, 244 /* LDImag */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0 } 248 245 }; 249 246 … … 306 303 // recursively compute conversion cost from T1 to T2. 307 304 // cv can be safely dropped because of 'implicit dereference' behavior. 308 refType-> base->accept( *this );309 if ( refType-> base->get_qualifiers() == dest->get_qualifiers() ) {305 refType->get_base()->accept( *this ); 306 if ( refType->get_base()->get_qualifiers() == dest->get_qualifiers() ) { 310 307 cost.incReference(); // prefer exact qualifiers 311 } else if ( refType-> base->get_qualifiers() < dest->get_qualifiers() ) {308 } else if ( refType->get_base()->get_qualifiers() < dest->get_qualifiers() ) { 312 309 cost.incSafe(); // then gaining qualifiers 313 310 } else { … … 321 318 void ConversionCost::visit(StructInstType *inst) { 322 319 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) { 323 if ( inst-> name == destAsInst->name) {320 if ( inst->get_name() == destAsInst->get_name() ) { 324 321 cost = Cost::zero; 325 322 } // if … … 328 325 329 326 void ConversionCost::visit(UnionInstType *inst) { 330 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {331 if ( inst-> name == destAsInst->name) {327 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) { 328 if ( inst->get_name() == destAsInst->get_name() ) { 332 329 cost = Cost::zero; 333 330 } // if -
src/ResolvExpr/ResolveTypeof.cc
r6840e7c rb96ec83 18 18 #include <cassert> // for assert 19 19 20 #include "Common/PassVisitor.h" // for PassVisitor21 20 #include "Resolver.h" // for resolveInVoidContext 22 21 #include "SynTree/Expression.h" // for Expression … … 42 41 } 43 42 44 class ResolveTypeof : public WithShortCircuiting{43 class ResolveTypeof : public Mutator { 45 44 public: 46 45 ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {} 47 void premutate( TypeofType *typeofType ); 48 Type * postmutate( TypeofType *typeofType ); 46 Type *mutate( TypeofType *typeofType ); 49 47 50 48 private: … … 52 50 }; 53 51 54 Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {55 PassVisitor<ResolveTypeof>mutator( indexer );52 Type *resolveTypeof( Type *type, const SymTab::Indexer &indexer ) { 53 ResolveTypeof mutator( indexer ); 56 54 return type->acceptMutator( mutator ); 57 55 } 58 56 59 void ResolveTypeof::premutate( TypeofType * ) { 60 visit_children = false; 61 } 62 63 Type * ResolveTypeof::postmutate( TypeofType *typeofType ) { 57 Type *ResolveTypeof::mutate( TypeofType *typeofType ) { 64 58 #if 0 65 std::c err<< "resolving typeof: ";66 typeofType->print( std::c err);67 std::c err<< std::endl;59 std::cout << "resolving typeof: "; 60 typeofType->print( std::cout ); 61 std::cout << std::endl; 68 62 #endif 69 if ( typeofType-> expr) {70 Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );71 assert( newExpr-> result && ! newExpr->result->isVoid() );72 Type * newType = newExpr->result;73 newExpr-> result = nullptr;63 if ( typeofType->get_expr() ) { 64 Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer ); 65 assert( newExpr->has_result() && ! newExpr->get_result()->isVoid() ); 66 Type *newType = newExpr->get_result(); 67 newExpr->set_result( nullptr ); 74 68 delete typeofType; 75 69 delete newExpr; -
src/ResolvExpr/Resolver.cc
r6840e7c rb96ec83 53 53 void previsit( FunctionDecl *functionDecl ); 54 54 void postvisit( FunctionDecl *functionDecl ); 55 void previsit( ObjectDecl * objectDecll );55 void previsit( ObjectDecl *functionDecl ); 56 56 void previsit( TypeDecl *typeDecl ); 57 57 void previsit( EnumDecl * enumDecl ); … … 109 109 110 110 namespace { 111 void finishExpr( Expression *expr, const TypeEnvironment &env , TypeSubstitution * oldenv = nullptr) {112 expr-> env = oldenv ? oldenv->clone() : new TypeSubstitution;111 void finishExpr( Expression *expr, const TypeEnvironment &env ) { 112 expr->set_env( new TypeSubstitution ); 113 113 env.makeSubstitution( *expr->get_env() ); 114 114 } 115 116 void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) {117 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {118 if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {119 // cast is to the same type as its argument, so it's unnecessary -- remove it120 expr = castExpr->arg;121 castExpr->arg = nullptr;122 std::swap( expr->env, castExpr->env );123 delete castExpr;124 }125 }126 }127 115 } // namespace 128 116 129 void findVoidExpression( Expression *&untyped, const SymTab::Indexer &indexer ) {117 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 130 118 global_renamer.reset(); 131 119 TypeEnvironment env; 132 120 Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); 133 finishExpr( newExpr, env, untyped->env ); 134 delete untyped; 135 untyped = newExpr; 136 } 137 138 void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) { 139 if ( ! untyped ) return; 121 finishExpr( newExpr, env ); 122 return newExpr; 123 } 124 125 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 140 126 TypeEnvironment env; 141 127 AlternativeFinder finder( indexer, env ); … … 143 129 #if 0 144 130 if ( finder.get_alternatives().size() != 1 ) { 145 std::c err<< "untyped expr is ";146 untyped->print( std::c err);147 std::c err<< std::endl << "alternatives are:";148 for ( const Alternative & alt : finder.get_alternatives()) {149 alt.print( std::cerr);131 std::cout << "untyped expr is "; 132 untyped->print( std::cout ); 133 std::cout << std::endl << "alternatives are:"; 134 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { 135 i->print( std::cout ); 150 136 } // for 151 137 } // if … … 154 140 Alternative &choice = finder.get_alternatives().front(); 155 141 Expression *newExpr = choice.expr->clone(); 156 finishExpr( newExpr, choice.env, untyped->env ); 157 delete untyped; 158 untyped = newExpr; 159 } 160 161 void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) { 162 assert( untyped && type ); 163 untyped = new CastExpr( untyped, type ); 164 findSingleExpression( untyped, indexer ); 165 removeExtraneousCast( untyped, indexer ); 142 finishExpr( newExpr, choice.env ); 143 return newExpr; 166 144 } 167 145 … … 179 157 } 180 158 181 void findIntegralExpression( Expression *&untyped, const SymTab::Indexer &indexer ) {159 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 182 160 TypeEnvironment env; 183 161 AlternativeFinder finder( indexer, env ); … … 208 186 throw SemanticError( "No interpretations for case control expression", untyped ); 209 187 } // if 210 finishExpr( newExpr, *newEnv, untyped->env ); 211 delete untyped; 212 untyped = newExpr; 188 finishExpr( newExpr, *newEnv ); 189 return newExpr; 213 190 } 214 191 … … 235 212 void Resolver::handlePtrType( PtrType * type ) { 236 213 if ( type->get_dimension() ) { 237 findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer ); 214 CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() ); 215 Expression *newExpr = findSingleExpression( castExpr, indexer ); 216 delete type->get_dimension(); 217 type->set_dimension( newExpr ); 238 218 } 239 219 } … … 265 245 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 266 246 } 247 267 248 268 249 void Resolver::postvisit( FunctionDecl *functionDecl ) { … … 288 269 void Resolver::previsit( ExprStmt *exprStmt ) { 289 270 visit_children = false; 290 assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" ); 291 findVoidExpression( exprStmt->expr, indexer ); 271 assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" ); 272 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer ); 273 delete exprStmt->get_expr(); 274 exprStmt->set_expr( newExpr ); 292 275 } 293 276 294 277 void Resolver::previsit( AsmExpr *asmExpr ) { 295 278 visit_children = false; 296 findVoidExpression( asmExpr->operand, indexer ); 279 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer ); 280 delete asmExpr->get_operand(); 281 asmExpr->set_operand( newExpr ); 297 282 if ( asmExpr->get_inout() ) { 298 findVoidExpression( asmExpr->inout, indexer ); 283 newExpr = findVoidExpression( asmExpr->get_inout(), indexer ); 284 delete asmExpr->get_inout(); 285 asmExpr->set_inout( newExpr ); 299 286 } // if 300 287 } … … 307 294 308 295 void Resolver::previsit( IfStmt *ifStmt ) { 309 findSingleExpression( ifStmt->condition, indexer ); 296 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer ); 297 delete ifStmt->get_condition(); 298 ifStmt->set_condition( newExpr ); 310 299 } 311 300 312 301 void Resolver::previsit( WhileStmt *whileStmt ) { 313 findSingleExpression( whileStmt->condition, indexer ); 302 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer ); 303 delete whileStmt->get_condition(); 304 whileStmt->set_condition( newExpr ); 314 305 } 315 306 316 307 void Resolver::previsit( ForStmt *forStmt ) { 317 if ( forStmt->condition ) { 318 findSingleExpression( forStmt->condition, indexer ); 308 if ( forStmt->get_condition() ) { 309 Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer ); 310 delete forStmt->get_condition(); 311 forStmt->set_condition( newExpr ); 319 312 } // if 320 313 321 if ( forStmt->increment ) { 322 findVoidExpression( forStmt->increment, indexer ); 314 if ( forStmt->get_increment() ) { 315 Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer ); 316 delete forStmt->get_increment(); 317 forStmt->set_increment( newExpr ); 323 318 } // if 324 319 } … … 326 321 void Resolver::previsit( SwitchStmt *switchStmt ) { 327 322 GuardValue( currentObject ); 328 findIntegralExpression( switchStmt->condition, indexer ); 329 330 currentObject = CurrentObject( switchStmt->condition->result ); 323 Expression *newExpr; 324 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer ); 325 delete switchStmt->get_condition(); 326 switchStmt->set_condition( newExpr ); 327 328 currentObject = CurrentObject( newExpr->get_result() ); 331 329 } 332 330 … … 335 333 std::list< InitAlternative > initAlts = currentObject.getOptions(); 336 334 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 337 // must remove cast from case statement because RangeExpr cannot be cast. 338 Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() ); 339 findSingleExpression( newExpr, indexer ); 340 CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 341 caseStmt->condition = castExpr->arg; 342 castExpr->arg = nullptr; 335 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 336 Expression * newExpr = findSingleExpression( castExpr, indexer ); 337 castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 338 caseStmt->set_condition( castExpr->get_arg() ); 339 castExpr->set_arg( nullptr ); 343 340 delete castExpr; 344 341 } … … 349 346 // must resolve the argument for a computed goto 350 347 if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement 351 if ( branchStmt->computedTarget ) { 352 // computed goto argument is void * 353 findSingleExpression( branchStmt->computedTarget, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), indexer ); 348 if ( Expression * arg = branchStmt->get_computedTarget() ) { 349 VoidType v = Type::Qualifiers(); // cast to void * for the alternative finder 350 PointerType pt( Type::Qualifiers(), v.clone() ); 351 CastExpr * castExpr = new CastExpr( arg, pt.clone() ); 352 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression 353 branchStmt->set_target( newExpr ); 354 354 } // if 355 355 } // if … … 358 358 void Resolver::previsit( ReturnStmt *returnStmt ) { 359 359 visit_children = false; 360 if ( returnStmt->expr ) { 361 findSingleExpression( returnStmt->expr, functionReturn->clone(), indexer ); 360 if ( returnStmt->get_expr() ) { 361 CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() ); 362 Expression *newExpr = findSingleExpression( castExpr, indexer ); 363 delete castExpr; 364 returnStmt->set_expr( newExpr ); 362 365 } // if 363 366 } … … 370 373 indexer.lookupStruct( "__cfaehm__base_exception_t" ); 371 374 assert( exception_decl ); 372 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) ); 373 findSingleExpression( throwStmt->expr, exceptType, indexer ); 375 Expression * wrapped = new CastExpr( 376 throwStmt->get_expr(), 377 new PointerType( 378 noQualifiers, 379 new StructInstType( 380 noQualifiers, 381 exception_decl 382 ) 383 ) 384 ); 385 Expression * newExpr = findSingleExpression( wrapped, indexer ); 386 throwStmt->set_expr( newExpr ); 374 387 } 375 388 } 376 389 377 390 void Resolver::previsit( CatchStmt *catchStmt ) { 378 if ( catchStmt->cond ) { 379 findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer ); 380 } 391 if ( catchStmt->get_cond() ) { 392 Expression * wrapped = new CastExpr( 393 catchStmt->get_cond(), 394 new BasicType( noQualifiers, BasicType::Bool ) 395 ); 396 catchStmt->set_cond( findSingleExpression( wrapped, indexer ) ); 397 } 398 } 399 400 inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) { 401 if( !expr ) return; 402 Expression * newExpr = findSingleExpression( expr, indexer ); 403 delete expr; 404 expr = newExpr; 405 } 406 407 inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) { 408 if( !expr ) return; 409 Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer ); 410 delete expr; 411 expr = newExpr; 381 412 } 382 413 … … 548 579 // Resolve the conditions as if it were an IfStmt 549 580 // Resolve the statments normally 550 findSingleExpression( clause.condition, this->indexer );581 resolveAsIf( clause.condition, this->indexer ); 551 582 clause.statement->accept( *visitor ); 552 583 } … … 557 588 // Resolve the conditions as if it were an IfStmt 558 589 // Resolve the statments normally 559 findSingleExpression( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );560 findSingleExpression( stmt->timeout.condition, this->indexer );590 resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer ); 591 resolveAsIf ( stmt->timeout.condition, this->indexer ); 561 592 stmt->timeout.statement->accept( *visitor ); 562 593 } … … 565 596 // Resolve the conditions as if it were an IfStmt 566 597 // Resolve the statments normally 567 findSingleExpression( stmt->orelse.condition, this->indexer );598 resolveAsIf( stmt->orelse.condition, this->indexer ); 568 599 stmt->orelse.statement->accept( *visitor ); 569 600 } … … 582 613 visit_children = false; 583 614 // resolve initialization using the possibilities as determined by the currentObject cursor 584 Expression * newExpr = new UntypedInitExpr( singleInit->value, currentObject.getOptions() );585 findSingleExpression( newExpr, indexer );615 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() ); 616 Expression * newExpr = findSingleExpression( untyped, indexer ); 586 617 InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr ); 587 618 … … 590 621 591 622 // discard InitExpr wrapper and retain relevant pieces 592 newExpr = initExpr->expr; 593 initExpr->expr = nullptr; 594 std::swap( initExpr->env, newExpr->env ); 623 newExpr = initExpr->get_expr(); 624 newExpr->set_env( initExpr->get_env() ); 625 initExpr->set_expr( nullptr ); 626 initExpr->set_env( nullptr ); 595 627 delete initExpr; 596 628 597 629 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 598 630 Type * initContext = currentObject.getCurrentType(); 599 600 removeExtraneousCast( newExpr, indexer );601 631 602 632 // check if actual object's type is char[] … … 606 636 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 607 637 if ( isCharType( pt->get_base() ) ) { 608 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) { 609 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 610 newExpr = ce->get_arg(); 611 ce->set_arg( nullptr ); 612 std::swap( ce->env, newExpr->env ); 613 delete ce; 614 } 638 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 639 CastExpr *ce = strict_dynamic_cast< CastExpr * >( newExpr ); 640 newExpr = ce->get_arg(); 641 ce->set_arg( nullptr ); 642 delete ce; 615 643 } 616 644 } … … 619 647 620 648 // set initializer expr to resolved express 621 singleInit-> value = newExpr;649 singleInit->set_value( newExpr ); 622 650 623 651 // move cursor to next object in preparation for next initializer -
src/ResolvExpr/Resolver.h
r6840e7c rb96ec83 30 30 void resolve( std::list< Declaration * > translationUnit ); 31 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 );32 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ); 33 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ); 34 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ); 35 35 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); 36 36 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ); -
src/ResolvExpr/TypeEnvironment.cc
r6840e7c rb96ec83 68 68 } 69 69 70 void EqvClass::print( std::ostream &os, Indenterindent ) const {71 os << "( ";70 void EqvClass::print( std::ostream &os, int indent ) const { 71 os << std::string( indent, ' ' ) << "( "; 72 72 std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) ); 73 73 os << ")"; 74 74 if ( type ) { 75 75 os << " -> "; 76 type->print( os, indent +1);76 type->print( os, indent ); 77 77 } // if 78 78 if ( ! allowWidening ) { … … 144 144 } 145 145 146 void TypeEnvironment::print( std::ostream &os, Indenterindent ) const {146 void TypeEnvironment::print( std::ostream &os, int indent ) const { 147 147 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) { 148 148 i->print( os, indent ); -
src/ResolvExpr/TypeEnvironment.h
r6840e7c rb96ec83 68 68 EqvClass &operator=( const EqvClass &other ); 69 69 ~EqvClass(); 70 void print( std::ostream &os, Indenter indent = {}) const;70 void print( std::ostream &os, int indent = 0 ) const; 71 71 }; 72 72 … … 80 80 void makeSubstitution( TypeSubstitution &result ) const; 81 81 bool isEmpty() const { return env.empty(); } 82 void print( std::ostream &os, Indenter indent = {}) const;82 void print( std::ostream &os, int indent = 0 ) const; 83 83 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ); 84 84 void simpleCombine( const TypeEnvironment &second ); -
src/ResolvExpr/Unify.cc
r6840e7c rb96ec83 22 22 #include <utility> // for pair 23 23 24 #include "Common/PassVisitor.h" // for PassVisitor25 24 #include "FindOpenVars.h" // for findOpenVars 26 25 #include "Parser/LinkageSpec.h" // for C … … 538 537 /// If this isn't done then argument lists can have wildly different 539 538 /// size and structure, when they should be compatible. 540 struct TtypeExpander : public WithShortCircuiting { 541 TypeEnvironment & tenv; 542 TtypeExpander( TypeEnvironment & tenv ) : tenv( tenv ) {} 543 void premutate( TypeInstType * ) { visit_children = false; } 544 Type * postmutate( TypeInstType * typeInst ) { 539 struct TtypeExpander : public Mutator { 540 TypeEnvironment & env; 541 TtypeExpander( TypeEnvironment & env ) : env( env ) {} 542 Type * mutate( TypeInstType * typeInst ) { 545 543 EqvClass eqvClass; 546 if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {544 if ( env.lookup( typeInst->get_name(), eqvClass ) ) { 547 545 if ( eqvClass.data.kind == TypeDecl::Ttype ) { 548 546 // expand ttype parameter into its actual type … … 562 560 dst.clear(); 563 561 for ( DeclarationWithType * dcl : src ) { 564 PassVisitor<TtypeExpander>expander( env );562 TtypeExpander expander( env ); 565 563 dcl->acceptMutator( expander ); 566 564 std::list< Type * > types; … … 752 750 std::list<Type *> types1, types2; 753 751 754 PassVisitor<TtypeExpander>expander( env );752 TtypeExpander expander( env ); 755 753 flat1->acceptMutator( expander ); 756 754 flat2->acceptMutator( expander ); -
src/SymTab/Autogen.cc
r6840e7c rb96ec83 43 43 namespace SymTab { 44 44 Type * SizeType = 0; 45 46 /// Data used to generate functions generically. Specifically, the name of the generated function and a function which generates the routine protoype 45 typedef ScopedMap< std::string, bool > TypeMap; 46 47 /// Data used to generate functions generically. Specifically, the name of the generated function, a function which generates the routine protoype, and a map which contains data to determine whether a function should be generated. 47 48 struct FuncData { 48 49 typedef FunctionType * (*TypeGen)( Type * ); 49 FuncData( const std::string & fname, const TypeGen & genType ) : fname( fname ), genType( genType) {}50 FuncData( const std::string & fname, const TypeGen & genType, TypeMap & map ) : fname( fname ), genType( genType ), map( map ) {} 50 51 std::string fname; 51 52 TypeGen genType; 53 TypeMap & map; 52 54 }; 53 55 54 struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting , public WithIndexer{56 struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting { 55 57 AutogenerateRoutines(); 56 58 … … 68 70 69 71 private: 70 71 72 GenPoly::ScopedSet< std::string > structsDone; 72 73 unsigned int functionNesting = 0; // current level of nested functions 73 74 InitTweak::ManagedTypes managedTypes; 74 /// Note: the following maps could be ScopedSets, but it should be easier to work 75 /// deleted functions in if they are maps, since the value false can be inserted 76 /// at the current scope without affecting outer scopes or requiring copies. 77 TypeMap copyable, assignable, constructable, destructable; 75 78 std::vector< FuncData > data; 76 79 }; … … 78 81 /// generates routines for tuple types. 79 82 struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting { 80 void previsit( FunctionDecl * functionDecl );81 82 void postvisit( TupleType * tupleType );83 84 void previsit( CompoundStmt * compoundStmt );83 void previsit( FunctionDecl *functionDecl ); 84 85 void postvisit( TupleType *tupleType ); 86 87 void previsit( CompoundStmt *compoundStmt ); 85 88 86 89 private: … … 98 101 } 99 102 100 //=============================================================================================101 // FuncGenerator definitions102 //=============================================================================================103 class FuncGenerator {104 public:105 std::list< Declaration * > definitions, forwards;106 107 FuncGenerator( Type * type, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : type( type ), data( data ), functionNesting( functionNesting ), indexer( indexer ) {}108 109 virtual bool shouldAutogen() const = 0;110 void genStandardFuncs();111 virtual void genFieldCtors() = 0;112 protected:113 Type * type;114 const std::vector< FuncData > & data;115 unsigned int functionNesting;116 SymTab::Indexer & indexer;117 118 virtual void genFuncBody( FunctionDecl * dcl ) = 0;119 virtual bool isConcurrentType() const = 0;120 121 void resolve( FunctionDecl * dcl );122 void generatePrototypes( std::list< FunctionDecl * > & newFuncs );123 };124 125 class StructFuncGenerator : public FuncGenerator {126 StructDecl * aggregateDecl;127 public:128 StructFuncGenerator( StructDecl * aggregateDecl, StructInstType * refType, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ), aggregateDecl( aggregateDecl) {}129 130 virtual bool shouldAutogen() const override;131 virtual bool isConcurrentType() const override;132 133 virtual void genFuncBody( FunctionDecl * dcl ) override;134 virtual void genFieldCtors() override;135 136 private:137 /// generates a single struct member operation (constructor call, destructor call, assignment call)138 void makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true );139 140 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies141 template<typename Iterator>142 void makeFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true );143 144 /// generate the body of a constructor which takes parameters that match fields, e.g.145 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.146 template<typename Iterator>147 void makeFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func );148 };149 150 class UnionFuncGenerator : public FuncGenerator {151 UnionDecl * aggregateDecl;152 public:153 UnionFuncGenerator( UnionDecl * aggregateDecl, UnionInstType * refType, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ), aggregateDecl( aggregateDecl) {}154 155 virtual bool shouldAutogen() const override;156 virtual bool isConcurrentType() const override;157 158 virtual void genFuncBody( FunctionDecl * dcl ) override;159 virtual void genFieldCtors() override;160 161 private:162 /// generates a single struct member operation (constructor call, destructor call, assignment call)163 template<typename OutputIterator>164 void makeMemberOp( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out );165 166 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies167 template<typename Iterator>168 void makeFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true );169 170 /// generate the body of a constructor which takes parameters that match fields, e.g.171 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.172 template<typename Iterator>173 void makeFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func );174 };175 176 class EnumFuncGenerator : public FuncGenerator {177 public:178 EnumFuncGenerator( EnumInstType * refType, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ) {}179 180 virtual bool shouldAutogen() const override;181 virtual bool isConcurrentType() const override;182 183 virtual void genFuncBody( FunctionDecl * dcl ) override;184 virtual void genFieldCtors() override;185 186 private:187 };188 189 class TypeFuncGenerator : public FuncGenerator {190 TypeDecl * typeDecl;191 public:192 TypeFuncGenerator( TypeDecl * typeDecl, TypeInstType * refType, const std::vector<FuncData> & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ), typeDecl( typeDecl ) {}193 194 virtual bool shouldAutogen() const override;195 virtual void genFuncBody( FunctionDecl * dcl ) override;196 virtual bool isConcurrentType() const override;197 virtual void genFieldCtors() override;198 };199 200 //=============================================================================================201 // helper functions202 //=============================================================================================203 void generateFunctions( FuncGenerator & gen, std::list< Declaration * > & declsToAdd ) {204 if ( ! gen.shouldAutogen() ) return;205 206 // generate each of the functions based on the supplied FuncData objects207 gen.genStandardFuncs();208 gen.genFieldCtors();209 210 declsToAdd.splice( declsToAdd.end(), gen.forwards );211 declsToAdd.splice( declsToAdd.end(), gen.definitions );212 }213 214 103 bool isUnnamedBitfield( ObjectDecl * obj ) { 215 return obj != nullptr && obj-> name == "" && obj->bitfieldWidth!= nullptr;104 return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr; 216 105 } 217 106 … … 219 108 void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) { 220 109 FunctionDecl * decl = functionDecl->clone(); 221 delete decl-> statements;222 decl->s tatements = nullptr;110 delete decl->get_statements(); 111 decl->set_statements( nullptr ); 223 112 declsToAdd.push_back( decl ); 224 113 decl->fixUniqueId(); 225 114 } 226 115 227 const std::list< TypeDecl * > getGenericParams( Type * t ) {228 std::list< TypeDecl * > * ret = nullptr;229 if ( StructInstType * inst = dynamic_cast< StructInstType * > ( t ) ) {230 ret = inst->get_baseParameters();231 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {232 ret = inst->get_baseParameters();233 }234 return ret ? *ret : std::list< TypeDecl * >();235 }236 237 116 /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *) 238 117 FunctionType * genDefaultType( Type * paramType ) { 239 const auto & typeParams = getGenericParams( paramType );240 118 FunctionType *ftype = new FunctionType( Type::Qualifiers(), false ); 241 cloneAll( typeParams, ftype->forall );242 119 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr ); 243 ftype-> parameters.push_back( dstParam );120 ftype->get_parameters().push_back( dstParam ); 244 121 return ftype; 245 122 } … … 249 126 FunctionType *ftype = genDefaultType( paramType ); 250 127 ObjectDecl *srcParam = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr ); 251 ftype-> parameters.push_back( srcParam );128 ftype->get_parameters().push_back( srcParam ); 252 129 return ftype; 253 130 } … … 257 134 FunctionType *ftype = genCopyType( paramType ); 258 135 ObjectDecl *returnVal = new ObjectDecl( "_ret", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr ); 259 ftype-> returnVals.push_back( returnVal );136 ftype->get_returnVals().push_back( returnVal ); 260 137 return ftype; 261 138 } … … 274 151 } 275 152 276 Type * declToType( Declaration * decl ) { 277 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 278 return dwt->get_type(); 279 } 280 return nullptr; 281 } 282 283 Type * declToTypeDeclBase( Declaration * decl ) { 284 if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) { 285 return td->base; 286 } 287 return nullptr; 288 } 289 290 //============================================================================================= 291 // FuncGenerator member definitions 292 //============================================================================================= 293 void FuncGenerator::genStandardFuncs() { 294 std::list< FunctionDecl * > newFuncs; 295 generatePrototypes( newFuncs ); 296 297 for ( FunctionDecl * dcl : newFuncs ) { 298 genFuncBody( dcl ); 299 if ( CodeGen::isAssignment( dcl->name ) ) { 300 // assignment needs to return a value 301 FunctionType * assignType = dcl->type; 302 assert( assignType->parameters.size() == 2 ); 303 assert( assignType->returnVals.size() == 1 ); 304 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.front() ); 305 dcl->statements->push_back( new ReturnStmt( noLabels, new VariableExpr( dstParam ) ) ); 306 } 307 resolve( dcl ); 308 } 309 } 310 311 void FuncGenerator::generatePrototypes( std::list< FunctionDecl * > & newFuncs ) { 312 bool concurrent_type = isConcurrentType(); 313 for ( const FuncData & data : data ) { 314 // generate a function (?{}, ?=?, ^?{}) based on the current FuncData. 315 FunctionType * ftype = data.genType( type ); 316 317 // destructor for concurrent type must be mutex 153 /// inserts base type of first argument into map if pred(funcDecl) is true 154 void insert( FunctionDecl *funcDecl, TypeMap & map, FunctionDecl * (*pred)(Declaration *) ) { 155 // insert type into constructable, etc. map if appropriate 156 if ( pred( funcDecl ) ) { 157 FunctionType * ftype = funcDecl->get_functionType(); 158 assert( ! ftype->get_parameters().empty() ); 159 Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() ); 160 assert( t ); 161 map.insert( Mangler::mangleType( t ), true ); 162 } 163 } 164 165 /// using map and t, determines if is constructable, etc. 166 bool lookup( const TypeMap & map, Type * t ) { 167 assertf( t, "Autogenerate lookup was given non-type: %s", toString( t ).c_str() ); 168 if ( dynamic_cast< PointerType * >( t ) ) { 169 // will need more complicated checking if we want this to work with pointer types, since currently 170 return true; 171 } else if ( ArrayType * at = dynamic_cast< ArrayType * >( t ) ) { 172 // an array's constructor, etc. is generated on the fly based on the base type's constructor, etc. 173 return lookup( map, at->get_base() ); 174 } 175 TypeMap::const_iterator it = map.find( Mangler::mangleType( t ) ); 176 if ( it != map.end() ) return it->second; 177 // something that does not appear in the map is by default not constructable, etc. 178 return false; 179 } 180 181 /// using map and aggr, examines each member to determine if constructor, etc. should be generated 182 template<typename Container> 183 bool shouldGenerate( const TypeMap & map, const Container & container ) { 184 for ( Type * t : container ) { 185 if ( ! lookup( map, t ) ) return false; 186 } 187 return true; 188 } 189 190 /// data structure for abstracting the generation of special functions 191 template< typename OutputIterator, typename Container > 192 struct FuncGenerator { 193 const Container & container; 194 Type *refType; 195 unsigned int functionNesting; 196 const std::list< TypeDecl* > & typeParams; 197 OutputIterator out; 198 FuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : container( container ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {} 199 200 /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map. 201 void gen( const FuncData & data, bool concurrent_type ) { 202 if ( ! shouldGenerate( data.map, container ) ) return; 203 FunctionType * ftype = data.genType( refType ); 204 318 205 if ( concurrent_type && CodeGen::isDestructor( data.fname ) ) { 319 206 ftype->parameters.front()->get_type()->set_mutex( true ); 320 207 } 321 208 322 newFuncs.push_back( genFunc( data.fname, ftype, functionNesting ) ); 323 } 324 } 325 326 void FuncGenerator::resolve( FunctionDecl * dcl ) { 327 try { 328 ResolvExpr::resolveDecl( dcl, indexer ); 329 if ( functionNesting == 0 ) { 330 // forward declare if top-level struct, so that 331 // type is complete as soon as its body ends 332 // Note: this is necessary if we want structs which contain 333 // generic (otype) structs as members. 334 addForwardDecl( dcl, forwards ); 335 } 336 definitions.push_back( dcl ); 337 indexer.addId( dcl ); 338 } catch ( SemanticError err ) { 339 // okay if decl does not resolve - that means the function should not be generated 340 delete dcl; 341 } 342 } 343 344 bool StructFuncGenerator::shouldAutogen() const { 345 // Builtins do not use autogeneration. 346 return ! aggregateDecl->linkage.is_builtin; 347 } 348 bool StructFuncGenerator::isConcurrentType() const { return aggregateDecl->is_thread() || aggregateDecl->is_monitor(); } 349 350 void StructFuncGenerator::genFuncBody( FunctionDecl * dcl ) { 351 // generate appropriate calls to member ctor, assignment 352 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 353 if ( ! CodeGen::isDestructor( dcl->name ) ) { 354 makeFunctionBody( aggregateDecl->members.begin(), aggregateDecl->members.end(), dcl ); 355 } else { 356 makeFunctionBody( aggregateDecl->members.rbegin(), aggregateDecl->members.rend(), dcl, false ); 357 } 358 } 359 360 void StructFuncGenerator::genFieldCtors() { 361 // field ctors are only generated if default constructor and copy constructor are both generated 362 unsigned numCtors = std::count_if( definitions.begin(), definitions.end(), [](Declaration * dcl) { return CodeGen::isConstructor( dcl->name ); } ); 363 364 // Field constructors are only generated if default and copy constructor 365 // are generated, since they need access to both 366 if ( numCtors != 2 ) return; 367 368 // create constructors which take each member type as a parameter. 369 // for example, for struct A { int x, y; }; generate 370 // void ?{}(A *, int) and void ?{}(A *, int, int) 371 FunctionType * memCtorType = genDefaultType( type ); 372 for ( Declaration * member : aggregateDecl->members ) { 373 DeclarationWithType * field = strict_dynamic_cast<DeclarationWithType *>( member ); 374 if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( field ) ) ) { 375 // don't make a function whose parameter is an unnamed bitfield 376 continue; 377 } 378 memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 ) ); 379 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 380 makeFieldCtorBody( aggregateDecl->members.begin(), aggregateDecl->members.end(), ctor ); 381 resolve( ctor ); 382 } 383 delete memCtorType; 384 } 385 386 void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) { 209 cloneAll( typeParams, ftype->forall ); 210 *out++ = genFunc( data.fname, ftype, functionNesting ); 211 data.map.insert( Mangler::mangleType( refType ), true ); 212 } 213 }; 214 215 template< typename OutputIterator, typename Container > 216 FuncGenerator<OutputIterator, Container> makeFuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) { 217 return FuncGenerator<OutputIterator, Container>( container, refType, functionNesting, typeParams, out ); 218 } 219 220 /// generates a single enumeration assignment expression 221 ApplicationExpr * genEnumAssign( FunctionType * ftype, FunctionDecl * assignDecl ) { 222 // enum copy construct and assignment is just C-style assignment. 223 // this looks like a bad recursive call, but code gen will turn it into 224 // a C-style assignment. 225 // This happens before function pointer type conversion, so need to do it manually here 226 // NOTE: ftype is not necessarily the functionType belonging to assignDecl - ftype is the 227 // type of the function that this expression is being generated for (so that the correct 228 // parameters) are using in the variable exprs 229 assert( ftype->get_parameters().size() == 2 ); 230 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() ); 231 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() ); 232 233 VariableExpr * assignVarExpr = new VariableExpr( assignDecl ); 234 Type * assignVarExprType = assignVarExpr->get_result(); 235 assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType ); 236 assignVarExpr->set_result( assignVarExprType ); 237 ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr ); 238 assignExpr->get_args().push_back( new VariableExpr( dstParam ) ); 239 assignExpr->get_args().push_back( new VariableExpr( srcParam ) ); 240 return assignExpr; 241 } 242 243 // E ?=?(E volatile*, int), 244 // ?=?(E _Atomic volatile*, int); 245 void makeEnumFunctions( EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) { 246 247 // T ?=?(E *, E); 248 FunctionType *assignType = genAssignType( refType ); 249 250 // void ?{}(E *); void ^?{}(E *); 251 FunctionType * ctorType = genDefaultType( refType->clone() ); 252 FunctionType * dtorType = genDefaultType( refType->clone() ); 253 254 // void ?{}(E *, E); 255 FunctionType *copyCtorType = genCopyType( refType->clone() ); 256 257 // add unused attribute to parameters of default constructor and destructor 258 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 259 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 260 261 // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)? 262 // right now these cases work, but that might change. 263 264 // xxx - Temporary: make these functions intrinsic so they codegen as C assignment. 265 // Really they're something of a cross between instrinsic and autogen, so should 266 // probably make a new linkage type 267 FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting, true ); 268 FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting, true ); 269 FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting, true ); 270 FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting, true ); 271 272 // body is either return stmt or expr stmt 273 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, genEnumAssign( assignType, assignDecl ) ) ); 274 copyCtorDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, genEnumAssign( copyCtorType, assignDecl ) ) ); 275 276 declsToAdd.push_back( ctorDecl ); 277 declsToAdd.push_back( copyCtorDecl ); 278 declsToAdd.push_back( dtorDecl ); 279 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 280 } 281 282 /// generates a single struct member operation (constructor call, destructor call, assignment call) 283 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true ) { 387 284 InitTweak::InitExpander srcParam( src ); 388 285 389 286 // assign to destination 390 Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), strict_dynamic_cast< ReferenceType* >( dstParam->get_type() )->base->clone() ) ); 391 genImplicitCall( srcParam, dstselect, func->name, back_inserter( func->statements->kids ), field, forward ); 392 } 393 287 Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), strict_dynamic_cast< ReferenceType* >( dstParam->get_type() )->get_base()->clone() ) ); 288 genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 289 } 290 291 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies 394 292 template<typename Iterator> 395 void StructFuncGenerator::makeFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward) {293 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ) { 396 294 for ( ; member != end; ++member ) { 397 295 if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate … … 403 301 } 404 302 405 if ( type->get_const() && CodeGen::isAssignment( func->name )) {303 if ( type->get_const() && func->get_name() == "?=?" ) { 406 304 // don't assign const members, but do construct/destruct 305 continue; 306 } 307 308 if ( field->get_name() == "" ) { 309 // don't assign to anonymous members 310 // xxx - this is a temporary fix. Anonymous members tie into 311 // our inheritance model. I think the correct way to handle this is to 312 // cast the structure to the type of the member and let the resolver 313 // figure out whether it's valid and have a pass afterwards that fixes 314 // the assignment to use pointer arithmetic with the offset of the 315 // member, much like how generic type members are handled. 407 316 continue; 408 317 } … … 414 323 srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() ); 415 324 } 416 417 325 // srcParam may be NULL, in which case we have default ctor/dtor 418 326 assert( dstParam ); 419 327 420 328 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr; 421 make MemberOp( dstParam, srcselect, field, func, forward );329 makeStructMemberOp( dstParam, srcselect, field, func, forward ); 422 330 } // if 423 331 } // for 424 } // makeFunctionBody 425 332 } // makeStructFunctionBody 333 334 /// generate the body of a constructor which takes parameters that match fields, e.g. 335 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 426 336 template<typename Iterator> 427 void StructFuncGenerator::makeFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) {428 FunctionType * ftype = func-> type;429 std::list<DeclarationWithType*> & params = ftype-> parameters;337 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) { 338 FunctionType * ftype = func->get_functionType(); 339 std::list<DeclarationWithType*> & params = ftype->get_parameters(); 430 340 assert( params.size() >= 2 ); // should not call this function for default ctor, etc. 431 341 … … 439 349 // don't make a function whose parameter is an unnamed bitfield 440 350 continue; 351 } else if ( field->get_name() == "" ) { 352 // don't assign to anonymous members 353 // xxx - this is a temporary fix. Anonymous members tie into 354 // our inheritance model. I think the correct way to handle this is to 355 // cast the structure to the type of the member and let the resolver 356 // figure out whether it's valid and have a pass afterwards that fixes 357 // the assignment to use pointer arithmetic with the offset of the 358 // member, much like how generic type members are handled. 359 continue; 441 360 } else if ( parameter != params.end() ) { 442 361 // matching parameter, initialize field with copy ctor 443 362 Expression *srcselect = new VariableExpr(*parameter); 444 make MemberOp( dstParam, srcselect, field, func );363 makeStructMemberOp( dstParam, srcselect, field, func ); 445 364 ++parameter; 446 365 } else { 447 366 // no matching parameter, initialize field with default ctor 448 make MemberOp( dstParam, nullptr, field, func );367 makeStructMemberOp( dstParam, nullptr, field, func ); 449 368 } 450 369 } … … 452 371 } 453 372 454 bool UnionFuncGenerator::shouldAutogen() const { 373 Type * declToType( Declaration * decl ) { 374 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 375 return dwt->get_type(); 376 } 377 return nullptr; 378 } 379 380 /// generates struct constructors, destructor, and assignment functions 381 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { 455 382 // Builtins do not use autogeneration. 456 return ! aggregateDecl->linkage.is_builtin; 457 } 458 459 // xxx - is this right? 460 bool UnionFuncGenerator::isConcurrentType() const { return false; }; 383 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) { 384 return; 385 } 386 387 // Make function polymorphic in same parameters as generic struct, if applicable 388 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 389 390 // generate each of the functions based on the supplied FuncData objects 391 std::list< FunctionDecl * > newFuncs; 392 // structure that iterates aggregate decl members, returning their types 393 auto generator = makeFuncGenerator( lazy_map( aggregateDecl->members, declToType ), refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 394 for ( const FuncData & d : data ) { 395 generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() ); 396 } 397 398 // field ctors are only generated if default constructor and copy constructor are both generated 399 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } ); 400 401 if ( functionNesting == 0 ) { 402 // forward declare if top-level struct, so that 403 // type is complete as soon as its body ends 404 // Note: this is necessary if we want structs which contain 405 // generic (otype) structs as members. 406 for ( FunctionDecl * dcl : newFuncs ) { 407 addForwardDecl( dcl, declsToAdd ); 408 } 409 } 410 411 for ( FunctionDecl * dcl : newFuncs ) { 412 // generate appropriate calls to member ctor, assignment 413 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 414 if ( ! CodeGen::isDestructor( dcl->get_name() ) ) { 415 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl ); 416 } else { 417 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, false ); 418 } 419 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 420 // assignment needs to return a value 421 FunctionType * assignType = dcl->get_functionType(); 422 assert( assignType->get_parameters().size() == 2 ); 423 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() ); 424 dcl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 425 } 426 declsToAdd.push_back( dcl ); 427 } 428 429 // create constructors which take each member type as a parameter. 430 // for example, for struct A { int x, y; }; generate 431 // void ?{}(A *, int) and void ?{}(A *, int, int) 432 // Field constructors are only generated if default and copy constructor 433 // are generated, since they need access to both 434 if ( numCtors == 2 ) { 435 FunctionType * memCtorType = genDefaultType( refType ); 436 cloneAll( typeParams, memCtorType->get_forall() ); 437 for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) { 438 DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i ); 439 assert( member ); 440 if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( member ) ) ) { 441 // don't make a function whose parameter is an unnamed bitfield 442 continue; 443 } else if ( member->get_name() == "" ) { 444 // don't assign to anonymous members 445 // xxx - this is a temporary fix. Anonymous members tie into 446 // our inheritance model. I think the correct way to handle this is to 447 // cast the structure to the type of the member and let the resolver 448 // figure out whether it's valid/choose the correct unnamed member 449 continue; 450 } 451 memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), Type::StorageClasses(), LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) ); 452 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 453 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor ); 454 declsToAdd.push_back( ctor ); 455 } 456 delete memCtorType; 457 } 458 } 461 459 462 460 /// generate a single union assignment expression (using memcpy) 463 461 template< typename OutputIterator > 464 void UnionFuncGenerator::makeMemberOp( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {462 void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) { 465 463 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 466 copy-> args.push_back( new AddressExpr( new VariableExpr( dstParam ) ) );467 copy-> args.push_back( new AddressExpr( new VariableExpr( srcParam ) ) );468 copy-> args.push_back( new SizeofExpr( srcParam->get_type()->clone() ) );464 copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) ); 465 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 466 copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); 469 467 *out++ = new ExprStmt( noLabels, copy ); 470 468 } 471 469 472 470 /// generates the body of a union assignment/copy constructor/field constructor 473 void UnionFuncGenerator::genFuncBody( FunctionDecl * funcDecl ) { 474 FunctionType * ftype = funcDecl->type; 475 if ( InitTweak::isCopyConstructor( funcDecl ) || InitTweak::isAssignment( funcDecl ) ) { 476 assert( ftype->parameters.size() == 2 ); 477 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 478 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.back() ); 479 makeMemberOp( srcParam, dstParam, back_inserter( funcDecl->statements->kids ) ); 480 } else { 481 // default ctor/dtor body is empty - add unused attribute to parameter to silence warnings 482 assert( ftype->parameters.size() == 1 ); 483 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 484 dstParam->attributes.push_back( new Attribute( "unused" ) ); 485 } 486 } 487 488 /// generate the body of a constructor which takes parameters that match fields, e.g. 489 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 490 void UnionFuncGenerator::genFieldCtors() { 491 // field ctors are only generated if default constructor and copy constructor are both generated 492 unsigned numCtors = std::count_if( definitions.begin(), definitions.end(), [](Declaration * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } ); 493 494 // Field constructors are only generated if default and copy constructor 495 // are generated, since they need access to both 496 if ( numCtors != 2 ) return; 471 void makeUnionAssignBody( FunctionDecl * funcDecl ) { 472 FunctionType * ftype = funcDecl->get_functionType(); 473 assert( ftype->get_parameters().size() == 2 ); 474 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() ); 475 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() ); 476 477 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) ); 478 if ( CodeGen::isAssignment( funcDecl->get_name() ) ) { 479 // also generate return statement in assignment 480 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 481 } 482 } 483 484 /// generates union constructors, destructors, and assignment operator 485 void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) { 486 // Make function polymorphic in same parameters as generic union, if applicable 487 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 488 489 // default ctor/dtor need only first parameter 490 // void ?{}(T *); void ^?{}(T *); 491 FunctionType *ctorType = genDefaultType( refType ); 492 FunctionType *dtorType = genDefaultType( refType ); 493 494 // copy ctor needs both parameters 495 // void ?{}(T *, T); 496 FunctionType *copyCtorType = genCopyType( refType ); 497 498 // assignment needs both and return value 499 // T ?=?(T *, T); 500 FunctionType *assignType = genAssignType( refType ); 501 502 cloneAll( typeParams, ctorType->get_forall() ); 503 cloneAll( typeParams, dtorType->get_forall() ); 504 cloneAll( typeParams, copyCtorType->get_forall() ); 505 cloneAll( typeParams, assignType->get_forall() ); 506 507 // add unused attribute to parameters of default constructor and destructor 508 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 509 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 510 511 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 512 // because each unit generates copies of the default routines for each aggregate. 513 FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting ); 514 FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting ); 515 FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting ); 516 FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting ); 517 518 makeUnionAssignBody( assignDecl ); 519 520 // body of assignment and copy ctor is the same 521 makeUnionAssignBody( copyCtorDecl ); 497 522 498 523 // create a constructor which takes the first member type as a parameter. … … 500 525 // void ?{}(A *, int) 501 526 // This is to mimic C's behaviour which initializes the first member of the union. 502 FunctionType * memCtorType = genDefaultType( type ); 503 for ( Declaration * member : aggregateDecl->members ) { 504 DeclarationWithType * field = strict_dynamic_cast<DeclarationWithType *>( member ); 505 if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( field ) ) ) { 506 // don't make a function whose parameter is an unnamed bitfield 527 std::list<Declaration *> memCtors; 528 for ( Declaration * member : aggregateDecl->get_members() ) { 529 if ( DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member ) ) { 530 ObjectDecl * srcParam = new ObjectDecl( "src", Type::StorageClasses(), LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 ); 531 532 FunctionType * memCtorType = ctorType->clone(); 533 memCtorType->get_parameters().push_back( srcParam ); 534 FunctionDecl * ctor = genFunc( "?{}", memCtorType, functionNesting ); 535 536 makeUnionAssignBody( ctor ); 537 memCtors.push_back( ctor ); 538 // only generate a ctor for the first field 507 539 break; 508 540 } 509 memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, field->get_type()->clone(), nullptr ) ); 510 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 511 ObjectDecl * srcParam = strict_dynamic_cast<ObjectDecl *>( ctor->type->parameters.back() ); 512 srcParam->fixUniqueId(); 513 ObjectDecl * dstParam = InitTweak::getParamThis( ctor->type ); 514 makeMemberOp( srcParam, dstParam, back_inserter( ctor->statements->kids ) ); 515 resolve( ctor ); 516 // only generate one field ctor for unions 517 break; 518 } 519 delete memCtorType; 520 } 521 522 void EnumFuncGenerator::genFuncBody( FunctionDecl * funcDecl ) { 523 // xxx - Temporary: make these functions intrinsic so they codegen as C assignment. 524 // Really they're something of a cross between instrinsic and autogen, so should 525 // probably make a new linkage type 526 funcDecl->linkage = LinkageSpec::Intrinsic; 527 FunctionType * ftype = funcDecl->type; 528 if ( InitTweak::isCopyConstructor( funcDecl ) || InitTweak::isAssignment( funcDecl ) ) { 529 assert( ftype->parameters.size() == 2 ); 530 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 531 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.back() ); 532 533 // enum copy construct and assignment is just C-style assignment. 534 // this looks like a bad recursive call, but code gen will turn it into 535 // a C-style assignment. 536 // This happens before function pointer type conversion, so need to do it manually here 537 ApplicationExpr * callExpr = new ApplicationExpr( VariableExpr::functionPointer( funcDecl ) ); 538 callExpr->get_args().push_back( new VariableExpr( dstParam ) ); 539 callExpr->get_args().push_back( new VariableExpr( srcParam ) ); 540 funcDecl->statements->push_back( new ExprStmt( noLabels, callExpr ) ); 541 } else { 542 // default ctor/dtor body is empty - add unused attribute to parameter to silence warnings 543 assert( ftype->parameters.size() == 1 ); 544 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 545 dstParam->attributes.push_back( new Attribute( "unused" ) ); 546 } 547 } 548 549 bool EnumFuncGenerator::shouldAutogen() const { return true; } 550 bool EnumFuncGenerator::isConcurrentType() const { return false; } 551 // enums do not have field constructors 552 void EnumFuncGenerator::genFieldCtors() {} 553 554 bool TypeFuncGenerator::shouldAutogen() const { return true; }; 555 556 void TypeFuncGenerator::genFuncBody( FunctionDecl * dcl ) { 557 FunctionType * ftype = dcl->type; 558 assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() ); 559 DeclarationWithType * dst = ftype->parameters.front(); 560 DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr; 561 // generate appropriate calls to member ctor, assignment 562 UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) ); 563 expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) ); 564 if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) ); 565 dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) ); 566 }; 567 568 // xxx - should reach in and determine if base type is concurrent? 569 bool TypeFuncGenerator::isConcurrentType() const { return false; }; 570 571 // opaque types do not have field constructors 572 void TypeFuncGenerator::genFieldCtors() {}; 573 574 //============================================================================================= 575 // Visitor definitions 576 //============================================================================================= 541 } 542 543 declsToAdd.push_back( ctorDecl ); 544 declsToAdd.push_back( copyCtorDecl ); 545 declsToAdd.push_back( dtorDecl ); 546 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 547 declsToAdd.splice( declsToAdd.end(), memCtors ); 548 } 549 577 550 AutogenerateRoutines::AutogenerateRoutines() { 578 551 // the order here determines the order that these functions are generated. 579 552 // assignment should come last since it uses copy constructor in return. 580 data.emplace_back( "?{}", genDefaultType );581 data.emplace_back( "?{}", genCopyType );582 data.emplace_back( "^?{}", genDefaultType );583 data.emplace_back( "?=?", genAssignType );553 data.emplace_back( "?{}", genDefaultType, constructable ); 554 data.emplace_back( "?{}", genCopyType, copyable ); 555 data.emplace_back( "^?{}", genDefaultType, destructable ); 556 data.emplace_back( "?=?", genAssignType, assignable ); 584 557 } 585 558 586 559 void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) { 587 // must visit children (enum constants) to add them to the indexer 588 if ( enumDecl->has_body() ) { 589 EnumInstType enumInst( Type::Qualifiers(), enumDecl->get_name() ); 590 enumInst.set_baseEnum( enumDecl ); 591 EnumFuncGenerator gen( &enumInst, data, functionNesting, indexer ); 592 generateFunctions( gen, declsToAddAfter ); 560 visit_children = false; 561 if ( ! enumDecl->get_members().empty() ) { 562 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); 563 // enumInst->set_baseEnum( enumDecl ); 564 makeEnumFunctions( enumInst, functionNesting, declsToAddAfter ); 593 565 } 594 566 } … … 596 568 void AutogenerateRoutines::previsit( StructDecl * structDecl ) { 597 569 visit_children = false; 598 if ( structDecl->has_body() ) {570 if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) { 599 571 StructInstType structInst( Type::Qualifiers(), structDecl->name ); 572 for ( TypeDecl * typeDecl : structDecl->parameters ) { 573 // need to visit assertions so that they are added to the appropriate maps 574 acceptAll( typeDecl->assertions, *visitor ); 575 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) ); 576 } 600 577 structInst.set_baseStruct( structDecl ); 601 for ( TypeDecl * typeDecl : structDecl->parameters ) { 602 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) ); 603 } 604 StructFuncGenerator gen( structDecl, &structInst, data, functionNesting, indexer ); 605 generateFunctions( gen, declsToAddAfter ); 578 makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data ); 579 structsDone.insert( structDecl->name ); 606 580 } // if 607 581 } … … 609 583 void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) { 610 584 visit_children = false; 611 if ( unionDecl->has_body()) {585 if ( ! unionDecl->get_members().empty() ) { 612 586 UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() ); 613 587 unionInst.set_baseUnion( unionDecl ); … … 615 589 unionInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) ); 616 590 } 617 UnionFuncGenerator gen( unionDecl, &unionInst, data, functionNesting, indexer ); 618 generateFunctions( gen, declsToAddAfter ); 591 makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAddAfter ); 619 592 } // if 593 } 594 595 Type * declToTypeDeclBase( Declaration * decl ) { 596 if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) { 597 return td->base; 598 } 599 return nullptr; 620 600 } 621 601 … … 625 605 if ( ! typeDecl->base ) return; 626 606 607 // generate each of the functions based on the supplied FuncData objects 608 std::list< FunctionDecl * > newFuncs; 609 std::list< Declaration * > tds { typeDecl }; 610 std::list< TypeDecl * > typeParams; 627 611 TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl ); 628 TypeFuncGenerator gen( typeDecl, &refType, data, functionNesting, indexer ); 629 generateFunctions( gen, declsToAddAfter ); 612 auto generator = makeFuncGenerator( lazy_map( tds, declToTypeDeclBase ), &refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 613 for ( const FuncData & d : data ) { 614 generator.gen( d, false ); 615 } 616 617 if ( functionNesting == 0 ) { 618 // forward declare if top-level struct, so that 619 // type is complete as soon as its body ends 620 // Note: this is necessary if we want structs which contain 621 // generic (otype) structs as members. 622 for ( FunctionDecl * dcl : newFuncs ) { 623 addForwardDecl( dcl, declsToAddAfter ); 624 } 625 } 626 627 for ( FunctionDecl * dcl : newFuncs ) { 628 FunctionType * ftype = dcl->type; 629 assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() ); 630 DeclarationWithType * dst = ftype->parameters.front(); 631 DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr; 632 // generate appropriate calls to member ctor, assignment 633 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 634 UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) ); 635 expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) ); 636 if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) ); 637 dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) ); 638 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 639 // assignment needs to return a value 640 FunctionType * assignType = dcl->type; 641 assert( assignType->parameters.size() == 2 ); 642 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.back() ); 643 dcl->statements->kids.push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 644 } 645 declsToAddAfter.push_back( dcl ); 646 } 630 647 } 631 648 … … 648 665 visit_children = false; 649 666 // record the existence of this function as appropriate 650 managedTypes.handleDWT( functionDecl ); 667 insert( functionDecl, constructable, InitTweak::isDefaultConstructor ); 668 insert( functionDecl, assignable, InitTweak::isAssignment ); 669 insert( functionDecl, copyable, InitTweak::isCopyConstructor ); 670 insert( functionDecl, destructable, InitTweak::isDestructor ); 651 671 652 672 maybeAccept( functionDecl->type, *visitor ); … … 657 677 658 678 void AutogenerateRoutines::previsit( CompoundStmt * ) { 659 GuardScope( managedTypes ); 679 GuardScope( constructable ); 680 GuardScope( assignable ); 681 GuardScope( copyable ); 682 GuardScope( destructable ); 660 683 GuardScope( structsDone ); 661 684 } -
src/SymTab/Autogen.h
r6840e7c rb96ec83 19 19 #include <string> // for string 20 20 21 #include "CodeGen/OperatorTable.h"22 21 #include "Common/UniqueName.h" // for UniqueName 23 22 #include "InitTweak/InitTweak.h" // for InitExpander … … 52 51 53 52 // generate the type of a copy constructor for paramType 54 FunctionType * gen CopyType( Type * paramType );53 FunctionType * genDefaultType( Type * paramType ); 55 54 56 55 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. … … 61 60 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 62 61 template< typename OutputIterator > 63 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, bool addCast = false ) { 64 bool isReferenceCtorDtor = false; 65 if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { 66 // reference constructors are essentially application of the rebind operator. 67 // apply & to both arguments, do not need a cast 68 fname = "?=?"; 69 dstParam = new AddressExpr( dstParam ); 70 addCast = false; 71 isReferenceCtorDtor = true; 72 } 73 62 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) { 74 63 // want to be able to generate assignment, ctor, and dtor generically, 75 64 // so fname is either ?=?, ?{}, or ^?{} 76 UntypedExpr * fExpr = new UntypedExpr( new NameExpr( fname ) );65 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 77 66 78 67 if ( addCast ) { … … 89 78 dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) ); 90 79 } 91 fExpr-> args.push_back( dstParam );80 fExpr->get_args().push_back( dstParam ); 92 81 93 82 Statement * listInit = srcParam.buildListInit( fExpr ); 94 83 95 // fetch next set of arguments 96 ++srcParam; 97 98 // return if adding reference fails - will happen on default constructor and destructor 99 if ( isReferenceCtorDtor && ! srcParam.addReference() ) { 100 delete fExpr; 101 return listInit; 102 } 103 104 std::list< Expression * > args = *srcParam; 105 fExpr->args.splice( fExpr->args.end(), args ); 84 std::list< Expression * > args = *++srcParam; 85 fExpr->get_args().splice( fExpr->get_args().end(), args ); 106 86 107 87 *out++ = new ExprStmt( noLabels, fExpr ); … … 125 105 // generate: for ( int i = 0; i < N; ++i ) 126 106 begin = new ConstantExpr( Constant::from_int( 0 ) ); 127 end = array-> dimension->clone();107 end = array->get_dimension()->clone(); 128 108 cmp = new NameExpr( "?<?" ); 129 109 update = new NameExpr( "++?" ); … … 131 111 // generate: for ( int i = N-1; i >= 0; --i ) 132 112 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 133 ((UntypedExpr*)begin)-> args.push_back( array->dimension->clone() );134 ((UntypedExpr*)begin)-> args.push_back( new ConstantExpr( Constant::from_int( 1 ) ) );113 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 114 ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) ); 135 115 end = new ConstantExpr( Constant::from_int( 0 ) ); 136 116 cmp = new NameExpr( "?>=?" ); … … 141 121 142 122 UntypedExpr *cond = new UntypedExpr( cmp ); 143 cond-> args.push_back( new VariableExpr( index ) );144 cond-> args.push_back( end );123 cond->get_args().push_back( new VariableExpr( index ) ); 124 cond->get_args().push_back( end ); 145 125 146 126 UntypedExpr *inc = new UntypedExpr( update ); 147 inc-> args.push_back( new VariableExpr( index ) );127 inc->get_args().push_back( new VariableExpr( index ) ); 148 128 149 129 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 150 dstIndex-> args.push_back( dstParam );151 dstIndex-> args.push_back( new VariableExpr( index ) );130 dstIndex->get_args().push_back( dstParam ); 131 dstIndex->get_args().push_back( new VariableExpr( index ) ); 152 132 dstParam = dstIndex; 153 133 154 134 // srcParam must keep track of the array indices to build the 155 135 // source parameter and/or array list initializer 156 srcParam.addArrayIndex( new VariableExpr( index ), array-> dimension->clone() );136 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() ); 157 137 158 138 // for stmt's body, eventually containing call 159 139 CompoundStmt * body = new CompoundStmt( noLabels ); 160 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body-> kids ), array->base, addCast, forward );140 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward ); 161 141 162 142 // block containing for stmt and index variable 163 143 std::list<Statement *> initList; 164 144 CompoundStmt * block = new CompoundStmt( noLabels ); 165 block-> push_back( new DeclStmt( noLabels, index ) );145 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 166 146 if ( listInit ) block->get_kids().push_back( listInit ); 167 block-> push_back( new ForStmt( noLabels, initList, cond, inc, body ) );147 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 168 148 169 149 *out++ = block; … … 171 151 172 152 template< typename OutputIterator > 173 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {153 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) { 174 154 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 175 155 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); … … 185 165 /// ImplicitCtorDtorStmt node. 186 166 template< typename OutputIterator > 187 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {167 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 188 168 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 189 169 assert( obj ); … … 193 173 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ); 194 174 std::list< Statement * > stmts; 195 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj-> type, addCast, forward );175 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward ); 196 176 197 177 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call -
src/SymTab/FixFunction.cc
r6840e7c rb96ec83 26 26 FixFunction::FixFunction() : isVoid( false ) {} 27 27 28 29 DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) { 28 DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) { 30 29 // can't delete function type because it may contain assertions, so transfer ownership to new object 31 ObjectDecl *pointer = new ObjectDecl( functionDecl-> name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes);32 functionDecl-> attributes.clear();30 ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() ); 31 functionDecl->get_attributes().clear(); 33 32 functionDecl->type = nullptr; 34 33 delete functionDecl; … … 36 35 } 37 36 38 Type * FixFunction::postmutate(ArrayType *arrayType) { 37 Type * FixFunction::mutate(VoidType *voidType) { 38 isVoid = true; 39 return voidType; 40 } 41 42 Type * FixFunction::mutate(BasicType *basicType) { 43 return basicType; 44 } 45 46 Type * FixFunction::mutate(PointerType *pointerType) { 47 return pointerType; 48 } 49 50 Type * FixFunction::mutate(ArrayType *arrayType) { 39 51 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 40 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic ); 41 arrayType->base = nullptr; 42 arrayType->dimension = nullptr; 52 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() ); 43 53 delete arrayType; 44 54 return pointerType; 45 55 } 46 56 47 void FixFunction::premutate(VoidType *) {48 isVoid = true;57 Type * FixFunction::mutate(StructInstType *aggregateUseType) { 58 return aggregateUseType; 49 59 } 50 60 51 void FixFunction::premutate(FunctionDecl *) { visit_children = false; } 52 void FixFunction::premutate(BasicType *) { visit_children = false; } 53 void FixFunction::premutate(PointerType *) { visit_children = false; } 54 void FixFunction::premutate(StructInstType *) { visit_children = false; } 55 void FixFunction::premutate(UnionInstType *) { visit_children = false; } 56 void FixFunction::premutate(EnumInstType *) { visit_children = false; } 57 void FixFunction::premutate(TraitInstType *) { visit_children = false; } 58 void FixFunction::premutate(TypeInstType *) { visit_children = false; } 59 void FixFunction::premutate(TupleType *) { visit_children = false; } 60 void FixFunction::premutate(VarArgsType *) { visit_children = false; } 61 void FixFunction::premutate(ZeroType *) { visit_children = false; } 62 void FixFunction::premutate(OneType *) { visit_children = false; } 61 Type * FixFunction::mutate(UnionInstType *aggregateUseType) { 62 return aggregateUseType; 63 } 64 65 Type * FixFunction::mutate(EnumInstType *aggregateUseType) { 66 return aggregateUseType; 67 } 68 69 Type * FixFunction::mutate(TraitInstType *aggregateUseType) { 70 return aggregateUseType; 71 } 72 73 Type * FixFunction::mutate(TypeInstType *aggregateUseType) { 74 return aggregateUseType; 75 } 76 77 Type * FixFunction::mutate(TupleType *tupleType) { 78 return tupleType; 79 } 80 81 Type * FixFunction::mutate(VarArgsType *varArgsType) { 82 return varArgsType; 83 } 84 85 Type * FixFunction::mutate(ZeroType *zeroType) { 86 return zeroType; 87 } 88 89 Type * FixFunction::mutate(OneType *oneType) { 90 return oneType; 91 } 63 92 } // namespace SymTab 64 93 -
src/SymTab/FixFunction.h
r6840e7c rb96ec83 16 16 #pragma once 17 17 18 #include " Common/PassVisitor.h" // for PassVisitor19 #include "SynTree/SynTree.h" // for Types18 #include "SynTree/Mutator.h" // for Mutator 19 #include "SynTree/SynTree.h" // for Types 20 20 21 21 namespace SymTab { 22 22 /// Replaces function and array types by equivalent pointer types. 23 class FixFunction : public WithShortCircuiting{23 class FixFunction : public Mutator { 24 24 typedef Mutator Parent; 25 25 public: 26 26 FixFunction(); 27 27 28 void premutate(FunctionDecl *functionDecl); 29 DeclarationWithType* postmutate(FunctionDecl *functionDecl); 28 bool get_isVoid() const { return isVoid; } 29 void set_isVoid( bool newValue ) { isVoid = newValue; } 30 private: 31 virtual DeclarationWithType* mutate(FunctionDecl *functionDecl); 30 32 31 Type * postmutate(ArrayType * arrayType); 32 33 void premutate(VoidType * voidType); 34 void premutate(BasicType * basicType); 35 void premutate(PointerType * pointerType); 36 void premutate(StructInstType * aggregateUseType); 37 void premutate(UnionInstType * aggregateUseType); 38 void premutate(EnumInstType * aggregateUseType); 39 void premutate(TraitInstType * aggregateUseType); 40 void premutate(TypeInstType * aggregateUseType); 41 void premutate(TupleType * tupleType); 42 void premutate(VarArgsType * varArgsType); 43 void premutate(ZeroType * zeroType); 44 void premutate(OneType * oneType); 33 virtual Type* mutate(VoidType *voidType); 34 virtual Type* mutate(BasicType *basicType); 35 virtual Type* mutate(PointerType *pointerType); 36 virtual Type* mutate(ArrayType *arrayType); 37 virtual Type* mutate(StructInstType *aggregateUseType); 38 virtual Type* mutate(UnionInstType *aggregateUseType); 39 virtual Type* mutate(EnumInstType *aggregateUseType); 40 virtual Type* mutate(TraitInstType *aggregateUseType); 41 virtual Type* mutate(TypeInstType *aggregateUseType); 42 virtual Type* mutate(TupleType *tupleType); 43 virtual Type* mutate(VarArgsType *varArgsType); 44 virtual Type* mutate(ZeroType *zeroType); 45 virtual Type* mutate(OneType *oneType); 45 46 46 47 bool isVoid; -
src/SymTab/Indexer.cc
r6840e7c rb96ec83 407 407 makeWritable(); 408 408 409 const std::string &name = decl-> name;409 const std::string &name = decl->get_name(); 410 410 std::string mangleName; 411 if ( LinkageSpec::isOverridable( decl-> linkage) ) {411 if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) { 412 412 // mangle the name without including the appropriate suffix, so overridable routines are placed into the 413 413 // same "bucket" as their user defined versions. … … 418 418 419 419 // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage 420 if ( ! LinkageSpec::isMangled( decl-> linkage) ) {420 if ( ! LinkageSpec::isMangled( decl->get_linkage() ) ) { 421 421 // NOTE this is broken in Richard's original code in such a way that it never triggers (it 422 422 // doesn't check decls that have the same manglename, and all C-linkage decls are defined to … … 571 571 572 572 if ( doDebug ) { 573 std::c err<< "--- Entering scope " << scope << std::endl;573 std::cout << "--- Entering scope " << scope << std::endl; 574 574 } 575 575 } 576 576 577 577 void Indexer::leaveScope() { 578 using std::c err;578 using std::cout; 579 579 580 580 assert( scope > 0 && "cannot leave initial scope" ); 581 if ( doDebug ) {582 cerr << "--- Leaving scope " << scope << " containing" << std::endl;583 }584 581 --scope; 585 582 586 583 while ( tables && tables->scope > scope ) { 587 584 if ( doDebug ) { 588 dump( tables->idTable, cerr ); 589 dump( tables->typeTable, cerr ); 590 dump( tables->structTable, cerr ); 591 dump( tables->enumTable, cerr ); 592 dump( tables->unionTable, cerr ); 593 dump( tables->traitTable, cerr ); 585 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl; 586 dump( tables->idTable, cout ); 587 dump( tables->typeTable, cout ); 588 dump( tables->structTable, cout ); 589 dump( tables->enumTable, cout ); 590 dump( tables->unionTable, cout ); 591 dump( tables->traitTable, cout ); 594 592 } 595 593 -
src/SymTab/Mangler.cc
r6840e7c rb96ec83 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:40:29 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Sep 25 15:49:26201713 // Update Count : 2 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 28 15:31:00 2017 13 // Update Count : 21 14 14 // 15 15 #include "Mangler.h" … … 115 115 "Id", // DoubleImaginary 116 116 "Ir", // LongDoubleImaginary 117 "w", // SignedInt128118 "Uw", // UnsignedInt128119 117 }; 120 118 -
src/SymTab/Validate.cc
r6840e7c rb96ec83 153 153 void previsit( ObjectDecl * object ); 154 154 void previsit( FunctionDecl * func ); 155 void previsit( StructDecl * aggrDecl );156 void previsit( UnionDecl * aggrDecl );157 155 }; 158 156 … … 272 270 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist 273 271 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 274 ReturnChecker::checkFunctionReturns( translationUnit );275 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen276 272 Concurrency::applyKeywords( translationUnit ); 277 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution278 273 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay 279 274 Concurrency::implementMutexFuncs( translationUnit ); 280 275 Concurrency::implementThreadStarter( translationUnit ); 276 ReturnChecker::checkFunctionReturns( translationUnit ); 281 277 mutateAll( translationUnit, compoundliteral ); 278 acceptAll( translationUnit, fpd ); 282 279 ArrayLength::computeLength( translationUnit ); 283 acceptAll( translationUnit, finder ); // xxx - remove this pass soon280 acceptAll( translationUnit, finder ); 284 281 mutateAll( translationUnit, labelAddrFixer ); 285 282 } … … 372 369 DWTIterator begin( dwts.begin() ), end( dwts.end() ); 373 370 if ( begin == end ) return; 374 PassVisitor<FixFunction>fixer;371 FixFunction fixer; 375 372 DWTIterator i = begin; 376 373 *i = (*i)->acceptMutator( fixer ); 377 if ( fixer. pass.isVoid) {374 if ( fixer.get_isVoid() ) { 378 375 DWTIterator j = i; 379 376 ++i; … … 386 383 ++i; 387 384 for ( ; i != end; ++i ) { 388 PassVisitor<FixFunction>fixer;385 FixFunction fixer; 389 386 *i = (*i)->acceptMutator( fixer ); 390 if ( fixer. pass.isVoid) {387 if ( fixer.get_isVoid() ) { 391 388 throw SemanticError( "invalid type void in function type ", func ); 392 389 } // if … … 600 597 // apply FixFunction to every assertion to check for invalid void type 601 598 for ( DeclarationWithType *& assertion : type->assertions ) { 602 PassVisitor<FixFunction>fixer;599 FixFunction fixer; 603 600 assertion = assertion->acceptMutator( fixer ); 604 if ( fixer. pass.isVoid) {601 if ( fixer.get_isVoid() ) { 605 602 throw SemanticError( "invalid type void in assertion of function ", node ); 606 603 } // if … … 621 618 forallFixer( func->type->forall, func ); 622 619 func->fixUniqueId(); 623 }624 625 void ForallPointerDecay::previsit( StructDecl * aggrDecl ) {626 forallFixer( aggrDecl->parameters, aggrDecl );627 }628 629 void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) {630 forallFixer( aggrDecl->parameters, aggrDecl );631 620 } 632 621 -
src/SynTree/AddressExpr.cc
r6840e7c rb96ec83 33 33 Type * addrType( Type * type ) { 34 34 if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( type ) ) { 35 return new ReferenceType( refType->get_qualifiers(), addrType( refType-> base) );35 return new ReferenceType( refType->get_qualifiers(), addrType( refType->get_base() ) ); 36 36 } else { 37 37 return new PointerType( Type::Qualifiers(), type->clone() ); … … 40 40 } 41 41 42 AddressExpr::AddressExpr( Expression *arg ) : Expression(), arg( arg ) {43 if ( arg-> result) {44 if ( arg-> result->get_lvalue() ) {42 AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) { 43 if ( arg->has_result() ) { 44 if ( arg->get_result()->get_lvalue() ) { 45 45 // lvalue, retains all layers of reference and gains a pointer inside the references 46 set_result( addrType( arg-> result) );46 set_result( addrType( arg->get_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 ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( arg->get_result() ); 50 set_result( addrType( refType->get_base() ) ); 51 51 } 52 52 // result of & is never an lvalue … … 62 62 } 63 63 64 void AddressExpr::print( std::ostream &os, Indenterindent ) const {64 void AddressExpr::print( std::ostream &os, int indent ) const { 65 65 os << "Address of:" << std::endl; 66 66 if ( arg ) { 67 os << indent+1;68 arg->print( os, indent+ 1);67 os << std::string( indent+2, ' ' ); 68 arg->print( os, indent+2 ); 69 69 } // if 70 70 } … … 77 77 LabelAddressExpr::~LabelAddressExpr() {} 78 78 79 void LabelAddressExpr::print( std::ostream & os, Indenter) const {80 os << "Address of label:" << arg;79 void LabelAddressExpr::print( std::ostream & os, int indent ) const { 80 os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg; 81 81 } 82 82 -
src/SynTree/AggregateDecl.cc
r6840e7c rb96ec83 41 41 } 42 42 43 void AggregateDecl::print( std::ostream &os, Indenterindent ) const {43 void AggregateDecl::print( std::ostream &os, int indent ) const { 44 44 using std::string; 45 45 using std::endl; 46 46 47 os << typeString() << " " << name<< ":";47 os << typeString() << " " << get_name() << ":"; 48 48 if ( get_linkage() != LinkageSpec::Cforall ) { 49 os << " " << LinkageSpec::linkageName( linkage);49 os << " " << LinkageSpec::linkageName( get_linkage() ); 50 50 } // if 51 os << " with body " << has_body() ;51 os << " with body " << has_body() << endl; 52 52 53 53 if ( ! parameters.empty() ) { 54 os << endl << indent << "...with parameters" << endl;55 printAll( parameters, os, indent+ 1);54 os << endl << string( indent+2, ' ' ) << "with parameters" << endl; 55 printAll( parameters, os, indent+4 ); 56 56 } // if 57 57 if ( ! members.empty() ) { 58 os << endl << indent << "...with members" << endl;59 printAll( members, os, indent+ 1);58 os << endl << string( indent+2, ' ' ) << "with members" << endl; 59 printAll( members, os, indent+4 ); 60 60 } // if 61 61 if ( ! attributes.empty() ) { 62 os << endl << indent << "...with attributes" << endl;63 printAll( attributes, os, indent+ 1);62 os << endl << string( indent+2, ' ' ) << "with attributes" << endl; 63 printAll( attributes, os, indent+4 ); 64 64 } // if 65 os << endl;66 65 } 67 66 68 void AggregateDecl::printShort( std::ostream &os, Indenterindent ) const {67 void AggregateDecl::printShort( std::ostream &os, int indent ) const { 69 68 using std::string; 70 69 using std::endl; 71 70 72 os << typeString() << " " << name << " with body " << has_body() << endl; 71 os << typeString() << " " << get_name(); 72 os << string( indent+2, ' ' ) << "with body " << has_body() << endl; 73 73 74 74 if ( ! parameters.empty() ) { 75 os << indent << "...with parameters" << endl;76 printAll( parameters, os, indent+ 1);75 os << endl << string( indent+2, ' ' ) << "with parameters" << endl; 76 printAll( parameters, os, indent+4 ); 77 77 } // if 78 78 } -
src/SynTree/ApplicationExpr.cc
r6840e7c rb96ec83 55 55 set_result( ResolvExpr::extractResultType( function ) ); 56 56 57 assert( result);57 assert( has_result() ); 58 58 } 59 59 … … 68 68 } 69 69 70 void printInferParams( const InferredParams & inferParams, std::ostream &os, Indenterindent, int level ) {70 void printInferParams( const InferredParams & inferParams, std::ostream &os, int indent, int level ) { 71 71 if ( ! inferParams.empty() ) { 72 os << indent<< "with inferred parameters " << level << ":" << std::endl;72 os << std::string(indent, ' ') << "with inferred parameters " << level << ":" << std::endl; 73 73 for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) { 74 os << indent+1;75 Declaration::declFromId( i->second.decl )->printShort( os, indent+ 1);74 os << std::string(indent+2, ' '); 75 Declaration::declFromId( i->second.decl )->printShort( os, indent+2 ); 76 76 os << std::endl; 77 printInferParams( *i->second.inferParams, os, indent+ 1, level+1 );77 printInferParams( *i->second.inferParams, os, indent+2, level+1 ); 78 78 } // for 79 79 } // if 80 80 } 81 81 82 void ApplicationExpr::print( std::ostream &os, Indenter indent ) const { 83 os << "Application of" << std::endl << indent+1; 84 function->print( os, indent+1 ); 85 os << std::endl; 82 void ApplicationExpr::print( std::ostream &os, int indent ) const { 83 os << "Application of" << std::endl << std::string(indent+2, ' '); 84 function->print( os, indent+2 ); 86 85 if ( ! args.empty() ) { 87 os << indent << "...to arguments" << std::endl;88 printAll( args, os, indent+ 1);86 os << std::string( indent, ' ' ) << "to arguments" << std::endl; 87 printAll( args, os, indent+2 ); 89 88 } // if 90 printInferParams( inferParams, os, indent+ 1, 0 );89 printInferParams( inferParams, os, indent+2, 0 ); 91 90 Expression::print( os, indent ); 92 91 } -
src/SynTree/ArrayType.cc
r6840e7c rb96ec83 39 39 } 40 40 41 void ArrayType::print( std::ostream &os, Indenterindent ) const {41 void ArrayType::print( std::ostream &os, int indent ) const { 42 42 Type::print( os, indent ); 43 43 if ( isStatic ) { -
src/SynTree/AttrType.cc
r6840e7c rb96ec83 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AttrType.cc.cc -- 7 // AttrType.cc.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 42 42 } 43 43 44 void AttrType::print( std::ostream &os, Indenterindent ) const {44 void AttrType::print( std::ostream &os, int indent ) const { 45 45 Type::print( os, indent ); 46 46 os << "attribute " << name << " applied to "; -
src/SynTree/Attribute.cc
r6840e7c rb96ec83 28 28 } 29 29 30 void Attribute::print( std::ostream &os, Indenterindent ) const {30 void Attribute::print( std::ostream &os, int indent ) const { 31 31 using std::endl; 32 32 using std::string; … … 36 36 if ( ! parameters.empty() ) { 37 37 os << " with parameters: " << endl; 38 printAll( parameters, os, indent +1);38 printAll( parameters, os, indent ); 39 39 } 40 40 } -
src/SynTree/Attribute.h
r6840e7c rb96ec83 43 43 bool empty() const { return name == ""; } 44 44 45 Attribute * clone() const override{ return new Attribute( *this ); }46 virtual void accept( Visitor & v ) override{ v.visit( this ); }47 virtual Attribute * acceptMutator( Mutator & m ) override{ return m.mutate( this ); }48 virtual void print( std::ostream & os, Indenter indent = {} ) const override;45 Attribute * clone() const { return new Attribute( *this ); } 46 virtual void accept( Visitor & v ) { v.visit( this ); } 47 virtual Attribute * acceptMutator( Mutator & m ) { return m.mutate( this ); } 48 virtual void print( std::ostream & os, int indent = 0 ) const; 49 49 }; 50 50 -
src/SynTree/BaseSyntaxNode.h
r6840e7c rb96ec83 17 17 18 18 #include "Common/CodeLocation.h" 19 #include "Common/Indenter.h"20 19 class Visitor; 21 20 class Mutator; … … 30 29 virtual void accept( Visitor & v ) = 0; 31 30 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. 35 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 } 31 virtual void print( std::ostream & os, int indent = 0 ) const = 0; 39 32 }; 40 33 -
src/SynTree/BasicType.cc
r6840e7c rb96ec83 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // BasicType.cc -- 7 // BasicType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 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:03201713 // Update Count : 1112 // Last Modified On : Mon Sep 11 12:52:05 2017 13 // Update Count : 9 14 14 // 15 15 … … 24 24 BasicType::BasicType( const Type::Qualifiers &tq, Kind bt, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), kind( bt ) {} 25 25 26 void BasicType::print( std::ostream &os, Indenterindent ) const {26 void BasicType::print( std::ostream &os, int indent ) const { 27 27 Type::print( os, indent ); 28 28 os << BasicType::typeNames[ kind ]; … … 43 43 case LongLongSignedInt: 44 44 case LongLongUnsignedInt: 45 case SignedInt128:46 case UnsignedInt128:47 45 return true; 48 46 case Float: -
src/SynTree/CommaExpr.cc
r6840e7c rb96ec83 21 21 #include "Type.h" // for Type 22 22 23 CommaExpr::CommaExpr( Expression *arg1, Expression *arg2 )24 : Expression( ), arg1( arg1 ), arg2( arg2 ) {23 CommaExpr::CommaExpr( Expression *arg1, Expression *arg2, Expression *_aname ) 24 : Expression( _aname ), arg1( arg1 ), arg2( arg2 ) { 25 25 // xxx - result of a comma expression is never an lvalue, so should set lvalue 26 26 // to false on all result types. Actually doing this causes some strange things … … 39 39 } 40 40 41 void CommaExpr::print( std::ostream &os, Indenterindent ) const {41 void CommaExpr::print( std::ostream &os, int indent ) const { 42 42 os << "Comma Expression:" << std::endl; 43 os << (indent+1);44 arg1->print( os, indent+ 1);43 os << std::string( indent+2, ' ' ); 44 arg1->print( os, indent+2 ); 45 45 os << std::endl; 46 os << (indent+1);47 arg2->print( os, indent+ 1);46 os << std::string( indent+2, ' ' ); 47 arg2->print( os, indent+2 ); 48 48 Expression::print( os, indent ); 49 49 } -
src/SynTree/CompoundStmt.cc
r6840e7c rb96ec83 73 73 } 74 74 75 void CompoundStmt::print( std::ostream &os, Indenterindent ) const {76 os << "CompoundStmt" << endl ;77 printAll( kids, os, indent +1);75 void CompoundStmt::print( std::ostream &os, int indent ) const { 76 os << "CompoundStmt" << endl ; 77 printAll( kids, os, indent + 2 ); 78 78 } 79 79 -
src/SynTree/Constant.cc
r6840e7c rb96ec83 71 71 } 72 72 73 void Constant::print( std::ostream &os , Indenter) const {73 void Constant::print( std::ostream &os ) const { 74 74 os << "(" << rep << " " << val.ival; 75 75 if ( type ) { -
src/SynTree/Constant.h
r6840e7c rb96ec83 19 19 #include <string> // for string 20 20 21 #include "BaseSyntaxNode.h"22 21 #include "Mutator.h" // for Mutator 23 22 #include "Visitor.h" // for Visitor … … 25 24 class Type; 26 25 27 class Constant : public BaseSyntaxNode{26 class Constant { 28 27 public: 29 28 Constant( Type * type, std::string rep, unsigned long long val ); … … 31 30 Constant( const Constant & other ); 32 31 virtual ~Constant(); 33 34 virtual Constant * clone() const { return new Constant( *this ); }35 32 36 33 Type * get_type() { return type; } … … 57 54 virtual void accept( Visitor & v ) { v.visit( this ); } 58 55 virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); } 59 virtual void print( std::ostream & os , Indenter indent = 0) const;56 virtual void print( std::ostream & os ) const; 60 57 private: 61 58 Type * type; -
src/SynTree/DeclStmt.cc
r6840e7c rb96ec83 33 33 } 34 34 35 void DeclStmt::print( std::ostream &os, Indenterindent ) const {35 void DeclStmt::print( std::ostream &os, int indent ) const { 36 36 assert( decl != 0 ); 37 37 os << "Declaration of "; -
src/SynTree/Declaration.cc
r6840e7c rb96ec83 42 42 43 43 void Declaration::fixUniqueId() { 44 // don't need to set unique ID twice45 if ( uniqueId ) return;46 44 uniqueId = ++lastUniqueId; 47 45 idMap[ uniqueId ] = this; … … 72 70 } 73 71 74 void AsmDecl::print( std::ostream &os, Indenterindent ) const {72 void AsmDecl::print( std::ostream &os, int indent ) const { 75 73 stmt->print( os, indent ); 76 74 } 77 75 78 void AsmDecl::printShort( std::ostream &os, Indenterindent ) const {76 void AsmDecl::printShort( std::ostream &os, int indent ) const { 79 77 stmt->print( os, indent ); 80 78 } -
src/SynTree/Declaration.h
r6840e7c rb96ec83 61 61 62 62 void fixUniqueId( void ); 63 virtual Declaration *clone() const override= 0;63 virtual Declaration *clone() const = 0; 64 64 virtual void accept( Visitor &v ) override = 0; 65 virtual Declaration *acceptMutator( Mutator &m ) override= 0;66 virtual void print( std::ostream &os, Indenter indent = {}) const override = 0;67 virtual void printShort( std::ostream &os, Indenter indent = {}) const = 0;65 virtual Declaration *acceptMutator( Mutator &m ) = 0; 66 virtual void print( std::ostream &os, int indent = 0 ) const override = 0; 67 virtual void printShort( std::ostream &os, int indent = 0 ) const = 0; 68 68 69 69 static void dumpIds( std::ostream &os ); … … 142 142 virtual void accept( Visitor &v ) override { v.visit( this ); } 143 143 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 144 virtual void print( std::ostream &os, Indenter indent = {}) const override;145 virtual void printShort( std::ostream &os, Indenter indent = {}) const override;144 virtual void print( std::ostream &os, int indent = 0 ) const override; 145 virtual void printShort( std::ostream &os, int indent = 0 ) const override; 146 146 }; 147 147 … … 170 170 virtual void accept( Visitor &v ) override { v.visit( this ); } 171 171 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 172 virtual void print( std::ostream &os, Indenter indent = {}) const override;173 virtual void printShort( std::ostream &os, Indenter indent = {}) const override;172 virtual void print( std::ostream &os, int indent = 0 ) const override; 173 virtual void printShort( std::ostream &os, int indent = 0 ) const override; 174 174 }; 175 175 … … 193 193 194 194 virtual NamedTypeDecl *clone() const override = 0; 195 virtual void print( std::ostream &os, Indenter indent = {}) const override;196 virtual void printShort( std::ostream &os, Indenter indent = {}) const override;195 virtual void print( std::ostream &os, int indent = 0 ) const override; 196 virtual void printShort( std::ostream &os, int indent = 0 ) const override; 197 197 }; 198 198 … … 235 235 virtual void accept( Visitor &v ) override { v.visit( this ); } 236 236 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 237 virtual void print( std::ostream &os, Indenter indent = {}) const override;237 virtual void print( std::ostream &os, int indent = 0 ) const override; 238 238 239 239 private: … … 276 276 AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; } 277 277 278 virtual void print( std::ostream &os, Indenter indent = {}) const override;279 virtual void printShort( std::ostream &os, Indenter indent = {}) const override;278 virtual void print( std::ostream &os, int indent = 0 ) const override; 279 virtual void printShort( std::ostream &os, int indent = 0 ) const override; 280 280 protected: 281 281 virtual std::string typeString() const = 0; … … 355 355 virtual void accept( Visitor &v ) override { v.visit( this ); } 356 356 virtual AsmDecl *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 357 virtual void print( std::ostream &os, Indenter indent = {}) const override;358 virtual void printShort( std::ostream &os, Indenter indent = {}) const override;357 virtual void print( std::ostream &os, int indent = 0 ) const override; 358 virtual void printShort( std::ostream &os, int indent = 0 ) const override; 359 359 }; 360 360 -
src/SynTree/Expression.cc
r6840e7c rb96ec83 33 33 #include "GenPoly/Lvalue.h" 34 34 35 Expression::Expression( ) : result( 0 ), env( 0) {}36 37 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ) {35 Expression::Expression( Expression *_aname ) : result( 0 ), env( 0 ), argName( _aname ) {} 36 37 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) { 38 38 } 39 39 40 40 Expression::~Expression() { 41 41 delete env; 42 delete argName; // xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix 42 43 delete result; 43 44 } 44 45 45 void Expression::print( std::ostream &os, Indenterindent ) const {46 void Expression::print( std::ostream &os, int indent ) const { 46 47 if ( env ) { 47 os << std:: endl << indent << "...with environment:" << std::endl;48 env->print( os, indent+ 1);48 os << std::string( indent, ' ' ) << "with environment:" << std::endl; 49 env->print( os, indent+2 ); 49 50 } // if 50 51 52 if ( argName ) { 53 os << std::string( indent, ' ' ) << "with designator:"; 54 argName->print( os, indent+2 ); 55 } // if 56 51 57 if ( extension ) { 52 os << std:: endl << indent << "...with extension:";58 os << std::string( indent, ' ' ) << "with extension:"; 53 59 } // if 54 60 } 55 61 56 ConstantExpr::ConstantExpr( Constant _c ) : Expression(), constant( _c ) {62 ConstantExpr::ConstantExpr( Constant _c, Expression *_aname ) : Expression( _aname ), constant( _c ) { 57 63 set_result( constant.get_type()->clone() ); 58 64 } … … 63 69 ConstantExpr::~ConstantExpr() {} 64 70 65 void ConstantExpr::print( std::ostream &os, Indenterindent ) const {71 void ConstantExpr::print( std::ostream &os, int indent ) const { 66 72 os << "constant expression " ; 67 73 constant.print( os ); … … 69 75 } 70 76 71 VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) {77 VariableExpr::VariableExpr( DeclarationWithType *_var, Expression *_aname ) : Expression( _aname ), var( _var ) { 72 78 assert( var ); 73 79 assert( var->get_type() ); … … 90 96 } 91 97 92 void VariableExpr::print( std::ostream &os, Indenterindent ) const {98 void VariableExpr::print( std::ostream &os, int indent ) const { 93 99 os << "Variable Expression: "; 94 var->printShort(os, indent); 95 Expression::print( os, indent ); 96 } 97 98 SizeofExpr::SizeofExpr( Expression *expr_ ) : 99 Expression(), expr(expr_), type(0), isType(false) { 100 101 Declaration *decl = get_var(); 102 if ( decl != 0) decl->printShort(os, indent + 2); 103 os << std::endl; 104 Expression::print( os, indent ); 105 } 106 107 SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) : 108 Expression( _aname ), expr(expr_), type(0), isType(false) { 100 109 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 101 110 } 102 111 103 SizeofExpr::SizeofExpr( Type *type_ ) :104 Expression( ), expr(0), type(type_), isType(true) {112 SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) : 113 Expression( _aname ), expr(0), type(type_), isType(true) { 105 114 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 106 115 } … … 115 124 } 116 125 117 void SizeofExpr::print( std::ostream &os, Indenterindent) const {126 void SizeofExpr::print( std::ostream &os, int indent) const { 118 127 os << "Sizeof Expression on: "; 119 if (isType) type->print(os, indent+1); 120 else expr->print(os, indent+1); 121 Expression::print( os, indent ); 122 } 123 124 AlignofExpr::AlignofExpr( Expression *expr_ ) : 125 Expression(), expr(expr_), type(0), isType(false) { 128 129 if (isType) 130 type->print(os, indent + 2); 131 else 132 expr->print(os, indent + 2); 133 134 os << std::endl; 135 Expression::print( os, indent ); 136 } 137 138 AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) : 139 Expression( _aname ), expr(expr_), type(0), isType(false) { 126 140 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 127 141 } 128 142 129 AlignofExpr::AlignofExpr( Type *type_ ) :130 Expression( ), expr(0), type(type_), isType(true) {143 AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) : 144 Expression( _aname ), expr(0), type(type_), isType(true) { 131 145 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 132 146 } … … 141 155 } 142 156 143 void AlignofExpr::print( std::ostream &os, Indenterindent) const {157 void AlignofExpr::print( std::ostream &os, int indent) const { 144 158 os << "Alignof Expression on: "; 145 if (isType) type->print(os, indent+1); 146 else expr->print(os, indent+1); 147 Expression::print( os, indent ); 148 } 149 150 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type, const std::string &member ) : 151 Expression(), type(type), member(member) { 152 assert( type ); 159 160 if (isType) 161 type->print(os, indent + 2); 162 else 163 expr->print(os, indent + 2); 164 165 os << std::endl; 166 Expression::print( os, indent ); 167 } 168 169 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) : 170 Expression( _aname ), type(type_), member(member_) { 153 171 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 154 172 } … … 161 179 } 162 180 163 void UntypedOffsetofExpr::print( std::ostream &os, Indenter indent) const { 164 os << "Untyped Offsetof Expression on member " << member << " of "; 165 type->print(os, indent+1); 166 Expression::print( os, indent ); 167 } 168 169 OffsetofExpr::OffsetofExpr( Type *type, DeclarationWithType *member ) : 170 Expression(), type(type), member(member) { 171 assert( member ); 172 assert( type ); 181 void UntypedOffsetofExpr::print( std::ostream &os, int indent) const { 182 os << std::string( indent, ' ' ) << "Untyped Offsetof Expression on member " << member << " of "; 183 184 if ( type ) { 185 type->print(os, indent + 2); 186 } else { 187 os << "<NULL>"; 188 } 189 190 os << std::endl; 191 Expression::print( os, indent ); 192 } 193 194 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) : 195 Expression( _aname ), type(type_), member(member_) { 173 196 set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ); 174 197 } … … 181 204 } 182 205 183 void OffsetofExpr::print( std::ostream &os, Indenter indent) const { 184 os << "Offsetof Expression on member " << member->name << " of "; 185 type->print(os, indent+1); 186 Expression::print( os, indent ); 187 } 188 189 OffsetPackExpr::OffsetPackExpr( StructInstType *type ) : Expression(), type( type ) { 190 assert( type ); 206 void OffsetofExpr::print( std::ostream &os, int indent) const { 207 os << std::string( indent, ' ' ) << "Offsetof Expression on member "; 208 209 if ( member ) { 210 os << member->get_name(); 211 } else { 212 os << "<NULL>"; 213 } 214 215 os << " of "; 216 217 if ( type ) { 218 type->print(os, indent + 2); 219 } else { 220 os << "<NULL>"; 221 } 222 223 os << std::endl; 224 Expression::print( os, indent ); 225 } 226 227 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) { 191 228 set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 192 229 } … … 196 233 OffsetPackExpr::~OffsetPackExpr() { delete type; } 197 234 198 void OffsetPackExpr::print( std::ostream &os, Indenter indent ) const { 199 os << "Offset pack expression on "; 200 type->print(os, indent+1); 201 Expression::print( os, indent ); 202 } 203 204 AttrExpr::AttrExpr( Expression *attr, Expression *expr_ ) : 205 Expression(), attr( attr ), expr(expr_), type(0), isType(false) { 206 } 207 208 AttrExpr::AttrExpr( Expression *attr, Type *type_ ) : 209 Expression(), attr( attr ), expr(0), type(type_), isType(true) { 235 void OffsetPackExpr::print( std::ostream &os, int indent ) const { 236 os << std::string( indent, ' ' ) << "Offset pack expression on "; 237 238 if ( type ) { 239 type->print(os, indent + 2); 240 } else { 241 os << "<NULL>"; 242 } 243 244 os << std::endl; 245 Expression::print( os, indent ); 246 } 247 248 AttrExpr::AttrExpr( Expression *attr, Expression *expr_, Expression *_aname ) : 249 Expression( _aname ), attr( attr ), expr(expr_), type(0), isType(false) { 250 } 251 252 AttrExpr::AttrExpr( Expression *attr, Type *type_, Expression *_aname ) : 253 Expression( _aname ), attr( attr ), expr(0), type(type_), isType(true) { 210 254 } 211 255 … … 220 264 } 221 265 222 void AttrExpr::print( std::ostream &os, Indenterindent) const {266 void AttrExpr::print( std::ostream &os, int indent) const { 223 267 os << "Attr "; 224 attr->print( os, indent +1);268 attr->print( os, indent + 2 ); 225 269 if ( isType || expr ) { 226 270 os << "applied to: "; 227 if (isType) type->print(os, indent+1); 228 else expr->print(os, indent+1); 271 272 if (isType) 273 type->print(os, indent + 2); 274 else 275 expr->print(os, indent + 2); 229 276 } // if 230 Expression::print( os, indent ); 231 } 232 233 CastExpr::CastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) { 277 278 os << std::endl; 279 Expression::print( os, indent ); 280 } 281 282 CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_) { 234 283 set_result(toType); 235 284 } 236 285 237 CastExpr::CastExpr( Expression *arg_ ) : Expression(), arg(arg_) {286 CastExpr::CastExpr( Expression *arg_, Expression *_aname ) : Expression( _aname ), arg(arg_) { 238 287 set_result( new VoidType( Type::Qualifiers() ) ); 239 288 } … … 246 295 } 247 296 248 void CastExpr::print( std::ostream &os, Indenter indent ) const { 249 os << "Cast of:" << std::endl << indent+1; 250 arg->print(os, indent+1); 251 os << std::endl << indent << "... to:"; 297 void CastExpr::print( std::ostream &os, int indent ) const { 298 os << "Cast of:" << std::endl << std::string( indent+2, ' ' ); 299 arg->print(os, indent+2); 300 os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl; 301 os << std::string( indent+2, ' ' ); 252 302 if ( result->isVoid() ) { 253 os << " nothing";303 os << "nothing"; 254 304 } else { 255 os << std::endl << indent+1; 256 result->print( os, indent+1 ); 305 result->print( os, indent+2 ); 257 306 } // if 307 os << std::endl; 258 308 Expression::print( os, indent ); 259 309 } … … 270 320 } 271 321 272 void VirtualCastExpr::print( std::ostream &os, Indenter indent ) const { 273 os << "Virtual Cast of:" << std::endl << indent+1; 274 arg->print(os, indent+1); 275 os << std::endl << indent << "... to:"; 322 void VirtualCastExpr::print( std::ostream &os, int indent ) const { 323 os << "Virtual Cast of:" << std::endl << std::string( indent+2, ' ' ); 324 arg->print(os, indent+2); 325 os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl; 326 os << std::string( indent+2, ' ' ); 276 327 if ( ! result ) { 277 os << " unknown";328 os << "unknown"; 278 329 } else { 279 os << std::endl << indent+1; 280 result->print( os, indent+1 ); 330 result->print( os, indent+2 ); 281 331 } // if 282 Expression::print( os, indent ); 283 } 284 285 UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression *aggregate ) : 286 Expression(), member(member), aggregate(aggregate) { 287 assert( aggregate ); 288 } 332 os << std::endl; 333 Expression::print( os, indent ); 334 } 335 336 UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) : 337 Expression( _aname ), member(_member), aggregate(_aggregate) {} 289 338 290 339 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) : … … 297 346 } 298 347 299 void UntypedMemberExpr::print( std::ostream &os, Indenter indent ) const { 300 os << "Untyped Member Expression, with field: " << std::endl << indent+1; 301 member->print(os, indent+1 ); 302 os << indent << "... from aggregate: " << std::endl << indent+1; 303 aggregate->print(os, indent+1); 348 void UntypedMemberExpr::print( std::ostream &os, int indent ) const { 349 os << "Untyped Member Expression, with field: " << std::endl; 350 os << std::string( indent+2, ' ' ); 351 get_member()->print(os, indent+4); 352 os << std::string( indent+2, ' ' ); 353 354 Expression *agg = get_aggregate(); 355 os << "from aggregate: " << std::endl; 356 if (agg != 0) { 357 os << std::string( indent + 4, ' ' ); 358 agg->print(os, indent + 4); 359 } 360 os << std::string( indent+2, ' ' ); 304 361 Expression::print( os, indent ); 305 362 } … … 320 377 321 378 322 MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) : 323 Expression(), member(member), aggregate(aggregate) { 324 assert( member ); 325 assert( aggregate ); 379 MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) : 380 Expression( _aname ), member(_member), aggregate(_aggregate) { 326 381 327 382 TypeSubstitution sub( makeSub( aggregate->get_result() ) ); … … 341 396 } 342 397 343 void MemberExpr::print( std::ostream &os, Indenterindent ) const {398 void MemberExpr::print( std::ostream &os, int indent ) const { 344 399 os << "Member Expression, with field: " << std::endl; 345 os << indent+1; 346 member->print( os, indent+1 ); 347 os << std::endl << indent << "... from aggregate: " << std::endl << indent+1; 348 aggregate->print(os, indent + 1); 349 Expression::print( os, indent ); 350 } 351 352 UntypedExpr::UntypedExpr( Expression *function, const std::list<Expression *> &args ) : 353 Expression(), function(function), args(args) {} 400 401 assert( member ); 402 os << std::string( indent + 2, ' ' ); 403 member->print( os, indent + 2 ); 404 os << std::endl; 405 406 Expression *agg = get_aggregate(); 407 os << std::string( indent, ' ' ) << "from aggregate: " << std::endl; 408 if (agg != 0) { 409 os << std::string( indent + 2, ' ' ); 410 agg->print(os, indent + 2); 411 } 412 os << std::string( indent+2, ' ' ); 413 Expression::print( os, indent ); 414 } 415 416 UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) : 417 Expression( _aname ), function(_function), args(_args) {} 354 418 355 419 UntypedExpr::UntypedExpr( const UntypedExpr &other ) : … … 392 456 393 457 394 void UntypedExpr::print( std::ostream &os, Indenterindent ) const {458 void UntypedExpr::print( std::ostream &os, int indent ) const { 395 459 os << "Applying untyped: " << std::endl; 396 os << indent+1; 397 function->print(os, indent+1); 398 os << std::endl << indent << "...to: " << std::endl; 399 printAll(args, os, indent+1); 400 Expression::print( os, indent ); 401 } 402 403 NameExpr::NameExpr( std::string name ) : Expression(), name(name) { 404 assertf(name != "0", "Zero is not a valid name"); 405 assertf(name != "1", "One is not a valid name"); 460 os << std::string( indent+2, ' ' ); 461 function->print(os, indent + 2); 462 os << std::string( indent, ' ' ) << "...to: " << std::endl; 463 printAll(args, os, indent + 2); 464 Expression::print( os, indent ); 465 } 466 467 void UntypedExpr::printArgs( std::ostream &os, int indent ) const { 468 std::list<Expression *>::const_iterator i; 469 for (i = args.begin(); i != args.end(); i++) { 470 os << std::string(indent, ' ' ); 471 (*i)->print(os, indent); 472 } 473 } 474 475 NameExpr::NameExpr( std::string _name, Expression *_aname ) : Expression( _aname ), name(_name) { 476 assertf(_name != "0", "Zero is not a valid name\n"); 477 assertf(_name != "1", "One is not a valid name\n"); 406 478 } 407 479 … … 411 483 NameExpr::~NameExpr() {} 412 484 413 void NameExpr::print( std::ostream &os, Indenterindent ) const {414 os << "Name: " << get_name() ;415 Expression::print( os, indent ); 416 } 417 418 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp ) :419 Expression( ), arg1(arg1_), arg2(arg2_), isAnd(andp) {485 void NameExpr::print( std::ostream &os, int indent ) const { 486 os << "Name: " << get_name() << std::endl; 487 Expression::print( os, indent ); 488 } 489 490 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp, Expression *_aname ) : 491 Expression( _aname ), arg1(arg1_), arg2(arg2_), isAnd(andp) { 420 492 set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 421 493 } … … 430 502 } 431 503 432 void LogicalExpr::print( std::ostream &os, Indenterindent )const {433 os << "Short-circuited operation (" << (isAnd ? "and" :"or") << ") on: ";504 void LogicalExpr::print( std::ostream &os, int indent )const { 505 os << "Short-circuited operation (" << (isAnd?"and":"or") << ") on: "; 434 506 arg1->print(os); 435 507 os << " and "; 436 508 arg2->print(os); 437 Expression::print( os, indent ); 438 } 439 440 ConditionalExpr::ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 ) : 441 Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {} 509 os << std::endl; 510 Expression::print( os, indent ); 511 } 512 513 ConditionalExpr::ConditionalExpr( Expression *arg1_, Expression *arg2_, Expression *arg3_, Expression *_aname ) : 514 Expression( _aname ), arg1(arg1_), arg2(arg2_), arg3(arg3_) {} 442 515 443 516 ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) : … … 451 524 } 452 525 453 void ConditionalExpr::print( std::ostream &os, Indenter indent ) const { 454 os << "Conditional expression on: " << std::endl << indent+1; 455 arg1->print( os, indent+1 ); 456 os << indent << "First alternative:" << std::endl << indent+1; 457 arg2->print( os, indent+1 ); 458 os << indent << "Second alternative:" << std::endl << indent+1; 459 arg3->print( os, indent+1 ); 526 void ConditionalExpr::print( std::ostream &os, int indent ) const { 527 os << "Conditional expression on: " << std::endl; 528 os << std::string( indent+2, ' ' ); 529 arg1->print( os, indent+2 ); 530 os << std::string( indent, ' ' ) << "First alternative:" << std::endl; 531 os << std::string( indent+2, ' ' ); 532 arg2->print( os, indent+2 ); 533 os << std::string( indent, ' ' ) << "Second alternative:" << std::endl; 534 os << std::string( indent+2, ' ' ); 535 arg3->print( os, indent+2 ); 536 os << std::endl; 460 537 Expression::print( os, indent ); 461 538 } … … 464 541 465 542 466 void AsmExpr::print( std::ostream &os, Indenterindent ) const {543 void AsmExpr::print( std::ostream &os, int indent ) const { 467 544 os << "Asm Expression: " << std::endl; 468 if ( inout ) inout->print( os, indent +1);469 if ( constraint ) constraint->print( os, indent +1);470 if ( operand ) operand->print( os, indent +1);545 if ( inout ) inout->print( os, indent + 2 ); 546 if ( constraint ) constraint->print( os, indent + 2 ); 547 if ( operand ) operand->print( os, indent + 2 ); 471 548 } 472 549 … … 474 551 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) { 475 552 assert( callExpr ); 476 assert( callExpr-> result);553 assert( callExpr->has_result() ); 477 554 set_result( callExpr->get_result()->clone() ); 478 555 } … … 492 569 } 493 570 494 void ImplicitCopyCtorExpr::print( std::ostream &os, Indenter indent ) const { 495 os << "Implicit Copy Constructor Expression: " << std::endl << indent+1; 496 callExpr->print( os, indent+1 ); 497 os << std::endl << indent << "... with temporaries:" << std::endl; 498 printAll( tempDecls, os, indent+1 ); 499 os << std::endl << indent << "... with return temporaries:" << std::endl; 500 printAll( returnDecls, os, indent+1 ); 571 void ImplicitCopyCtorExpr::print( std::ostream &os, int indent ) const { 572 os << "Implicit Copy Constructor Expression: " << std::endl; 573 assert( callExpr ); 574 os << std::string( indent+2, ' ' ); 575 callExpr->print( os, indent + 2 ); 576 os << std::endl << std::string( indent, ' ' ) << "with temporaries:" << std::endl; 577 printAll(tempDecls, os, indent+2); 578 os << std::endl << std::string( indent, ' ' ) << "with return temporaries:" << std::endl; 579 printAll(returnDecls, os, indent+2); 501 580 Expression::print( os, indent ); 502 581 } … … 508 587 Expression * arg = InitTweak::getCallArg( callExpr, 0 ); 509 588 assert( arg ); 510 set_result( maybeClone( arg-> result) );589 set_result( maybeClone( arg->get_result() ) ); 511 590 } 512 591 … … 518 597 } 519 598 520 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const { 521 os << "Constructor Expression: " << std::endl << indent+1; 599 void ConstructorExpr::print( std::ostream &os, int indent ) const { 600 os << "Constructor Expression: " << std::endl; 601 assert( callExpr ); 602 os << std::string( indent+2, ' ' ); 522 603 callExpr->print( os, indent + 2 ); 523 604 Expression::print( os, indent ); … … 537 618 } 538 619 539 void CompoundLiteralExpr::print( std::ostream &os, Indenter indent ) const { 540 os << "Compound Literal Expression: " << std::endl << indent+1; 541 result->print( os, indent+1 ); 542 os << indent+1; 543 initializer->print( os, indent+1 ); 620 void CompoundLiteralExpr::print( std::ostream &os, int indent ) const { 621 os << "Compound Literal Expression: " << std::endl; 622 os << std::string( indent+2, ' ' ); 623 get_result()->print( os, indent + 2 ); 624 os << std::string( indent+2, ' ' ); 625 initializer->print( os, indent + 2 ); 544 626 Expression::print( os, indent ); 545 627 } … … 547 629 RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {} 548 630 RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {} 549 void RangeExpr::print( std::ostream &os, Indenterindent ) const {631 void RangeExpr::print( std::ostream &os, int indent ) const { 550 632 os << "Range Expression: "; 551 633 low->print( os, indent ); … … 577 659 deleteAll( returnDecls ); 578 660 } 579 void StmtExpr::print( std::ostream &os, Indenterindent ) const {580 os << "Statement Expression: " << std::endl << indent+1;581 statements->print( os, indent+ 1);661 void StmtExpr::print( std::ostream &os, int indent ) const { 662 os << "Statement Expression: " << std::endl << std::string( indent, ' ' ); 663 statements->print( os, indent+2 ); 582 664 if ( ! returnDecls.empty() ) { 583 os << indent+1 << "...with returnDecls: ";584 printAll( returnDecls, os, indent+ 1);665 os << std::string( indent+2, ' ' ) << "with returnDecls: "; 666 printAll( returnDecls, os, indent+2 ); 585 667 } 586 668 if ( ! dtors.empty() ) { 587 os << indent+1 << "...with dtors: ";588 printAll( dtors, os, indent+ 1);669 os << std::string( indent+2, ' ' ) << "with dtors: "; 670 printAll( dtors, os, indent+2 ); 589 671 } 590 672 Expression::print( os, indent ); … … 608 690 delete var; 609 691 } 610 void UniqueExpr::print( std::ostream &os, Indenterindent ) const {611 os << "Unique Expression with id:" << id << std::endl << indent+1;612 expr->print( os, indent+1);613 if ( object) {614 os << indent << "...with decl: ";615 get_object()->printShort( os, indent+ 1);692 void UniqueExpr::print( std::ostream &os, int indent ) const { 693 os << "Unique Expression with id:" << id << std::endl << std::string( indent+2, ' ' ); 694 get_expr()->print( os, indent+2 ); 695 if ( get_object() ) { 696 os << std::string( indent+2, ' ' ) << "with decl: "; 697 get_object()->printShort( os, indent+2 ); 616 698 } 617 699 Expression::print( os, indent ); … … 631 713 } 632 714 633 void UntypedInitExpr::print( std::ostream & os, Indenterindent ) const {634 os << "Untyped Init Expression" << std::endl << indent+1;635 expr->print( os, indent+ 1);715 void UntypedInitExpr::print( std::ostream & os, int indent ) const { 716 os << "Untyped Init Expression" << std::endl << std::string( indent+2, ' ' ); 717 expr->print( os, indent+2 ); 636 718 if ( ! initAlts.empty() ) { 637 719 for ( const InitAlternative & alt : initAlts ) { 638 os << indent+1<< "InitAlternative: ";639 alt.type->print( os, indent+ 1);640 alt.designation->print( os, indent+ 1);720 os << std::string( indent+2, ' ' ) << "InitAlternative: "; 721 alt.type->print( os, indent+2 ); 722 alt.designation->print( os, indent+2 ); 641 723 } 642 724 } … … 652 734 } 653 735 654 void InitExpr::print( std::ostream & os, Indenterindent ) const {655 os << "Init Expression" << std::endl << indent+1;656 expr->print( os, indent+ 1);657 os << indent+1 << "...with designation: ";658 designation->print( os, indent+ 1);736 void InitExpr::print( std::ostream & os, int indent ) const { 737 os << "Init Expression" << std::endl << std::string( indent+2, ' ' ); 738 expr->print( os, indent+2 ); 739 os << std::string( indent+2, ' ' ) << "with designation: "; 740 designation->print( os, indent+2 ); 659 741 } 660 742 -
src/SynTree/Expression.h
r6840e7c rb96ec83 36 36 Type * result; 37 37 TypeSubstitution * env; 38 Expression * argName; // if expression is used as an argument, it can be "designated" by this name 38 39 bool extension = false; 39 40 40 Expression( );41 Expression( Expression * _aname = nullptr ); 41 42 Expression( const Expression & other ); 42 43 virtual ~Expression(); … … 45 46 const Type * get_result() const { return result; } 46 47 void set_result( Type * newValue ) { result = newValue; } 48 bool has_result() const { return result != nullptr; } 47 49 48 50 TypeSubstitution * get_env() const { return env; } 49 51 void set_env( TypeSubstitution * newValue ) { env = newValue; } 52 Expression * get_argName() const { return argName; } 53 void set_argName( Expression * name ) { argName = name; } 50 54 bool get_extension() const { return extension; } 51 55 Expression * set_extension( bool exten ) { extension = exten; return this; } 52 56 53 virtual Expression * clone() const override= 0;54 virtual void accept( Visitor & v ) override= 0;55 virtual Expression * acceptMutator( Mutator & m ) override= 0;56 virtual void print( std::ostream & os, Indenter indent = {} ) const override;57 virtual Expression * clone() const = 0; 58 virtual void accept( Visitor & v ) = 0; 59 virtual Expression * acceptMutator( Mutator & m ) = 0; 60 virtual void print( std::ostream & os, int indent = 0 ) const; 57 61 }; 58 62 … … 97 101 virtual void accept( Visitor & v ) { v.visit( this ); } 98 102 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 99 virtual void print( std::ostream & os, Indenter indent = {}) const;103 virtual void print( std::ostream & os, int indent = 0 ) const; 100 104 }; 101 105 … … 108 112 std::list<Expression*> args; 109 113 110 UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() );114 UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >(), Expression *_aname = nullptr ); 111 115 UntypedExpr( const UntypedExpr & other ); 112 116 virtual ~UntypedExpr(); … … 115 119 void set_function( Expression * newValue ) { function = newValue; } 116 120 121 void set_args( std::list<Expression *> & listArgs ) { args = listArgs; } 117 122 std::list<Expression*>::iterator begin_args() { return args.begin(); } 118 123 std::list<Expression*>::iterator end_args() { return args.end(); } … … 125 130 virtual void accept( Visitor & v ) { v.visit( this ); } 126 131 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 127 virtual void print( std::ostream & os, Indenter indent = {} ) const; 132 virtual void print( std::ostream & os, int indent = 0 ) const; 133 virtual void printArgs(std::ostream & os, int indent = 0) const; 128 134 }; 129 135 … … 133 139 std::string name; 134 140 135 NameExpr( std::string name );141 NameExpr( std::string name, Expression *_aname = nullptr ); 136 142 NameExpr( const NameExpr & other ); 137 143 virtual ~NameExpr(); … … 143 149 virtual void accept( Visitor & v ) { v.visit( this ); } 144 150 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 145 virtual void print( std::ostream & os, Indenter indent = {}) const;151 virtual void print( std::ostream & os, int indent = 0 ) const; 146 152 }; 147 153 … … 154 160 Expression * arg; 155 161 156 AddressExpr( Expression * arg );162 AddressExpr( Expression * arg, Expression *_aname = nullptr ); 157 163 AddressExpr( const AddressExpr & other ); 158 164 virtual ~AddressExpr(); … … 164 170 virtual void accept( Visitor & v ) { v.visit( this ); } 165 171 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 166 virtual void print( std::ostream & os, Indenter indent = {}) const;172 virtual void print( std::ostream & os, int indent = 0 ) const; 167 173 }; 168 174 … … 180 186 virtual void accept( Visitor & v ) { v.visit( this ); } 181 187 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 182 virtual void print( std::ostream & os, Indenter indent = {}) const;188 virtual void print( std::ostream & os, int indent = 0 ) const; 183 189 }; 184 190 … … 188 194 Expression * arg; 189 195 190 CastExpr( Expression * arg );191 CastExpr( Expression * arg, Type * toType );196 CastExpr( Expression * arg, Expression *_aname = nullptr ); 197 CastExpr( Expression * arg, Type * toType, Expression *_aname = nullptr ); 192 198 CastExpr( const CastExpr & other ); 193 199 virtual ~CastExpr(); … … 199 205 virtual void accept( Visitor & v ) { v.visit( this ); } 200 206 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 201 virtual void print( std::ostream & os, Indenter indent = {}) const;207 virtual void print( std::ostream & os, int indent = 0 ) const; 202 208 }; 203 209 … … 217 223 virtual void accept( Visitor & v ) { v.visit( this ); } 218 224 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 219 virtual void print( std::ostream & os, Indenter indent = {}) const;225 virtual void print( std::ostream & os, int indent = 0 ) const; 220 226 }; 221 227 … … 226 232 Expression * aggregate; 227 233 228 UntypedMemberExpr( Expression * member, Expression * aggregate );234 UntypedMemberExpr( Expression * member, Expression * aggregate, Expression *_aname = nullptr ); 229 235 UntypedMemberExpr( const UntypedMemberExpr & other ); 230 236 virtual ~UntypedMemberExpr(); … … 238 244 virtual void accept( Visitor & v ) { v.visit( this ); } 239 245 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 240 virtual void print( std::ostream & os, Indenter indent = {}) const;246 virtual void print( std::ostream & os, int indent = 0 ) const; 241 247 }; 242 248 … … 248 254 Expression * aggregate; 249 255 250 MemberExpr( DeclarationWithType * member, Expression * aggregate );256 MemberExpr( DeclarationWithType * member, Expression * aggregate, Expression *_aname = nullptr ); 251 257 MemberExpr( const MemberExpr & other ); 252 258 virtual ~MemberExpr(); … … 260 266 virtual void accept( Visitor & v ) { v.visit( this ); } 261 267 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 262 virtual void print( std::ostream & os, Indenter indent = {}) const;268 virtual void print( std::ostream & os, int indent = 0 ) const; 263 269 }; 264 270 … … 269 275 DeclarationWithType * var; 270 276 271 VariableExpr( DeclarationWithType * var );277 VariableExpr( DeclarationWithType * var, Expression *_aname = nullptr ); 272 278 VariableExpr( const VariableExpr & other ); 273 279 virtual ~VariableExpr(); … … 281 287 virtual void accept( Visitor & v ) { v.visit( this ); } 282 288 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 283 virtual void print( std::ostream & os, Indenter indent = {}) const;289 virtual void print( std::ostream & os, int indent = 0 ) const; 284 290 }; 285 291 … … 289 295 Constant constant; 290 296 291 ConstantExpr( Constant constant );297 ConstantExpr( Constant constant, Expression *_aname = nullptr ); 292 298 ConstantExpr( const ConstantExpr & other ); 293 299 virtual ~ConstantExpr(); … … 299 305 virtual void accept( Visitor & v ) { v.visit( this ); } 300 306 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 301 virtual void print( std::ostream & os, Indenter indent = {}) const;307 virtual void print( std::ostream & os, int indent = 0 ) const; 302 308 }; 303 309 … … 309 315 bool isType; 310 316 311 SizeofExpr( Expression * expr );317 SizeofExpr( Expression * expr, Expression *_aname = nullptr ); 312 318 SizeofExpr( const SizeofExpr & other ); 313 SizeofExpr( Type * type );319 SizeofExpr( Type * type, Expression *_aname = nullptr ); 314 320 virtual ~SizeofExpr(); 315 321 … … 324 330 virtual void accept( Visitor & v ) { v.visit( this ); } 325 331 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 326 virtual void print( std::ostream & os, Indenter indent = {}) const;332 virtual void print( std::ostream & os, int indent = 0 ) const; 327 333 }; 328 334 … … 334 340 bool isType; 335 341 336 AlignofExpr( Expression * expr );342 AlignofExpr( Expression * expr, Expression *_aname = nullptr ); 337 343 AlignofExpr( const AlignofExpr & other ); 338 AlignofExpr( Type * type );344 AlignofExpr( Type * type, Expression *_aname = nullptr ); 339 345 virtual ~AlignofExpr(); 340 346 … … 349 355 virtual void accept( Visitor & v ) { v.visit( this ); } 350 356 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 351 virtual void print( std::ostream & os, Indenter indent = {}) const;357 virtual void print( std::ostream & os, int indent = 0 ) const; 352 358 }; 353 359 … … 358 364 std::string member; 359 365 360 UntypedOffsetofExpr( Type * type, const std::string & member );366 UntypedOffsetofExpr( Type * type, const std::string & member, Expression *_aname = nullptr ); 361 367 UntypedOffsetofExpr( const UntypedOffsetofExpr & other ); 362 368 virtual ~UntypedOffsetofExpr(); … … 370 376 virtual void accept( Visitor & v ) { v.visit( this ); } 371 377 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 372 virtual void print( std::ostream & os, Indenter indent = {}) const;378 virtual void print( std::ostream & os, int indent = 0 ) const; 373 379 }; 374 380 … … 379 385 DeclarationWithType * member; 380 386 381 OffsetofExpr( Type * type, DeclarationWithType * member );387 OffsetofExpr( Type * type, DeclarationWithType * member, Expression *_aname = nullptr ); 382 388 OffsetofExpr( const OffsetofExpr & other ); 383 389 virtual ~OffsetofExpr(); … … 391 397 virtual void accept( Visitor & v ) { v.visit( this ); } 392 398 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 393 virtual void print( std::ostream & os, Indenter indent = {}) const;399 virtual void print( std::ostream & os, int indent = 0 ) const; 394 400 }; 395 401 … … 399 405 StructInstType * type; 400 406 401 OffsetPackExpr( StructInstType * type );407 OffsetPackExpr( StructInstType * type_, Expression * aname_ = 0 ); 402 408 OffsetPackExpr( const OffsetPackExpr & other ); 403 409 virtual ~OffsetPackExpr(); … … 409 415 virtual void accept( Visitor & v ) { v.visit( this ); } 410 416 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 411 virtual void print( std::ostream & os, Indenter indent = {}) const;417 virtual void print( std::ostream & os, int indent = 0 ) const; 412 418 }; 413 419 … … 420 426 bool isType; 421 427 422 AttrExpr(Expression * attr, Expression * expr );428 AttrExpr(Expression * attr, Expression * expr, Expression *_aname = nullptr ); 423 429 AttrExpr( const AttrExpr & other ); 424 AttrExpr( Expression * attr, Type * type );430 AttrExpr( Expression * attr, Type * type, Expression *_aname = nullptr ); 425 431 virtual ~AttrExpr(); 426 432 … … 437 443 virtual void accept( Visitor & v ) { v.visit( this ); } 438 444 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 439 virtual void print( std::ostream & os, Indenter indent = {}) const;445 virtual void print( std::ostream & os, int indent = 0 ) const; 440 446 }; 441 447 … … 446 452 Expression * arg2; 447 453 448 LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true );454 LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true, Expression *_aname = nullptr ); 449 455 LogicalExpr( const LogicalExpr & other ); 450 456 virtual ~LogicalExpr(); … … 459 465 virtual void accept( Visitor & v ) { v.visit( this ); } 460 466 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 461 virtual void print( std::ostream & os, Indenter indent = {}) const;467 virtual void print( std::ostream & os, int indent = 0 ) const; 462 468 463 469 private: … … 472 478 Expression * arg3; 473 479 474 ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 );480 ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3, Expression *_aname = nullptr ); 475 481 ConditionalExpr( const ConditionalExpr & other ); 476 482 virtual ~ConditionalExpr(); … … 486 492 virtual void accept( Visitor & v ) { v.visit( this ); } 487 493 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 488 virtual void print( std::ostream & os, Indenter indent = {}) const;494 virtual void print( std::ostream & os, int indent = 0 ) const; 489 495 }; 490 496 … … 495 501 Expression * arg2; 496 502 497 CommaExpr( Expression * arg1, Expression * arg2 );503 CommaExpr( Expression * arg1, Expression * arg2, Expression *_aname = nullptr ); 498 504 CommaExpr( const CommaExpr & other ); 499 505 virtual ~CommaExpr(); … … 507 513 virtual void accept( Visitor & v ) { v.visit( this ); } 508 514 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 509 virtual void print( std::ostream & os, Indenter indent = {}) const;515 virtual void print( std::ostream & os, int indent = 0 ) const; 510 516 }; 511 517 … … 525 531 virtual void accept( Visitor & v ) { v.visit( this ); } 526 532 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 527 virtual void print( std::ostream & os, Indenter indent = {}) const;533 virtual void print( std::ostream & os, int indent = 0 ) const; 528 534 }; 529 535 … … 551 557 virtual void accept( Visitor & v ) { v.visit( this ); } 552 558 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 553 virtual void print( std::ostream & os, Indenter indent = {}) const;559 virtual void print( std::ostream & os, int indent = 0 ) const; 554 560 555 561 // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints … … 579 585 virtual void accept( Visitor & v ) { v.visit( this ); } 580 586 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 581 virtual void print( std::ostream & os, Indenter indent = {}) const;587 virtual void print( std::ostream & os, int indent = 0 ) const; 582 588 }; 583 589 … … 597 603 virtual void accept( Visitor & v ) { v.visit( this ); } 598 604 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 599 virtual void print( std::ostream & os, Indenter indent = {}) const;605 virtual void print( std::ostream & os, int indent = 0 ) const; 600 606 }; 601 607 … … 615 621 virtual void accept( Visitor & v ) { v.visit( this ); } 616 622 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 617 virtual void print( std::ostream & os, Indenter indent = {}) const;623 virtual void print( std::ostream & os, int indent = 0 ) const; 618 624 }; 619 625 … … 634 640 virtual void accept( Visitor & v ) { v.visit( this ); } 635 641 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 636 virtual void print( std::ostream & os, Indenter indent = {}) const;642 virtual void print( std::ostream & os, int indent = 0 ) const; 637 643 }; 638 644 … … 642 648 std::list<Expression*> exprs; 643 649 644 UntypedTupleExpr( const std::list< Expression * > & exprs );650 UntypedTupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr ); 645 651 UntypedTupleExpr( const UntypedTupleExpr & other ); 646 652 virtual ~UntypedTupleExpr(); … … 651 657 virtual void accept( Visitor & v ) { v.visit( this ); } 652 658 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 653 virtual void print( std::ostream & os, Indenter indent = {}) const;659 virtual void print( std::ostream & os, int indent = 0 ) const; 654 660 }; 655 661 … … 659 665 std::list<Expression*> exprs; 660 666 661 TupleExpr( const std::list< Expression * > & exprs );667 TupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr ); 662 668 TupleExpr( const TupleExpr & other ); 663 669 virtual ~TupleExpr(); … … 668 674 virtual void accept( Visitor & v ) { v.visit( this ); } 669 675 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 670 virtual void print( std::ostream & os, Indenter indent = {}) const;676 virtual void print( std::ostream & os, int indent = 0 ) const; 671 677 }; 672 678 … … 689 695 virtual void accept( Visitor & v ) { v.visit( this ); } 690 696 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 691 virtual void print( std::ostream & os, Indenter indent = {}) const;697 virtual void print( std::ostream & os, int indent = 0 ) const; 692 698 }; 693 699 … … 697 703 StmtExpr * stmtExpr = nullptr; 698 704 699 TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls );705 TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname = nullptr ); 700 706 TupleAssignExpr( const TupleAssignExpr & other ); 701 707 virtual ~TupleAssignExpr(); … … 707 713 virtual void accept( Visitor & v ) { v.visit( this ); } 708 714 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 709 virtual void print( std::ostream & os, Indenter indent = {}) const;715 virtual void print( std::ostream & os, int indent = 0 ) const; 710 716 }; 711 717 … … 730 736 virtual void accept( Visitor & v ) { v.visit( this ); } 731 737 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 732 virtual void print( std::ostream & os, Indenter indent = {}) const;738 virtual void print( std::ostream & os, int indent = 0 ) const; 733 739 }; 734 740 … … 757 763 virtual void accept( Visitor & v ) { v.visit( this ); } 758 764 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 759 virtual void print( std::ostream & os, Indenter indent = {}) const;765 virtual void print( std::ostream & os, int indent = 0 ) const; 760 766 761 767 private: … … 791 797 virtual void accept( Visitor & v ) { v.visit( this ); } 792 798 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 793 virtual void print( std::ostream & os, Indenter indent = {}) const;799 virtual void print( std::ostream & os, int indent = 0 ) const; 794 800 }; 795 801 … … 812 818 virtual void accept( Visitor & v ) { v.visit( this ); } 813 819 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 814 virtual void print( std::ostream & os, Indenter indent = {}) const;820 virtual void print( std::ostream & os, int indent = 0 ) const; 815 821 }; 816 822 -
src/SynTree/FunctionDecl.cc
r6840e7c rb96ec83 63 63 } 64 64 65 void FunctionDecl::print( std::ostream &os, Indenterindent ) const {65 void FunctionDecl::print( std::ostream &os, int indent ) const { 66 66 using std::endl; 67 67 using std::string; 68 68 69 if ( name!= "" ) {70 os << name<< ": ";69 if ( get_name() != "" ) { 70 os << get_name() << ": "; 71 71 } // if 72 if ( linkage!= LinkageSpec::Cforall ) {73 os << LinkageSpec::linkageName( linkage) << " ";72 if ( get_linkage() != LinkageSpec::Cforall ) { 73 os << LinkageSpec::linkageName( get_linkage() ) << " "; 74 74 } // if 75 75 76 printAll( attributes, os, indent );76 printAll( get_attributes(), os, indent ); 77 77 78 78 get_storageClasses().print( os ); 79 79 get_funcSpec().print( os ); 80 80 81 if ( type) {82 type->print( os, indent );81 if ( get_type() ) { 82 get_type()->print( os, indent ); 83 83 } else { 84 84 os << "untyped entity "; … … 86 86 87 87 if ( statements ) { 88 os << indent << "... with body " << endl << indent+1; 89 statements->print( os, indent+1 ); 88 os << string( indent + 2, ' ' ) << "with body " << endl; 89 os << string( indent + 4, ' ' ); 90 statements->print( os, indent + 4 ); 90 91 } // if 91 92 } 92 93 93 void FunctionDecl::printShort( std::ostream &os, Indenterindent ) const {94 void FunctionDecl::printShort( std::ostream &os, int indent ) const { 94 95 using std::endl; 95 96 using std::string; 96 97 97 if ( name!= "" ) {98 os << name<< ": ";98 if ( get_name() != "" ) { 99 os << get_name() << ": "; 99 100 } // if 101 102 // xxx - should printShort print attributes? 100 103 101 104 get_storageClasses().print( os ); 102 105 get_funcSpec().print( os ); 103 106 104 if ( type) {105 type->print( os, indent );107 if ( get_type() ) { 108 get_type()->print( os, indent ); 106 109 } else { 107 110 os << "untyped entity "; -
src/SynTree/FunctionType.cc
r6840e7c rb96ec83 51 51 } 52 52 53 void FunctionType::print( std::ostream &os, Indenterindent ) const {53 void FunctionType::print( std::ostream &os, int indent ) const { 54 54 using std::string; 55 55 using std::endl; … … 58 58 os << "function" << endl; 59 59 if ( ! parameters.empty() ) { 60 os << indent << "...with parameters" << endl;61 printAll( parameters, os, indent +1);60 os << string( indent + 2, ' ' ) << "with parameters" << endl; 61 printAll( parameters, os, indent + 4 ); 62 62 if ( isVarArgs ) { 63 os << indent+1<< "and a variable number of other arguments" << endl;63 os << string( indent + 4, ' ' ) << "and a variable number of other arguments" << endl; 64 64 } // if 65 65 } else if ( isVarArgs ) { 66 os << indent+1<< "accepting unspecified arguments" << endl;66 os << string( indent + 4, ' ' ) << "accepting unspecified arguments" << endl; 67 67 } // if 68 os << indent << "...returning ";68 os << string( indent + 2, ' ' ) << "returning "; 69 69 if ( returnVals.empty() ) { 70 os << "nothing " << endl;70 os << endl << string( indent + 4, ' ' ) << "nothing " << endl; 71 71 } else { 72 72 os << endl; 73 printAll( returnVals, os, indent +1);73 printAll( returnVals, os, indent + 4 ); 74 74 } // if 75 75 } -
src/SynTree/Initializer.cc
r6840e7c rb96ec83 38 38 } 39 39 40 void Designation::print( std::ostream &os, Indenterindent ) const {40 void Designation::print( std::ostream &os, int indent ) const { 41 41 if ( ! designators.empty() ) { 42 os << "... designated by: " << std::endl; 43 for ( const Expression * d : designators ) { 44 os << indent+1; 45 d->print(os, indent+1 ); 46 os << std::endl; 42 os << std::string(indent + 2, ' ' ) << "designated by: " << std::endl; 43 for ( std::list < Expression * >::const_iterator i = designators.begin(); i != designators.end(); i++ ) { 44 os << std::string(indent + 4, ' ' ); 45 ( *i )->print(os, indent + 4 ); 47 46 } 47 os << std::endl; 48 48 } // if 49 49 } … … 64 64 } 65 65 66 void SingleInit::print( std::ostream &os, Indenter indent ) const { 67 os << "Simple Initializer: "; 68 value->print( os, indent ); 66 void SingleInit::print( std::ostream &os, int indent ) const { 67 os << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl; 68 os << std::string(indent+4, ' ' ); 69 value->print( os, indent+4 ); 69 70 } 70 71 … … 92 93 } 93 94 94 void ListInit::print( std::ostream &os, Indenter indent ) const { 95 os << "Compound initializer: " << std::endl; 96 for ( auto p : group_iterate( designations, initializers ) ) { 97 const Designation * d = std::get<0>(p); 98 const Initializer * init = std::get<1>(p); 99 os << indent+1; 100 init->print( os, indent+1 ); 95 void ListInit::print( std::ostream &os, int indent ) const { 96 os << std::string(indent, ' ') << "Compound initializer: " << std::endl; 97 for ( Designation * d : designations ) { 98 d->print( os, indent + 2 ); 99 } 100 101 for ( const Initializer * init : initializers ) { 102 init->print( os, indent + 2 ); 101 103 os << std::endl; 102 if ( ! d->designators.empty() ) {103 os << indent+1;104 d->print( os, indent+1 );105 }106 104 } 107 105 } … … 118 116 } 119 117 120 void ConstructorInit::print( std::ostream &os, Indenterindent ) const {121 os << "Constructor initializer: " << std::endl;118 void ConstructorInit::print( std::ostream &os, int indent ) const { 119 os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl; 122 120 if ( ctor ) { 123 os << indent << "... initially constructed with "; 124 ctor->print( os, indent+1 ); 121 os << std::string(indent+2, ' '); 122 os << "initially constructed with "; 123 ctor->print( os, indent+4 ); 125 124 } // if 126 125 127 126 if ( dtor ) { 128 os << indent << "... destructed with "; 129 dtor->print( os, indent+1 ); 127 os << std::string(indent+2, ' '); 128 os << "destructed with "; 129 dtor->print( os, indent+4 ); 130 130 } 131 131 132 132 if ( init ) { 133 os << indent << "... with fallback C-style initializer: "; 134 init->print( os, indent+1 ); 133 os << std::string(indent+2, ' '); 134 os << "with fallback C-style initializer: "; 135 init->print( os, indent+4 ); 135 136 } 136 137 } -
src/SynTree/Initializer.h
r6840e7c rb96ec83 37 37 std::list< Expression * > & get_designators() { return designators; } 38 38 39 virtual Designation * clone() const override{ return new Designation( *this ); };39 virtual Designation * clone() const { return new Designation( *this ); }; 40 40 virtual void accept( Visitor &v ) override { v.visit( this ); } 41 virtual Designation * acceptMutator( Mutator &m ) override{ return m.mutate( this ); }42 virtual void print( std::ostream &os, Indenter indent = {}) const override;41 virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); } 42 virtual void print( std::ostream &os, int indent = 0 ) const override; 43 43 }; 44 44 … … 54 54 bool get_maybeConstructed() { return maybeConstructed; } 55 55 56 virtual Initializer *clone() const override= 0;56 virtual Initializer *clone() const = 0; 57 57 virtual void accept( Visitor &v ) override = 0; 58 virtual Initializer *acceptMutator( Mutator &m ) override= 0;59 virtual void print( std::ostream &os, Indenter indent = {}) const override = 0;58 virtual Initializer *acceptMutator( Mutator &m ) = 0; 59 virtual void print( std::ostream &os, int indent = 0 ) const override = 0; 60 60 private: 61 61 bool maybeConstructed; … … 78 78 virtual void accept( Visitor &v ) override { v.visit( this ); } 79 79 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 80 virtual void print( std::ostream &os, Indenter indent = {}) const override;80 virtual void print( std::ostream &os, int indent = 0 ) const override; 81 81 }; 82 82 … … 106 106 virtual void accept( Visitor &v ) override { v.visit( this ); } 107 107 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 108 virtual void print( std::ostream &os, Indenter indent = {}) const override;108 virtual void print( std::ostream &os, int indent = 0 ) const override; 109 109 }; 110 110 … … 135 135 virtual void accept( Visitor &v ) override { v.visit( this ); } 136 136 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 137 virtual void print( std::ostream &os, Indenter indent = {}) const override;137 virtual void print( std::ostream &os, int indent = 0 ) const override; 138 138 139 139 private: -
src/SynTree/Mutator.cc
r6840e7c rb96ec83 626 626 } 627 627 628 TypeSubstitution * Mutator::mutate( TypeSubstitution * sub ) {629 for ( auto & p : sub->typeEnv ) {630 p.second = maybeMutate( p.second, *this );631 }632 for ( auto & p : sub->varEnv ) {633 p.second = maybeMutate( p.second, *this );634 }635 return sub;636 }637 638 628 // Local Variables: // 639 629 // tab-width: 4 // -
src/SynTree/Mutator.h
r6840e7c rb96ec83 117 117 118 118 virtual Attribute * mutate( Attribute * attribute ); 119 120 virtual TypeSubstitution * mutate( TypeSubstitution * sub );121 122 119 private: 123 120 virtual Declaration * handleAggregateDecl(AggregateDecl * aggregateDecl ); -
src/SynTree/NamedTypeDecl.cc
r6840e7c rb96ec83 38 38 } 39 39 40 void NamedTypeDecl::print( std::ostream &os, Indenterindent ) const {40 void NamedTypeDecl::print( std::ostream &os, int indent ) const { 41 41 using namespace std; 42 42 43 if ( name != "" ) os << name << ": "; 44 45 if ( linkage != LinkageSpec::Cforall ) { 46 os << LinkageSpec::linkageName( linkage ) << " "; 43 if ( get_name() != "" ) { 44 os << get_name() << ": "; 45 } // if 46 if ( get_linkage() != LinkageSpec::Cforall ) { 47 os << LinkageSpec::linkageName( get_linkage() ) << " "; 47 48 } // if 48 49 get_storageClasses().print( os ); … … 50 51 if ( base ) { 51 52 os << " for "; 52 base->print( os, indent +1);53 base->print( os, indent ); 53 54 } // if 54 55 if ( ! parameters.empty() ) { 55 os << endl << indent << "...with parameters" << endl;56 printAll( parameters, os, indent+ 1);56 os << endl << string( indent, ' ' ) << "with parameters" << endl; 57 printAll( parameters, os, indent+2 ); 57 58 } // if 58 59 if ( ! assertions.empty() ) { 59 os << endl << indent << "...with assertions" << endl;60 printAll( assertions, os, indent+ 1);60 os << endl << string( indent, ' ' ) << "with assertions" << endl; 61 printAll( assertions, os, indent+2 ); 61 62 } // if 62 63 } 63 64 64 void NamedTypeDecl::printShort( std::ostream &os, Indenterindent ) const {65 void NamedTypeDecl::printShort( std::ostream &os, int indent ) const { 65 66 using namespace std; 66 67 67 if ( name != "" ) os << name << ": "; 68 if ( get_name() != "" ) { 69 os << get_name() << ": "; 70 } // if 68 71 get_storageClasses().print( os ); 69 72 os << typeString(); 70 73 if ( base ) { 71 74 os << " for "; 72 base->print( os, indent +1);75 base->print( os, indent ); 73 76 } // if 74 77 if ( ! parameters.empty() ) { 75 os << endl << indent << "...with parameters" << endl;76 printAll( parameters, os, indent+ 1);78 os << endl << string( indent, ' ' ) << "with parameters" << endl; 79 printAll( parameters, os, indent+2 ); 77 80 } // if 78 81 } -
src/SynTree/ObjectDecl.cc
r6840e7c rb96ec83 44 44 } 45 45 46 void ObjectDecl::print( std::ostream &os, Indenter indent ) const { 47 if ( name != "" ) os << name << ": "; 46 void ObjectDecl::print( std::ostream &os, int indent ) const { 47 if ( get_name() != "" ) { 48 os << get_name() << ": "; 49 } // if 48 50 49 if ( linkage!= LinkageSpec::Cforall ) {50 os << LinkageSpec::linkageName( linkage) << " ";51 if ( get_linkage() != LinkageSpec::Cforall ) { 52 os << LinkageSpec::linkageName( get_linkage() ) << " "; 51 53 } // if 54 55 printAll( get_attributes(), os, indent ); 52 56 53 57 get_storageClasses().print( os ); 54 58 55 if ( type) {56 type->print( os, indent );59 if ( get_type() ) { 60 get_type()->print( os, indent ); 57 61 } else { 58 62 os << " untyped entity "; … … 60 64 61 65 if ( init ) { 62 os << " with initializer (" << (init->get_maybeConstructed() ? "maybe constructed" : "not constructed") << ")" << std::endl << indent+1; 63 init->print( os, indent+1 ); 64 os << std::endl; 66 os << " with initializer " << std::endl; 67 init->print( os, indent+2 ); 68 os << std::endl << std::string(indent+2, ' '); 69 os << "maybeConstructed? " << init->get_maybeConstructed(); 65 70 } // if 66 71 67 if ( ! attributes.empty() ) {68 os << std::endl << indent << "... with attributes: " << std::endl;69 printAll( attributes, os, indent+1 );70 }71 72 72 if ( bitfieldWidth ) { 73 os << indent << " with bitfield width "; 73 os << std::string(indent, ' '); 74 os << " with bitfield width "; 74 75 bitfieldWidth->print( os ); 75 76 } // if 76 77 } 77 78 78 void ObjectDecl::printShort( std::ostream &os, Indenterindent ) const {79 void ObjectDecl::printShort( std::ostream &os, int indent ) const { 79 80 #if 0 80 81 if ( get_mangleName() != "") { … … 82 83 } else 83 84 #endif 84 if ( name != "" ) os << name << ": "; 85 if ( get_name() != "" ) { 86 os << get_name() << ": "; 87 } // if 88 89 // xxx - should printShort print attributes? 85 90 86 91 get_storageClasses().print( os ); 87 92 88 if ( type) {89 type->print( os, indent );93 if ( get_type() ) { 94 get_type()->print( os, indent ); 90 95 } else { 91 96 os << "untyped entity "; -
src/SynTree/PointerType.cc
r6840e7c rb96ec83 41 41 } 42 42 43 void PointerType::print( std::ostream &os, Indenterindent ) const {43 void PointerType::print( std::ostream &os, int indent ) const { 44 44 Type::print( os, indent ); 45 45 if ( ! is_array() ) { -
src/SynTree/ReferenceToType.cc
r6840e7c rb96ec83 14 14 // 15 15 16 #include <stddef.h> // for NULL 16 17 #include <cassert> // for assert 17 18 #include <list> // for list, _List_const_iterator, list<>::cons... … … 37 38 } 38 39 39 void ReferenceToType::print( std::ostream &os, Indenterindent ) const {40 void ReferenceToType::print( std::ostream &os, int indent ) const { 40 41 using std::endl; 41 42 … … 43 44 os << "instance of " << typeString() << " " << name << " "; 44 45 if ( ! parameters.empty() ) { 45 os << endl << indent << "...with parameters" << endl;46 printAll( parameters, os, indent+ 1);46 os << endl << std::string( indent, ' ' ) << "with parameters" << endl; 47 printAll( parameters, os, indent+2 ); 47 48 } // if 48 49 } … … 64 65 65 66 std::list<TypeDecl*>* StructInstType::get_baseParameters() { 66 if ( ! baseStruct ) return nullptr;67 if ( ! baseStruct ) return NULL; 67 68 return &baseStruct->get_parameters(); 68 69 } … … 75 76 } 76 77 77 void StructInstType::print( std::ostream &os, Indenterindent ) const {78 void StructInstType::print( std::ostream &os, int indent ) const { 78 79 using std::endl; 79 80 80 if ( baseStruct == nullptr) ReferenceToType::print( os, indent );81 if ( baseStruct == NULL ) ReferenceToType::print( os, indent ); 81 82 else { 82 83 Type::print( os, indent ); 83 84 os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body() << " "; 84 85 if ( ! parameters.empty() ) { 85 os << endl << indent << "...with parameters" << endl;86 printAll( parameters, os, indent+ 1);86 os << endl << std::string( indent, ' ' ) << "with parameters" << endl; 87 printAll( parameters, os, indent+2 ); 87 88 } // if 88 89 } // if … … 96 97 97 98 std::list< TypeDecl * > * UnionInstType::get_baseParameters() { 98 if ( ! baseUnion ) return nullptr;99 if ( ! baseUnion ) return NULL; 99 100 return &baseUnion->get_parameters(); 100 101 } … … 107 108 } 108 109 109 void UnionInstType::print( std::ostream &os, Indenterindent ) const {110 void UnionInstType::print( std::ostream &os, int indent ) const { 110 111 using std::endl; 111 112 112 if ( baseUnion == nullptr) ReferenceToType::print( os, indent );113 if ( baseUnion == NULL ) ReferenceToType::print( os, indent ); 113 114 else { 114 115 Type::print( os, indent ); 115 116 os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body() << " "; 116 117 if ( ! parameters.empty() ) { 117 os << endl << indent << "...with parameters" << endl;118 printAll( parameters, os, indent+ 1);118 os << endl << std::string( indent, ' ' ) << "with parameters" << endl; 119 printAll( parameters, os, indent+2 ); 119 120 } // if 120 121 } // if … … 128 129 129 130 bool EnumInstType::isComplete() const { return baseEnum ? baseEnum->has_body() : false; } 130 131 void EnumInstType::print( std::ostream &os, Indenter indent ) const {132 using std::endl;133 134 if ( baseEnum == nullptr ) ReferenceToType::print( os, indent );135 else {136 Type::print( os, indent );137 os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body() << " ";138 } // if139 }140 141 131 142 132 std::string TraitInstType::typeString() const { return "trait"; } … … 176 166 bool TypeInstType::isComplete() const { return baseType->isComplete(); } 177 167 178 void TypeInstType::print( std::ostream &os, Indenterindent ) const {168 void TypeInstType::print( std::ostream &os, int indent ) const { 179 169 using std::endl; 180 170 … … 182 172 os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type) "; 183 173 if ( ! parameters.empty() ) { 184 os << endl << indent << "...with parameters" << endl;185 printAll( parameters, os, indent+ 1);174 os << endl << std::string( indent, ' ' ) << "with parameters" << endl; 175 printAll( parameters, os, indent+2 ); 186 176 } // if 187 177 } -
src/SynTree/ReferenceType.cc
r6840e7c rb96ec83 35 35 } 36 36 37 void ReferenceType::print( std::ostream &os, Indenterindent ) const {37 void ReferenceType::print( std::ostream &os, int indent ) const { 38 38 Type::print( os, indent ); 39 39 os << "reference to "; -
src/SynTree/Statement.cc
r6840e7c rb96ec83 34 34 Statement::Statement( std::list<Label> labels ) : labels( labels ) {} 35 35 36 void Statement::print( std::ostream & os, Indenter ) const { 37 if ( ! labels.empty() ) { 38 os << "Labels: {"; 39 for ( const Label & l : labels ) { 40 os << l << ","; 41 } 42 os << "}" << endl; 43 } 44 } 36 void Statement::print( __attribute__((unused)) std::ostream &, __attribute__((unused)) int indent ) const {} 45 37 46 38 Statement::~Statement() {} … … 54 46 } 55 47 56 void ExprStmt::print( std::ostream &os, Indenterindent ) const {57 os << "Expression Statement:" << endl << indent+1;58 expr->print( os, indent +1);48 void ExprStmt::print( std::ostream &os, int indent ) const { 49 os << "Expression Statement:" << endl << std::string( indent + 2, ' ' ); 50 expr->print( os, indent + 2 ); 59 51 } 60 52 … … 75 67 } 76 68 77 void AsmStmt::print( std::ostream &os, Indenterindent ) const {69 void AsmStmt::print( std::ostream &os, int indent ) const { 78 70 os << "Assembler Statement:" << endl; 79 os << indent+1 << "instruction: " << endl << indent;80 instruction->print( os, indent +1);71 os << std::string( indent, ' ' ) << "instruction: " << endl << std::string( indent, ' ' ); 72 instruction->print( os, indent + 2 ); 81 73 if ( ! output.empty() ) { 82 os << endl << indent+1<< "output: " << endl;83 printAll( output, os, indent +1);74 os << endl << std::string( indent, ' ' ) << "output: " << endl; 75 printAll( output, os, indent + 2 ); 84 76 } // if 85 77 if ( ! input.empty() ) { 86 os << indent+1 << "input: " << endl;87 printAll( input, os, indent +1);78 os << std::string( indent, ' ' ) << "input: " << endl << std::string( indent, ' ' ); 79 printAll( input, os, indent + 2 ); 88 80 } // if 89 81 if ( ! clobber.empty() ) { 90 os << indent+1<< "clobber: " << endl;91 printAll( clobber, os, indent +1);82 os << std::string( indent, ' ' ) << "clobber: " << endl; 83 printAll( clobber, os, indent + 2 ); 92 84 } // if 93 85 } … … 111 103 } 112 104 113 void BranchStmt::print( std::ostream &os, Indenterindent ) const {114 os << "Branch (" << brType[type] << ")" << endl ;115 if ( target != "" ) os << indent+1<< "with target: " << target << endl;116 if ( originalTarget != "" ) os << indent+1<< "with original target: " << originalTarget << endl;117 if ( computedTarget != nullptr ) os << indent+1<< "with computed target: " << computedTarget << endl;105 void BranchStmt::print( std::ostream &os, int indent ) const { 106 os << string( indent, ' ' ) << "Branch (" << brType[type] << ")" << endl ; 107 if ( target != "" ) os << string( indent+2, ' ' ) << "with target: " << target << endl; 108 if ( originalTarget != "" ) os << string( indent+2, ' ' ) << "with original target: " << originalTarget << endl; 109 if ( computedTarget != nullptr ) os << string( indent+2, ' ' ) << "with computed target: " << computedTarget << endl; 118 110 } 119 111 … … 126 118 } 127 119 128 void ReturnStmt::print( std::ostream &os, Indenterindent ) const {129 os << "Return Statement, returning: ";130 if ( expr != nullptr) {131 os << endl << indent+1;132 expr->print( os, indent +1);120 void ReturnStmt::print( std::ostream &os, int indent ) const { 121 os << "Return Statement, returning: "; 122 if ( expr != 0 ) { 123 os << endl << string( indent+2, ' ' ); 124 expr->print( os, indent + 2 ); 133 125 } 134 126 os << endl; … … 150 142 } 151 143 152 void IfStmt::print( std::ostream &os, Indenterindent ) const {153 os << "If on condition: " << endl ;154 os << indent+1;155 condition->print( os, indent +1);144 void IfStmt::print( std::ostream &os, int indent ) const { 145 os << "If on condition: " << endl ; 146 os << string( indent+4, ' ' ); 147 condition->print( os, indent + 4 ); 156 148 157 149 if ( !initialization.empty() ) { 158 os << indent << "... withinitialization: \n";159 for ( const Statement * stmt : initialization) {160 os << indent+1;161 stmt->print( os, indent+1);150 os << string( indent + 2, ' ' ) << "initialization: \n"; 151 for ( std::list<Statement *>::const_iterator it = initialization.begin(); it != initialization.end(); ++it ) { 152 os << string( indent + 4, ' ' ); 153 (*it)->print( os, indent + 4 ); 162 154 } 163 155 os << endl; 164 156 } 165 157 166 os << indent<< "... then: " << endl;167 168 os << indent+1;169 thenPart->print( os, indent +1);158 os << string( indent+2, ' ' ) << "... then: " << endl; 159 160 os << string( indent+4, ' ' ); 161 thenPart->print( os, indent + 4 ); 170 162 171 163 if ( elsePart != 0 ) { 172 os << indent<< "... else: " << endl;173 os << indent+1;174 elsePart->print( os, indent +1);164 os << string( indent+2, ' ' ) << "... else: " << endl; 165 os << string( indent+4, ' ' ); 166 elsePart->print( os, indent + 4 ); 175 167 } // if 176 168 } … … 191 183 } 192 184 193 void SwitchStmt::print( std::ostream &os, Indenterindent ) const {185 void SwitchStmt::print( std::ostream &os, int indent ) const { 194 186 os << "Switch on condition: "; 195 187 condition->print( os ); 196 188 os << endl; 197 189 198 for ( const Statement * stmt : statements ) { 199 stmt->print( os, indent+1 ); 200 } 190 // statements 191 std::list<Statement *>::const_iterator i; 192 for ( i = statements.begin(); i != statements.end(); i++) 193 (*i)->print( os, indent + 4 ); 194 195 //for_each( statements.begin(), statements.end(), mem_fun( bind1st(&Statement::print ), os )); 201 196 } 202 197 203 198 CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) : 204 199 Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) { 205 if ( isDefault() && condition != 0 ) throw SemanticError("default case with condition: ", condition); 200 if ( isDefault() && condition != 0 ) 201 throw SemanticError("default with conditions"); 206 202 } 207 203 … … 220 216 } 221 217 222 void CaseStmt::print( std::ostream &os, Indenter indent ) const { 223 if ( isDefault() ) os << "Default "; 218 void CaseStmt::print( std::ostream &os, int indent ) const { 219 os << string( indent, ' ' ); 220 221 if ( isDefault() ) 222 os << "Default "; 224 223 else { 225 224 os << "Case "; 226 condition->print( os , indent);225 condition->print( os ); 227 226 } // if 227 228 228 os << endl; 229 229 230 for ( Statement * stmt : stmts ) {231 stmt->print( os, indent+1 );232 }230 std::list<Statement *>::const_iterator i; 231 for ( i = stmts.begin(); i != stmts.end(); i++) 232 (*i )->print( os, indent + 4 ); 233 233 } 234 234 … … 246 246 } 247 247 248 void WhileStmt::print( std::ostream &os, Indenterindent ) const {248 void WhileStmt::print( std::ostream &os, int indent ) const { 249 249 os << "While on condition: " << endl ; 250 condition->print( os, indent +1);251 252 os << indent << "... with body: " << endl;253 254 if ( body != 0 ) body->print( os, indent +1);250 condition->print( os, indent + 4 ); 251 252 os << string( indent, ' ' ) << ".... with body: " << endl; 253 254 if ( body != 0 ) body->print( os, indent + 4 ); 255 255 } 256 256 … … 272 272 } 273 273 274 void ForStmt::print( std::ostream &os, Indenter indent ) const { 275 Statement::print( os, indent ); // print labels 276 277 os << "For Statement" << endl; 278 279 if ( ! initialization.empty() ) { 280 os << indent << "... initialization: \n"; 281 for ( Statement * stmt : initialization ) { 282 os << indent+1; 283 stmt->print( os, indent+1 ); 284 } 285 } 286 287 if ( condition != nullptr ) { 288 os << indent << "... condition: \n" << indent+1; 289 condition->print( os, indent+1 ); 290 } 291 292 if ( increment != nullptr ) { 293 os << "\n" << indent << "... increment: \n" << indent+1; 294 increment->print( os, indent+1 ); 295 } 296 274 void ForStmt::print( std::ostream &os, int indent ) const { 275 os << "Labels: {"; 276 for ( std::list<Label>::const_iterator it = get_labels().begin(); it != get_labels().end(); ++it) { 277 os << *it << ","; 278 } 279 os << "}" << endl; 280 281 os << string( indent, ' ' ) << "For Statement" << endl ; 282 283 os << string( indent + 2, ' ' ) << "initialization: \n"; 284 for ( std::list<Statement *>::const_iterator it = initialization.begin(); it != initialization.end(); ++it ) { 285 os << string( indent + 4, ' ' ); 286 (*it)->print( os, indent + 4 ); 287 } 288 289 os << "\n" << string( indent + 2, ' ' ) << "condition: \n"; 290 if ( condition != 0 ) { 291 os << string( indent + 4, ' ' ); 292 condition->print( os, indent + 4 ); 293 } 294 295 os << "\n" << string( indent + 2, ' ' ) << "increment: \n"; 296 if ( increment != 0 ) { 297 os << string( indent + 4, ' ' ); 298 increment->print( os, indent + 4 ); 299 } 300 301 os << "\n" << string( indent + 2, ' ' ) << "statement block: \n"; 297 302 if ( body != 0 ) { 298 os << "\n" << indent << "... with body: \n" << indent+1; 299 body->print( os, indent+1 ); 300 } 303 os << string( indent + 4, ' ' ); 304 body->print( os, indent + 4 ); 305 } 306 301 307 os << endl; 302 308 } … … 316 322 } 317 323 318 void ThrowStmt::print( std::ostream &os, Indenter indent) const { 319 if ( target ) os << "Non-Local "; 324 void ThrowStmt::print( std::ostream &os, int indent) const { 325 if ( target ) { 326 os << "Non-Local "; 327 } 320 328 os << "Throw Statement, raising: "; 321 expr->print(os, indent +1);329 expr->print(os, indent + 4); 322 330 if ( target ) { 323 os << " ... at: ";324 target->print(os, indent +1);331 os << "At: "; 332 target->print(os, indent + 4); 325 333 } 326 334 } … … 340 348 } 341 349 342 void TryStmt::print( std::ostream &os, Indenterindent ) const {350 void TryStmt::print( std::ostream &os, int indent ) const { 343 351 os << "Try Statement" << endl; 344 os << indent << "... with block:" << endl << indent+1; 345 block->print( os, indent+1 ); 352 os << string( indent + 2, ' ' ) << "with block:" << endl; 353 os << string( indent + 4, ' ' ); 354 block->print( os, indent + 4 ); 346 355 347 356 // handlers 348 os << indent << "...and handlers:" << endl;349 for ( const CatchStmt * stmt : handlers) {350 os << indent+1;351 stmt->print( os, indent+1);357 os << string( indent + 2, ' ' ) << "and handlers:" << endl; 358 for ( std::list<CatchStmt *>::const_iterator i = handlers.begin(); i != handlers.end(); i++) { 359 os << string( indent + 4, ' ' ); 360 (*i )->print( os, indent + 4 ); 352 361 } 353 362 354 363 // finally block 355 364 if ( finallyBlock != 0 ) { 356 os << indent << "... and finally:" << endl << indent+1;357 finallyBlock->print( os, indent +1);365 os << string( indent + 2, ' ' ) << "and finally:" << endl; 366 finallyBlock->print( os, indent + 4 ); 358 367 } // if 359 368 } … … 361 370 CatchStmt::CatchStmt( std::list<Label> labels, Kind kind, Declaration *decl, Expression *cond, Statement *body ) : 362 371 Statement( labels ), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) { 363 assertf( decl, "Catch clause must have a declaration." );364 372 } 365 373 … … 373 381 } 374 382 375 void CatchStmt::print( std::ostream &os, Indenterindent ) const {383 void CatchStmt::print( std::ostream &os, int indent ) const { 376 384 os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl; 377 385 378 os << indent << "... catching: "; 379 decl->printShort( os, indent+1 ); 380 os << endl; 386 os << string( indent + 2, ' ' ) << "... catching: "; 387 if ( decl ) { 388 decl->printShort( os, indent + 4 ); 389 os << endl; 390 } 391 else 392 os << string( indent + 4 , ' ' ) << ">>> Error: this catch clause must have a declaration <<<" << endl; 381 393 382 394 if ( cond ) { 383 os << indent << "... with conditional:" << endl << indent+1; 384 cond->print( os, indent+1 ); 385 } 386 387 os << indent << "... with block:" << endl; 388 os << indent+1; 389 body->print( os, indent+1 ); 395 os << string( indent + 2, ' ' ) << "with conditional:" << endl; 396 os << string( indent + 4, ' ' ); 397 cond->print( os, indent + 4 ); 398 } 399 else 400 os << string( indent + 2, ' ' ) << "with no conditional" << endl; 401 402 os << string( indent + 2, ' ' ) << "with block:" << endl; 403 os << string( indent + 4, ' ' ); 404 body->print( os, indent + 4 ); 390 405 } 391 406 … … 402 417 } 403 418 404 void FinallyStmt::print( std::ostream &os, Indenterindent ) const {419 void FinallyStmt::print( std::ostream &os, int indent ) const { 405 420 os << "Finally Statement" << endl; 406 os << indent << "... with block:" << endl << indent+1; 407 block->print( os, indent+1 ); 421 os << string( indent + 2, ' ' ) << "with block:" << endl; 422 os << string( indent + 4, ' ' ); 423 block->print( os, indent + 4 ); 408 424 } 409 425 … … 449 465 } 450 466 451 void WaitForStmt::print( std::ostream &os, Indenterindent ) const {467 void WaitForStmt::print( std::ostream &os, int indent ) const { 452 468 os << "Waitfor Statement" << endl; 453 os << indent << "... with block:" << endl << indent+1; 469 os << string( indent + 2, ' ' ) << "with block:" << endl; 470 os << string( indent + 4, ' ' ); 454 471 // block->print( os, indent + 4 ); 455 472 } … … 458 475 NullStmt::NullStmt() : Statement( std::list<Label>() ) {} 459 476 460 void NullStmt::print( std::ostream &os, Indenter) const {461 os << "Null Statement" << endl ;477 void NullStmt::print( std::ostream &os, __attribute__((unused)) int indent ) const { 478 os << "Null Statement" << endl ; 462 479 } 463 480 … … 473 490 } 474 491 475 void ImplicitCtorDtorStmt::print( std::ostream &os, Indenterindent ) const {492 void ImplicitCtorDtorStmt::print( std::ostream &os, int indent ) const { 476 493 os << "Implicit Ctor Dtor Statement" << endl; 477 os << indent << "...with Ctor/Dtor: ";478 callStmt->print( os, indent +1);494 os << string( indent + 2, ' ' ) << "with Ctor/Dtor: "; 495 callStmt->print( os, indent + 2); 479 496 os << endl; 480 497 } -
src/SynTree/Statement.h
r6840e7c rb96ec83 43 43 const std::list<Label> & get_labels() const { return labels; } 44 44 45 virtual Statement *clone() const override= 0;45 virtual Statement *clone() const = 0; 46 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;47 virtual Statement *acceptMutator( Mutator &m ) = 0; 48 virtual void print( std::ostream &os, int indent = 0 ) const override; 49 49 }; 50 50 … … 65 65 virtual void accept( Visitor &v ) override { v.visit( this ); } 66 66 virtual CompoundStmt *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 67 virtual void print( std::ostream &os, Indenter indent = {}) const override;67 virtual void print( std::ostream &os, int indent = 0 ) const override; 68 68 }; 69 69 … … 76 76 virtual void accept( Visitor &v ) override { v.visit( this ); } 77 77 virtual NullStmt *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 78 virtual void print( std::ostream &os, Indenter indent = {}) const override;78 virtual void print( std::ostream &os, int indent = 0 ) const override; 79 79 }; 80 80 … … 93 93 virtual void accept( Visitor &v ) override { v.visit( this ); } 94 94 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 95 virtual void print( std::ostream &os, Indenter indent = {}) const override;95 virtual void print( std::ostream &os, int indent = 0 ) const override; 96 96 }; 97 97 … … 124 124 virtual void accept( Visitor & v ) { v.visit( this ); } 125 125 virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); } 126 virtual void print( std::ostream & os, Indenter indent = {}) const;126 virtual void print( std::ostream & os, int indent = 0 ) const; 127 127 }; 128 128 … … 150 150 virtual void accept( Visitor &v ) override { v.visit( this ); } 151 151 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 152 virtual void print( std::ostream &os, Indenter indent = {}) const override;152 virtual void print( std::ostream &os, int indent = 0 ) const override; 153 153 }; 154 154 … … 171 171 172 172 virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); } 173 virtual void print( std::ostream &os, Indenter indent = {}) const override;173 virtual void print( std::ostream &os, int indent = 0 ) const override; 174 174 175 175 }; … … 199 199 200 200 virtual CaseStmt *clone() const override { return new CaseStmt( *this ); } 201 virtual void print( std::ostream &os, Indenter indent = {}) const override;201 virtual void print( std::ostream &os, int indent = 0 ) const override; 202 202 private: 203 203 bool _isDefault; … … 225 225 virtual void accept( Visitor &v ) override { v.visit( this ); } 226 226 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 227 virtual void print( std::ostream &os, Indenter indent = {}) const override;227 virtual void print( std::ostream &os, int indent = 0 ) const override; 228 228 }; 229 229 … … 251 251 virtual void accept( Visitor &v ) override { v.visit( this ); } 252 252 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 253 virtual void print( std::ostream &os, Indenter indent = {}) const override;253 virtual void print( std::ostream &os, int indent = 0 ) const override; 254 254 }; 255 255 … … 280 280 virtual void accept( Visitor &v ) override { v.visit( this ); } 281 281 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 282 virtual void print( std::ostream &os, Indenter indent = {}) const override;282 virtual void print( std::ostream &os, int indent = 0 ) const override; 283 283 private: 284 284 static const char *brType[]; … … 299 299 virtual void accept( Visitor &v ) override { v.visit( this ); } 300 300 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 301 virtual void print( std::ostream &os, Indenter indent = {}) const override;301 virtual void print( std::ostream &os, int indent = 0 ) const override; 302 302 }; 303 303 … … 323 323 virtual void accept( Visitor &v ) override { v.visit( this ); } 324 324 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 325 virtual void print( std::ostream &os, Indenter indent = {}) const override;325 virtual void print( std::ostream &os, int indent = 0 ) const override; 326 326 }; 327 327 … … 346 346 virtual void accept( Visitor &v ) override { v.visit( this ); } 347 347 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 348 virtual void print( std::ostream &os, Indenter indent = {}) const override;348 virtual void print( std::ostream &os, int indent = 0 ) const override; 349 349 }; 350 350 … … 374 374 virtual void accept( Visitor &v ) override { v.visit( this ); } 375 375 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 376 virtual void print( std::ostream &os, Indenter indent = {}) const override;376 virtual void print( std::ostream &os, int indent = 0 ) const override; 377 377 }; 378 378 … … 391 391 virtual void accept( Visitor &v ) override { v.visit( this ); } 392 392 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 393 virtual void print( std::ostream &os, Indenter indent = {}) const override;393 virtual void print( std::ostream &os, int indent = 0 ) const override; 394 394 }; 395 395 … … 428 428 virtual void accept( Visitor &v ) override { v.visit( this ); } 429 429 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 430 virtual void print( std::ostream &os, Indenter indent = {}) const override;430 virtual void print( std::ostream &os, int indent = 0 ) const override; 431 431 432 432 }; … … 448 448 virtual void accept( Visitor &v ) override { v.visit( this ); } 449 449 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 450 virtual void print( std::ostream &os, Indenter indent = {}) const override;450 virtual void print( std::ostream &os, int indent = 0 ) const override; 451 451 }; 452 452 … … 470 470 virtual void accept( Visitor &v ) override { v.visit( this ); } 471 471 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 472 virtual void print( std::ostream &os, Indenter indent = {}) const override;472 virtual void print( std::ostream &os, int indent = 0 ) const override; 473 473 }; 474 474 -
src/SynTree/TupleExpr.cc
r6840e7c rb96ec83 28 28 #include "Type.h" // for TupleType, Type 29 29 30 UntypedTupleExpr::UntypedTupleExpr( const std::list< Expression * > & exprs ) : Expression(), exprs( exprs ) {30 UntypedTupleExpr::UntypedTupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) { 31 31 } 32 32 … … 39 39 } 40 40 41 void UntypedTupleExpr::print( std::ostream &os, Indenterindent ) const {41 void UntypedTupleExpr::print( std::ostream &os, int indent ) const { 42 42 os << "Untyped Tuple:" << std::endl; 43 printAll( exprs, os, indent+ 1);43 printAll( exprs, os, indent+2 ); 44 44 Expression::print( os, indent ); 45 45 } 46 46 47 TupleExpr::TupleExpr( const std::list< Expression * > & exprs ) : Expression(), exprs( exprs ) {47 TupleExpr::TupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) { 48 48 set_result( Tuples::makeTupleType( exprs ) ); 49 49 } … … 57 57 } 58 58 59 void TupleExpr::print( std::ostream &os, Indenterindent ) const {59 void TupleExpr::print( std::ostream &os, int indent ) const { 60 60 os << "Tuple:" << std::endl; 61 printAll( exprs, os, indent+ 1);61 printAll( exprs, os, indent+2 ); 62 62 Expression::print( os, indent ); 63 63 } … … 78 78 } 79 79 80 void TupleIndexExpr::print( std::ostream &os, Indenterindent ) const {80 void TupleIndexExpr::print( std::ostream &os, int indent ) const { 81 81 os << "Tuple Index Expression, with tuple:" << std::endl; 82 os << indent+1;83 tuple->print( os, indent+ 1);84 os << indent+1<< "with index: " << index << std::endl;82 os << std::string( indent+2, ' ' ); 83 tuple->print( os, indent+2 ); 84 os << std::string( indent+2, ' ' ) << "with index: " << index << std::endl; 85 85 Expression::print( os, indent ); 86 86 } 87 87 88 TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls ) : Expression() {88 TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ) { 89 89 // convert internally into a StmtExpr which contains the declarations and produces the tuple of the assignments 90 90 set_result( Tuples::makeTupleType( assigns ) ); … … 109 109 } 110 110 111 void TupleAssignExpr::print( std::ostream &os, Indenterindent ) const {111 void TupleAssignExpr::print( std::ostream &os, int indent ) const { 112 112 os << "Tuple Assignment Expression, with stmt expr:" << std::endl; 113 os << indent+1;114 stmtExpr->print( os, indent+ 1);113 os << std::string( indent+2, ' ' ); 114 stmtExpr->print( os, indent+4 ); 115 115 Expression::print( os, indent ); 116 116 } -
src/SynTree/TupleType.cc
r6840e7c rb96ec83 48 48 } 49 49 50 void TupleType::print( std::ostream &os, Indenterindent ) const {50 void TupleType::print( std::ostream &os, int indent ) const { 51 51 Type::print( os, indent ); 52 52 os << "tuple of types" << std::endl; 53 printAll( types, os, indent+ 1);53 printAll( types, os, indent+2 ); 54 54 } 55 55 -
src/SynTree/Type.cc
r6840e7c rb96ec83 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:32201713 // Update Count : 3 812 // Last Modified On : Mon Sep 11 13:21:25 2017 13 // Update Count : 37 14 14 // 15 15 #include "Type.h" … … 45 45 "double _Imaginary", 46 46 "long double _Imaginary", 47 "__int128",48 "unsigned __int128",49 47 }; 50 48 … … 75 73 Type * type; 76 74 ReferenceType * ref; 77 for ( type = this; (ref = dynamic_cast<ReferenceType *>( type )); type = ref-> base);75 for ( type = this; (ref = dynamic_cast<ReferenceType *>( type )); type = ref->get_base() ); 78 76 return type; 79 77 } … … 81 79 int Type::referenceDepth() const { return 0; } 82 80 83 void Type::print( std::ostream &os, Indenterindent ) const {81 void Type::print( std::ostream &os, int indent ) const { 84 82 if ( ! forall.empty() ) { 85 83 os << "forall" << std::endl; 86 printAll( forall, os, indent +1);87 os << ++indent;84 printAll( forall, os, indent + 4 ); 85 os << std::string( indent+2, ' ' ); 88 86 } // if 89 87 90 88 if ( ! attributes.empty() ) { 91 os << "with attributes" << endl;92 printAll( attributes, os, indent+ 1);89 os << endl << string( indent+2, ' ' ) << "with attributes" << endl; 90 printAll( attributes, os, indent+4 ); 93 91 } // if 94 92 -
src/SynTree/Type.h
r6840e7c rb96ec83 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:01201713 // Update Count : 15 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Aug 9 14:25:00 2017 13 // Update Count : 152 14 14 // 15 15 … … 181 181 virtual void accept( Visitor & v ) = 0; 182 182 virtual Type *acceptMutator( Mutator & m ) = 0; 183 virtual void print( std::ostream & os, Indenter indent = {}) const;183 virtual void print( std::ostream & os, int indent = 0 ) const; 184 184 }; 185 185 … … 198 198 virtual void accept( Visitor & v ) override { v.visit( this ); } 199 199 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 200 virtual void print( std::ostream & os, Indenter indent = {}) const override;200 virtual void print( std::ostream & os, int indent = 0 ) const override; 201 201 }; 202 202 … … 225 225 DoubleImaginary, 226 226 LongDoubleImaginary, 227 SignedInt128,228 UnsignedInt128,229 227 NUMBER_OF_BASIC_TYPES 230 228 } kind; … … 240 238 virtual void accept( Visitor & v ) override { v.visit( this ); } 241 239 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 242 virtual void print( std::ostream & os, Indenter indent = {}) const override;240 virtual void print( std::ostream & os, int indent = 0 ) const override; 243 241 244 242 bool isInteger() const; … … 275 273 virtual void accept( Visitor & v ) override { v.visit( this ); } 276 274 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 277 virtual void print( std::ostream & os, Indenter indent = {}) const override;275 virtual void print( std::ostream & os, int indent = 0 ) const override; 278 276 }; 279 277 … … 303 301 virtual void accept( Visitor & v ) override { v.visit( this ); } 304 302 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 305 virtual void print( std::ostream & os, Indenter indent = {}) const override;303 virtual void print( std::ostream & os, int indent = 0 ) const override; 306 304 }; 307 305 … … 327 325 virtual void accept( Visitor & v ) override { v.visit( this ); } 328 326 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 329 virtual void print( std::ostream & os, Indenter indent = {}) const override;327 virtual void print( std::ostream & os, int indent = 0 ) const override; 330 328 }; 331 329 … … 354 352 virtual void accept( Visitor & v ) override { v.visit( this ); } 355 353 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 356 virtual void print( std::ostream & os, Indenter indent = {}) const override;354 virtual void print( std::ostream & os, int indent = 0 ) const override; 357 355 }; 358 356 … … 376 374 virtual void accept( Visitor & v ) override = 0; 377 375 virtual Type *acceptMutator( Mutator & m ) override = 0; 378 virtual void print( std::ostream & os, Indenter indent = {}) const override;376 virtual void print( std::ostream & os, int indent = 0 ) const override; 379 377 380 378 virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {} … … 410 408 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 411 409 412 virtual void print( std::ostream & os, Indenter indent = {}) const override;410 virtual void print( std::ostream & os, int indent = 0 ) const override; 413 411 private: 414 412 virtual std::string typeString() const override; … … 442 440 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 443 441 444 virtual void print( std::ostream & os, Indenter indent = {}) const override;442 virtual void print( std::ostream & os, int indent = 0 ) const override; 445 443 private: 446 444 virtual std::string typeString() const override; … … 466 464 virtual void accept( Visitor & v ) override { v.visit( this ); } 467 465 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 468 469 virtual void print( std::ostream & os, Indenter indent = {} ) const override;470 466 private: 471 467 virtual std::string typeString() const override; … … 516 512 virtual void accept( Visitor & v ) override { v.visit( this ); } 517 513 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 518 virtual void print( std::ostream & os, Indenter indent = {}) const override;514 virtual void print( std::ostream & os, int indent = 0 ) const override; 519 515 private: 520 516 virtual std::string typeString() const override; … … 553 549 virtual void accept( Visitor & v ) override { v.visit( this ); } 554 550 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 555 virtual void print( std::ostream & os, Indenter indent = {}) const override;551 virtual void print( std::ostream & os, int indent = 0 ) const override; 556 552 }; 557 553 … … 572 568 virtual void accept( Visitor & v ) override { v.visit( this ); } 573 569 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 574 virtual void print( std::ostream & os, Indenter indent = {}) const override;570 virtual void print( std::ostream & os, int indent = 0 ) const override; 575 571 }; 576 572 … … 601 597 virtual void accept( Visitor & v ) override { v.visit( this ); } 602 598 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 603 virtual void print( std::ostream & os, Indenter indent = {}) const override;599 virtual void print( std::ostream & os, int indent = 0 ) const override; 604 600 }; 605 601 … … 615 611 virtual void accept( Visitor & v ) override { v.visit( this ); } 616 612 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 617 virtual void print( std::ostream & os, Indenter indent = {}) const override;613 virtual void print( std::ostream & os, int indent = 0 ) const override; 618 614 }; 619 615 … … 627 623 virtual void accept( Visitor & v ) override { v.visit( this ); } 628 624 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 629 virtual void print( std::ostream & os, Indenter indent = {}) const override;625 virtual void print( std::ostream & os, int indent = 0 ) const override; 630 626 }; 631 627 … … 639 635 virtual void accept( Visitor & v ) override { v.visit( this ); } 640 636 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 641 virtual void print( std::ostream & os, Indenter indent = {}) const override;637 virtual void print( std::ostream & os, int indent = 0 ) const override; 642 638 }; 643 639 -
src/SynTree/TypeDecl.cc
r6840e7c rb96ec83 41 41 } 42 42 43 void TypeDecl::print( std::ostream &os, Indenterindent ) const {43 void TypeDecl::print( std::ostream &os, int indent ) const { 44 44 NamedTypeDecl::print( os, indent ); 45 45 if ( init ) { 46 os << std::endl << indent<< "with type initializer: ";47 init->print( os, indent + 1);46 os << std::endl << std::string( indent, ' ' ) << "with type initializer: "; 47 init->print( os, indent + 2 ); 48 48 } 49 49 } -
src/SynTree/TypeExpr.cc
r6840e7c rb96ec83 30 30 } 31 31 32 void TypeExpr::print( std::ostream &os, Indenterindent ) const {32 void TypeExpr::print( std::ostream &os, int indent ) const { 33 33 if ( type ) type->print( os, indent ); 34 34 Expression::print( os, indent ); -
src/SynTree/TypeSubstitution.cc
r6840e7c rb96ec83 148 148 template< typename TypeClass > 149 149 Type *TypeSubstitution::handleType( TypeClass *type ) { 150 ValueGuard<BoundVarsType>oldBoundVars( boundVars );150 BoundVarsType oldBoundVars( boundVars ); 151 151 // bind type variables from forall-qualifiers 152 152 if ( freeOnly ) { … … 156 156 } // if 157 157 Type *ret = Mutator::mutate( type ); 158 boundVars = oldBoundVars; 158 159 return ret; 159 160 } … … 161 162 template< typename TypeClass > 162 163 Type *TypeSubstitution::handleAggregateType( TypeClass *type ) { 163 ValueGuard<BoundVarsType>oldBoundVars( boundVars );164 BoundVarsType oldBoundVars( boundVars ); 164 165 // bind type variables from forall-qualifiers 165 166 if ( freeOnly ) { … … 176 177 } // if 177 178 Type *ret = Mutator::mutate( type ); 179 boundVars = oldBoundVars; 178 180 return ret; 179 181 } … … 231 233 } 232 234 233 void TypeSubstitution::print( std::ostream &os, Indenter indent ) const { 234 os << indent << "Types:" << std::endl; 235 TypeSubstitution * TypeSubstitution::acceptMutator( Mutator & mutator ) { 236 for ( auto & p : typeEnv ) { 237 p.second = maybeMutate( p.second, mutator ); 238 } 239 for ( auto & p : varEnv ) { 240 p.second = maybeMutate( p.second, mutator ); 241 } 242 return this; 243 } 244 245 void TypeSubstitution::print( std::ostream &os, int indent ) const { 246 os << std::string( indent, ' ' ) << "Types:" << std::endl; 235 247 for ( TypeEnvType::const_iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { 236 os << indent+1<< i->first << " -> ";237 i->second->print( os, indent+ 2);248 os << std::string( indent+2, ' ' ) << i->first << " -> "; 249 i->second->print( os, indent+4 ); 238 250 os << std::endl; 239 251 } // for 240 os << indent<< "Non-types:" << std::endl;252 os << std::string( indent, ' ' ) << "Non-types:" << std::endl; 241 253 for ( VarEnvType::const_iterator i = varEnv.begin(); i != varEnv.end(); ++i ) { 242 os << indent+1<< i->first << " -> ";243 i->second->print( os, indent+ 2);254 os << std::string( indent+2, ' ' ) << i->first << " -> "; 255 i->second->print( os, indent+4 ); 244 256 os << std::endl; 245 257 } // for -
src/SynTree/TypeSubstitution.h
r6840e7c rb96ec83 59 59 void normalize(); 60 60 61 TypeSubstitution * acceptMutator( Mutator & m ) { return m.mutate( this ); }61 TypeSubstitution * acceptMutator( Mutator & mutator ); 62 62 63 void print( std::ostream &os, Indenter indent = {}) const;63 void print( std::ostream &os, int indent = 0 ) const; 64 64 TypeSubstitution *clone() const { return new TypeSubstitution( *this ); } 65 65 private: … … 89 89 90 90 void initialize( const TypeSubstitution &src, TypeSubstitution &dest ); 91 92 friend class Mutator;93 94 template<typename pass_type>95 friend class PassVisitor;96 91 97 92 typedef std::map< std::string, Type* > TypeEnvType; -
src/SynTree/TypeofType.cc
r6840e7c rb96ec83 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypeofType.cc -- 7 // TypeofType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 33 33 } 34 34 35 void TypeofType::print( std::ostream &os, Indenterindent ) const {35 void TypeofType::print( std::ostream &os, int indent ) const { 36 36 Type::print( os, indent ); 37 37 os << "type-of expression "; -
src/SynTree/VarArgsType.cc
r6840e7c rb96ec83 25 25 VarArgsType::VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {} 26 26 27 void VarArgsType::print( std::ostream &os, Indenterindent ) const {27 void VarArgsType::print( std::ostream &os, int indent ) const { 28 28 Type::print( os, indent ); 29 29 os << "builtin var args pack"; -
src/SynTree/VoidType.cc
r6840e7c rb96ec83 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // VoidType.cc -- 7 // VoidType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 24 24 } 25 25 26 void VoidType::print( std::ostream &os, Indenterindent ) const {26 void VoidType::print( std::ostream &os, int indent ) const { 27 27 Type::print( os, indent ); 28 28 os << "void "; -
src/SynTree/ZeroOneType.cc
r6840e7c rb96ec83 25 25 ZeroType::ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {} 26 26 27 void ZeroType::print( std::ostream &os, Indenter) const {27 void ZeroType::print( std::ostream &os, __attribute__((unused)) int indent ) const { 28 28 os << "zero_t"; 29 29 } … … 33 33 OneType::OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes ) : Type( tq, attributes ) {} 34 34 35 void OneType::print( std::ostream &os, Indenter) const {35 void OneType::print( std::ostream &os, __attribute__((unused)) int indent ) const { 36 36 os << "one_t"; 37 37 } -
src/Tuples/Explode.h
r6840e7c rb96ec83 30 30 Expression * distributeReference( Expression * ); 31 31 32 static inline CastExpr * isReferenceCast( Expression * expr ) {33 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {34 if ( dynamic_cast< ReferenceType * >( castExpr->result ) ) {35 return castExpr;36 }37 }38 return nullptr;39 }40 41 32 /// helper function used by explode 42 33 template< typename OutputIterator > … … 44 35 if ( isTupleAssign ) { 45 36 // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components 46 if ( CastExpr * castExpr = isReferenceCast( expr ) ) {37 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 47 38 ResolvExpr::AltList alts; 48 39 explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); -
src/Tuples/TupleAssignment.cc
r6840e7c rb96ec83 41 41 #include "SynTree/Visitor.h" // for Visitor 42 42 43 #if 044 #define PRINT(x) x45 #else46 #define PRINT(x)47 #endif48 49 43 namespace Tuples { 50 44 class TupleAssignSpotter { … … 90 84 bool isTuple( Expression *expr ) { 91 85 if ( ! expr ) return false; 92 assert( expr-> result);86 assert( expr->has_result() ); 93 87 return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() ); 94 88 } … … 125 119 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { 126 120 if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) { 127 fname = op->get_name(); 128 PRINT( std::cerr << "TupleAssignment: " << fname << std::endl; ) 121 fname = op->get_name(); 129 122 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 130 123 if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal … … 138 131 const ResolvExpr::Alternative & alt1 = ali->front(); 139 132 auto begin = std::next(ali->begin(), 1), end = ali->end(); 140 PRINT( std::cerr << "alt1 is " << alt1.expr << std::endl; )141 133 if ( refToTuple(alt1.expr) ) { 142 PRINT( std::cerr << "and is reference to tuple" << std::endl; )143 134 if ( isMultAssign( begin, end ) ) { 144 PRINT( std::cerr << "possible multiple assignment" << std::endl; )145 135 matcher.reset( new MultipleAssignMatcher( *this, *ali ) ); 146 136 } else { 147 137 // mass assignment 148 PRINT( std::cerr << "possible mass assignment" << std::endl; )149 138 matcher.reset( new MassAssignMatcher( *this, *ali ) ); 150 139 } … … 170 159 // now resolve new assignments 171 160 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 172 PRINT(173 std::cerr << "== resolving tuple assign ==" << std::endl;174 std::cerr << *i << std::endl;175 )176 177 161 ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() ); 178 162 try { … … 254 238 255 239 ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) { 256 assert( expr-> result&& ! expr->get_result()->isVoid() );240 assert( expr->has_result() && ! expr->get_result()->isVoid() ); 257 241 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) ); 258 242 // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient. … … 264 248 ctorInit->accept( rm ); 265 249 } 266 PRINT( std::cerr << "new object: " << ret << std::endl; )267 250 return ret; 268 251 } -
src/benchmark/Makefile.am
r6840e7c rb96ec83 48 48 @rm -f a.out .result.log 49 49 50 ctxswitch-pthread$(EXEEXT):51 @BACKEND_CC@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -lrt -pthread -DN=50000000 PthrdCtxSwitch.c52 @rm -f .result.log53 @for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \54 ./a.out | tee -a .result.log ; \55 done56 @./stat.py .result.log57 @rm -f a.out .result.log58 59 50 sched-int$(EXEEXT): 60 51 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c -
src/benchmark/Makefile.in
r6840e7c rb96ec83 598 598 @rm -f a.out .result.log 599 599 600 ctxswitch-pthread$(EXEEXT):601 @BACKEND_CC@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -lrt -pthread -DN=50000000 PthrdCtxSwitch.c602 @rm -f .result.log603 @for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \604 ./a.out | tee -a .result.log ; \605 done606 @./stat.py .result.log607 @rm -f a.out .result.log608 609 600 sched-int$(EXEEXT): 610 601 ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c -
src/benchmark/bench.h
r6840e7c rb96ec83 10 10 } 11 11 #endif 12 12 13 13 14 static inline unsigned long long int Time() { -
src/benchmark/create_cfaThrd.c
r6840e7c rb96ec83 4 4 5 5 thread MyThread {}; 6 void main(MyThread &this) {}6 void main(MyThread * this) {} 7 7 8 8 int main(int argc, char* argv[]) { -
src/driver/cfa.cc
r6840e7c rb96ec83 9 9 // Author : Peter A. Buhr 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Sep 26 23:12:38201713 // Update Count : 15 911 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 17 15:24:00 2017 13 // Update Count : 156 14 14 // 15 15 … … 346 346 args[nargs] = "-fgnu89-inline"; 347 347 nargs += 1; 348 args[nargs] = "-D__int8_t_defined"; // prevent gcc type-size attributes349 nargs += 1;350 348 args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str(); 351 349 nargs += 1; -
src/include/cassert
r6840e7c rb96ec83 41 41 static inline T strict_dynamic_cast( const U & src ) { 42 42 T ret = dynamic_cast<T>(src); 43 assert f(ret, "%s", toString(src).c_str());43 assert(ret); 44 44 return ret; 45 45 } -
src/libcfa/Makefile.am
r6840e7c rb96ec83 31 31 32 32 libcfa_a-libcfa-prelude.o : libcfa-prelude.c 33 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ - Wall -O2 -c -o $@ $<33 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -O2 -c -o $@ $< 34 34 35 35 libcfa_d_a-libcfa-prelude.o : libcfa-prelude.c 36 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ - Wall -O0 -c -o $@ $<36 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -O0 -c -o $@ $< 37 37 38 38 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@ -
src/libcfa/Makefile.in
r6840e7c rb96ec83 1498 1498 1499 1499 libcfa_a-libcfa-prelude.o : libcfa-prelude.c 1500 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ - Wall -O2 -c -o $@ $<1500 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -O2 -c -o $@ $< 1501 1501 1502 1502 libcfa_d_a-libcfa-prelude.o : libcfa-prelude.c 1503 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ - Wall -O0 -c -o $@ $<1503 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -O0 -c -o $@ $< 1504 1504 1505 1505 # extensionless header files are overridden by -o flag in default makerule => explicitly override default rule to silently do nothing -
src/libcfa/concurrency/invoke.h
r6840e7c rb96ec83 96 96 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 97 97 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 98 struct __waitfor_mask_t mask; // mask used to know if some thread is waiting for something while holding the monitor 99 struct __condition_node_t * dtor_node; // node used to signal the dtor in a waitfor dtor 98 struct __waitfor_mask_t mask; // mask used to know if some thread is waiting for something while holding the monitor 100 99 }; 101 100 … … 111 110 struct monitor_desc self_mon; // monitor body used for mutual exclusion 112 111 struct monitor_desc * self_mon_p; // pointer to monitor with sufficient lifetime for current monitors 113 struct __monitor_group_t monitors; // monitors currently held by this thread112 struct __monitor_group_t monitors; // monitors currently held by this thread 114 113 115 114 // Link lists fields -
src/libcfa/concurrency/monitor
r6840e7c rb96ec83 10 10 // Created On : Thd Feb 23 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Oct 7 18:06:45201713 // Update Count : 1012 // Last Modified On : Sat Jul 22 09:59:01 2017 13 // Update Count : 3 14 14 // 15 15 … … 29 29 static inline void ?{}(monitor_desc & this) { 30 30 (this.lock){}; 31 this.owner = NULL; 31 32 (this.entry_queue){}; 32 33 (this.signal_stack){}; 33 this.owner = NULL; 34 this.recursion = 0; 34 this.recursion = 0; 35 35 this.mask.accepted = NULL; 36 36 this.mask.clauses = NULL; 37 37 this.mask.size = 0; 38 this.dtor_node = NULL;39 38 } 40 41 // static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {42 // return ((intptr_t)lhs) < ((intptr_t)rhs);43 // }44 39 45 40 struct monitor_guard_t { … … 51 46 }; 52 47 48 static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) { 49 return ((intptr_t)lhs) < ((intptr_t)rhs); 50 } 51 53 52 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ); 54 53 void ^?{}( monitor_guard_t & this ); 55 56 struct monitor_dtor_guard_t {57 monitor_desc * m;58 monitor_desc ** prev_mntrs;59 unsigned short prev_count;60 fptr_t prev_func;61 };62 63 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, void (*func)() );64 void ^?{}( monitor_dtor_guard_t & this );65 66 static inline forall( dtype T | sized(T) | { void ^?{}( T & mutex ); } )67 void delete( T * th ) {68 ^(*th){};69 free( th );70 }71 54 72 55 //----------------------------------------------------------------------------- … … 92 75 __condition_node_t ** tail; 93 76 }; 94 95 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info );96 void ?{}(__condition_criterion_t & this );97 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner );98 77 99 78 void ?{}( __condition_blocked_queue_t & ); -
src/libcfa/concurrency/monitor.c
r6840e7c rb96ec83 23 23 //----------------------------------------------------------------------------- 24 24 // Forward declarations 25 static inline void set_owner ( monitor_desc * this, thread_desc * owner ); 26 static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner ); 27 static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ); 28 static inline void reset_mask( monitor_desc * this ); 25 static inline void set_owner( monitor_desc * this, thread_desc * owner ); 26 static inline void set_owner( monitor_desc ** storage, short count, thread_desc * owner ); 27 static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ); 29 28 30 29 static inline thread_desc * next_thread( monitor_desc * this ); … … 73 72 #define monitor_restore restore( monitors, count, locks, recursions, masks ) 74 73 74 #define blockAndWake( thrd, cnt ) /* Create the necessary information to use the signaller stack */ \ 75 monitor_save; /* Save monitor states */ \ 76 BlockInternal( locks, count, thrd, cnt ); /* Everything is ready to go to sleep */ \ 77 monitor_restore; /* We are back, restore the owners and recursions */ \ 78 75 79 76 80 //----------------------------------------------------------------------------- … … 94 98 } 95 99 else if( this->owner == thrd) { 96 // We already have the monitor, just not ehow many times we took it100 // We already have the monitor, just not how many times we took it 97 101 verify( this->recursion > 0 ); 98 102 this->recursion += 1; … … 104 108 set_owner( this, thrd ); 105 109 106 // Reset mask107 reset_mask( this );108 109 110 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts \n"); 110 111 } … … 127 128 unlock( &this->lock ); 128 129 return; 129 }130 131 static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {132 // Lock the monitor spinlock, lock_yield to reduce contention133 lock_yield( &this->lock DEBUG_CTX2 );134 thread_desc * thrd = this_thread;135 136 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);137 138 139 if( !this->owner ) {140 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying free mon %p\n", this);141 142 // No one has the monitor, just take it143 set_owner( this, thrd );144 145 unlock( &this->lock );146 return;147 }148 else if( this->owner == thrd) {149 // We already have the monitor... but where about to destroy it so the nesting will fail150 // Abort!151 abortf("Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.");152 }153 154 int count = 1;155 monitor_desc ** monitors = &this;156 __monitor_group_t group = { &this, 1, func };157 if( is_accepted( this, group) ) {158 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts dtor, block and signal it \n");159 160 // Wake the thread that is waiting for this161 __condition_criterion_t * urgent = pop( &this->signal_stack );162 verify( urgent );163 164 // Reset mask165 reset_mask( this );166 167 // Create the node specific to this wait operation168 wait_ctx_primed( this_thread, 0 )169 170 // Some one else has the monitor, wait for him to finish and then run171 BlockInternal( &this->lock, urgent->owner->waiting_thread );172 173 // Some one was waiting for us, enter174 set_owner( this, thrd );175 }176 else {177 LIB_DEBUG_PRINT_SAFE("Kernel : blocking \n");178 179 wait_ctx( this_thread, 0 )180 this->dtor_node = &waiter;181 182 // Some one else has the monitor, wait in line for it183 append( &this->entry_queue, thrd );184 BlockInternal( &this->lock );185 186 // BlockInternal will unlock spinlock, no need to unlock ourselves187 return;188 }189 190 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying %p\n", this);191 192 130 } 193 131 … … 221 159 } 222 160 223 // Leave single monitor for the last time224 void __leave_dtor_monitor_desc( monitor_desc * this ) {225 LIB_DEBUG_DO(226 if( this_thread != this->owner ) {227 abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);228 }229 if( this->recursion != 1 ) {230 abortf("Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);231 }232 )233 }234 235 161 // Leave the thread monitor 236 162 // last routine called by a thread. … … 285 211 // Ctor for monitor guard 286 212 // Sorts monitors before entering 287 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func) {213 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) { 288 214 // Store current array 289 215 this.m = m; … … 303 229 this_thread->monitors.func = func; 304 230 305 //LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);231 LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count); 306 232 307 233 // Enter the monitors in order … … 309 235 enter( group ); 310 236 311 //LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n");237 LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n"); 312 238 } 313 239 … … 315 241 // Dtor for monitor guard 316 242 void ^?{}( monitor_guard_t & this ) { 317 //LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);243 LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count); 318 244 319 245 // Leave the monitors in order 320 246 leave( this.m, this.count ); 321 247 322 // LIB_DEBUG_PRINT_SAFE("MGUARD : left\n"); 323 324 // Restore thread context 325 this_thread->monitors.list = this.prev_mntrs; 326 this_thread->monitors.size = this.prev_count; 327 this_thread->monitors.func = this.prev_func; 328 } 329 330 331 // Ctor for monitor guard 332 // Sorts monitors before entering 333 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) { 334 // Store current array 335 this.m = *m; 336 337 // Save previous thread context 338 this.prev_mntrs = this_thread->monitors.list; 339 this.prev_count = this_thread->monitors.size; 340 this.prev_func = this_thread->monitors.func; 341 342 // Update thread context (needed for conditions) 343 this_thread->monitors.list = m; 344 this_thread->monitors.size = 1; 345 this_thread->monitors.func = func; 346 347 __enter_monitor_dtor( this.m, func ); 348 } 349 350 351 // Dtor for monitor guard 352 void ^?{}( monitor_dtor_guard_t & this ) { 353 // Leave the monitors in order 354 __leave_dtor_monitor_desc( this.m ); 248 LIB_DEBUG_PRINT_SAFE("MGUARD : left\n"); 355 249 356 250 // Restore thread context … … 409 303 short thread_count = 0; 410 304 thread_desc * threads[ count ]; 411 __builtin_memset( threads, 0, sizeof( threads ) ); 305 for(int i = 0; i < count; i++) { 306 threads[i] = 0; 307 } 412 308 413 309 // Save monitor states … … 533 429 short max = count_max( mask ); 534 430 monitor_desc * mon_storage[max]; 535 __builtin_memset( mon_storage, 0, sizeof( mon_storage ) );536 431 short actual_count = aggregate( mon_storage, mask ); 537 432 538 LIB_DEBUG_PRINT_SAFE("Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (short)max);539 540 433 if(actual_count == 0) return; 541 542 LIB_DEBUG_PRINT_SAFE("Kernel : waitfor internal proceeding\n");543 434 544 435 // Create storage for monitor context … … 554 445 555 446 if( next ) { 556 *mask.accepted = index;557 447 if( mask.clauses[index].is_dtor ) { 558 LIB_DEBUG_PRINT_SAFE("Kernel : dtor already there\n"); 559 verifyf( mask.clauses[index].size == 1 , "ERROR: Accepted dtor has more than 1 mutex parameter." ); 560 561 monitor_desc * mon2dtor = mask.clauses[index].list[0]; 562 verifyf( mon2dtor->dtor_node, "ERROR: Accepted monitor has no dtor_node." ); 563 564 __condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria; 565 push( &mon2dtor->signal_stack, dtor_crit ); 566 567 unlock_all( locks, count ); 448 #warning case not implemented 568 449 } 569 450 else { 570 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, baton-passing\n"); 571 572 // Create the node specific to this wait operation 573 wait_ctx_primed( this_thread, 0 ); 574 575 // Save monitor states 576 monitor_save; 577 578 // Set the owners to be the next thread 579 set_owner( monitors, count, next ); 580 581 // Everything is ready to go to sleep 582 BlockInternal( locks, count, &next, 1 ); 583 584 // We are back, restore the owners and recursions 585 monitor_restore; 586 587 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, returned\n"); 451 blockAndWake( &next, 1 ); 588 452 } 589 453 590 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted); 591 592 return; 454 return index; 593 455 } 594 456 } … … 596 458 597 459 if( duration == 0 ) { 598 LIB_DEBUG_PRINT_SAFE("Kernel : non-blocking, exiting\n");599 600 460 unlock_all( locks, count ); 601 602 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);603 461 return; 604 462 } … … 607 465 verifyf( duration < 0, "Timeout on waitfor statments not supported yet."); 608 466 609 LIB_DEBUG_PRINT_SAFE("Kernel : blocking waitfor\n");610 611 // Create the node specific to this wait operation612 wait_ctx_primed( this_thread, 0 );613 467 614 468 monitor_save; 615 469 set_mask( monitors, count, mask ); 616 470 617 for(int i = 0; i < count; i++) { 618 verify( monitors[i]->owner == this_thread ); 619 } 620 621 //Everything is ready to go to sleep 622 BlockInternal( locks, count ); 623 624 625 // WE WOKE UP 626 627 628 //We are back, restore the masks and recursions 629 monitor_restore; 630 631 LIB_DEBUG_PRINT_SAFE("Kernel : exiting\n"); 632 633 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted); 471 BlockInternal( locks, count ); // Everything is ready to go to sleep 472 //WE WOKE UP 473 monitor_restore; //We are back, restore the masks and recursions 634 474 } 635 475 … … 638 478 639 479 static inline void set_owner( monitor_desc * this, thread_desc * owner ) { 640 //LIB_DEBUG_PRINT_SAFE("Kernal : Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );480 LIB_DEBUG_PRINT_SAFE("Kernal : Setting owner of %p to %p ( was %p)\n", this, owner, this->owner ); 641 481 642 482 //Pass the monitor appropriately … … 657 497 storage[i]->mask = mask; 658 498 } 659 }660 661 static inline void reset_mask( monitor_desc * this ) {662 this->mask.accepted = NULL;663 this->mask.clauses = NULL;664 this->mask.size = 0;665 499 } 666 500 … … 750 584 } 751 585 752 static inline void save ( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) {586 static inline void save ( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 753 587 for( int i = 0; i < count; i++ ) { 754 588 recursions[i] = ctx[i]->recursion; -
src/libcfa/iostream
r6840e7c rb96ec83 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Oct 10 14:51:10201713 // Update Count : 1 4012 // Last Modified On : Wed Sep 13 12:53:46 2017 13 // Update Count : 138 14 14 // 15 15 … … 79 79 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char * ); 80 80 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char16_t * ); 81 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous82 81 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char32_t * ); 83 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )84 82 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const wchar_t * ); 85 83 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const void * ); -
src/libcfa/iostream.c
r6840e7c rb96ec83 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Oct 10 14:51:09201713 // Update Count : 42 412 // Last Modified On : Sun Sep 17 23:24:25 2017 13 // Update Count : 422 14 14 // 15 15 … … 191 191 } // ?|? 192 192 193 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous194 193 forall( dtype ostype | ostream( ostype ) ) 195 194 ostype * ?|?( ostype * os, const char32_t * str ) { … … 198 197 return os; 199 198 } // ?|? 200 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )201 199 202 200 forall( dtype ostype | ostream( ostype ) ) -
src/main.cc
r6840e7c rb96ec83 44 44 #include "ControlStruct/Mutate.h" // for mutate 45 45 #include "GenPoly/Box.h" // for box 46 #include "GenPoly/CopyParams.h" // for copyParams 46 47 #include "GenPoly/InstantiateGeneric.h" // for instantiateGeneric 47 48 #include "GenPoly/Lvalue.h" // for convertLvalue … … 320 321 OPTPRINT("instantiateGenerics") 321 322 GenPoly::instantiateGeneric( translationUnit ); 323 OPTPRINT( "copyParams" ); 324 GenPoly::copyParams( translationUnit ); 322 325 OPTPRINT( "convertLvalue" ) 323 326 GenPoly::convertLvalue( translationUnit ); -
src/prelude/extras.c
r6840e7c rb96ec83 1 1 #include <stddef.h> // size_t, ptrdiff_t 2 #include <stdint.h> // intX_t, uintX_t, where X is 8, 16, 32, 643 2 #include <uchar.h> // char16_t, char32_t 4 3 #include <wchar.h> // wchar_t -
src/prelude/extras.regx
r6840e7c rb96ec83 1 1 typedef.* size_t; 2 2 typedef.* ptrdiff_t; 3 typedef.* int8_t;4 typedef.* int16_t;5 typedef.* int32_t;6 typedef.* int64_t;7 typedef.* uint8_t;8 typedef.* uint16_t;9 typedef.* uint32_t;10 typedef.* uint64_t;11 3 typedef.* char16_t; 12 4 typedef.* char32_t; -
src/prelude/prelude.cf
r6840e7c rb96ec83 7 7 // Created On : Sat Nov 29 07:23:41 2014 8 8 // Last Modified By : Peter A. Buhr 9 // Last Modified On : Sun Oct 8 12:21:33201710 // Update Count : 9 79 // Last Modified On : Wed Aug 30 07:56:07 2017 10 // Update Count : 93 11 11 // 12 12 … … 558 558 signed long long int ?+=?( signed long long int &, signed long long int ), ?+=?( volatile signed long long int &, signed long long int ); 559 559 unsigned long long int ?+=?( unsigned long long int &, unsigned long long int ), ?+=?( volatile unsigned long long int &, unsigned long long int ); 560 //signed int128 ?+=?( signed int128 &, signed int128 ), ?+=?( volatile signed int128 &, signed int128 );561 //unsigned int128 ?+=?( unsigned int128 &, unsigned int128 ), ?+=?( volatile unsigned int128 &, unsigned int128 );562 560 563 561 _Bool ?-=?( _Bool &, _Bool ), ?-=?( volatile _Bool &, _Bool ); -
src/tests/.expect/32/KRfunctions.txt
r6840e7c rb96ec83 21 21 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 22 22 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 23 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1);24 23 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 25 24 ((void)((*___dst__R2sS_1).__i__i_1) /* ?{} */); … … 34 33 struct S ___ret__2sS_1; 35 34 ((void)((*___dst__R2sS_1).__i__i_1=___src__2sS_1.__i__i_1)); 36 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));37 return ___ret__2sS_1;35 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1)); 36 return ((struct S )___ret__2sS_1); 38 37 } 39 38 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1){ … … 66 65 signed int *__x__FPi_ii__2(signed int __anonymous_object2, signed int __anonymous_object3); 67 66 ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */); 68 return ___retval_f10__PFPi_ii__1;67 return ((signed int *(*)(signed int __x__i_1, signed int __y__i_1))___retval_f10__PFPi_ii__1); 69 68 } 70 69 signed int (*__f11__FPA0i_iPiPi__1(signed int __a__i_1, signed int *__b__Pi_1, signed int *__c__Pi_1))[]{ -
src/tests/.expect/32/attributes.txt
r6840e7c rb96ec83 23 23 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){ 24 24 struct __anonymous0 ___ret__13s__anonymous0_1; 25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1)));26 return ___ret__13s__anonymous0_1;25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1)); 26 return ((struct __anonymous0 )___ret__13s__anonymous0_1); 27 27 } 28 28 __attribute__ ((unused)) struct Agn1; … … 41 41 static inline struct Agn2 ___operator_assign__F5sAgn2_R5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__R5sAgn2_1, struct Agn2 ___src__5sAgn2_1){ 42 42 struct Agn2 ___ret__5sAgn2_1; 43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__R5sAgn2_1)));44 return ___ret__5sAgn2_1;43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), ___src__5sAgn2_1)); 44 return ((struct Agn2 )___ret__5sAgn2_1); 45 45 } 46 46 enum __attribute__ ((unused)) __anonymous1 { … … 69 69 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1); 70 70 static inline struct Fdl ___operator_assign__F4sFdl_R4sFdl4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1, struct Fdl ___src__4sFdl_1); 71 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1);72 static inline void ___constructor__F_R4sFdlii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1);73 static inline void ___constructor__F_R4sFdliii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1);74 static inline void ___constructor__F_R4sFdliiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1);75 static inline void ___constructor__F_R4sFdliiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1);76 static inline void ___constructor__F_R4sFdliiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1);77 static inline void ___constructor__F_R4sFdliiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1);78 static inline void ___constructor__F_R4sFdliiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1);79 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object1);80 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object2, signed int *__f9__Pi_1);81 71 static inline void ___constructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 82 72 ((void)((*___dst__R4sFdl_1).__f1__i_1) /* ?{} */); … … 88 78 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 89 79 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 90 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);91 80 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 92 81 } … … 100 89 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */); 101 90 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1) /* ?{} */); 102 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0) /* ?{} */);103 91 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */); 104 92 } 105 93 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 106 94 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ^?{} */); 107 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ^?{} */);108 95 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ^?{} */); 109 96 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ^?{} */); … … 125 112 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1)); 126 113 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1)); 127 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0));128 114 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1)); 129 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__R4sFdl_1)));130 return ___ret__4sFdl_1;115 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), ___src__4sFdl_1)); 116 return ((struct Fdl )___ret__4sFdl_1); 131 117 } 132 118 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1){ … … 139 125 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 140 126 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 141 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);142 127 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 143 128 } … … 151 136 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 152 137 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 153 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);154 138 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 155 139 } … … 163 147 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 164 148 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 165 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);166 149 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 167 150 } … … 175 158 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 176 159 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 177 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);178 160 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 179 161 } … … 187 169 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 188 170 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 189 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);190 171 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 191 172 } … … 199 180 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 200 181 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 201 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);202 182 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 203 183 } … … 211 191 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 212 192 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 213 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);214 193 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 215 194 } … … 223 202 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 224 203 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 225 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 226 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 227 } 228 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object3){ 204 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 205 } 206 static inline void ___constructor__F_R4sFdliiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int *__f9__Pi_1){ 229 207 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */); 230 208 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */); … … 235 213 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 236 214 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 237 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object3) /* ?{} */);238 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);239 }240 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object4, signed int *__f9__Pi_1){241 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);242 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);243 ((void)((*___dst__R4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);244 ((void)((*___dst__R4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);245 ((void)((*___dst__R4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);246 ((void)((*___dst__R4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);247 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);248 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);249 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object4) /* ?{} */);250 215 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */); 251 216 } … … 267 232 __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1; 268 233 } 269 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object 5))[];234 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object1))[]; 270 235 __attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{ 271 236 __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[]; 272 237 } 273 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 6);274 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 7){275 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object 8);238 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object2); 239 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object3){ 240 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object4); 276 241 } 277 242 signed int __vtr__Fi___1(){ … … 303 268 signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1); 304 269 signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1); 305 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 9)(__attribute__ ((unused,unused)) signed int __anonymous_object10[((unsigned int )5)]));270 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object5)(__attribute__ ((unused,unused)) signed int __anonymous_object6[((unsigned int )5)])); 306 271 signed int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 307 272 signed int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 308 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 11)(__attribute__ ((unused)) signed int (*__anonymous_object12)(__attribute__ ((unused,unused)) signed int __anonymous_object13)));273 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object7)(__attribute__ ((unused)) signed int (*__anonymous_object8)(__attribute__ ((unused,unused)) signed int __anonymous_object9))); 309 274 signed int __ad__Fi___1(){ 310 275 __attribute__ ((unused)) signed int ___retval_ad__i_1; … … 335 300 struct __anonymous4 ___ret__13s__anonymous4_2; 336 301 ((void)((*___dst__R13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2)); 337 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), (*___dst__R13s__anonymous4_2)));338 return ___ret__13s__anonymous4_2;302 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), ___src__13s__anonymous4_2)); 303 return ((struct __anonymous4 )___ret__13s__anonymous4_2); 339 304 } 340 305 inline void ___constructor__F_R13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__R13s__anonymous4_2, signed int __i__i_2){ … … 348 313 } 349 314 inline void ___constructor__F_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 350 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) /* ?{} */);315 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)); 351 316 } 352 317 inline void ___destructor__F_R13e__anonymous5_intrinsic___2(__attribute__ ((unused)) enum __anonymous5 *___dst__R13e__anonymous5_2){ … … 354 319 inline enum __anonymous5 ___operator_assign__F13e__anonymous5_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 355 320 enum __anonymous5 ___ret__13e__anonymous5_2; 356 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)); 357 ((void)(___ret__13e__anonymous5_2=(*___dst__R13e__anonymous5_2)) /* ?{} */); 358 return ___ret__13e__anonymous5_2; 321 ((void)(___ret__13e__anonymous5_2=((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)) /* ?{} */); 322 return ((enum __anonymous5 )___ret__13e__anonymous5_2); 359 323 } 360 324 ((void)sizeof(enum __anonymous5 )); 361 325 } 362 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 4, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);363 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object1 6, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object17);364 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 8, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object19);365 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 20)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object21)());366 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 22)(__attribute__ ((unused)) signed int __anonymous_object23), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25));367 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 6)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object27)());368 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 8)(__attribute__ ((unused)) signed int __anonymous_object29), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object30)(__attribute__ ((unused)) signed int __anonymous_object31));326 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object10, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object11); 327 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object13); 328 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15); 329 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)()); 330 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object18)(__attribute__ ((unused)) signed int __anonymous_object19), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(__attribute__ ((unused)) signed int __anonymous_object21)); 331 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)()); 332 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(__attribute__ ((unused)) signed int __anonymous_object27)); 369 333 struct Vad { 370 __attribute__ ((unused)) signed int __anonymous_object 32;371 __attribute__ ((unused,unused)) signed int *__anonymous_object 33;372 __attribute__ ((unused,unused)) signed int __anonymous_object3 4[((unsigned int )10)];373 __attribute__ ((unused,unused)) signed int (*__anonymous_object3 5)();334 __attribute__ ((unused)) signed int __anonymous_object28; 335 __attribute__ ((unused,unused)) signed int *__anonymous_object29; 336 __attribute__ ((unused,unused)) signed int __anonymous_object30[((unsigned int )10)]; 337 __attribute__ ((unused,unused)) signed int (*__anonymous_object31)(); 374 338 }; 375 339 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); … … 377 341 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); 378 342 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1); 379 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object36);380 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object37, signed int *__anonymous_object38);381 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object39, signed int *__anonymous_object40, signed int __anonymous_object41[((unsigned int )10)]);382 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object42, signed int *__anonymous_object43, signed int __anonymous_object44[((unsigned int )10)], signed int (*__anonymous_object45)());383 343 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 384 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ?{} */);385 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */);386 {387 signed int _index0 = 0;388 for (;(_index0<10);((void)(++_index0))) {389 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index0])))) /* ?{} */);390 }391 392 }393 394 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */);395 344 } 396 345 static inline void ___constructor__F_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 397 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32) /* ?{} */);398 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33) /* ?{} */);399 {400 signed int _index1 = 0;401 for (;(_index1<10);((void)(++_index1))) {402 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index1])))=___src__4sVad_1.__anonymous_object34[_index1]) /* ?{} */);403 }404 405 }406 407 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35) /* ?{} */);408 346 } 409 347 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 410 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ^?{} */);411 {412 signed int _index2 = (10-1);413 for (;(_index2>=0);((void)(--_index2))) {414 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index2])))) /* ^?{} */);415 }416 417 }418 419 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ^?{} */);420 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ^?{} */);421 348 } 422 349 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 423 350 struct Vad ___ret__4sVad_1; 424 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32)); 425 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33)); 426 { 427 signed int _index3 = 0; 428 for (;(_index3<10);((void)(++_index3))) { 429 ((void)((*___dst__R4sVad_1).__anonymous_object34[_index3]=___src__4sVad_1.__anonymous_object34[_index3])); 430 } 431 432 } 433 434 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35)); 435 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), (*___dst__R4sVad_1))); 436 return ___ret__4sVad_1; 437 } 438 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object46){ 439 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object46) /* ?{} */); 440 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */); 441 { 442 signed int _index4 = 0; 443 for (;(_index4<10);((void)(++_index4))) { 444 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index4])))) /* ?{} */); 445 } 446 447 } 448 449 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 450 } 451 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object47, signed int *__anonymous_object48){ 452 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object47) /* ?{} */); 453 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object48) /* ?{} */); 454 { 455 signed int _index5 = 0; 456 for (;(_index5<10);((void)(++_index5))) { 457 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index5])))) /* ?{} */); 458 } 459 460 } 461 462 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 463 } 464 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object49, signed int *__anonymous_object50, signed int __anonymous_object51[((unsigned int )10)]){ 465 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object49) /* ?{} */); 466 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object50) /* ?{} */); 467 { 468 signed int _index6 = 0; 469 for (;(_index6<10);((void)(++_index6))) { 470 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index6])))=__anonymous_object51[_index6]) /* ?{} */); 471 } 472 473 } 474 475 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 476 } 477 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object52, signed int *__anonymous_object53, signed int __anonymous_object54[((unsigned int )10)], signed int (*__anonymous_object55)()){ 478 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object52) /* ?{} */); 479 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object53) /* ?{} */); 480 { 481 signed int _index7 = 0; 482 for (;(_index7<10);((void)(++_index7))) { 483 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[_index7])))=__anonymous_object54[_index7]) /* ?{} */); 484 } 485 486 } 487 488 ((void)((*___dst__R4sVad_1).__anonymous_object35=__anonymous_object55) /* ?{} */); 489 } 351 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), ___src__4sVad_1)); 352 return ((struct Vad )___ret__4sVad_1); 353 } -
src/tests/.expect/32/declarationSpecifier.txt
r6840e7c rb96ec83 20 20 static inline void ___destructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1); 21 21 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 22 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1);23 22 static inline void ___constructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1){ 24 23 ((void)((*___dst__R13s__anonymous0_1).__i__i_1) /* ?{} */); … … 33 32 struct __anonymous0 ___ret__13s__anonymous0_1; 34 33 ((void)((*___dst__R13s__anonymous0_1).__i__i_1=___src__13s__anonymous0_1.__i__i_1)); 35 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1)));36 return ___ret__13s__anonymous0_1;34 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1)); 35 return ((struct __anonymous0 )___ret__13s__anonymous0_1); 37 36 } 38 37 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1){ … … 47 46 static inline void ___destructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1); 48 47 static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_R13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1); 49 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1);50 48 static inline void ___constructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1){ 51 49 ((void)((*___dst__R13s__anonymous1_1).__i__i_1) /* ?{} */); … … 60 58 struct __anonymous1 ___ret__13s__anonymous1_1; 61 59 ((void)((*___dst__R13s__anonymous1_1).__i__i_1=___src__13s__anonymous1_1.__i__i_1)); 62 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), (*___dst__R13s__anonymous1_1)));63 return ___ret__13s__anonymous1_1;60 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), ___src__13s__anonymous1_1)); 61 return ((struct __anonymous1 )___ret__13s__anonymous1_1); 64 62 } 65 63 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1){ … … 74 72 static inline void ___destructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1); 75 73 static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_R13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1); 76 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1);77 74 static inline void ___constructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1){ 78 75 ((void)((*___dst__R13s__anonymous2_1).__i__i_1) /* ?{} */); … … 87 84 struct __anonymous2 ___ret__13s__anonymous2_1; 88 85 ((void)((*___dst__R13s__anonymous2_1).__i__i_1=___src__13s__anonymous2_1.__i__i_1)); 89 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__R13s__anonymous2_1)));90 return ___ret__13s__anonymous2_1;86 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), ___src__13s__anonymous2_1)); 87 return ((struct __anonymous2 )___ret__13s__anonymous2_1); 91 88 } 92 89 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1){ … … 101 98 static inline void ___destructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1); 102 99 static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_R13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1); 103 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1);104 100 static inline void ___constructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1){ 105 101 ((void)((*___dst__R13s__anonymous3_1).__i__i_1) /* ?{} */); … … 114 110 struct __anonymous3 ___ret__13s__anonymous3_1; 115 111 ((void)((*___dst__R13s__anonymous3_1).__i__i_1=___src__13s__anonymous3_1.__i__i_1)); 116 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), (*___dst__R13s__anonymous3_1)));117 return ___ret__13s__anonymous3_1;112 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), ___src__13s__anonymous3_1)); 113 return ((struct __anonymous3 )___ret__13s__anonymous3_1); 118 114 } 119 115 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1){ … … 128 124 static inline void ___destructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1); 129 125 static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_R13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1); 130 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1);131 126 static inline void ___constructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1){ 132 127 ((void)((*___dst__R13s__anonymous4_1).__i__i_1) /* ?{} */); … … 141 136 struct __anonymous4 ___ret__13s__anonymous4_1; 142 137 ((void)((*___dst__R13s__anonymous4_1).__i__i_1=___src__13s__anonymous4_1.__i__i_1)); 143 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), (*___dst__R13s__anonymous4_1)));144 return ___ret__13s__anonymous4_1;138 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), ___src__13s__anonymous4_1)); 139 return ((struct __anonymous4 )___ret__13s__anonymous4_1); 145 140 } 146 141 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1){ … … 155 150 static inline void ___destructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1); 156 151 static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_R13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1); 157 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1);158 152 static inline void ___constructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1){ 159 153 ((void)((*___dst__R13s__anonymous5_1).__i__i_1) /* ?{} */); … … 168 162 struct __anonymous5 ___ret__13s__anonymous5_1; 169 163 ((void)((*___dst__R13s__anonymous5_1).__i__i_1=___src__13s__anonymous5_1.__i__i_1)); 170 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), (*___dst__R13s__anonymous5_1)));171 return ___ret__13s__anonymous5_1;164 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), ___src__13s__anonymous5_1)); 165 return ((struct __anonymous5 )___ret__13s__anonymous5_1); 172 166 } 173 167 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1){ … … 182 176 static inline void ___destructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1); 183 177 static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_R13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1); 184 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1);185 178 static inline void ___constructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1){ 186 179 ((void)((*___dst__R13s__anonymous6_1).__i__i_1) /* ?{} */); … … 195 188 struct __anonymous6 ___ret__13s__anonymous6_1; 196 189 ((void)((*___dst__R13s__anonymous6_1).__i__i_1=___src__13s__anonymous6_1.__i__i_1)); 197 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), (*___dst__R13s__anonymous6_1)));198 return ___ret__13s__anonymous6_1;190 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), ___src__13s__anonymous6_1)); 191 return ((struct __anonymous6 )___ret__13s__anonymous6_1); 199 192 } 200 193 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1){ … … 209 202 static inline void ___destructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1); 210 203 static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_R13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1); 211 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1);212 204 static inline void ___constructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1){ 213 205 ((void)((*___dst__R13s__anonymous7_1).__i__i_1) /* ?{} */); … … 222 214 struct __anonymous7 ___ret__13s__anonymous7_1; 223 215 ((void)((*___dst__R13s__anonymous7_1).__i__i_1=___src__13s__anonymous7_1.__i__i_1)); 224 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), (*___dst__R13s__anonymous7_1)));225 return ___ret__13s__anonymous7_1;216 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), ___src__13s__anonymous7_1)); 217 return ((struct __anonymous7 )___ret__13s__anonymous7_1); 226 218 } 227 219 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1){ … … 244 236 static inline void ___destructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1); 245 237 static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_R13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1); 246 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1);247 238 static inline void ___constructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1){ 248 239 ((void)((*___dst__R13s__anonymous8_1).__i__s_1) /* ?{} */); … … 257 248 struct __anonymous8 ___ret__13s__anonymous8_1; 258 249 ((void)((*___dst__R13s__anonymous8_1).__i__s_1=___src__13s__anonymous8_1.__i__s_1)); 259 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), (*___dst__R13s__anonymous8_1)));260 return ___ret__13s__anonymous8_1;250 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), ___src__13s__anonymous8_1)); 251 return ((struct __anonymous8 )___ret__13s__anonymous8_1); 261 252 } 262 253 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1){ … … 271 262 static inline void ___destructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1); 272 263 static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_R13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1); 273 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1);274 264 static inline void ___constructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1){ 275 265 ((void)((*___dst__R13s__anonymous9_1).__i__s_1) /* ?{} */); … … 284 274 struct __anonymous9 ___ret__13s__anonymous9_1; 285 275 ((void)((*___dst__R13s__anonymous9_1).__i__s_1=___src__13s__anonymous9_1.__i__s_1)); 286 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), (*___dst__R13s__anonymous9_1)));287 return ___ret__13s__anonymous9_1;276 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), ___src__13s__anonymous9_1)); 277 return ((struct __anonymous9 )___ret__13s__anonymous9_1); 288 278 } 289 279 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1){ … … 298 288 static inline void ___destructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1); 299 289 static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_R14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1); 300 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1);301 290 static inline void ___constructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1){ 302 291 ((void)((*___dst__R14s__anonymous10_1).__i__s_1) /* ?{} */); … … 311 300 struct __anonymous10 ___ret__14s__anonymous10_1; 312 301 ((void)((*___dst__R14s__anonymous10_1).__i__s_1=___src__14s__anonymous10_1.__i__s_1)); 313 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), (*___dst__R14s__anonymous10_1)));314 return ___ret__14s__anonymous10_1;302 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), ___src__14s__anonymous10_1)); 303 return ((struct __anonymous10 )___ret__14s__anonymous10_1); 315 304 } 316 305 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1){ … … 325 314 static inline void ___destructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1); 326 315 static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_R14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1); 327 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1);328 316 static inline void ___constructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1){ 329 317 ((void)((*___dst__R14s__anonymous11_1).__i__s_1) /* ?{} */); … … 338 326 struct __anonymous11 ___ret__14s__anonymous11_1; 339 327 ((void)((*___dst__R14s__anonymous11_1).__i__s_1=___src__14s__anonymous11_1.__i__s_1)); 340 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), (*___dst__R14s__anonymous11_1)));341 return ___ret__14s__anonymous11_1;328 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), ___src__14s__anonymous11_1)); 329 return ((struct __anonymous11 )___ret__14s__anonymous11_1); 342 330 } 343 331 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1){ … … 352 340 static inline void ___destructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1); 353 341 static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_R14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1); 354 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1);355 342 static inline void ___constructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1){ 356 343 ((void)((*___dst__R14s__anonymous12_1).__i__s_1) /* ?{} */); … … 365 352 struct __anonymous12 ___ret__14s__anonymous12_1; 366 353 ((void)((*___dst__R14s__anonymous12_1).__i__s_1=___src__14s__anonymous12_1.__i__s_1)); 367 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), (*___dst__R14s__anonymous12_1)));368 return ___ret__14s__anonymous12_1;354 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), ___src__14s__anonymous12_1)); 355 return ((struct __anonymous12 )___ret__14s__anonymous12_1); 369 356 } 370 357 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1){ … … 379 366 static inline void ___destructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1); 380 367 static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_R14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1); 381 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1);382 368 static inline void ___constructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1){ 383 369 ((void)((*___dst__R14s__anonymous13_1).__i__s_1) /* ?{} */); … … 392 378 struct __anonymous13 ___ret__14s__anonymous13_1; 393 379 ((void)((*___dst__R14s__anonymous13_1).__i__s_1=___src__14s__anonymous13_1.__i__s_1)); 394 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), (*___dst__R14s__anonymous13_1)));395 return ___ret__14s__anonymous13_1;380 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), ___src__14s__anonymous13_1)); 381 return ((struct __anonymous13 )___ret__14s__anonymous13_1); 396 382 } 397 383 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1){ … … 406 392 static inline void ___destructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1); 407 393 static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_R14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1); 408 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1);409 394 static inline void ___constructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1){ 410 395 ((void)((*___dst__R14s__anonymous14_1).__i__s_1) /* ?{} */); … … 419 404 struct __anonymous14 ___ret__14s__anonymous14_1; 420 405 ((void)((*___dst__R14s__anonymous14_1).__i__s_1=___src__14s__anonymous14_1.__i__s_1)); 421 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), (*___dst__R14s__anonymous14_1)));422 return ___ret__14s__anonymous14_1;406 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), ___src__14s__anonymous14_1)); 407 return ((struct __anonymous14 )___ret__14s__anonymous14_1); 423 408 } 424 409 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1){ … … 433 418 static inline void ___destructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1); 434 419 static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_R14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1); 435 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1);436 420 static inline void ___constructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1){ 437 421 ((void)((*___dst__R14s__anonymous15_1).__i__s_1) /* ?{} */); … … 446 430 struct __anonymous15 ___ret__14s__anonymous15_1; 447 431 ((void)((*___dst__R14s__anonymous15_1).__i__s_1=___src__14s__anonymous15_1.__i__s_1)); 448 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), (*___dst__R14s__anonymous15_1)));449 return ___ret__14s__anonymous15_1;432 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), ___src__14s__anonymous15_1)); 433 return ((struct __anonymous15 )___ret__14s__anonymous15_1); 450 434 } 451 435 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1){ … … 476 460 static inline void ___destructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1); 477 461 static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_R14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1); 478 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1);479 462 static inline void ___constructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1){ 480 463 ((void)((*___dst__R14s__anonymous16_1).__i__i_1) /* ?{} */); … … 489 472 struct __anonymous16 ___ret__14s__anonymous16_1; 490 473 ((void)((*___dst__R14s__anonymous16_1).__i__i_1=___src__14s__anonymous16_1.__i__i_1)); 491 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), (*___dst__R14s__anonymous16_1)));492 return ___ret__14s__anonymous16_1;474 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), ___src__14s__anonymous16_1)); 475 return ((struct __anonymous16 )___ret__14s__anonymous16_1); 493 476 } 494 477 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1){ … … 503 486 static inline void ___destructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1); 504 487 static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_R14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1); 505 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1);506 488 static inline void ___constructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1){ 507 489 ((void)((*___dst__R14s__anonymous17_1).__i__i_1) /* ?{} */); … … 516 498 struct __anonymous17 ___ret__14s__anonymous17_1; 517 499 ((void)((*___dst__R14s__anonymous17_1).__i__i_1=___src__14s__anonymous17_1.__i__i_1)); 518 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), (*___dst__R14s__anonymous17_1)));519 return ___ret__14s__anonymous17_1;500 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), ___src__14s__anonymous17_1)); 501 return ((struct __anonymous17 )___ret__14s__anonymous17_1); 520 502 } 521 503 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1){ … … 530 512 static inline void ___destructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1); 531 513 static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_R14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1); 532 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1);533 514 static inline void ___constructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1){ 534 515 ((void)((*___dst__R14s__anonymous18_1).__i__i_1) /* ?{} */); … … 543 524 struct __anonymous18 ___ret__14s__anonymous18_1; 544 525 ((void)((*___dst__R14s__anonymous18_1).__i__i_1=___src__14s__anonymous18_1.__i__i_1)); 545 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), (*___dst__R14s__anonymous18_1)));546 return ___ret__14s__anonymous18_1;526 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), ___src__14s__anonymous18_1)); 527 return ((struct __anonymous18 )___ret__14s__anonymous18_1); 547 528 } 548 529 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1){ … … 557 538 static inline void ___destructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1); 558 539 static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_R14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1); 559 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1);560 540 static inline void ___constructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1){ 561 541 ((void)((*___dst__R14s__anonymous19_1).__i__i_1) /* ?{} */); … … 570 550 struct __anonymous19 ___ret__14s__anonymous19_1; 571 551 ((void)((*___dst__R14s__anonymous19_1).__i__i_1=___src__14s__anonymous19_1.__i__i_1)); 572 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), (*___dst__R14s__anonymous19_1)));573 return ___ret__14s__anonymous19_1;552 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), ___src__14s__anonymous19_1)); 553 return ((struct __anonymous19 )___ret__14s__anonymous19_1); 574 554 } 575 555 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1){ … … 584 564 static inline void ___destructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1); 585 565 static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_R14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1); 586 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1);587 566 static inline void ___constructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1){ 588 567 ((void)((*___dst__R14s__anonymous20_1).__i__i_1) /* ?{} */); … … 597 576 struct __anonymous20 ___ret__14s__anonymous20_1; 598 577 ((void)((*___dst__R14s__anonymous20_1).__i__i_1=___src__14s__anonymous20_1.__i__i_1)); 599 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), (*___dst__R14s__anonymous20_1)));600 return ___ret__14s__anonymous20_1;578 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), ___src__14s__anonymous20_1)); 579 return ((struct __anonymous20 )___ret__14s__anonymous20_1); 601 580 } 602 581 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1){ … … 611 590 static inline void ___destructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1); 612 591 static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_R14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1); 613 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1);614 592 static inline void ___constructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1){ 615 593 ((void)((*___dst__R14s__anonymous21_1).__i__i_1) /* ?{} */); … … 624 602 struct __anonymous21 ___ret__14s__anonymous21_1; 625 603 ((void)((*___dst__R14s__anonymous21_1).__i__i_1=___src__14s__anonymous21_1.__i__i_1)); 626 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), (*___dst__R14s__anonymous21_1)));627 return ___ret__14s__anonymous21_1;604 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), ___src__14s__anonymous21_1)); 605 return ((struct __anonymous21 )___ret__14s__anonymous21_1); 628 606 } 629 607 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1){ … … 638 616 static inline void ___destructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1); 639 617 static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_R14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1); 640 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1);641 618 static inline void ___constructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1){ 642 619 ((void)((*___dst__R14s__anonymous22_1).__i__i_1) /* ?{} */); … … 651 628 struct __anonymous22 ___ret__14s__anonymous22_1; 652 629 ((void)((*___dst__R14s__anonymous22_1).__i__i_1=___src__14s__anonymous22_1.__i__i_1)); 653 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), (*___dst__R14s__anonymous22_1)));654 return ___ret__14s__anonymous22_1;630 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), ___src__14s__anonymous22_1)); 631 return ((struct __anonymous22 )___ret__14s__anonymous22_1); 655 632 } 656 633 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1){ … … 665 642 static inline void ___destructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1); 666 643 static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_R14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1); 667 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1);668 644 static inline void ___constructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1){ 669 645 ((void)((*___dst__R14s__anonymous23_1).__i__i_1) /* ?{} */); … … 678 654 struct __anonymous23 ___ret__14s__anonymous23_1; 679 655 ((void)((*___dst__R14s__anonymous23_1).__i__i_1=___src__14s__anonymous23_1.__i__i_1)); 680 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), (*___dst__R14s__anonymous23_1)));681 return ___ret__14s__anonymous23_1;656 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), ___src__14s__anonymous23_1)); 657 return ((struct __anonymous23 )___ret__14s__anonymous23_1); 682 658 } 683 659 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1){ … … 696 672 __attribute__ ((unused)) signed int ___retval_main__i_1; 697 673 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 698 return ___retval_main__i_1;674 return ((signed int )___retval_main__i_1); 699 675 ((void)(___retval_main__i_1=0) /* ?{} */); 700 return ___retval_main__i_1;676 return ((signed int )___retval_main__i_1); 701 677 } 702 678 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 713 689 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 714 690 ((void)(_tmp_cp_ret0) /* ^?{} */); 715 return ___retval_main__i_1;716 } 691 return ((signed int )___retval_main__i_1); 692 } -
src/tests/.expect/32/extension.txt
r6840e7c rb96ec83 17 17 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 18 18 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 19 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1);20 static inline void ___constructor__F_R2sSii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1);21 static inline void ___constructor__F_R2sSiii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1, signed int __c__i_1);22 19 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 23 20 ((void)((*___dst__R2sS_1).__a__i_1) /* ?{} */); … … 40 37 ((void)((*___dst__R2sS_1).__b__i_1=___src__2sS_1.__b__i_1)); 41 38 ((void)((*___dst__R2sS_1).__c__i_1=___src__2sS_1.__c__i_1)); 42 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));43 return ___ret__2sS_1;39 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1)); 40 return ((struct S )___ret__2sS_1); 44 41 } 45 42 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1){ … … 63 60 __extension__ signed int __c__i_1; 64 61 }; 65 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1);66 static inline void ___constructor__F_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1);67 static inline void ___destructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1);68 static inline union U ___operator_assign__F2uU_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1);69 static inline void ___constructor__F_R2uUi_autogen___1(union U *___dst__R2uU_1, signed int __a__i_1);70 62 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1){ 71 63 } … … 78 70 union U ___ret__2uU_1; 79 71 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&___src__2uU_1)), sizeof(union U ))); 80 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), (*___dst__R2uU_1)));81 return ___ret__2uU_1;72 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), ___src__2uU_1)); 73 return ((union U )___ret__2uU_1); 82 74 } 83 static inline void ___constructor__F_R2uUi_autogen___1( union U *___dst__R2uU_1, signed int __a__i_1){84 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__ a__i_1)), sizeof(signed int )));75 static inline void ___constructor__F_R2uUi_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1, signed int __src__i_1){ 76 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__src__i_1)), sizeof(signed int ))); 85 77 } 86 78 __extension__ enum E { … … 102 94 __extension__ signed int *__z__Pi_2; 103 95 }; 104 inline void ___constructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 105 ((void)((*___dst__R2sS_2).__a__i_2) /* ?{} */); 106 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 107 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 108 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 109 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 110 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 111 } 112 inline void ___constructor__F_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 113 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2) /* ?{} */); 114 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2) /* ?{} */); 115 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2) /* ?{} */); 116 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2) /* ?{} */); 117 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2) /* ?{} */); 118 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2) /* ?{} */); 119 } 120 inline void ___destructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 121 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ^?{} */); 122 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ^?{} */); 123 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ^?{} */); 124 ((void)((*___dst__R2sS_2).__c__i_2) /* ^?{} */); 125 ((void)((*___dst__R2sS_2).__b__i_2) /* ^?{} */); 126 ((void)((*___dst__R2sS_2).__a__i_2) /* ^?{} */); 127 } 128 inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 129 struct S ___ret__2sS_2; 130 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2)); 131 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 132 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 133 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2)); 134 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2)); 135 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2)); 136 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2))); 137 return ___ret__2sS_2; 138 } 139 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ 140 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 141 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 142 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 143 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 144 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 145 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 146 } 147 inline void ___constructor__F_R2sSii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2){ 148 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 149 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 150 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 151 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 152 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 153 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 154 } 155 inline void ___constructor__F_R2sSiii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2){ 156 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 157 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 158 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 159 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 160 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 161 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 162 } 163 inline void ___constructor__F_R2sSiiiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2){ 164 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 165 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 166 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 167 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 168 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 169 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 170 } 171 inline void ___constructor__F_R2sSiiiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2){ 172 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 173 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 174 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 175 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 176 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 177 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 178 } 179 inline void ___constructor__F_R2sSiiiPiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2, signed int *__z__Pi_2){ 180 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 181 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 182 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 183 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 184 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 185 ((void)((*___dst__R2sS_2).__z__Pi_2=__z__Pi_2) /* ?{} */); 186 } 187 signed int __i__i_2 = (__extension__ __a__i_1+__extension__ 3); 96 signed int __i__i_2 = ((signed int )(__extension__ __a__i_1+__extension__ 3)); 188 97 ((void)__extension__ 3); 189 98 ((void)__extension__ __a__i_1); -
src/tests/.expect/32/gccExtensions.txt
r6840e7c rb96ec83 63 63 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 64 64 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2)));66 return ___ret__2sS_2;65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), ___src__2sS_2)); 66 return ((struct S )___ret__2sS_2); 67 67 } 68 68 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ … … 81 81 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 82 82 } 83 signed int __i__i_2 = __extension__ 3;83 signed int __i__i_2 = ((signed int )__extension__ 3); 84 84 __extension__ signed int __a__i_2; 85 85 __extension__ signed int __b__i_2; … … 113 113 struct s2 ___ret__3ss2_2; 114 114 ((void)((*___dst__R3ss2_2).__i__i_2=___src__3ss2_2.__i__i_2)); 115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), (*___dst__R3ss2_2)));116 return ___ret__3ss2_2;115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), ___src__3ss2_2)); 116 return ((struct s2 )___ret__3ss2_2); 117 117 } 118 118 inline void ___constructor__F_R3ss2i_autogen___2(struct s2 *___dst__R3ss2_2, signed int __i__i_2){ … … 134 134 struct s3 ___ret__3ss3_2; 135 135 ((void)((*___dst__R3ss3_2).__i__i_2=___src__3ss3_2.__i__i_2)); 136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), (*___dst__R3ss3_2)));137 return ___ret__3ss3_2;136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), ___src__3ss3_2)); 137 return ((struct s3 )___ret__3ss3_2); 138 138 } 139 139 inline void ___constructor__F_R3ss3i_autogen___2(struct s3 *___dst__R3ss3_2, signed int __i__i_2){ … … 157 157 struct s4 ___ret__3ss4_2; 158 158 ((void)((*___dst__R3ss4_2).__i__i_2=___src__3ss4_2.__i__i_2)); 159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), (*___dst__R3ss4_2)));160 return ___ret__3ss4_2;159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), ___src__3ss4_2)); 160 return ((struct s4 )___ret__3ss4_2); 161 161 } 162 162 inline void ___constructor__F_R3ss4i_autogen___2(struct s4 *___dst__R3ss4_2, signed int __i__i_2){ … … 169 169 signed int __m3__A0A0i_2[((unsigned int )10)][((unsigned int )10)]; 170 170 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 171 return ___retval_main__i_1;171 return ((signed int )___retval_main__i_1); 172 172 ((void)(___retval_main__i_1=0) /* ?{} */); 173 return ___retval_main__i_1;173 return ((signed int )___retval_main__i_1); 174 174 } 175 175 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 186 186 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 187 187 ((void)(_tmp_cp_ret0) /* ^?{} */); 188 return ___retval_main__i_1;188 return ((signed int )___retval_main__i_1); 189 189 } -
src/tests/.expect/32/literals.txt
r6840e7c rb96ec83 64 64 static inline void ___destructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1); 65 65 static inline struct _Istream_cstrUC ___operator_assign__F16s_Istream_cstrUC_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, struct _Istream_cstrUC ___src__16s_Istream_cstrUC_1); 66 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1);67 66 static inline void ___constructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1){ 68 67 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1) /* ?{} */); … … 77 76 struct _Istream_cstrUC ___ret__16s_Istream_cstrUC_1; 78 77 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1=___src__16s_Istream_cstrUC_1.__s__Pc_1)); 79 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), (*___dst__R16s_Istream_cstrUC_1)));80 return ___ret__16s_Istream_cstrUC_1;78 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), ___src__16s_Istream_cstrUC_1)); 79 return ((struct _Istream_cstrUC )___ret__16s_Istream_cstrUC_1); 81 80 } 82 81 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1){ … … 93 92 static inline void ___destructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1); 94 93 static inline struct _Istream_cstrC ___operator_assign__F15s_Istream_cstrC_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, struct _Istream_cstrC ___src__15s_Istream_cstrC_1); 95 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1);96 static inline void ___constructor__F_R15s_Istream_cstrCPci_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1, signed int __size__i_1);97 94 static inline void ___constructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1){ 98 95 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1) /* ?{} */); … … 111 108 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1=___src__15s_Istream_cstrC_1.__s__Pc_1)); 112 109 ((void)((*___dst__R15s_Istream_cstrC_1).__size__i_1=___src__15s_Istream_cstrC_1.__size__i_1)); 113 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), (*___dst__R15s_Istream_cstrC_1)));114 return ___ret__15s_Istream_cstrC_1;110 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), ___src__15s_Istream_cstrC_1)); 111 return ((struct _Istream_cstrC )___ret__15s_Istream_cstrC_1); 115 112 } 116 113 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1){ … … 125 122 void *___operator_bitor__A0_1_0_0___fail__PFi_Pd0___eof__PFi_Pd0___open__PF_Pd0PCcPCc___close__PF_Pd0___read__PFPd0_Pd0PcUl___ungetc__PFPd0_Pd0c___fmt__PFi_Pd0PCc__FPd0_Pd015s_Istream_cstrC__1(__attribute__ ((unused)) signed int (*__fail__PFi_P7tistype__1)(void *__anonymous_object1284), __attribute__ ((unused)) signed int (*__eof__PFi_P7tistype__1)(void *__anonymous_object1285), __attribute__ ((unused)) void (*__open__PF_P7tistypePCcPCc__1)(void *__is__P7tistype_1, const char *__name__PCc_1, const char *__mode__PCc_1), __attribute__ ((unused)) void (*__close__PF_P7tistype__1)(void *__is__P7tistype_1), __attribute__ ((unused)) void *(*__read__PFP7tistype_P7tistypePcUl__1)(void *__anonymous_object1286, char *__anonymous_object1287, unsigned long int __anonymous_object1288), __attribute__ ((unused)) void *(*__ungetc__PFP7tistype_P7tistypec__1)(void *__anonymous_object1289, char __anonymous_object1290), __attribute__ ((unused)) signed int (*__fmt__PFi_P7tistypePCc__1)(void *__anonymous_object1291, const char *__fmt__PCc_1, ...), void *__anonymous_object1292, struct _Istream_cstrC __anonymous_object1293); 126 123 enum __anonymous0 { 127 __sepSize__C13e__anonymous0_1 = 16,124 __sepSize__C13e__anonymous0_1 = ((signed int )16), 128 125 }; 129 126 struct ofstream { … … 140 137 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1); 141 138 static inline struct ofstream ___operator_assign__F9sofstream_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1); 142 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1);143 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1);144 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1);145 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1);146 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1);147 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]);148 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]);149 139 static inline void ___constructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 150 140 ((void)((*___dst__R9sofstream_1).__file__Pv_1) /* ?{} */); … … 154 144 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 155 145 { 156 signed int _index0 = 0;146 signed int _index0 = ((signed int )0); 157 147 for (;(_index0<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index0))) { 158 148 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index0])))) /* ?{} */); … … 160 150 161 151 } 162 163 { 164 signed int _index1 = 0; 152 { 153 signed int _index1 = ((signed int )0); 165 154 for (;(_index1<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index1))) { 166 155 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index1])))) /* ?{} */); … … 168 157 169 158 } 170 171 159 } 172 160 static inline void ___constructor__F_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1){ … … 177 165 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1) /* ?{} */); 178 166 { 179 signed int _index2 = 0;167 signed int _index2 = ((signed int )0); 180 168 for (;(_index2<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index2))) { 181 169 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index2])))=___src__9sofstream_1.__separator__A0c_1[_index2]) /* ?{} */); … … 183 171 184 172 } 185 186 { 187 signed int _index3 = 0; 173 { 174 signed int _index3 = ((signed int )0); 188 175 for (;(_index3<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index3))) { 189 176 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index3])))=___src__9sofstream_1.__tupleSeparator__A0c_1[_index3]) /* ?{} */); … … 191 178 192 179 } 193 194 180 } 195 181 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 196 182 { 197 signed int _index4 = (( (signed int )__sepSize__C13e__anonymous0_1)-1);183 signed int _index4 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1)); 198 184 for (;(_index4>=0);((void)(--_index4))) { 199 185 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index4])))) /* ^?{} */); … … 201 187 202 188 } 203 204 { 205 signed int _index5 = (((signed int )__sepSize__C13e__anonymous0_1)-1); 189 { 190 signed int _index5 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1)); 206 191 for (;(_index5>=0);((void)(--_index5))) { 207 192 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index5])))) /* ^?{} */); … … 209 194 210 195 } 211 212 196 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ^?{} */); 213 197 ((void)((*___dst__R9sofstream_1).__sawNL__b_1) /* ^?{} */); … … 224 208 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1)); 225 209 { 226 signed int _index6 = 0;210 signed int _index6 = ((signed int )0); 227 211 for (;(_index6<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index6))) { 228 212 ((void)((*___dst__R9sofstream_1).__separator__A0c_1[_index6]=___src__9sofstream_1.__separator__A0c_1[_index6])); … … 232 216 233 217 { 234 signed int _index7 = 0;218 signed int _index7 = ((signed int )0); 235 219 for (;(_index7<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index7))) { 236 220 ((void)((*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index7]=___src__9sofstream_1.__tupleSeparator__A0c_1[_index7])); … … 239 223 } 240 224 241 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), (*___dst__R9sofstream_1)));242 return ___ret__9sofstream_1;225 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), ___src__9sofstream_1)); 226 return ((struct ofstream )___ret__9sofstream_1); 243 227 } 244 228 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1){ … … 249 233 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 250 234 { 251 signed int _index8 = 0;235 signed int _index8 = ((signed int )0); 252 236 for (;(_index8<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index8))) { 253 237 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index8])))) /* ?{} */); … … 255 239 256 240 } 257 258 { 259 signed int _index9 = 0; 241 { 242 signed int _index9 = ((signed int )0); 260 243 for (;(_index9<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index9))) { 261 244 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index9])))) /* ?{} */); … … 263 246 264 247 } 265 266 248 } 267 249 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1){ … … 272 254 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 273 255 { 274 signed int _index10 = 0;256 signed int _index10 = ((signed int )0); 275 257 for (;(_index10<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index10))) { 276 258 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index10])))) /* ?{} */); … … 278 260 279 261 } 280 281 { 282 signed int _index11 = 0; 262 { 263 signed int _index11 = ((signed int )0); 283 264 for (;(_index11<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index11))) { 284 265 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index11])))) /* ?{} */); … … 286 267 287 268 } 288 289 269 } 290 270 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1){ … … 295 275 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 296 276 { 297 signed int _index12 = 0;277 signed int _index12 = ((signed int )0); 298 278 for (;(_index12<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index12))) { 299 279 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index12])))) /* ?{} */); … … 301 281 302 282 } 303 304 { 305 signed int _index13 = 0; 283 { 284 signed int _index13 = ((signed int )0); 306 285 for (;(_index13<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index13))) { 307 286 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index13])))) /* ?{} */); … … 309 288 310 289 } 311 312 290 } 313 291 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1){ … … 318 296 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 319 297 { 320 signed int _index14 = 0;298 signed int _index14 = ((signed int )0); 321 299 for (;(_index14<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index14))) { 322 300 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index14])))) /* ?{} */); … … 324 302 325 303 } 326 327 { 328 signed int _index15 = 0; 304 { 305 signed int _index15 = ((signed int )0); 329 306 for (;(_index15<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index15))) { 330 307 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index15])))) /* ?{} */); … … 332 309 333 310 } 334 335 311 } 336 312 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1){ … … 341 317 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 342 318 { 343 signed int _index16 = 0;319 signed int _index16 = ((signed int )0); 344 320 for (;(_index16<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index16))) { 345 321 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index16])))) /* ?{} */); … … 347 323 348 324 } 349 350 { 351 signed int _index17 = 0; 325 { 326 signed int _index17 = ((signed int )0); 352 327 for (;(_index17<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index17))) { 353 328 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index17])))) /* ?{} */); … … 355 330 356 331 } 357 358 332 } 359 333 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]){ … … 364 338 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 365 339 { 366 signed int _index18 = 0;340 signed int _index18 = ((signed int )0); 367 341 for (;(_index18<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index18))) { 368 342 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index18])))=__separator__A0c_1[_index18]) /* ?{} */); … … 370 344 371 345 } 372 373 { 374 signed int _index19 = 0; 346 { 347 signed int _index19 = ((signed int )0); 375 348 for (;(_index19<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index19))) { 376 349 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index19])))) /* ?{} */); … … 378 351 379 352 } 380 381 353 } 382 354 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned int )__sepSize__C13e__anonymous0_1)]){ … … 387 359 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 388 360 { 389 signed int _index20 = 0;361 signed int _index20 = ((signed int )0); 390 362 for (;(_index20<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index20))) { 391 363 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[_index20])))=__separator__A0c_1[_index20]) /* ?{} */); … … 393 365 394 366 } 395 396 { 397 signed int _index21 = 0; 367 { 368 signed int _index21 = ((signed int )0); 398 369 for (;(_index21<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index21))) { 399 370 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[_index21])))=__tupleSeparator__A0c_1[_index21]) /* ?{} */); … … 401 372 402 373 } 403 404 374 } 405 375 _Bool __sepPrt__Fb_P9sofstream__1(struct ofstream *__anonymous_object1294); … … 434 404 static inline void ___destructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1); 435 405 static inline struct ifstream ___operator_assign__F9sifstream_R9sifstream9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1, struct ifstream ___src__9sifstream_1); 436 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1);437 406 static inline void ___constructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1){ 438 407 ((void)((*___dst__R9sifstream_1).__file__Pv_1) /* ?{} */); … … 447 416 struct ifstream ___ret__9sifstream_1; 448 417 ((void)((*___dst__R9sifstream_1).__file__Pv_1=___src__9sifstream_1.__file__Pv_1)); 449 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), (*___dst__R9sifstream_1)));450 return ___ret__9sifstream_1;418 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), ___src__9sifstream_1)); 419 return ((struct ifstream )___ret__9sifstream_1); 451 420 } 452 421 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1){ … … 739 708 ((void)0123456789.e-09L); 740 709 ((void)0123456789.e-09DL); 741 ((void)( +0123456789.e-09));742 ((void)( +0123456789.e-09f));743 ((void)( +0123456789.e-09l));744 ((void)( +0123456789.e-09F));745 ((void)( +0123456789.e-09L));746 ((void)( +0123456789.e-09DL));710 ((void)(-0123456789.e-09)); 711 ((void)(-0123456789.e-09f)); 712 ((void)(-0123456789.e-09l)); 713 ((void)(-0123456789.e-09F)); 714 ((void)(-0123456789.e-09L)); 715 ((void)(-0123456789.e-09DL)); 747 716 ((void)(-0123456789.e-09)); 748 717 ((void)(-0123456789.e-09f)); … … 883 852 ((void)0123456789.0123456789E-09L); 884 853 ((void)0123456789.0123456789E-09DL); 885 ((void)( +0123456789.0123456789E-09));886 ((void)( +0123456789.0123456789E-09f));887 ((void)( +0123456789.0123456789E-09l));888 ((void)( +0123456789.0123456789E-09F));889 ((void)( +0123456789.0123456789E-09L));890 ((void)( +0123456789.0123456789E-09DL));854 ((void)(-0123456789.0123456789E-09)); 855 ((void)(-0123456789.0123456789E-09f)); 856 ((void)(-0123456789.0123456789E-09l)); 857 ((void)(-0123456789.0123456789E-09F)); 858 ((void)(-0123456789.0123456789E-09L)); 859 ((void)(-0123456789.0123456789E-09DL)); 891 860 ((void)(-0123456789.0123456789E-09)); 892 861 ((void)(-0123456789.0123456789E-09f)); … … 930 899 ((void)0x0123456789.p-09F); 931 900 ((void)0x0123456789.p-09L); 932 ((void)( +0x0123456789.p-09));933 ((void)( +0x0123456789.p-09f));934 ((void)( +0x0123456789.p-09l));935 ((void)( +0x0123456789.p-09F));936 ((void)( +0x0123456789.p-09L));901 ((void)(-0x0123456789.p-09)); 902 ((void)(-0x0123456789.p-09f)); 903 ((void)(-0x0123456789.p-09l)); 904 ((void)(-0x0123456789.p-09F)); 905 ((void)(-0x0123456789.p-09L)); 937 906 ((void)(-0x0123456789.p-09)); 938 907 ((void)(-0x0123456789.p-09f)); … … 975 944 ((void)0x.0123456789P-09F); 976 945 ((void)0x.0123456789P-09L); 977 ((void)( +0x.0123456789P-09));978 ((void)( +0x.0123456789P-09f));979 ((void)( +0x.0123456789P-09l));980 ((void)( +0x.0123456789P-09F));981 ((void)( +0x.0123456789P-09L));946 ((void)(-0x.0123456789P-09)); 947 ((void)(-0x.0123456789P-09f)); 948 ((void)(-0x.0123456789P-09l)); 949 ((void)(-0x.0123456789P-09F)); 950 ((void)(-0x.0123456789P-09L)); 982 951 ((void)(-0x.0123456789P-09)); 983 952 ((void)(-0x.0123456789P-09f)); … … 1020 989 ((void)0X0123456789.0123456789P-09F); 1021 990 ((void)0X0123456789.0123456789P-09L); 1022 ((void)(+0X0123456789.0123456789P-09));1023 ((void)(+0X0123456789.0123456789P-09f));1024 ((void)(+0X0123456789.0123456789P-09l));1025 ((void)(+0X0123456789.0123456789P-09F));1026 ((void)(+0X0123456789.0123456789P-09L));1027 991 ((void)(-0X0123456789.0123456789P-09)); 1028 992 ((void)(-0X0123456789.0123456789P-09f)); … … 1030 994 ((void)(-0X0123456789.0123456789P-09F)); 1031 995 ((void)(-0X0123456789.0123456789P-09L)); 1032 ((void)((signed char )01234567)); 1033 ((void)((signed short int )01234567)); 1034 ((void)((signed int )01234567)); 1035 ((void)((signed long long int )01234567)); 1036 ((void)((__int128 )01234567)); 1037 ((void)((unsigned char )01234567u)); 1038 ((void)((signed short int )01234567u)); 1039 ((void)((unsigned int )01234567u)); 1040 ((void)((signed long long int )01234567u)); 1041 ((void)((__int128 )01234567u)); 1042 ((void)(+((signed int )((signed char )01234567)))); 1043 ((void)(+((signed int )((signed short int )01234567)))); 1044 ((void)(+((signed int )01234567))); 1045 ((void)(+((signed long long int )01234567))); 1046 ((void)(+((float )((__int128 )01234567)))); 1047 ((void)(+((signed int )((unsigned char )01234567u)))); 1048 ((void)(+((signed int )((signed short int )01234567u)))); 1049 ((void)(+((unsigned int )01234567u))); 1050 ((void)(+((signed long long int )01234567u))); 1051 ((void)(+((float )((__int128 )01234567u)))); 1052 ((void)(-((signed int )((signed char )01234567)))); 1053 ((void)(-((signed int )((signed short int )01234567)))); 1054 ((void)(-((signed int )01234567))); 1055 ((void)(-((signed long long int )01234567))); 1056 ((void)(-((float )((__int128 )01234567)))); 1057 ((void)(-((signed int )((unsigned char )01234567u)))); 1058 ((void)(-((signed int )((signed short int )01234567u)))); 1059 ((void)(-((unsigned int )01234567u))); 1060 ((void)(-((signed long long int )01234567u))); 1061 ((void)(-((float )((__int128 )01234567u)))); 1062 ((void)((signed char )1234567890)); 1063 ((void)((signed short int )1234567890)); 1064 ((void)((signed int )1234567890)); 1065 ((void)((signed long long int )1234567890)); 1066 ((void)((__int128 )1234567890)); 1067 ((void)((signed char )1234567890U)); 1068 ((void)((unsigned short int )1234567890U)); 1069 ((void)((signed int )1234567890U)); 1070 ((void)((unsigned long long int )1234567890u)); 1071 ((void)((unsigned __int128 )1234567890u)); 1072 ((void)(+((signed int )((signed char )1234567890)))); 1073 ((void)(+((signed int )((signed short int )1234567890)))); 1074 ((void)(+((signed int )1234567890))); 1075 ((void)(+((signed long long int )1234567890))); 1076 ((void)(+((float )((__int128 )1234567890)))); 1077 ((void)(+((signed int )((signed char )1234567890U)))); 1078 ((void)(+((signed int )((unsigned short int )1234567890U)))); 1079 ((void)(+((signed int )1234567890U))); 1080 ((void)(+((unsigned long long int )1234567890u))); 1081 ((void)(+((float )((unsigned __int128 )1234567890u)))); 1082 ((void)(-((signed int )((signed char )1234567890)))); 1083 ((void)(-((signed int )((signed short int )1234567890)))); 1084 ((void)(-((signed int )1234567890))); 1085 ((void)(-((signed long long int )1234567890))); 1086 ((void)(-((float )((__int128 )1234567890)))); 1087 ((void)(-((signed int )((signed char )1234567890U)))); 1088 ((void)(-((signed int )((unsigned short int )1234567890U)))); 1089 ((void)(-((signed int )1234567890U))); 1090 ((void)(-((unsigned long long int )1234567890u))); 1091 ((void)(-((float )((unsigned __int128 )1234567890u)))); 1092 ((void)((signed char )0x0123456789abcdef)); 1093 ((void)((signed short int )0x0123456789abcdef)); 1094 ((void)((signed int )0x0123456789abcdef)); 1095 ((void)((signed long long int )0x0123456789abcdef)); 1096 ((void)((signed char )0x0123456789abcdefu)); 1097 ((void)((unsigned short int )0x0123456789abcdefu)); 1098 ((void)((signed int )0x0123456789abcdefu)); 1099 ((void)((unsigned long long int )0x0123456789abcdefu)); 1100 ((void)(+((signed int )((signed char )0x0123456789abcdef)))); 1101 ((void)(+((signed int )((signed short int )0x0123456789abcdef)))); 1102 ((void)(+((signed int )0x0123456789abcdef))); 1103 ((void)(+((signed long long int )0x0123456789abcdef))); 1104 ((void)(+((signed int )((signed char )0x0123456789abcdefu)))); 1105 ((void)(+((signed int )((unsigned short int )0x0123456789abcdefu)))); 1106 ((void)(+((signed int )0x0123456789abcdefu))); 1107 ((void)(+((unsigned long long int )0x0123456789abcdefu))); 1108 ((void)(-((signed int )((signed char )0x0123456789abcdef)))); 1109 ((void)(-((signed int )((signed short int )0x0123456789abcdef)))); 1110 ((void)(-((signed int )0x0123456789abcdef))); 1111 ((void)(-((signed long long int )0x0123456789abcdef))); 1112 ((void)(-((signed int )((signed char )0x0123456789abcdefu)))); 1113 ((void)(-((signed int )((unsigned short int )0x0123456789abcdefu)))); 1114 ((void)(-((signed int )0x0123456789abcdefu))); 1115 ((void)(-((unsigned long long int )0x0123456789abcdefu))); 1116 ((void)((signed char )0x0123456789ABCDEF)); 1117 ((void)((signed short int )0x0123456789ABCDEF)); 1118 ((void)((signed int )0x0123456789ABCDEF)); 1119 ((void)((signed long long int )0x0123456789ABCDEF)); 1120 ((void)((signed char )0x0123456789ABCDEFu)); 1121 ((void)((unsigned short int )0x0123456789ABCDEFu)); 1122 ((void)((signed int )0x0123456789ABCDEFu)); 1123 ((void)((unsigned long long int )0x0123456789ABCDEFu)); 1124 ((void)(+((signed int )((signed char )0x0123456789ABCDEF)))); 1125 ((void)(+((signed int )((signed short int )0x0123456789ABCDEF)))); 1126 ((void)(+((signed int )0x0123456789ABCDEF))); 1127 ((void)(+((signed long long int )0x0123456789ABCDEF))); 1128 ((void)(+((signed int )((signed char )0x0123456789ABCDEFu)))); 1129 ((void)(+((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1130 ((void)(+((signed int )0x0123456789ABCDEFu))); 1131 ((void)(+((unsigned long long int )0x0123456789ABCDEFu))); 1132 ((void)(-((signed int )((signed char )0x0123456789ABCDEF)))); 1133 ((void)(-((signed int )((signed short int )0x0123456789ABCDEF)))); 1134 ((void)(-((signed int )0x0123456789ABCDEF))); 1135 ((void)(-((signed long long int )0x0123456789ABCDEF))); 1136 ((void)(-((signed int )((signed char )0x0123456789ABCDEFu)))); 1137 ((void)(-((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1138 ((void)(-((signed int )0x0123456789ABCDEFu))); 1139 ((void)(-((unsigned long long int )0x0123456789ABCDEFu))); 1140 ((void)((signed char )0X0123456789abcdef)); 1141 ((void)((signed short int )0X0123456789abcdef)); 1142 ((void)((signed int )0X0123456789abcdef)); 1143 ((void)((signed long long int )0X0123456789abcdef)); 1144 ((void)((signed char )0X0123456789abcdefu)); 1145 ((void)((unsigned short int )0X0123456789abcdefu)); 1146 ((void)((signed int )0X0123456789abcdefu)); 1147 ((void)((unsigned long long int )0X0123456789abcdefu)); 1148 ((void)(+((signed int )((signed char )0X0123456789abcdef)))); 1149 ((void)(+((signed int )((signed short int )0X0123456789abcdef)))); 1150 ((void)(+((signed int )0X0123456789abcdef))); 1151 ((void)(+((signed long long int )0X0123456789abcdef))); 1152 ((void)(+((signed int )((signed char )0X0123456789abcdefu)))); 1153 ((void)(+((signed int )((unsigned short int )0X0123456789abcdefu)))); 1154 ((void)(+((signed int )0X0123456789abcdefu))); 1155 ((void)(+((unsigned long long int )0X0123456789abcdefu))); 1156 ((void)(-((signed int )((signed char )0X0123456789abcdef)))); 1157 ((void)(-((signed int )((signed short int )0X0123456789abcdef)))); 1158 ((void)(-((signed int )0X0123456789abcdef))); 1159 ((void)(-((signed long long int )0X0123456789abcdef))); 1160 ((void)(-((signed int )((signed char )0X0123456789abcdefu)))); 1161 ((void)(-((signed int )((unsigned short int )0X0123456789abcdefu)))); 1162 ((void)(-((signed int )0X0123456789abcdefu))); 1163 ((void)(-((unsigned long long int )0X0123456789abcdefu))); 1164 ((void)((signed char )0X0123456789ABCDEF)); 1165 ((void)((signed short int )0X0123456789ABCDEF)); 1166 ((void)((signed int )0X0123456789ABCDEF)); 1167 ((void)((signed long long int )0X0123456789ABCDEF)); 1168 ((void)((signed char )0X0123456789ABCDEFu)); 1169 ((void)((unsigned short int )0X0123456789ABCDEFu)); 1170 ((void)((signed int )0X0123456789ABCDEFu)); 1171 ((void)((unsigned long long int )0X0123456789ABCDEFu)); 1172 ((void)(+((signed int )((signed char )0X0123456789ABCDEF)))); 1173 ((void)(+((signed int )((signed short int )0X0123456789ABCDEF)))); 1174 ((void)(+((signed int )0X0123456789ABCDEF))); 1175 ((void)(+((signed long long int )0X0123456789ABCDEF))); 1176 ((void)(+((signed int )((signed char )0X0123456789ABCDEFu)))); 1177 ((void)(+((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1178 ((void)(+((signed int )0X0123456789ABCDEFu))); 1179 ((void)(+((unsigned long long int )0X0123456789ABCDEFu))); 1180 ((void)(-((signed int )((signed char )0X0123456789ABCDEF)))); 1181 ((void)(-((signed int )((signed short int )0X0123456789ABCDEF)))); 1182 ((void)(-((signed int )0X0123456789ABCDEF))); 1183 ((void)(-((signed long long int )0X0123456789ABCDEF))); 1184 ((void)(-((signed int )((signed char )0X0123456789ABCDEFu)))); 1185 ((void)(-((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1186 ((void)(-((signed int )0X0123456789ABCDEFu))); 1187 ((void)(-((unsigned long long int )0X0123456789ABCDEFu))); 1188 ((void)((float )0123456789.)); 1189 ((void)((double )0123456789.)); 1190 ((void)((long double )0123456789.)); 1191 ((void)((long double )0123456789.)); 1192 ((void)(+((float )0123456789.))); 1193 ((void)(+((double )0123456789.))); 1194 ((void)(+((long double )0123456789.))); 1195 ((void)(+((long double )0123456789.))); 1196 ((void)(-((float )0123456789.))); 1197 ((void)(-((double )0123456789.))); 1198 ((void)(-((long double )0123456789.))); 1199 ((void)(-((long double )0123456789.))); 1200 ((void)((float )0123456789.e09)); 1201 ((void)((double )0123456789.e09)); 1202 ((void)((long double )0123456789.e09)); 1203 ((void)((long double )0123456789.e09)); 1204 ((void)(+((float )0123456789.e+09))); 1205 ((void)(+((double )0123456789.e+09))); 1206 ((void)(+((long double )0123456789.e+09))); 1207 ((void)(+((long double )0123456789.e+09))); 1208 ((void)(-((float )0123456789.e-09))); 1209 ((void)(-((double )0123456789.e-09))); 1210 ((void)(-((long double )0123456789.e-09))); 1211 ((void)(-((long double )0123456789.e-09))); 1212 ((void)((float ).0123456789e09)); 1213 ((void)((double ).0123456789e09)); 1214 ((void)((long double ).0123456789e09)); 1215 ((void)((long double ).0123456789e09)); 1216 ((void)(+((float ).0123456789E+09))); 1217 ((void)(+((double ).0123456789E+09))); 1218 ((void)(+((long double ).0123456789E+09))); 1219 ((void)(+((long double ).0123456789E+09))); 1220 ((void)(-((float ).0123456789E-09))); 1221 ((void)(-((double ).0123456789E-09))); 1222 ((void)(-((long double ).0123456789E-09))); 1223 ((void)(-((long double ).0123456789E-09))); 1224 ((void)((float )0123456789.0123456789)); 1225 ((void)((double )0123456789.0123456789)); 1226 ((void)((long double )0123456789.0123456789)); 1227 ((void)((long double )0123456789.0123456789)); 1228 ((void)(+((float )0123456789.0123456789E09))); 1229 ((void)(+((double )0123456789.0123456789E09))); 1230 ((void)(+((long double )0123456789.0123456789E09))); 1231 ((void)(+((long double )0123456789.0123456789E09))); 1232 ((void)(-((float )0123456789.0123456789E+09))); 1233 ((void)(-((double )0123456789.0123456789E+09))); 1234 ((void)(-((long double )0123456789.0123456789E+09))); 1235 ((void)(-((long double )0123456789.0123456789E+09))); 1236 ((void)((float )0123456789.0123456789E-09)); 1237 ((void)((double )0123456789.0123456789E-09)); 1238 ((void)((long double )0123456789.0123456789E-09)); 1239 ((void)((long double )0123456789.0123456789E-09)); 1240 ((void)((float )0x0123456789.p09)); 1241 ((void)((double )0x0123456789.p09)); 1242 ((void)((long double )0x0123456789.p09)); 1243 ((void)((long double )0x0123456789.p09)); 1244 ((void)(+((float )0x0123456789.p09))); 1245 ((void)(+((double )0x0123456789.p09))); 1246 ((void)(+((long double )0x0123456789.p09))); 1247 ((void)(+((long double )0x0123456789.p09))); 1248 ((void)(-((float )0x0123456789.p09))); 1249 ((void)(-((double )0x0123456789.p09))); 1250 ((void)(-((long double )0x0123456789.p09))); 1251 ((void)(-((long double )0x0123456789.p09))); 1252 ((void)((float )0x0123456789.p+09)); 1253 ((void)((double )0x0123456789.p+09)); 1254 ((void)((long double )0x0123456789.p+09)); 1255 ((void)((long double )0x0123456789.p+09)); 1256 ((void)(+((float )0x0123456789.p-09))); 1257 ((void)(+((double )0x0123456789.p-09))); 1258 ((void)(+((long double )0x0123456789.p-09))); 1259 ((void)(+((long double )0x0123456789.p-09))); 1260 ((void)(-((float )0x.0123456789p09))); 1261 ((void)(-((double )0x.0123456789p09))); 1262 ((void)(-((long double )0x.0123456789p09))); 1263 ((void)(-((long double )0x.0123456789p09))); 996 ((void)(-0X0123456789.0123456789P-09)); 997 ((void)(-0X0123456789.0123456789P-09f)); 998 ((void)(-0X0123456789.0123456789P-09l)); 999 ((void)(-0X0123456789.0123456789P-09F)); 1000 ((void)(-0X0123456789.0123456789P-09L)); 1264 1001 ((void)__f__F_c__1('a')); 1265 1002 ((void)__f__F_Sc__1(20)); … … 1374 1111 ((void)L"a" "b" "c"); 1375 1112 ((void)(___retval_main__i_1=0) /* ?{} */); 1376 return ___retval_main__i_1;1113 return ((signed int )___retval_main__i_1); 1377 1114 } 1378 1115 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } … … 1389 1126 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 1390 1127 ((void)(_tmp_cp_ret0) /* ^?{} */); 1391 return ___retval_main__i_1;1392 } 1128 return ((signed int )___retval_main__i_1); 1129 } -
src/tests/.expect/64/KRfunctions.txt
r6840e7c rb96ec83 21 21 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 22 22 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 23 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1);24 23 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 25 24 ((void)((*___dst__R2sS_1).__i__i_1) /* ?{} */); … … 34 33 struct S ___ret__2sS_1; 35 34 ((void)((*___dst__R2sS_1).__i__i_1=___src__2sS_1.__i__i_1)); 36 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));37 return ___ret__2sS_1;35 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1)); 36 return ((struct S )___ret__2sS_1); 38 37 } 39 38 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __i__i_1){ … … 66 65 signed int *__x__FPi_ii__2(signed int __anonymous_object2, signed int __anonymous_object3); 67 66 ((void)(___retval_f10__PFPi_ii__1=__x__FPi_ii__2) /* ?{} */); 68 return ___retval_f10__PFPi_ii__1;67 return ((signed int *(*)(signed int __x__i_1, signed int __y__i_1))___retval_f10__PFPi_ii__1); 69 68 } 70 69 signed int (*__f11__FPA0i_iPiPi__1(signed int __a__i_1, signed int *__b__Pi_1, signed int *__c__Pi_1))[]{ -
src/tests/.expect/64/attributes.txt
r6840e7c rb96ec83 23 23 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){ 24 24 struct __anonymous0 ___ret__13s__anonymous0_1; 25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1)));26 return ___ret__13s__anonymous0_1;25 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1)); 26 return ((struct __anonymous0 )___ret__13s__anonymous0_1); 27 27 } 28 28 __attribute__ ((unused)) struct Agn1; … … 41 41 static inline struct Agn2 ___operator_assign__F5sAgn2_R5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__R5sAgn2_1, struct Agn2 ___src__5sAgn2_1){ 42 42 struct Agn2 ___ret__5sAgn2_1; 43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__R5sAgn2_1)));44 return ___ret__5sAgn2_1;43 ((void)___constructor__F_R5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), ___src__5sAgn2_1)); 44 return ((struct Agn2 )___ret__5sAgn2_1); 45 45 } 46 46 enum __attribute__ ((unused)) __anonymous1 { … … 69 69 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1); 70 70 static inline struct Fdl ___operator_assign__F4sFdl_R4sFdl4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1, struct Fdl ___src__4sFdl_1); 71 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1);72 static inline void ___constructor__F_R4sFdlii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1);73 static inline void ___constructor__F_R4sFdliii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1);74 static inline void ___constructor__F_R4sFdliiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1);75 static inline void ___constructor__F_R4sFdliiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1);76 static inline void ___constructor__F_R4sFdliiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1);77 static inline void ___constructor__F_R4sFdliiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1);78 static inline void ___constructor__F_R4sFdliiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1);79 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object1);80 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object2, signed int *__f9__Pi_1);81 71 static inline void ___constructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 82 72 ((void)((*___dst__R4sFdl_1).__f1__i_1) /* ?{} */); … … 88 78 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 89 79 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 90 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);91 80 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 92 81 } … … 100 89 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */); 101 90 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1) /* ?{} */); 102 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0) /* ?{} */);103 91 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */); 104 92 } 105 93 static inline void ___destructor__F_R4sFdl_autogen___1(struct Fdl *___dst__R4sFdl_1){ 106 94 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ^?{} */); 107 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ^?{} */);108 95 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ^?{} */); 109 96 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ^?{} */); … … 125 112 ((void)((*___dst__R4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1)); 126 113 ((void)((*___dst__R4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1)); 127 ((void)((*___dst__R4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0));128 114 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1)); 129 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__R4sFdl_1)));130 return ___ret__4sFdl_1;115 ((void)___constructor__F_R4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), ___src__4sFdl_1)); 116 return ((struct Fdl )___ret__4sFdl_1); 131 117 } 132 118 static inline void ___constructor__F_R4sFdli_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1){ … … 139 125 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 140 126 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 141 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);142 127 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 143 128 } … … 151 136 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 152 137 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 153 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);154 138 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 155 139 } … … 163 147 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 164 148 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 165 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);166 149 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 167 150 } … … 175 158 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 176 159 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 177 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);178 160 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 179 161 } … … 187 169 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 188 170 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 189 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);190 171 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 191 172 } … … 199 180 ((void)((*___dst__R4sFdl_1).__f7__i_1) /* ?{} */); 200 181 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 201 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);202 182 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 203 183 } … … 211 191 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 212 192 ((void)((*___dst__R4sFdl_1).__f8__i_1) /* ?{} */); 213 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */);214 193 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 215 194 } … … 223 202 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 224 203 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 225 ((void)((*___dst__R4sFdl_1).__anonymous_object0) /* ?{} */); 226 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 227 } 228 static inline void ___constructor__F_R4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object3){ 204 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */); 205 } 206 static inline void ___constructor__F_R4sFdliiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int *__f9__Pi_1){ 229 207 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */); 230 208 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */); … … 235 213 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */); 236 214 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */); 237 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object3) /* ?{} */);238 ((void)((*___dst__R4sFdl_1).__f9__Pi_1) /* ?{} */);239 }240 static inline void ___constructor__F_R4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__R4sFdl_1, signed int __f1__i_1, signed int __f2__i_1, signed int __f3__i_1, signed int __f4__i_1, signed int __f5__i_1, signed int __f6__i_1, signed int __f7__i_1, signed int __f8__i_1, signed int __anonymous_object4, signed int *__f9__Pi_1){241 ((void)((*___dst__R4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);242 ((void)((*___dst__R4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);243 ((void)((*___dst__R4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);244 ((void)((*___dst__R4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);245 ((void)((*___dst__R4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);246 ((void)((*___dst__R4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);247 ((void)((*___dst__R4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);248 ((void)((*___dst__R4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);249 ((void)((*___dst__R4sFdl_1).__anonymous_object0=__anonymous_object4) /* ?{} */);250 215 ((void)((*___dst__R4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */); 251 216 } … … 267 232 __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1; 268 233 } 269 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object 5))[];234 __attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object1))[]; 270 235 __attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{ 271 236 __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[]; 272 237 } 273 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 6);274 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object 7){275 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object 8);238 __attribute__ ((unused,used,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object2); 239 __attribute__ ((unused,unused)) signed int (*__f4__FPFi_i____1())(signed int __anonymous_object3){ 240 __attribute__ ((unused)) signed int (*___retval_f4__PFi_i__1)(signed int __anonymous_object4); 276 241 } 277 242 signed int __vtr__Fi___1(){ … … 303 268 signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1); 304 269 signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1); 305 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 9)(__attribute__ ((unused,unused)) signed int __anonymous_object10[((unsigned long int )5)]));270 signed int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object5)(__attribute__ ((unused,unused)) signed int __anonymous_object6[((unsigned long int )5)])); 306 271 signed int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 307 272 signed int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__PFi___1)()); 308 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object 11)(__attribute__ ((unused)) signed int (*__anonymous_object12)(__attribute__ ((unused,unused)) signed int __anonymous_object13)));273 signed int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object7)(__attribute__ ((unused)) signed int (*__anonymous_object8)(__attribute__ ((unused,unused)) signed int __anonymous_object9))); 309 274 signed int __ad__Fi___1(){ 310 275 __attribute__ ((unused)) signed int ___retval_ad__i_1; … … 335 300 struct __anonymous4 ___ret__13s__anonymous4_2; 336 301 ((void)((*___dst__R13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2)); 337 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), (*___dst__R13s__anonymous4_2)));338 return ___ret__13s__anonymous4_2;302 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___2((&___ret__13s__anonymous4_2), ___src__13s__anonymous4_2)); 303 return ((struct __anonymous4 )___ret__13s__anonymous4_2); 339 304 } 340 305 inline void ___constructor__F_R13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__R13s__anonymous4_2, signed int __i__i_2){ … … 348 313 } 349 314 inline void ___constructor__F_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 350 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2) /* ?{} */);315 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)); 351 316 } 352 317 inline void ___destructor__F_R13e__anonymous5_intrinsic___2(__attribute__ ((unused)) enum __anonymous5 *___dst__R13e__anonymous5_2){ … … 354 319 inline enum __anonymous5 ___operator_assign__F13e__anonymous5_R13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__R13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 355 320 enum __anonymous5 ___ret__13e__anonymous5_2; 356 ((void)((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)); 357 ((void)(___ret__13e__anonymous5_2=(*___dst__R13e__anonymous5_2)) /* ?{} */); 358 return ___ret__13e__anonymous5_2; 321 ((void)(___ret__13e__anonymous5_2=((*___dst__R13e__anonymous5_2)=___src__13e__anonymous5_2)) /* ?{} */); 322 return ((enum __anonymous5 )___ret__13e__anonymous5_2); 359 323 } 360 324 ((void)sizeof(enum __anonymous5 )); 361 325 } 362 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 4, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);363 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object1 6, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object17);364 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object1 8, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object19);365 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 20)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object21)());366 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object 22)(__attribute__ ((unused)) signed int __anonymous_object23), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25));367 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 6)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object27)());368 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object2 8)(__attribute__ ((unused)) signed int __anonymous_object29), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object30)(__attribute__ ((unused)) signed int __anonymous_object31));326 signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object10, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object11); 327 signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object13); 328 signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15); 329 signed int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)()); 330 signed int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object18)(__attribute__ ((unused)) signed int __anonymous_object19), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(__attribute__ ((unused)) signed int __anonymous_object21)); 331 signed int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)()); 332 signed int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(__attribute__ ((unused)) signed int __anonymous_object27)); 369 333 struct Vad { 370 __attribute__ ((unused)) signed int __anonymous_object 32;371 __attribute__ ((unused,unused)) signed int *__anonymous_object 33;372 __attribute__ ((unused,unused)) signed int __anonymous_object3 4[((unsigned long int )10)];373 __attribute__ ((unused,unused)) signed int (*__anonymous_object3 5)();334 __attribute__ ((unused)) signed int __anonymous_object28; 335 __attribute__ ((unused,unused)) signed int *__anonymous_object29; 336 __attribute__ ((unused,unused)) signed int __anonymous_object30[((unsigned long int )10)]; 337 __attribute__ ((unused,unused)) signed int (*__anonymous_object31)(); 374 338 }; 375 339 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); … … 377 341 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1); 378 342 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1); 379 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object36);380 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object37, signed int *__anonymous_object38);381 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object39, signed int *__anonymous_object40, signed int __anonymous_object41[((unsigned long int )10)]);382 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object42, signed int *__anonymous_object43, signed int __anonymous_object44[((unsigned long int )10)], signed int (*__anonymous_object45)());383 343 static inline void ___constructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 384 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ?{} */);385 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */);386 {387 signed int _index0 = 0;388 for (;(_index0<10);((void)(++_index0))) {389 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index0)])))) /* ?{} */);390 }391 392 }393 394 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */);395 344 } 396 345 static inline void ___constructor__F_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 397 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32) /* ?{} */);398 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33) /* ?{} */);399 {400 signed int _index1 = 0;401 for (;(_index1<10);((void)(++_index1))) {402 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index1)])))=___src__4sVad_1.__anonymous_object34[((signed long int )_index1)]) /* ?{} */);403 }404 405 }406 407 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35) /* ?{} */);408 346 } 409 347 static inline void ___destructor__F_R4sVad_autogen___1(struct Vad *___dst__R4sVad_1){ 410 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ^?{} */);411 {412 signed int _index2 = (10-1);413 for (;(_index2>=0);((void)(--_index2))) {414 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index2)])))) /* ^?{} */);415 }416 417 }418 419 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ^?{} */);420 ((void)((*___dst__R4sVad_1).__anonymous_object32) /* ^?{} */);421 348 } 422 349 static inline struct Vad ___operator_assign__F4sVad_R4sVad4sVad_autogen___1(struct Vad *___dst__R4sVad_1, struct Vad ___src__4sVad_1){ 423 350 struct Vad ___ret__4sVad_1; 424 ((void)((*___dst__R4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32)); 425 ((void)((*___dst__R4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33)); 426 { 427 signed int _index3 = 0; 428 for (;(_index3<10);((void)(++_index3))) { 429 ((void)((*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index3)]=___src__4sVad_1.__anonymous_object34[((signed long int )_index3)])); 430 } 431 432 } 433 434 ((void)((*___dst__R4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35)); 435 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), (*___dst__R4sVad_1))); 436 return ___ret__4sVad_1; 437 } 438 static inline void ___constructor__F_R4sVadi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object46){ 439 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object46) /* ?{} */); 440 ((void)((*___dst__R4sVad_1).__anonymous_object33) /* ?{} */); 441 { 442 signed int _index4 = 0; 443 for (;(_index4<10);((void)(++_index4))) { 444 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index4)])))) /* ?{} */); 445 } 446 447 } 448 449 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 450 } 451 static inline void ___constructor__F_R4sVadiPi_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object47, signed int *__anonymous_object48){ 452 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object47) /* ?{} */); 453 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object48) /* ?{} */); 454 { 455 signed int _index5 = 0; 456 for (;(_index5<10);((void)(++_index5))) { 457 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index5)])))) /* ?{} */); 458 } 459 460 } 461 462 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 463 } 464 static inline void ___constructor__F_R4sVadiPiA0i_autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object49, signed int *__anonymous_object50, signed int __anonymous_object51[((unsigned long int )10)]){ 465 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object49) /* ?{} */); 466 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object50) /* ?{} */); 467 { 468 signed int _index6 = 0; 469 for (;(_index6<10);((void)(++_index6))) { 470 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index6)])))=__anonymous_object51[((signed long int )_index6)]) /* ?{} */); 471 } 472 473 } 474 475 ((void)((*___dst__R4sVad_1).__anonymous_object35) /* ?{} */); 476 } 477 static inline void ___constructor__F_R4sVadiPiA0iPFi___autogen___1(struct Vad *___dst__R4sVad_1, signed int __anonymous_object52, signed int *__anonymous_object53, signed int __anonymous_object54[((unsigned long int )10)], signed int (*__anonymous_object55)()){ 478 ((void)((*___dst__R4sVad_1).__anonymous_object32=__anonymous_object52) /* ?{} */); 479 ((void)((*___dst__R4sVad_1).__anonymous_object33=__anonymous_object53) /* ?{} */); 480 { 481 signed int _index7 = 0; 482 for (;(_index7<10);((void)(++_index7))) { 483 ((void)((*((signed int *)(&(*___dst__R4sVad_1).__anonymous_object34[((signed long int )_index7)])))=__anonymous_object54[((signed long int )_index7)]) /* ?{} */); 484 } 485 486 } 487 488 ((void)((*___dst__R4sVad_1).__anonymous_object35=__anonymous_object55) /* ?{} */); 489 } 351 ((void)___constructor__F_R4sVad4sVad_autogen___1((&___ret__4sVad_1), ___src__4sVad_1)); 352 return ((struct Vad )___ret__4sVad_1); 353 } -
src/tests/.expect/64/declarationSpecifier.txt
r6840e7c rb96ec83 20 20 static inline void ___destructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1); 21 21 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_R13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 22 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1);23 22 static inline void ___constructor__F_R13s__anonymous0_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1){ 24 23 ((void)((*___dst__R13s__anonymous0_1).__i__i_1) /* ?{} */); … … 33 32 struct __anonymous0 ___ret__13s__anonymous0_1; 34 33 ((void)((*___dst__R13s__anonymous0_1).__i__i_1=___src__13s__anonymous0_1.__i__i_1)); 35 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__R13s__anonymous0_1)));36 return ___ret__13s__anonymous0_1;34 ((void)___constructor__F_R13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), ___src__13s__anonymous0_1)); 35 return ((struct __anonymous0 )___ret__13s__anonymous0_1); 37 36 } 38 37 static inline void ___constructor__F_R13s__anonymous0i_autogen___1(struct __anonymous0 *___dst__R13s__anonymous0_1, signed int __i__i_1){ … … 47 46 static inline void ___destructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1); 48 47 static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_R13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1); 49 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1);50 48 static inline void ___constructor__F_R13s__anonymous1_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1){ 51 49 ((void)((*___dst__R13s__anonymous1_1).__i__i_1) /* ?{} */); … … 60 58 struct __anonymous1 ___ret__13s__anonymous1_1; 61 59 ((void)((*___dst__R13s__anonymous1_1).__i__i_1=___src__13s__anonymous1_1.__i__i_1)); 62 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), (*___dst__R13s__anonymous1_1)));63 return ___ret__13s__anonymous1_1;60 ((void)___constructor__F_R13s__anonymous113s__anonymous1_autogen___1((&___ret__13s__anonymous1_1), ___src__13s__anonymous1_1)); 61 return ((struct __anonymous1 )___ret__13s__anonymous1_1); 64 62 } 65 63 static inline void ___constructor__F_R13s__anonymous1i_autogen___1(struct __anonymous1 *___dst__R13s__anonymous1_1, signed int __i__i_1){ … … 74 72 static inline void ___destructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1); 75 73 static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_R13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1); 76 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1);77 74 static inline void ___constructor__F_R13s__anonymous2_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1){ 78 75 ((void)((*___dst__R13s__anonymous2_1).__i__i_1) /* ?{} */); … … 87 84 struct __anonymous2 ___ret__13s__anonymous2_1; 88 85 ((void)((*___dst__R13s__anonymous2_1).__i__i_1=___src__13s__anonymous2_1.__i__i_1)); 89 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__R13s__anonymous2_1)));90 return ___ret__13s__anonymous2_1;86 ((void)___constructor__F_R13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), ___src__13s__anonymous2_1)); 87 return ((struct __anonymous2 )___ret__13s__anonymous2_1); 91 88 } 92 89 static inline void ___constructor__F_R13s__anonymous2i_autogen___1(struct __anonymous2 *___dst__R13s__anonymous2_1, signed int __i__i_1){ … … 101 98 static inline void ___destructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1); 102 99 static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_R13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1); 103 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1);104 100 static inline void ___constructor__F_R13s__anonymous3_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1){ 105 101 ((void)((*___dst__R13s__anonymous3_1).__i__i_1) /* ?{} */); … … 114 110 struct __anonymous3 ___ret__13s__anonymous3_1; 115 111 ((void)((*___dst__R13s__anonymous3_1).__i__i_1=___src__13s__anonymous3_1.__i__i_1)); 116 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), (*___dst__R13s__anonymous3_1)));117 return ___ret__13s__anonymous3_1;112 ((void)___constructor__F_R13s__anonymous313s__anonymous3_autogen___1((&___ret__13s__anonymous3_1), ___src__13s__anonymous3_1)); 113 return ((struct __anonymous3 )___ret__13s__anonymous3_1); 118 114 } 119 115 static inline void ___constructor__F_R13s__anonymous3i_autogen___1(struct __anonymous3 *___dst__R13s__anonymous3_1, signed int __i__i_1){ … … 128 124 static inline void ___destructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1); 129 125 static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_R13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1); 130 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1);131 126 static inline void ___constructor__F_R13s__anonymous4_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1){ 132 127 ((void)((*___dst__R13s__anonymous4_1).__i__i_1) /* ?{} */); … … 141 136 struct __anonymous4 ___ret__13s__anonymous4_1; 142 137 ((void)((*___dst__R13s__anonymous4_1).__i__i_1=___src__13s__anonymous4_1.__i__i_1)); 143 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), (*___dst__R13s__anonymous4_1)));144 return ___ret__13s__anonymous4_1;138 ((void)___constructor__F_R13s__anonymous413s__anonymous4_autogen___1((&___ret__13s__anonymous4_1), ___src__13s__anonymous4_1)); 139 return ((struct __anonymous4 )___ret__13s__anonymous4_1); 145 140 } 146 141 static inline void ___constructor__F_R13s__anonymous4i_autogen___1(struct __anonymous4 *___dst__R13s__anonymous4_1, signed int __i__i_1){ … … 155 150 static inline void ___destructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1); 156 151 static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_R13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1); 157 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1);158 152 static inline void ___constructor__F_R13s__anonymous5_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1){ 159 153 ((void)((*___dst__R13s__anonymous5_1).__i__i_1) /* ?{} */); … … 168 162 struct __anonymous5 ___ret__13s__anonymous5_1; 169 163 ((void)((*___dst__R13s__anonymous5_1).__i__i_1=___src__13s__anonymous5_1.__i__i_1)); 170 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), (*___dst__R13s__anonymous5_1)));171 return ___ret__13s__anonymous5_1;164 ((void)___constructor__F_R13s__anonymous513s__anonymous5_autogen___1((&___ret__13s__anonymous5_1), ___src__13s__anonymous5_1)); 165 return ((struct __anonymous5 )___ret__13s__anonymous5_1); 172 166 } 173 167 static inline void ___constructor__F_R13s__anonymous5i_autogen___1(struct __anonymous5 *___dst__R13s__anonymous5_1, signed int __i__i_1){ … … 182 176 static inline void ___destructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1); 183 177 static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_R13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1); 184 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1);185 178 static inline void ___constructor__F_R13s__anonymous6_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1){ 186 179 ((void)((*___dst__R13s__anonymous6_1).__i__i_1) /* ?{} */); … … 195 188 struct __anonymous6 ___ret__13s__anonymous6_1; 196 189 ((void)((*___dst__R13s__anonymous6_1).__i__i_1=___src__13s__anonymous6_1.__i__i_1)); 197 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), (*___dst__R13s__anonymous6_1)));198 return ___ret__13s__anonymous6_1;190 ((void)___constructor__F_R13s__anonymous613s__anonymous6_autogen___1((&___ret__13s__anonymous6_1), ___src__13s__anonymous6_1)); 191 return ((struct __anonymous6 )___ret__13s__anonymous6_1); 199 192 } 200 193 static inline void ___constructor__F_R13s__anonymous6i_autogen___1(struct __anonymous6 *___dst__R13s__anonymous6_1, signed int __i__i_1){ … … 209 202 static inline void ___destructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1); 210 203 static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_R13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1); 211 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1);212 204 static inline void ___constructor__F_R13s__anonymous7_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1){ 213 205 ((void)((*___dst__R13s__anonymous7_1).__i__i_1) /* ?{} */); … … 222 214 struct __anonymous7 ___ret__13s__anonymous7_1; 223 215 ((void)((*___dst__R13s__anonymous7_1).__i__i_1=___src__13s__anonymous7_1.__i__i_1)); 224 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), (*___dst__R13s__anonymous7_1)));225 return ___ret__13s__anonymous7_1;216 ((void)___constructor__F_R13s__anonymous713s__anonymous7_autogen___1((&___ret__13s__anonymous7_1), ___src__13s__anonymous7_1)); 217 return ((struct __anonymous7 )___ret__13s__anonymous7_1); 226 218 } 227 219 static inline void ___constructor__F_R13s__anonymous7i_autogen___1(struct __anonymous7 *___dst__R13s__anonymous7_1, signed int __i__i_1){ … … 244 236 static inline void ___destructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1); 245 237 static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_R13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1); 246 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1);247 238 static inline void ___constructor__F_R13s__anonymous8_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1){ 248 239 ((void)((*___dst__R13s__anonymous8_1).__i__s_1) /* ?{} */); … … 257 248 struct __anonymous8 ___ret__13s__anonymous8_1; 258 249 ((void)((*___dst__R13s__anonymous8_1).__i__s_1=___src__13s__anonymous8_1.__i__s_1)); 259 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), (*___dst__R13s__anonymous8_1)));260 return ___ret__13s__anonymous8_1;250 ((void)___constructor__F_R13s__anonymous813s__anonymous8_autogen___1((&___ret__13s__anonymous8_1), ___src__13s__anonymous8_1)); 251 return ((struct __anonymous8 )___ret__13s__anonymous8_1); 261 252 } 262 253 static inline void ___constructor__F_R13s__anonymous8s_autogen___1(struct __anonymous8 *___dst__R13s__anonymous8_1, signed short int __i__s_1){ … … 271 262 static inline void ___destructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1); 272 263 static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_R13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1); 273 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1);274 264 static inline void ___constructor__F_R13s__anonymous9_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1){ 275 265 ((void)((*___dst__R13s__anonymous9_1).__i__s_1) /* ?{} */); … … 284 274 struct __anonymous9 ___ret__13s__anonymous9_1; 285 275 ((void)((*___dst__R13s__anonymous9_1).__i__s_1=___src__13s__anonymous9_1.__i__s_1)); 286 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), (*___dst__R13s__anonymous9_1)));287 return ___ret__13s__anonymous9_1;276 ((void)___constructor__F_R13s__anonymous913s__anonymous9_autogen___1((&___ret__13s__anonymous9_1), ___src__13s__anonymous9_1)); 277 return ((struct __anonymous9 )___ret__13s__anonymous9_1); 288 278 } 289 279 static inline void ___constructor__F_R13s__anonymous9s_autogen___1(struct __anonymous9 *___dst__R13s__anonymous9_1, signed short int __i__s_1){ … … 298 288 static inline void ___destructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1); 299 289 static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_R14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1); 300 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1);301 290 static inline void ___constructor__F_R14s__anonymous10_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1){ 302 291 ((void)((*___dst__R14s__anonymous10_1).__i__s_1) /* ?{} */); … … 311 300 struct __anonymous10 ___ret__14s__anonymous10_1; 312 301 ((void)((*___dst__R14s__anonymous10_1).__i__s_1=___src__14s__anonymous10_1.__i__s_1)); 313 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), (*___dst__R14s__anonymous10_1)));314 return ___ret__14s__anonymous10_1;302 ((void)___constructor__F_R14s__anonymous1014s__anonymous10_autogen___1((&___ret__14s__anonymous10_1), ___src__14s__anonymous10_1)); 303 return ((struct __anonymous10 )___ret__14s__anonymous10_1); 315 304 } 316 305 static inline void ___constructor__F_R14s__anonymous10s_autogen___1(struct __anonymous10 *___dst__R14s__anonymous10_1, signed short int __i__s_1){ … … 325 314 static inline void ___destructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1); 326 315 static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_R14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1); 327 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1);328 316 static inline void ___constructor__F_R14s__anonymous11_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1){ 329 317 ((void)((*___dst__R14s__anonymous11_1).__i__s_1) /* ?{} */); … … 338 326 struct __anonymous11 ___ret__14s__anonymous11_1; 339 327 ((void)((*___dst__R14s__anonymous11_1).__i__s_1=___src__14s__anonymous11_1.__i__s_1)); 340 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), (*___dst__R14s__anonymous11_1)));341 return ___ret__14s__anonymous11_1;328 ((void)___constructor__F_R14s__anonymous1114s__anonymous11_autogen___1((&___ret__14s__anonymous11_1), ___src__14s__anonymous11_1)); 329 return ((struct __anonymous11 )___ret__14s__anonymous11_1); 342 330 } 343 331 static inline void ___constructor__F_R14s__anonymous11s_autogen___1(struct __anonymous11 *___dst__R14s__anonymous11_1, signed short int __i__s_1){ … … 352 340 static inline void ___destructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1); 353 341 static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_R14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1); 354 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1);355 342 static inline void ___constructor__F_R14s__anonymous12_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1){ 356 343 ((void)((*___dst__R14s__anonymous12_1).__i__s_1) /* ?{} */); … … 365 352 struct __anonymous12 ___ret__14s__anonymous12_1; 366 353 ((void)((*___dst__R14s__anonymous12_1).__i__s_1=___src__14s__anonymous12_1.__i__s_1)); 367 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), (*___dst__R14s__anonymous12_1)));368 return ___ret__14s__anonymous12_1;354 ((void)___constructor__F_R14s__anonymous1214s__anonymous12_autogen___1((&___ret__14s__anonymous12_1), ___src__14s__anonymous12_1)); 355 return ((struct __anonymous12 )___ret__14s__anonymous12_1); 369 356 } 370 357 static inline void ___constructor__F_R14s__anonymous12s_autogen___1(struct __anonymous12 *___dst__R14s__anonymous12_1, signed short int __i__s_1){ … … 379 366 static inline void ___destructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1); 380 367 static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_R14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1); 381 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1);382 368 static inline void ___constructor__F_R14s__anonymous13_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1){ 383 369 ((void)((*___dst__R14s__anonymous13_1).__i__s_1) /* ?{} */); … … 392 378 struct __anonymous13 ___ret__14s__anonymous13_1; 393 379 ((void)((*___dst__R14s__anonymous13_1).__i__s_1=___src__14s__anonymous13_1.__i__s_1)); 394 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), (*___dst__R14s__anonymous13_1)));395 return ___ret__14s__anonymous13_1;380 ((void)___constructor__F_R14s__anonymous1314s__anonymous13_autogen___1((&___ret__14s__anonymous13_1), ___src__14s__anonymous13_1)); 381 return ((struct __anonymous13 )___ret__14s__anonymous13_1); 396 382 } 397 383 static inline void ___constructor__F_R14s__anonymous13s_autogen___1(struct __anonymous13 *___dst__R14s__anonymous13_1, signed short int __i__s_1){ … … 406 392 static inline void ___destructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1); 407 393 static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_R14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1); 408 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1);409 394 static inline void ___constructor__F_R14s__anonymous14_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1){ 410 395 ((void)((*___dst__R14s__anonymous14_1).__i__s_1) /* ?{} */); … … 419 404 struct __anonymous14 ___ret__14s__anonymous14_1; 420 405 ((void)((*___dst__R14s__anonymous14_1).__i__s_1=___src__14s__anonymous14_1.__i__s_1)); 421 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), (*___dst__R14s__anonymous14_1)));422 return ___ret__14s__anonymous14_1;406 ((void)___constructor__F_R14s__anonymous1414s__anonymous14_autogen___1((&___ret__14s__anonymous14_1), ___src__14s__anonymous14_1)); 407 return ((struct __anonymous14 )___ret__14s__anonymous14_1); 423 408 } 424 409 static inline void ___constructor__F_R14s__anonymous14s_autogen___1(struct __anonymous14 *___dst__R14s__anonymous14_1, signed short int __i__s_1){ … … 433 418 static inline void ___destructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1); 434 419 static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_R14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1); 435 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1);436 420 static inline void ___constructor__F_R14s__anonymous15_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1){ 437 421 ((void)((*___dst__R14s__anonymous15_1).__i__s_1) /* ?{} */); … … 446 430 struct __anonymous15 ___ret__14s__anonymous15_1; 447 431 ((void)((*___dst__R14s__anonymous15_1).__i__s_1=___src__14s__anonymous15_1.__i__s_1)); 448 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), (*___dst__R14s__anonymous15_1)));449 return ___ret__14s__anonymous15_1;432 ((void)___constructor__F_R14s__anonymous1514s__anonymous15_autogen___1((&___ret__14s__anonymous15_1), ___src__14s__anonymous15_1)); 433 return ((struct __anonymous15 )___ret__14s__anonymous15_1); 450 434 } 451 435 static inline void ___constructor__F_R14s__anonymous15s_autogen___1(struct __anonymous15 *___dst__R14s__anonymous15_1, signed short int __i__s_1){ … … 476 460 static inline void ___destructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1); 477 461 static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_R14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1); 478 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1);479 462 static inline void ___constructor__F_R14s__anonymous16_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1){ 480 463 ((void)((*___dst__R14s__anonymous16_1).__i__i_1) /* ?{} */); … … 489 472 struct __anonymous16 ___ret__14s__anonymous16_1; 490 473 ((void)((*___dst__R14s__anonymous16_1).__i__i_1=___src__14s__anonymous16_1.__i__i_1)); 491 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), (*___dst__R14s__anonymous16_1)));492 return ___ret__14s__anonymous16_1;474 ((void)___constructor__F_R14s__anonymous1614s__anonymous16_autogen___1((&___ret__14s__anonymous16_1), ___src__14s__anonymous16_1)); 475 return ((struct __anonymous16 )___ret__14s__anonymous16_1); 493 476 } 494 477 static inline void ___constructor__F_R14s__anonymous16i_autogen___1(struct __anonymous16 *___dst__R14s__anonymous16_1, signed int __i__i_1){ … … 503 486 static inline void ___destructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1); 504 487 static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_R14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1); 505 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1);506 488 static inline void ___constructor__F_R14s__anonymous17_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1){ 507 489 ((void)((*___dst__R14s__anonymous17_1).__i__i_1) /* ?{} */); … … 516 498 struct __anonymous17 ___ret__14s__anonymous17_1; 517 499 ((void)((*___dst__R14s__anonymous17_1).__i__i_1=___src__14s__anonymous17_1.__i__i_1)); 518 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), (*___dst__R14s__anonymous17_1)));519 return ___ret__14s__anonymous17_1;500 ((void)___constructor__F_R14s__anonymous1714s__anonymous17_autogen___1((&___ret__14s__anonymous17_1), ___src__14s__anonymous17_1)); 501 return ((struct __anonymous17 )___ret__14s__anonymous17_1); 520 502 } 521 503 static inline void ___constructor__F_R14s__anonymous17i_autogen___1(struct __anonymous17 *___dst__R14s__anonymous17_1, signed int __i__i_1){ … … 530 512 static inline void ___destructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1); 531 513 static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_R14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1); 532 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1);533 514 static inline void ___constructor__F_R14s__anonymous18_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1){ 534 515 ((void)((*___dst__R14s__anonymous18_1).__i__i_1) /* ?{} */); … … 543 524 struct __anonymous18 ___ret__14s__anonymous18_1; 544 525 ((void)((*___dst__R14s__anonymous18_1).__i__i_1=___src__14s__anonymous18_1.__i__i_1)); 545 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), (*___dst__R14s__anonymous18_1)));546 return ___ret__14s__anonymous18_1;526 ((void)___constructor__F_R14s__anonymous1814s__anonymous18_autogen___1((&___ret__14s__anonymous18_1), ___src__14s__anonymous18_1)); 527 return ((struct __anonymous18 )___ret__14s__anonymous18_1); 547 528 } 548 529 static inline void ___constructor__F_R14s__anonymous18i_autogen___1(struct __anonymous18 *___dst__R14s__anonymous18_1, signed int __i__i_1){ … … 557 538 static inline void ___destructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1); 558 539 static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_R14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1); 559 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1);560 540 static inline void ___constructor__F_R14s__anonymous19_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1){ 561 541 ((void)((*___dst__R14s__anonymous19_1).__i__i_1) /* ?{} */); … … 570 550 struct __anonymous19 ___ret__14s__anonymous19_1; 571 551 ((void)((*___dst__R14s__anonymous19_1).__i__i_1=___src__14s__anonymous19_1.__i__i_1)); 572 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), (*___dst__R14s__anonymous19_1)));573 return ___ret__14s__anonymous19_1;552 ((void)___constructor__F_R14s__anonymous1914s__anonymous19_autogen___1((&___ret__14s__anonymous19_1), ___src__14s__anonymous19_1)); 553 return ((struct __anonymous19 )___ret__14s__anonymous19_1); 574 554 } 575 555 static inline void ___constructor__F_R14s__anonymous19i_autogen___1(struct __anonymous19 *___dst__R14s__anonymous19_1, signed int __i__i_1){ … … 584 564 static inline void ___destructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1); 585 565 static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_R14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1); 586 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1);587 566 static inline void ___constructor__F_R14s__anonymous20_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1){ 588 567 ((void)((*___dst__R14s__anonymous20_1).__i__i_1) /* ?{} */); … … 597 576 struct __anonymous20 ___ret__14s__anonymous20_1; 598 577 ((void)((*___dst__R14s__anonymous20_1).__i__i_1=___src__14s__anonymous20_1.__i__i_1)); 599 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), (*___dst__R14s__anonymous20_1)));600 return ___ret__14s__anonymous20_1;578 ((void)___constructor__F_R14s__anonymous2014s__anonymous20_autogen___1((&___ret__14s__anonymous20_1), ___src__14s__anonymous20_1)); 579 return ((struct __anonymous20 )___ret__14s__anonymous20_1); 601 580 } 602 581 static inline void ___constructor__F_R14s__anonymous20i_autogen___1(struct __anonymous20 *___dst__R14s__anonymous20_1, signed int __i__i_1){ … … 611 590 static inline void ___destructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1); 612 591 static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_R14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1); 613 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1);614 592 static inline void ___constructor__F_R14s__anonymous21_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1){ 615 593 ((void)((*___dst__R14s__anonymous21_1).__i__i_1) /* ?{} */); … … 624 602 struct __anonymous21 ___ret__14s__anonymous21_1; 625 603 ((void)((*___dst__R14s__anonymous21_1).__i__i_1=___src__14s__anonymous21_1.__i__i_1)); 626 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), (*___dst__R14s__anonymous21_1)));627 return ___ret__14s__anonymous21_1;604 ((void)___constructor__F_R14s__anonymous2114s__anonymous21_autogen___1((&___ret__14s__anonymous21_1), ___src__14s__anonymous21_1)); 605 return ((struct __anonymous21 )___ret__14s__anonymous21_1); 628 606 } 629 607 static inline void ___constructor__F_R14s__anonymous21i_autogen___1(struct __anonymous21 *___dst__R14s__anonymous21_1, signed int __i__i_1){ … … 638 616 static inline void ___destructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1); 639 617 static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_R14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1); 640 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1);641 618 static inline void ___constructor__F_R14s__anonymous22_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1){ 642 619 ((void)((*___dst__R14s__anonymous22_1).__i__i_1) /* ?{} */); … … 651 628 struct __anonymous22 ___ret__14s__anonymous22_1; 652 629 ((void)((*___dst__R14s__anonymous22_1).__i__i_1=___src__14s__anonymous22_1.__i__i_1)); 653 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), (*___dst__R14s__anonymous22_1)));654 return ___ret__14s__anonymous22_1;630 ((void)___constructor__F_R14s__anonymous2214s__anonymous22_autogen___1((&___ret__14s__anonymous22_1), ___src__14s__anonymous22_1)); 631 return ((struct __anonymous22 )___ret__14s__anonymous22_1); 655 632 } 656 633 static inline void ___constructor__F_R14s__anonymous22i_autogen___1(struct __anonymous22 *___dst__R14s__anonymous22_1, signed int __i__i_1){ … … 665 642 static inline void ___destructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1); 666 643 static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_R14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1); 667 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1);668 644 static inline void ___constructor__F_R14s__anonymous23_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1){ 669 645 ((void)((*___dst__R14s__anonymous23_1).__i__i_1) /* ?{} */); … … 678 654 struct __anonymous23 ___ret__14s__anonymous23_1; 679 655 ((void)((*___dst__R14s__anonymous23_1).__i__i_1=___src__14s__anonymous23_1.__i__i_1)); 680 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), (*___dst__R14s__anonymous23_1)));681 return ___ret__14s__anonymous23_1;656 ((void)___constructor__F_R14s__anonymous2314s__anonymous23_autogen___1((&___ret__14s__anonymous23_1), ___src__14s__anonymous23_1)); 657 return ((struct __anonymous23 )___ret__14s__anonymous23_1); 682 658 } 683 659 static inline void ___constructor__F_R14s__anonymous23i_autogen___1(struct __anonymous23 *___dst__R14s__anonymous23_1, signed int __i__i_1){ … … 696 672 __attribute__ ((unused)) signed int ___retval_main__i_1; 697 673 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 698 return ___retval_main__i_1;674 return ((signed int )___retval_main__i_1); 699 675 ((void)(___retval_main__i_1=0) /* ?{} */); 700 return ___retval_main__i_1;676 return ((signed int )___retval_main__i_1); 701 677 } 702 678 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 713 689 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 714 690 ((void)(_tmp_cp_ret0) /* ^?{} */); 715 return ___retval_main__i_1;716 } 691 return ((signed int )___retval_main__i_1); 692 } -
src/tests/.expect/64/extension.txt
r6840e7c rb96ec83 17 17 static inline void ___destructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1); 18 18 static inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___1(struct S *___dst__R2sS_1, struct S ___src__2sS_1); 19 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1);20 static inline void ___constructor__F_R2sSii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1);21 static inline void ___constructor__F_R2sSiii_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1, signed int __b__i_1, signed int __c__i_1);22 19 static inline void ___constructor__F_R2sS_autogen___1(struct S *___dst__R2sS_1){ 23 20 ((void)((*___dst__R2sS_1).__a__i_1) /* ?{} */); … … 40 37 ((void)((*___dst__R2sS_1).__b__i_1=___src__2sS_1.__b__i_1)); 41 38 ((void)((*___dst__R2sS_1).__c__i_1=___src__2sS_1.__c__i_1)); 42 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), (*___dst__R2sS_1)));43 return ___ret__2sS_1;39 ((void)___constructor__F_R2sS2sS_autogen___1((&___ret__2sS_1), ___src__2sS_1)); 40 return ((struct S )___ret__2sS_1); 44 41 } 45 42 static inline void ___constructor__F_R2sSi_autogen___1(struct S *___dst__R2sS_1, signed int __a__i_1){ … … 63 60 __extension__ signed int __c__i_1; 64 61 }; 65 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1);66 static inline void ___constructor__F_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1);67 static inline void ___destructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1);68 static inline union U ___operator_assign__F2uU_R2uU2uU_autogen___1(union U *___dst__R2uU_1, union U ___src__2uU_1);69 static inline void ___constructor__F_R2uUi_autogen___1(union U *___dst__R2uU_1, signed int __a__i_1);70 62 static inline void ___constructor__F_R2uU_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1){ 71 63 } … … 78 70 union U ___ret__2uU_1; 79 71 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&___src__2uU_1)), sizeof(union U ))); 80 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), (*___dst__R2uU_1)));81 return ___ret__2uU_1;72 ((void)___constructor__F_R2uU2uU_autogen___1((&___ret__2uU_1), ___src__2uU_1)); 73 return ((union U )___ret__2uU_1); 82 74 } 83 static inline void ___constructor__F_R2uUi_autogen___1( union U *___dst__R2uU_1, signed int __a__i_1){84 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__ a__i_1)), sizeof(signed int )));75 static inline void ___constructor__F_R2uUi_autogen___1(__attribute__ ((unused)) union U *___dst__R2uU_1, signed int __src__i_1){ 76 ((void)__builtin_memcpy(((void *)___dst__R2uU_1), ((const void *)(&__src__i_1)), sizeof(signed int ))); 85 77 } 86 78 __extension__ enum E { … … 102 94 __extension__ signed int *__z__Pi_2; 103 95 }; 104 inline void ___constructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 105 ((void)((*___dst__R2sS_2).__a__i_2) /* ?{} */); 106 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 107 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 108 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 109 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 110 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 111 } 112 inline void ___constructor__F_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 113 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2) /* ?{} */); 114 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2) /* ?{} */); 115 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2) /* ?{} */); 116 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2) /* ?{} */); 117 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2) /* ?{} */); 118 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2) /* ?{} */); 119 } 120 inline void ___destructor__F_R2sS_autogen___2(struct S *___dst__R2sS_2){ 121 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ^?{} */); 122 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ^?{} */); 123 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ^?{} */); 124 ((void)((*___dst__R2sS_2).__c__i_2) /* ^?{} */); 125 ((void)((*___dst__R2sS_2).__b__i_2) /* ^?{} */); 126 ((void)((*___dst__R2sS_2).__a__i_2) /* ^?{} */); 127 } 128 inline struct S ___operator_assign__F2sS_R2sS2sS_autogen___2(struct S *___dst__R2sS_2, struct S ___src__2sS_2){ 129 struct S ___ret__2sS_2; 130 ((void)((*___dst__R2sS_2).__a__i_2=___src__2sS_2.__a__i_2)); 131 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 132 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 133 ((void)((*___dst__R2sS_2).__x__Pi_2=___src__2sS_2.__x__Pi_2)); 134 ((void)((*___dst__R2sS_2).__y__Pi_2=___src__2sS_2.__y__Pi_2)); 135 ((void)((*___dst__R2sS_2).__z__Pi_2=___src__2sS_2.__z__Pi_2)); 136 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2))); 137 return ___ret__2sS_2; 138 } 139 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ 140 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 141 ((void)((*___dst__R2sS_2).__b__i_2) /* ?{} */); 142 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 143 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 144 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 145 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 146 } 147 inline void ___constructor__F_R2sSii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2){ 148 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 149 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 150 ((void)((*___dst__R2sS_2).__c__i_2) /* ?{} */); 151 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 152 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 153 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 154 } 155 inline void ___constructor__F_R2sSiii_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2){ 156 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 157 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 158 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 159 ((void)((*___dst__R2sS_2).__x__Pi_2) /* ?{} */); 160 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 161 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 162 } 163 inline void ___constructor__F_R2sSiiiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2){ 164 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 165 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 166 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 167 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 168 ((void)((*___dst__R2sS_2).__y__Pi_2) /* ?{} */); 169 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 170 } 171 inline void ___constructor__F_R2sSiiiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2){ 172 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 173 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 174 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 175 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 176 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 177 ((void)((*___dst__R2sS_2).__z__Pi_2) /* ?{} */); 178 } 179 inline void ___constructor__F_R2sSiiiPiPiPi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2, signed int __b__i_2, signed int __c__i_2, signed int *__x__Pi_2, signed int *__y__Pi_2, signed int *__z__Pi_2){ 180 ((void)((*___dst__R2sS_2).__a__i_2=__a__i_2) /* ?{} */); 181 ((void)((*___dst__R2sS_2).__b__i_2=__b__i_2) /* ?{} */); 182 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 183 ((void)((*___dst__R2sS_2).__x__Pi_2=__x__Pi_2) /* ?{} */); 184 ((void)((*___dst__R2sS_2).__y__Pi_2=__y__Pi_2) /* ?{} */); 185 ((void)((*___dst__R2sS_2).__z__Pi_2=__z__Pi_2) /* ?{} */); 186 } 187 signed int __i__i_2 = (__extension__ __a__i_1+__extension__ 3); 96 signed int __i__i_2 = ((signed int )(__extension__ __a__i_1+__extension__ 3)); 188 97 ((void)__extension__ 3); 189 98 ((void)__extension__ __a__i_1); -
src/tests/.expect/64/gccExtensions.txt
r6840e7c rb96ec83 63 63 ((void)((*___dst__R2sS_2).__b__i_2=___src__2sS_2.__b__i_2)); 64 64 ((void)((*___dst__R2sS_2).__c__i_2=___src__2sS_2.__c__i_2)); 65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), (*___dst__R2sS_2)));66 return ___ret__2sS_2;65 ((void)___constructor__F_R2sS2sS_autogen___2((&___ret__2sS_2), ___src__2sS_2)); 66 return ((struct S )___ret__2sS_2); 67 67 } 68 68 inline void ___constructor__F_R2sSi_autogen___2(struct S *___dst__R2sS_2, signed int __a__i_2){ … … 81 81 ((void)((*___dst__R2sS_2).__c__i_2=__c__i_2) /* ?{} */); 82 82 } 83 signed int __i__i_2 = __extension__ 3;83 signed int __i__i_2 = ((signed int )__extension__ 3); 84 84 __extension__ signed int __a__i_2; 85 85 __extension__ signed int __b__i_2; … … 113 113 struct s2 ___ret__3ss2_2; 114 114 ((void)((*___dst__R3ss2_2).__i__i_2=___src__3ss2_2.__i__i_2)); 115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), (*___dst__R3ss2_2)));116 return ___ret__3ss2_2;115 ((void)___constructor__F_R3ss23ss2_autogen___2((&___ret__3ss2_2), ___src__3ss2_2)); 116 return ((struct s2 )___ret__3ss2_2); 117 117 } 118 118 inline void ___constructor__F_R3ss2i_autogen___2(struct s2 *___dst__R3ss2_2, signed int __i__i_2){ … … 134 134 struct s3 ___ret__3ss3_2; 135 135 ((void)((*___dst__R3ss3_2).__i__i_2=___src__3ss3_2.__i__i_2)); 136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), (*___dst__R3ss3_2)));137 return ___ret__3ss3_2;136 ((void)___constructor__F_R3ss33ss3_autogen___2((&___ret__3ss3_2), ___src__3ss3_2)); 137 return ((struct s3 )___ret__3ss3_2); 138 138 } 139 139 inline void ___constructor__F_R3ss3i_autogen___2(struct s3 *___dst__R3ss3_2, signed int __i__i_2){ … … 157 157 struct s4 ___ret__3ss4_2; 158 158 ((void)((*___dst__R3ss4_2).__i__i_2=___src__3ss4_2.__i__i_2)); 159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), (*___dst__R3ss4_2)));160 return ___ret__3ss4_2;159 ((void)___constructor__F_R3ss43ss4_autogen___2((&___ret__3ss4_2), ___src__3ss4_2)); 160 return ((struct s4 )___ret__3ss4_2); 161 161 } 162 162 inline void ___constructor__F_R3ss4i_autogen___2(struct s4 *___dst__R3ss4_2, signed int __i__i_2){ … … 169 169 signed int __m3__A0A0i_2[((unsigned long int )10)][((unsigned long int )10)]; 170 170 ((void)(___retval_main__i_1=((signed int )0)) /* ?{} */); 171 return ___retval_main__i_1;171 return ((signed int )___retval_main__i_1); 172 172 ((void)(___retval_main__i_1=0) /* ?{} */); 173 return ___retval_main__i_1;173 return ((signed int )___retval_main__i_1); 174 174 } 175 175 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } … … 186 186 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 187 187 ((void)(_tmp_cp_ret0) /* ^?{} */); 188 return ___retval_main__i_1;188 return ((signed int )___retval_main__i_1); 189 189 } -
src/tests/.expect/64/literals.txt
r6840e7c rb96ec83 64 64 static inline void ___destructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1); 65 65 static inline struct _Istream_cstrUC ___operator_assign__F16s_Istream_cstrUC_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, struct _Istream_cstrUC ___src__16s_Istream_cstrUC_1); 66 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1);67 66 static inline void ___constructor__F_R16s_Istream_cstrUC_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1){ 68 67 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1) /* ?{} */); … … 77 76 struct _Istream_cstrUC ___ret__16s_Istream_cstrUC_1; 78 77 ((void)((*___dst__R16s_Istream_cstrUC_1).__s__Pc_1=___src__16s_Istream_cstrUC_1.__s__Pc_1)); 79 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), (*___dst__R16s_Istream_cstrUC_1)));80 return ___ret__16s_Istream_cstrUC_1;78 ((void)___constructor__F_R16s_Istream_cstrUC16s_Istream_cstrUC_autogen___1((&___ret__16s_Istream_cstrUC_1), ___src__16s_Istream_cstrUC_1)); 79 return ((struct _Istream_cstrUC )___ret__16s_Istream_cstrUC_1); 81 80 } 82 81 static inline void ___constructor__F_R16s_Istream_cstrUCPc_autogen___1(struct _Istream_cstrUC *___dst__R16s_Istream_cstrUC_1, char *__s__Pc_1){ … … 93 92 static inline void ___destructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1); 94 93 static inline struct _Istream_cstrC ___operator_assign__F15s_Istream_cstrC_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, struct _Istream_cstrC ___src__15s_Istream_cstrC_1); 95 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1);96 static inline void ___constructor__F_R15s_Istream_cstrCPci_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1, signed int __size__i_1);97 94 static inline void ___constructor__F_R15s_Istream_cstrC_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1){ 98 95 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1) /* ?{} */); … … 111 108 ((void)((*___dst__R15s_Istream_cstrC_1).__s__Pc_1=___src__15s_Istream_cstrC_1.__s__Pc_1)); 112 109 ((void)((*___dst__R15s_Istream_cstrC_1).__size__i_1=___src__15s_Istream_cstrC_1.__size__i_1)); 113 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), (*___dst__R15s_Istream_cstrC_1)));114 return ___ret__15s_Istream_cstrC_1;110 ((void)___constructor__F_R15s_Istream_cstrC15s_Istream_cstrC_autogen___1((&___ret__15s_Istream_cstrC_1), ___src__15s_Istream_cstrC_1)); 111 return ((struct _Istream_cstrC )___ret__15s_Istream_cstrC_1); 115 112 } 116 113 static inline void ___constructor__F_R15s_Istream_cstrCPc_autogen___1(struct _Istream_cstrC *___dst__R15s_Istream_cstrC_1, char *__s__Pc_1){ … … 125 122 void *___operator_bitor__A0_1_0_0___fail__PFi_Pd0___eof__PFi_Pd0___open__PF_Pd0PCcPCc___close__PF_Pd0___read__PFPd0_Pd0PcUl___ungetc__PFPd0_Pd0c___fmt__PFi_Pd0PCc__FPd0_Pd015s_Istream_cstrC__1(__attribute__ ((unused)) signed int (*__fail__PFi_P7tistype__1)(void *__anonymous_object1284), __attribute__ ((unused)) signed int (*__eof__PFi_P7tistype__1)(void *__anonymous_object1285), __attribute__ ((unused)) void (*__open__PF_P7tistypePCcPCc__1)(void *__is__P7tistype_1, const char *__name__PCc_1, const char *__mode__PCc_1), __attribute__ ((unused)) void (*__close__PF_P7tistype__1)(void *__is__P7tistype_1), __attribute__ ((unused)) void *(*__read__PFP7tistype_P7tistypePcUl__1)(void *__anonymous_object1286, char *__anonymous_object1287, unsigned long int __anonymous_object1288), __attribute__ ((unused)) void *(*__ungetc__PFP7tistype_P7tistypec__1)(void *__anonymous_object1289, char __anonymous_object1290), __attribute__ ((unused)) signed int (*__fmt__PFi_P7tistypePCc__1)(void *__anonymous_object1291, const char *__fmt__PCc_1, ...), void *__anonymous_object1292, struct _Istream_cstrC __anonymous_object1293); 126 123 enum __anonymous0 { 127 __sepSize__C13e__anonymous0_1 = 16,124 __sepSize__C13e__anonymous0_1 = ((signed int )16), 128 125 }; 129 126 struct ofstream { … … 140 137 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1); 141 138 static inline struct ofstream ___operator_assign__F9sofstream_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1); 142 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1);143 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1);144 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1);145 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1);146 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1);147 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]);148 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]);149 139 static inline void ___constructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 150 140 ((void)((*___dst__R9sofstream_1).__file__Pv_1) /* ?{} */); … … 154 144 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 155 145 { 156 signed int _index0 = 0;146 signed int _index0 = ((signed int )0); 157 147 for (;(_index0<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index0))) { 158 148 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index0)])))) /* ?{} */); … … 160 150 161 151 } 162 163 { 164 signed int _index1 = 0; 152 { 153 signed int _index1 = ((signed int )0); 165 154 for (;(_index1<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index1))) { 166 155 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index1)])))) /* ?{} */); … … 168 157 169 158 } 170 171 159 } 172 160 static inline void ___constructor__F_R9sofstream9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1, struct ofstream ___src__9sofstream_1){ … … 177 165 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1) /* ?{} */); 178 166 { 179 signed int _index2 = 0;167 signed int _index2 = ((signed int )0); 180 168 for (;(_index2<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index2))) { 181 169 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index2)])))=___src__9sofstream_1.__separator__A0c_1[((signed long int )_index2)]) /* ?{} */); … … 183 171 184 172 } 185 186 { 187 signed int _index3 = 0; 173 { 174 signed int _index3 = ((signed int )0); 188 175 for (;(_index3<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index3))) { 189 176 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index3)])))=___src__9sofstream_1.__tupleSeparator__A0c_1[((signed long int )_index3)]) /* ?{} */); … … 191 178 192 179 } 193 194 180 } 195 181 static inline void ___destructor__F_R9sofstream_autogen___1(struct ofstream *___dst__R9sofstream_1){ 196 182 { 197 signed int _index4 = (( (signed int )__sepSize__C13e__anonymous0_1)-1);183 signed int _index4 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1)); 198 184 for (;(_index4>=0);((void)(--_index4))) { 199 185 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index4)])))) /* ^?{} */); … … 201 187 202 188 } 203 204 { 205 signed int _index5 = (((signed int )__sepSize__C13e__anonymous0_1)-1); 189 { 190 signed int _index5 = ((signed int )(((signed int )__sepSize__C13e__anonymous0_1)-1)); 206 191 for (;(_index5>=0);((void)(--_index5))) { 207 192 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index5)])))) /* ^?{} */); … … 209 194 210 195 } 211 212 196 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ^?{} */); 213 197 ((void)((*___dst__R9sofstream_1).__sawNL__b_1) /* ^?{} */); … … 224 208 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=___src__9sofstream_1.__sepCur__PCc_1)); 225 209 { 226 signed int _index6 = 0;210 signed int _index6 = ((signed int )0); 227 211 for (;(_index6<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index6))) { 228 212 ((void)((*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index6)]=___src__9sofstream_1.__separator__A0c_1[((signed long int )_index6)])); … … 232 216 233 217 { 234 signed int _index7 = 0;218 signed int _index7 = ((signed int )0); 235 219 for (;(_index7<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index7))) { 236 220 ((void)((*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index7)]=___src__9sofstream_1.__tupleSeparator__A0c_1[((signed long int )_index7)])); … … 239 223 } 240 224 241 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), (*___dst__R9sofstream_1)));242 return ___ret__9sofstream_1;225 ((void)___constructor__F_R9sofstream9sofstream_autogen___1((&___ret__9sofstream_1), ___src__9sofstream_1)); 226 return ((struct ofstream )___ret__9sofstream_1); 243 227 } 244 228 static inline void ___constructor__F_R9sofstreamPv_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1){ … … 249 233 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 250 234 { 251 signed int _index8 = 0;235 signed int _index8 = ((signed int )0); 252 236 for (;(_index8<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index8))) { 253 237 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index8)])))) /* ?{} */); … … 255 239 256 240 } 257 258 { 259 signed int _index9 = 0; 241 { 242 signed int _index9 = ((signed int )0); 260 243 for (;(_index9<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index9))) { 261 244 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index9)])))) /* ?{} */); … … 263 246 264 247 } 265 266 248 } 267 249 static inline void ___constructor__F_R9sofstreamPvb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1){ … … 272 254 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 273 255 { 274 signed int _index10 = 0;256 signed int _index10 = ((signed int )0); 275 257 for (;(_index10<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index10))) { 276 258 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index10)])))) /* ?{} */); … … 278 260 279 261 } 280 281 { 282 signed int _index11 = 0; 262 { 263 signed int _index11 = ((signed int )0); 283 264 for (;(_index11<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index11))) { 284 265 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index11)])))) /* ?{} */); … … 286 267 287 268 } 288 289 269 } 290 270 static inline void ___constructor__F_R9sofstreamPvbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1){ … … 295 275 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 296 276 { 297 signed int _index12 = 0;277 signed int _index12 = ((signed int )0); 298 278 for (;(_index12<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index12))) { 299 279 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index12)])))) /* ?{} */); … … 301 281 302 282 } 303 304 { 305 signed int _index13 = 0; 283 { 284 signed int _index13 = ((signed int )0); 306 285 for (;(_index13<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index13))) { 307 286 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index13)])))) /* ?{} */); … … 309 288 310 289 } 311 312 290 } 313 291 static inline void ___constructor__F_R9sofstreamPvbbb_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1){ … … 318 296 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1) /* ?{} */); 319 297 { 320 signed int _index14 = 0;298 signed int _index14 = ((signed int )0); 321 299 for (;(_index14<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index14))) { 322 300 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index14)])))) /* ?{} */); … … 324 302 325 303 } 326 327 { 328 signed int _index15 = 0; 304 { 305 signed int _index15 = ((signed int )0); 329 306 for (;(_index15<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index15))) { 330 307 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index15)])))) /* ?{} */); … … 332 309 333 310 } 334 335 311 } 336 312 static inline void ___constructor__F_R9sofstreamPvbbbPCc_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1){ … … 341 317 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 342 318 { 343 signed int _index16 = 0;319 signed int _index16 = ((signed int )0); 344 320 for (;(_index16<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index16))) { 345 321 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index16)])))) /* ?{} */); … … 347 323 348 324 } 349 350 { 351 signed int _index17 = 0; 325 { 326 signed int _index17 = ((signed int )0); 352 327 for (;(_index17<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index17))) { 353 328 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index17)])))) /* ?{} */); … … 355 330 356 331 } 357 358 332 } 359 333 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]){ … … 364 338 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 365 339 { 366 signed int _index18 = 0;340 signed int _index18 = ((signed int )0); 367 341 for (;(_index18<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index18))) { 368 342 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index18)])))=__separator__A0c_1[((signed long int )_index18)]) /* ?{} */); … … 370 344 371 345 } 372 373 { 374 signed int _index19 = 0; 346 { 347 signed int _index19 = ((signed int )0); 375 348 for (;(_index19<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index19))) { 376 349 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index19)])))) /* ?{} */); … … 378 351 379 352 } 380 381 353 } 382 354 static inline void ___constructor__F_R9sofstreamPvbbbPCcA0cA0c_autogen___1(struct ofstream *___dst__R9sofstream_1, void *__file__Pv_1, _Bool __sepDefault__b_1, _Bool __sepOnOff__b_1, _Bool __sawNL__b_1, const char *__sepCur__PCc_1, char __separator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)], char __tupleSeparator__A0c_1[((unsigned long int )__sepSize__C13e__anonymous0_1)]){ … … 387 359 ((void)((*___dst__R9sofstream_1).__sepCur__PCc_1=__sepCur__PCc_1) /* ?{} */); 388 360 { 389 signed int _index20 = 0;361 signed int _index20 = ((signed int )0); 390 362 for (;(_index20<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index20))) { 391 363 ((void)((*((char *)(&(*___dst__R9sofstream_1).__separator__A0c_1[((signed long int )_index20)])))=__separator__A0c_1[((signed long int )_index20)]) /* ?{} */); … … 393 365 394 366 } 395 396 { 397 signed int _index21 = 0; 367 { 368 signed int _index21 = ((signed int )0); 398 369 for (;(_index21<((signed int )__sepSize__C13e__anonymous0_1));((void)(++_index21))) { 399 370 ((void)((*((char *)(&(*___dst__R9sofstream_1).__tupleSeparator__A0c_1[((signed long int )_index21)])))=__tupleSeparator__A0c_1[((signed long int )_index21)]) /* ?{} */); … … 401 372 402 373 } 403 404 374 } 405 375 _Bool __sepPrt__Fb_P9sofstream__1(struct ofstream *__anonymous_object1294); … … 434 404 static inline void ___destructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1); 435 405 static inline struct ifstream ___operator_assign__F9sifstream_R9sifstream9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1, struct ifstream ___src__9sifstream_1); 436 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1);437 406 static inline void ___constructor__F_R9sifstream_autogen___1(struct ifstream *___dst__R9sifstream_1){ 438 407 ((void)((*___dst__R9sifstream_1).__file__Pv_1) /* ?{} */); … … 447 416 struct ifstream ___ret__9sifstream_1; 448 417 ((void)((*___dst__R9sifstream_1).__file__Pv_1=___src__9sifstream_1.__file__Pv_1)); 449 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), (*___dst__R9sifstream_1)));450 return ___ret__9sifstream_1;418 ((void)___constructor__F_R9sifstream9sifstream_autogen___1((&___ret__9sifstream_1), ___src__9sifstream_1)); 419 return ((struct ifstream )___ret__9sifstream_1); 451 420 } 452 421 static inline void ___constructor__F_R9sifstreamPv_autogen___1(struct ifstream *___dst__R9sifstream_1, void *__file__Pv_1){ … … 739 708 ((void)0123456789.e-09L); 740 709 ((void)0123456789.e-09DL); 741 ((void)( +0123456789.e-09));742 ((void)( +0123456789.e-09f));743 ((void)( +0123456789.e-09l));744 ((void)( +0123456789.e-09F));745 ((void)( +0123456789.e-09L));746 ((void)( +0123456789.e-09DL));710 ((void)(-0123456789.e-09)); 711 ((void)(-0123456789.e-09f)); 712 ((void)(-0123456789.e-09l)); 713 ((void)(-0123456789.e-09F)); 714 ((void)(-0123456789.e-09L)); 715 ((void)(-0123456789.e-09DL)); 747 716 ((void)(-0123456789.e-09)); 748 717 ((void)(-0123456789.e-09f)); … … 883 852 ((void)0123456789.0123456789E-09L); 884 853 ((void)0123456789.0123456789E-09DL); 885 ((void)( +0123456789.0123456789E-09));886 ((void)( +0123456789.0123456789E-09f));887 ((void)( +0123456789.0123456789E-09l));888 ((void)( +0123456789.0123456789E-09F));889 ((void)( +0123456789.0123456789E-09L));890 ((void)( +0123456789.0123456789E-09DL));854 ((void)(-0123456789.0123456789E-09)); 855 ((void)(-0123456789.0123456789E-09f)); 856 ((void)(-0123456789.0123456789E-09l)); 857 ((void)(-0123456789.0123456789E-09F)); 858 ((void)(-0123456789.0123456789E-09L)); 859 ((void)(-0123456789.0123456789E-09DL)); 891 860 ((void)(-0123456789.0123456789E-09)); 892 861 ((void)(-0123456789.0123456789E-09f)); … … 930 899 ((void)0x0123456789.p-09F); 931 900 ((void)0x0123456789.p-09L); 932 ((void)( +0x0123456789.p-09));933 ((void)( +0x0123456789.p-09f));934 ((void)( +0x0123456789.p-09l));935 ((void)( +0x0123456789.p-09F));936 ((void)( +0x0123456789.p-09L));901 ((void)(-0x0123456789.p-09)); 902 ((void)(-0x0123456789.p-09f)); 903 ((void)(-0x0123456789.p-09l)); 904 ((void)(-0x0123456789.p-09F)); 905 ((void)(-0x0123456789.p-09L)); 937 906 ((void)(-0x0123456789.p-09)); 938 907 ((void)(-0x0123456789.p-09f)); … … 975 944 ((void)0x.0123456789P-09F); 976 945 ((void)0x.0123456789P-09L); 977 ((void)( +0x.0123456789P-09));978 ((void)( +0x.0123456789P-09f));979 ((void)( +0x.0123456789P-09l));980 ((void)( +0x.0123456789P-09F));981 ((void)( +0x.0123456789P-09L));946 ((void)(-0x.0123456789P-09)); 947 ((void)(-0x.0123456789P-09f)); 948 ((void)(-0x.0123456789P-09l)); 949 ((void)(-0x.0123456789P-09F)); 950 ((void)(-0x.0123456789P-09L)); 982 951 ((void)(-0x.0123456789P-09)); 983 952 ((void)(-0x.0123456789P-09f)); … … 1020 989 ((void)0X0123456789.0123456789P-09F); 1021 990 ((void)0X0123456789.0123456789P-09L); 1022 ((void)(+0X0123456789.0123456789P-09));1023 ((void)(+0X0123456789.0123456789P-09f));1024 ((void)(+0X0123456789.0123456789P-09l));1025 ((void)(+0X0123456789.0123456789P-09F));1026 ((void)(+0X0123456789.0123456789P-09L));1027 991 ((void)(-0X0123456789.0123456789P-09)); 1028 992 ((void)(-0X0123456789.0123456789P-09f)); … … 1030 994 ((void)(-0X0123456789.0123456789P-09F)); 1031 995 ((void)(-0X0123456789.0123456789P-09L)); 1032 ((void)((signed char )01234567)); 1033 ((void)((signed short int )01234567)); 1034 ((void)((signed int )01234567)); 1035 ((void)((signed long int )01234567)); 1036 ((void)((__int128 )01234567)); 1037 ((void)((unsigned char )01234567u)); 1038 ((void)((signed short int )01234567u)); 1039 ((void)((unsigned int )01234567u)); 1040 ((void)((signed long int )01234567u)); 1041 ((void)((__int128 )01234567u)); 1042 ((void)(+((signed int )((signed char )01234567)))); 1043 ((void)(+((signed int )((signed short int )01234567)))); 1044 ((void)(+((signed int )01234567))); 1045 ((void)(+((signed long int )01234567))); 1046 ((void)(+((float )((__int128 )01234567)))); 1047 ((void)(+((signed int )((unsigned char )01234567u)))); 1048 ((void)(+((signed int )((signed short int )01234567u)))); 1049 ((void)(+((unsigned int )01234567u))); 1050 ((void)(+((signed long int )01234567u))); 1051 ((void)(+((float )((__int128 )01234567u)))); 1052 ((void)(-((signed int )((signed char )01234567)))); 1053 ((void)(-((signed int )((signed short int )01234567)))); 1054 ((void)(-((signed int )01234567))); 1055 ((void)(-((signed long int )01234567))); 1056 ((void)(-((float )((__int128 )01234567)))); 1057 ((void)(-((signed int )((unsigned char )01234567u)))); 1058 ((void)(-((signed int )((signed short int )01234567u)))); 1059 ((void)(-((unsigned int )01234567u))); 1060 ((void)(-((signed long int )01234567u))); 1061 ((void)(-((float )((__int128 )01234567u)))); 1062 ((void)((signed char )1234567890)); 1063 ((void)((signed short int )1234567890)); 1064 ((void)((signed int )1234567890)); 1065 ((void)((signed long int )1234567890)); 1066 ((void)((__int128 )1234567890)); 1067 ((void)((signed char )1234567890U)); 1068 ((void)((unsigned short int )1234567890U)); 1069 ((void)((signed int )1234567890U)); 1070 ((void)((unsigned long int )1234567890u)); 1071 ((void)((unsigned __int128 )1234567890u)); 1072 ((void)(+((signed int )((signed char )1234567890)))); 1073 ((void)(+((signed int )((signed short int )1234567890)))); 1074 ((void)(+((signed int )1234567890))); 1075 ((void)(+((signed long int )1234567890))); 1076 ((void)(+((float )((__int128 )1234567890)))); 1077 ((void)(+((signed int )((signed char )1234567890U)))); 1078 ((void)(+((signed int )((unsigned short int )1234567890U)))); 1079 ((void)(+((signed int )1234567890U))); 1080 ((void)(+((unsigned long int )1234567890u))); 1081 ((void)(+((float )((unsigned __int128 )1234567890u)))); 1082 ((void)(-((signed int )((signed char )1234567890)))); 1083 ((void)(-((signed int )((signed short int )1234567890)))); 1084 ((void)(-((signed int )1234567890))); 1085 ((void)(-((signed long int )1234567890))); 1086 ((void)(-((float )((__int128 )1234567890)))); 1087 ((void)(-((signed int )((signed char )1234567890U)))); 1088 ((void)(-((signed int )((unsigned short int )1234567890U)))); 1089 ((void)(-((signed int )1234567890U))); 1090 ((void)(-((unsigned long int )1234567890u))); 1091 ((void)(-((float )((unsigned __int128 )1234567890u)))); 1092 ((void)((signed char )0x0123456789abcdef)); 1093 ((void)((signed short int )0x0123456789abcdef)); 1094 ((void)((signed int )0x0123456789abcdef)); 1095 ((void)((signed long int )0x0123456789abcdef)); 1096 ((void)((signed char )0x0123456789abcdefu)); 1097 ((void)((unsigned short int )0x0123456789abcdefu)); 1098 ((void)((signed int )0x0123456789abcdefu)); 1099 ((void)((unsigned long int )0x0123456789abcdefu)); 1100 ((void)(+((signed int )((signed char )0x0123456789abcdef)))); 1101 ((void)(+((signed int )((signed short int )0x0123456789abcdef)))); 1102 ((void)(+((signed int )0x0123456789abcdef))); 1103 ((void)(+((signed long int )0x0123456789abcdef))); 1104 ((void)(+((signed int )((signed char )0x0123456789abcdefu)))); 1105 ((void)(+((signed int )((unsigned short int )0x0123456789abcdefu)))); 1106 ((void)(+((signed int )0x0123456789abcdefu))); 1107 ((void)(+((unsigned long int )0x0123456789abcdefu))); 1108 ((void)(-((signed int )((signed char )0x0123456789abcdef)))); 1109 ((void)(-((signed int )((signed short int )0x0123456789abcdef)))); 1110 ((void)(-((signed int )0x0123456789abcdef))); 1111 ((void)(-((signed long int )0x0123456789abcdef))); 1112 ((void)(-((signed int )((signed char )0x0123456789abcdefu)))); 1113 ((void)(-((signed int )((unsigned short int )0x0123456789abcdefu)))); 1114 ((void)(-((signed int )0x0123456789abcdefu))); 1115 ((void)(-((unsigned long int )0x0123456789abcdefu))); 1116 ((void)((signed char )0x0123456789ABCDEF)); 1117 ((void)((signed short int )0x0123456789ABCDEF)); 1118 ((void)((signed int )0x0123456789ABCDEF)); 1119 ((void)((signed long int )0x0123456789ABCDEF)); 1120 ((void)((signed char )0x0123456789ABCDEFu)); 1121 ((void)((unsigned short int )0x0123456789ABCDEFu)); 1122 ((void)((signed int )0x0123456789ABCDEFu)); 1123 ((void)((unsigned long int )0x0123456789ABCDEFu)); 1124 ((void)(+((signed int )((signed char )0x0123456789ABCDEF)))); 1125 ((void)(+((signed int )((signed short int )0x0123456789ABCDEF)))); 1126 ((void)(+((signed int )0x0123456789ABCDEF))); 1127 ((void)(+((signed long int )0x0123456789ABCDEF))); 1128 ((void)(+((signed int )((signed char )0x0123456789ABCDEFu)))); 1129 ((void)(+((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1130 ((void)(+((signed int )0x0123456789ABCDEFu))); 1131 ((void)(+((unsigned long int )0x0123456789ABCDEFu))); 1132 ((void)(-((signed int )((signed char )0x0123456789ABCDEF)))); 1133 ((void)(-((signed int )((signed short int )0x0123456789ABCDEF)))); 1134 ((void)(-((signed int )0x0123456789ABCDEF))); 1135 ((void)(-((signed long int )0x0123456789ABCDEF))); 1136 ((void)(-((signed int )((signed char )0x0123456789ABCDEFu)))); 1137 ((void)(-((signed int )((unsigned short int )0x0123456789ABCDEFu)))); 1138 ((void)(-((signed int )0x0123456789ABCDEFu))); 1139 ((void)(-((unsigned long int )0x0123456789ABCDEFu))); 1140 ((void)((signed char )0X0123456789abcdef)); 1141 ((void)((signed short int )0X0123456789abcdef)); 1142 ((void)((signed int )0X0123456789abcdef)); 1143 ((void)((signed long int )0X0123456789abcdef)); 1144 ((void)((signed char )0X0123456789abcdefu)); 1145 ((void)((unsigned short int )0X0123456789abcdefu)); 1146 ((void)((signed int )0X0123456789abcdefu)); 1147 ((void)((unsigned long int )0X0123456789abcdefu)); 1148 ((void)(+((signed int )((signed char )0X0123456789abcdef)))); 1149 ((void)(+((signed int )((signed short int )0X0123456789abcdef)))); 1150 ((void)(+((signed int )0X0123456789abcdef))); 1151 ((void)(+((signed long int )0X0123456789abcdef))); 1152 ((void)(+((signed int )((signed char )0X0123456789abcdefu)))); 1153 ((void)(+((signed int )((unsigned short int )0X0123456789abcdefu)))); 1154 ((void)(+((signed int )0X0123456789abcdefu))); 1155 ((void)(+((unsigned long int )0X0123456789abcdefu))); 1156 ((void)(-((signed int )((signed char )0X0123456789abcdef)))); 1157 ((void)(-((signed int )((signed short int )0X0123456789abcdef)))); 1158 ((void)(-((signed int )0X0123456789abcdef))); 1159 ((void)(-((signed long int )0X0123456789abcdef))); 1160 ((void)(-((signed int )((signed char )0X0123456789abcdefu)))); 1161 ((void)(-((signed int )((unsigned short int )0X0123456789abcdefu)))); 1162 ((void)(-((signed int )0X0123456789abcdefu))); 1163 ((void)(-((unsigned long int )0X0123456789abcdefu))); 1164 ((void)((signed char )0X0123456789ABCDEF)); 1165 ((void)((signed short int )0X0123456789ABCDEF)); 1166 ((void)((signed int )0X0123456789ABCDEF)); 1167 ((void)((signed long int )0X0123456789ABCDEF)); 1168 ((void)((signed char )0X0123456789ABCDEFu)); 1169 ((void)((unsigned short int )0X0123456789ABCDEFu)); 1170 ((void)((signed int )0X0123456789ABCDEFu)); 1171 ((void)((unsigned long int )0X0123456789ABCDEFu)); 1172 ((void)(+((signed int )((signed char )0X0123456789ABCDEF)))); 1173 ((void)(+((signed int )((signed short int )0X0123456789ABCDEF)))); 1174 ((void)(+((signed int )0X0123456789ABCDEF))); 1175 ((void)(+((signed long int )0X0123456789ABCDEF))); 1176 ((void)(+((signed int )((signed char )0X0123456789ABCDEFu)))); 1177 ((void)(+((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1178 ((void)(+((signed int )0X0123456789ABCDEFu))); 1179 ((void)(+((unsigned long int )0X0123456789ABCDEFu))); 1180 ((void)(-((signed int )((signed char )0X0123456789ABCDEF)))); 1181 ((void)(-((signed int )((signed short int )0X0123456789ABCDEF)))); 1182 ((void)(-((signed int )0X0123456789ABCDEF))); 1183 ((void)(-((signed long int )0X0123456789ABCDEF))); 1184 ((void)(-((signed int )((signed char )0X0123456789ABCDEFu)))); 1185 ((void)(-((signed int )((unsigned short int )0X0123456789ABCDEFu)))); 1186 ((void)(-((signed int )0X0123456789ABCDEFu))); 1187 ((void)(-((unsigned long int )0X0123456789ABCDEFu))); 1188 ((void)((float )0123456789.)); 1189 ((void)((double )0123456789.)); 1190 ((void)((long double )0123456789.)); 1191 ((void)((long double )0123456789.)); 1192 ((void)(+((float )0123456789.))); 1193 ((void)(+((double )0123456789.))); 1194 ((void)(+((long double )0123456789.))); 1195 ((void)(+((long double )0123456789.))); 1196 ((void)(-((float )0123456789.))); 1197 ((void)(-((double )0123456789.))); 1198 ((void)(-((long double )0123456789.))); 1199 ((void)(-((long double )0123456789.))); 1200 ((void)((float )0123456789.e09)); 1201 ((void)((double )0123456789.e09)); 1202 ((void)((long double )0123456789.e09)); 1203 ((void)((long double )0123456789.e09)); 1204 ((void)(+((float )0123456789.e+09))); 1205 ((void)(+((double )0123456789.e+09))); 1206 ((void)(+((long double )0123456789.e+09))); 1207 ((void)(+((long double )0123456789.e+09))); 1208 ((void)(-((float )0123456789.e-09))); 1209 ((void)(-((double )0123456789.e-09))); 1210 ((void)(-((long double )0123456789.e-09))); 1211 ((void)(-((long double )0123456789.e-09))); 1212 ((void)((float ).0123456789e09)); 1213 ((void)((double ).0123456789e09)); 1214 ((void)((long double ).0123456789e09)); 1215 ((void)((long double ).0123456789e09)); 1216 ((void)(+((float ).0123456789E+09))); 1217 ((void)(+((double ).0123456789E+09))); 1218 ((void)(+((long double ).0123456789E+09))); 1219 ((void)(+((long double ).0123456789E+09))); 1220 ((void)(-((float ).0123456789E-09))); 1221 ((void)(-((double ).0123456789E-09))); 1222 ((void)(-((long double ).0123456789E-09))); 1223 ((void)(-((long double ).0123456789E-09))); 1224 ((void)((float )0123456789.0123456789)); 1225 ((void)((double )0123456789.0123456789)); 1226 ((void)((long double )0123456789.0123456789)); 1227 ((void)((long double )0123456789.0123456789)); 1228 ((void)(+((float )0123456789.0123456789E09))); 1229 ((void)(+((double )0123456789.0123456789E09))); 1230 ((void)(+((long double )0123456789.0123456789E09))); 1231 ((void)(+((long double )0123456789.0123456789E09))); 1232 ((void)(-((float )0123456789.0123456789E+09))); 1233 ((void)(-((double )0123456789.0123456789E+09))); 1234 ((void)(-((long double )0123456789.0123456789E+09))); 1235 ((void)(-((long double )0123456789.0123456789E+09))); 1236 ((void)((float )0123456789.0123456789E-09)); 1237 ((void)((double )0123456789.0123456789E-09)); 1238 ((void)((long double )0123456789.0123456789E-09)); 1239 ((void)((long double )0123456789.0123456789E-09)); 1240 ((void)((float )0x0123456789.p09)); 1241 ((void)((double )0x0123456789.p09)); 1242 ((void)((long double )0x0123456789.p09)); 1243 ((void)((long double )0x0123456789.p09)); 1244 ((void)(+((float )0x0123456789.p09))); 1245 ((void)(+((double )0x0123456789.p09))); 1246 ((void)(+((long double )0x0123456789.p09))); 1247 ((void)(+((long double )0x0123456789.p09))); 1248 ((void)(-((float )0x0123456789.p09))); 1249 ((void)(-((double )0x0123456789.p09))); 1250 ((void)(-((long double )0x0123456789.p09))); 1251 ((void)(-((long double )0x0123456789.p09))); 1252 ((void)((float )0x0123456789.p+09)); 1253 ((void)((double )0x0123456789.p+09)); 1254 ((void)((long double )0x0123456789.p+09)); 1255 ((void)((long double )0x0123456789.p+09)); 1256 ((void)(+((float )0x0123456789.p-09))); 1257 ((void)(+((double )0x0123456789.p-09))); 1258 ((void)(+((long double )0x0123456789.p-09))); 1259 ((void)(+((long double )0x0123456789.p-09))); 1260 ((void)(-((float )0x.0123456789p09))); 1261 ((void)(-((double )0x.0123456789p09))); 1262 ((void)(-((long double )0x.0123456789p09))); 1263 ((void)(-((long double )0x.0123456789p09))); 996 ((void)(-0X0123456789.0123456789P-09)); 997 ((void)(-0X0123456789.0123456789P-09f)); 998 ((void)(-0X0123456789.0123456789P-09l)); 999 ((void)(-0X0123456789.0123456789P-09F)); 1000 ((void)(-0X0123456789.0123456789P-09L)); 1264 1001 ((void)__f__F_c__1('a')); 1265 1002 ((void)__f__F_Sc__1(20)); … … 1374 1111 ((void)L"a" "b" "c"); 1375 1112 ((void)(___retval_main__i_1=0) /* ?{} */); 1376 return ___retval_main__i_1;1113 return ((signed int )___retval_main__i_1); 1377 1114 } 1378 1115 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } … … 1389 1126 ((void)(___retval_main__i_1=(((void)(_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1))) , _tmp_cp_ret0)) /* ?{} */); 1390 1127 ((void)(_tmp_cp_ret0) /* ^?{} */); 1391 return ___retval_main__i_1;1392 } 1128 return ((signed int )___retval_main__i_1); 1129 } -
src/tests/.expect/castError.txt
r6840e7c rb96ec83 1 castError.c:7:1 error: Cannot choose between 3 alternatives for expression 2 Cast of: 1 castError.c:7:1 error: Cannot choose between 3 alternatives for expression Cast of: 3 2 Name: f 4 ... to:5 charAlternatives are:6 Cost ( 1, 0, 0, 0 ): Cast of:7 Variable Expression: f: function8 accepting unspecified arguments9 ... returning nothing10 3 11 ... to: 12 char 13 (types: 14 char 15 ) 16 Environment: 17 18 Cost ( 1, 0, 0, 0 ): Cast of: 19 Variable Expression: f: signed int 20 ... to: 21 char 22 (types: 23 char 24 ) 25 Environment: 26 27 Cost ( 1, 0, 0, 0 ): Cast of: 28 Variable Expression: f: double 29 ... to: 30 char 31 (types: 32 char 33 ) 34 Environment: 4 to: 5 char 6 Alternatives are: Cost ( 1, 0, 0, 0 ): Cast of: 7 Variable Expression: f: function 8 accepting unspecified arguments 9 returning 10 nothing 35 11 36 12 13 to: 14 char 15 (types: 16 char 17 ) 18 Environment: 19 20 Cost ( 1, 0, 0, 0 ): Cast of: 21 Variable Expression: f: signed int 22 23 to: 24 char 25 (types: 26 char 27 ) 28 Environment: 29 30 Cost ( 1, 0, 0, 0 ): Cast of: 31 Variable Expression: f: double 32 33 to: 34 char 35 (types: 36 char 37 ) 38 Environment: 39 40 -
src/tests/.expect/scopeErrors.txt
r6840e7c rb96ec83 1 1 scopeErrors.c:2:1 error: duplicate object definition for thisIsAnError: signed int 2 2 scopeErrors.c:20:1 error: duplicate function definition for butThisIsAnError: function 3 ... with parameters 4 double 5 ... returning 6 _retval_butThisIsAnError: double 7 ... with attributes: 8 Attribute with name: unused 3 with parameters 4 double 5 returning 6 _retval_butThisIsAnError: Attribute with name: unused 7 double 8 with body 9 CompoundStmt 9 10 10 ... with body11 CompoundStmt12 -
src/tests/Makefile.am
r6840e7c rb96ec83 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Tue Oct 10 14:04:40201714 ## Update Count : 4 713 ## Last Modified On : Mon Sep 11 16:17:16 2017 14 ## Update Count : 45 15 15 ############################################################################### 16 16 … … 22 22 concurrent = yes 23 23 quick_test += coroutine thread monitor 24 concurrent_test = \ 25 coroutine \ 26 fmtLines \ 27 pingpong \ 28 prodcons \ 29 thread \ 30 matrixSum \ 31 monitor \ 32 multi-monitor \ 33 boundedBuffer \ 34 preempt \ 35 sched-int-block \ 36 sched-int-disjoint \ 37 sched-int-wait \ 38 sched-ext-barge \ 39 sched-ext-dtor \ 40 sched-ext-else \ 41 sched-ext-parse \ 42 sched-ext-recurse \ 43 sched-ext-statment \ 44 sched-ext-when 24 concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt 45 25 else 46 26 concurrent=no … … 133 113 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 134 114 135 ctor-autogen-ERR1: ctor-autogen.c @CFA_BINDIR@/@CFA_NAME@136 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}137 138 115 completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@ 139 116 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} -
src/tests/Makefile.in
r6840e7c rb96ec83 320 320 @BUILD_CONCURRENCY_TRUE@concurrent = yes 321 321 @BUILD_CONCURRENCY_FALSE@concurrent_test = 322 @BUILD_CONCURRENCY_TRUE@concurrent_test = \ 323 @BUILD_CONCURRENCY_TRUE@ coroutine \ 324 @BUILD_CONCURRENCY_TRUE@ fmtLines \ 325 @BUILD_CONCURRENCY_TRUE@ pingpong \ 326 @BUILD_CONCURRENCY_TRUE@ prodcons \ 327 @BUILD_CONCURRENCY_TRUE@ thread \ 328 @BUILD_CONCURRENCY_TRUE@ matrixSum \ 329 @BUILD_CONCURRENCY_TRUE@ monitor \ 330 @BUILD_CONCURRENCY_TRUE@ multi-monitor \ 331 @BUILD_CONCURRENCY_TRUE@ boundedBuffer \ 332 @BUILD_CONCURRENCY_TRUE@ preempt \ 333 @BUILD_CONCURRENCY_TRUE@ sched-int-block \ 334 @BUILD_CONCURRENCY_TRUE@ sched-int-disjoint \ 335 @BUILD_CONCURRENCY_TRUE@ sched-int-wait \ 336 @BUILD_CONCURRENCY_TRUE@ sched-ext-barge \ 337 @BUILD_CONCURRENCY_TRUE@ sched-ext-dtor \ 338 @BUILD_CONCURRENCY_TRUE@ sched-ext-else \ 339 @BUILD_CONCURRENCY_TRUE@ sched-ext-parse \ 340 @BUILD_CONCURRENCY_TRUE@ sched-ext-recurse \ 341 @BUILD_CONCURRENCY_TRUE@ sched-ext-statment \ 342 @BUILD_CONCURRENCY_TRUE@ sched-ext-when 343 322 @BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt 344 323 345 324 # applies to both programs … … 886 865 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 887 866 888 ctor-autogen-ERR1: ctor-autogen.c @CFA_BINDIR@/@CFA_NAME@889 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}890 891 867 completeTypeError : completeTypeError.c @CFA_BINDIR@/@CFA_NAME@ 892 868 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} -
src/tests/coroutine.c
r6840e7c rb96ec83 10 10 // Created On : Thu Jun 8 07:29:37 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 17 21:38:15201713 // Update Count : 712 // Last Modified On : Thu Jun 8 07:37:12 2017 13 // Update Count : 5 14 14 // 15 15 … … 18 18 19 19 coroutine Fibonacci { 20 int fn; // used for communication20 int fn; // used for communication 21 21 }; 22 22 … … 26 26 27 27 void main( Fibonacci & this ) { 28 int fn1, fn2; // retained between resumes29 this.fn = 0; // case 028 int fn1, fn2; // retained between resumes 29 this.fn = 0; // case 0 30 30 fn1 = this.fn; 31 suspend(); // restartlast resume31 suspend(); // return to last resume 32 32 33 this.fn = 1; // case 1 34 fn2 = fn1; fn1 = this.fn; 35 suspend(); // restart last resume 33 this.fn = 1; // case 1 34 fn2 = fn1; 35 fn1 = this.fn; 36 suspend(); // return to last resume 36 37 37 for ( ;; ) { // general case38 for ( ;; ) { // general case 38 39 this.fn = fn1 + fn2; 39 fn2 = fn1; fn1 = this.fn; 40 suspend(); // restart last resume 40 fn2 = fn1; 41 fn1 = this.fn; 42 suspend(); // return to last resume 41 43 } // for 42 44 } 43 45 44 46 int next( Fibonacci & this ) { 45 resume( this ); // restartlast suspend47 resume( this ); // transfer to last suspend 46 48 return this.fn; 47 49 } … … 50 52 Fibonacci f1, f2; 51 53 for ( int i = 1; i <= 10; i += 1 ) { 52 sout | next( f1 ) | next( f2 ) | endl;54 sout | next( f1 ) | ' ' | next( f2 ) | endl; 53 55 } // for 54 56 } -
src/tests/fmtLines.c
r6840e7c rb96ec83 10 10 // Created On : Sun Sep 17 21:56:15 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Oct 1 11:57:19201713 // Update Count : 3 412 // Last Modified On : Mon Sep 18 11:35:57 2017 13 // Update Count : 31 14 14 // 15 15 … … 23 23 24 24 void ?{}( Format & fmt ) { 25 resume( fmt ); // prime (start)coroutine25 resume( fmt ); // start coroutine 26 26 } 27 27 28 28 void ^?{}( Format & fmt ) { 29 if ( fmt.g != 0 || fmt.b != 0 ) sout | endl;29 if ( fmt.g != 0 || fmt.b != 0 ) sout | endl; 30 30 } 31 31 … … 47 47 48 48 void prt( Format & fmt, char ch ) { 49 fmt.ch = ch;50 resume( fmt );49 fmt.ch = ch; 50 resume( fmt ); 51 51 } // prt 52 52 53 53 int main() { 54 Format fmt; // format characters into blocks of 4 and groups of 5 blocks per line54 Format fmt; 55 55 char ch; 56 56 57 Eof: for ( ;; ) { // read until end of file57 for ( ;; ) { 58 58 sin | ch; // read one character 59 if ( eof( sin ) ) break Eof;// eof ?60 prt( fmt, ch ); // push character for formatting59 if ( eof( sin ) ) break; // eof ? 60 prt( fmt, ch ); 61 61 } // for 62 62 } // main -
src/tests/gmp.c
r6840e7c rb96ec83 10 10 // Created On : Tue Apr 19 08:55:51 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Sep 28 18:33:51201713 // Update Count : 55 512 // Last Modified On : Mon Sep 4 09:51:18 2017 13 // Update Count : 550 14 14 // 15 15 … … 97 97 98 98 sout | "Factorial Numbers" | endl; 99 Int fact = 1; // 1st case 99 Int fact; 100 fact = 1; // 1st case 100 101 sout | (int)0 | fact | endl; 101 102 for ( unsigned int i = 1; i <= 40; i += 1 ) { -
src/tests/literals.c
r6840e7c rb96ec83 10 10 // Created On : Sat Sep 9 16:34:38 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 20:26:00201713 // Update Count : 13212 // Last Modified On : Tue Sep 12 07:45:46 2017 13 // Update Count : 88 14 14 // 15 15 16 16 #ifdef __CFA__ 17 #include <stdint.h>18 17 #include <fstream> 19 18 … … 73 72 74 73 0123456789.e-09; 0123456789.e-09f; 0123456789.e-09l; 0123456789.e-09F; 0123456789.e-09L; 0123456789.e-09DL; 75 +0123456789.e-09; +0123456789.e-09f; +0123456789.e-09l; +0123456789.e-09F; +0123456789.e-09L; +0123456789.e-09DL;74 -0123456789.e-09; -0123456789.e-09f; -0123456789.e-09l; -0123456789.e-09F; -0123456789.e-09L; -0123456789.e-09DL; 76 75 -0123456789.e-09; -0123456789.e-09f; -0123456789.e-09l; -0123456789.e-09F; -0123456789.e-09L; -0123456789.e-09DL; 77 76 … … 105 104 106 105 0123456789.0123456789E-09; 0123456789.0123456789E-09f; 0123456789.0123456789E-09l; 0123456789.0123456789E-09F; 0123456789.0123456789E-09L; 0123456789.0123456789E-09DL; 107 +0123456789.0123456789E-09; +0123456789.0123456789E-09f; +0123456789.0123456789E-09l; +0123456789.0123456789E-09F; +0123456789.0123456789E-09L; +0123456789.0123456789E-09DL;106 -0123456789.0123456789E-09; -0123456789.0123456789E-09f; -0123456789.0123456789E-09l; -0123456789.0123456789E-09F; -0123456789.0123456789E-09L; -0123456789.0123456789E-09DL; 108 107 -0123456789.0123456789E-09; -0123456789.0123456789E-09f; -0123456789.0123456789E-09l; -0123456789.0123456789E-09F; -0123456789.0123456789E-09L; -0123456789.0123456789E-09DL; 109 108 … … 119 118 120 119 0x0123456789.p-09; 0x0123456789.p-09f; 0x0123456789.p-09l; 0x0123456789.p-09F; 0x0123456789.p-09L; 121 +0x0123456789.p-09; +0x0123456789.p-09f; +0x0123456789.p-09l; +0x0123456789.p-09F; +0x0123456789.p-09L;120 -0x0123456789.p-09; -0x0123456789.p-09f; -0x0123456789.p-09l; -0x0123456789.p-09F; -0x0123456789.p-09L; 122 121 -0x0123456789.p-09; -0x0123456789.p-09f; -0x0123456789.p-09l; -0x0123456789.p-09F; -0x0123456789.p-09L; 123 122 … … 131 130 132 131 0x.0123456789P-09; 0x.0123456789P-09f; 0x.0123456789P-09l; 0x.0123456789P-09F; 0x.0123456789P-09L; 133 +0x.0123456789P-09; +0x.0123456789P-09f; +0x.0123456789P-09l; +0x.0123456789P-09F; +0x.0123456789P-09L;132 -0x.0123456789P-09; -0x.0123456789P-09f; -0x.0123456789P-09l; -0x.0123456789P-09F; -0x.0123456789P-09L; 134 133 -0x.0123456789P-09; -0x.0123456789P-09f; -0x.0123456789P-09l; -0x.0123456789P-09F; -0x.0123456789P-09L; 135 134 … … 143 142 144 143 0X0123456789.0123456789P-09; 0X0123456789.0123456789P-09f; 0X0123456789.0123456789P-09l; 0X0123456789.0123456789P-09F; 0X0123456789.0123456789P-09L; 145 +0X0123456789.0123456789P-09; +0X0123456789.0123456789P-09f; +0X0123456789.0123456789P-09l; +0X0123456789.0123456789P-09F; +0X0123456789.0123456789P-09L;146 144 -0X0123456789.0123456789P-09; -0X0123456789.0123456789P-09f; -0X0123456789.0123456789P-09l; -0X0123456789.0123456789P-09F; -0X0123456789.0123456789P-09L; 145 -0X0123456789.0123456789P-09; -0X0123456789.0123456789P-09f; -0X0123456789.0123456789P-09l; -0X0123456789.0123456789P-09F; -0X0123456789.0123456789P-09L; 146 147 // char, short, int suffix overloading 147 148 148 149 #ifdef __CFA__ 149 // fixed-size length150 151 // octal152 01234567_l8; 01234567_l16; 01234567_l32; 01234567_l64; 01234567_l128; 01234567_l8u; 01234567_ul16; 01234567_l32u; 01234567_ul64; 01234567_ul128;153 +01234567_l8; +01234567_l16; +01234567_l32; +01234567_l64; +01234567_l128; +01234567_l8u; +01234567_ul16; +01234567_l32u; +01234567_ul64; +01234567_ul128;154 -01234567_l8; -01234567_l16; -01234567_l32; -01234567_l64; -01234567_l128; -01234567_l8u; -01234567_ul16; -01234567_l32u; -01234567_ul64; -01234567_ul128;155 156 // decimal157 1234567890L8; 1234567890L16; 1234567890l32; 1234567890l64; 1234567890l128; 1234567890UL8; 1234567890L16U; 1234567890Ul32; 1234567890l64u; 1234567890l128u;158 +1234567890L8; +1234567890L16; +1234567890l32; +1234567890l64; +1234567890l128; +1234567890UL8; +1234567890L16U; +1234567890Ul32; +1234567890l64u; +1234567890l128u;159 -1234567890L8; -1234567890L16; -1234567890l32; -1234567890l64; -1234567890l128; -1234567890UL8; -1234567890L16U; -1234567890Ul32; -1234567890l64u; -1234567890l128u;160 161 // hexadecimal162 0x0123456789abcdef_l8; 0x0123456789abcdef_l16; 0x0123456789abcdefl32; 0x0123456789abcdefl64; 0x0123456789abcdef_ul8; 0x0123456789abcdef_l16u; 0x0123456789abcdeful32; 0x0123456789abcdefl64u;163 +0x0123456789abcdef_l8; +0x0123456789abcdef_l16; +0x0123456789abcdefl32; +0x0123456789abcdefl64; +0x0123456789abcdef_ul8; +0x0123456789abcdef_l16u; +0x0123456789abcdeful32; +0x0123456789abcdefl64u;164 -0x0123456789abcdef_l8; -0x0123456789abcdef_l16; -0x0123456789abcdefl32; -0x0123456789abcdefl64; -0x0123456789abcdef_ul8; -0x0123456789abcdef_l16u; -0x0123456789abcdeful32; -0x0123456789abcdefl64u;165 166 0x0123456789ABCDEF_l8; 0x0123456789ABCDEF_l16; 0x0123456789ABCDEFl32; 0x0123456789ABCDEFl64; 0x0123456789ABCDEF_ul8; 0x0123456789ABCDEF_l16u; 0x0123456789ABCDEFul32; 0x0123456789ABCDEFl64u;167 +0x0123456789ABCDEF_l8; +0x0123456789ABCDEF_l16; +0x0123456789ABCDEFl32; +0x0123456789ABCDEFl64; +0x0123456789ABCDEF_ul8; +0x0123456789ABCDEF_l16u; +0x0123456789ABCDEFul32; +0x0123456789ABCDEFl64u;168 -0x0123456789ABCDEF_l8; -0x0123456789ABCDEF_l16; -0x0123456789ABCDEFl32; -0x0123456789ABCDEFl64; -0x0123456789ABCDEF_ul8; -0x0123456789ABCDEF_l16u; -0x0123456789ABCDEFul32; -0x0123456789ABCDEFl64u;169 170 0X0123456789abcdef_l8; 0X0123456789abcdef_l16; 0X0123456789abcdefl32; 0X0123456789abcdefl64; 0X0123456789abcdef_ul8; 0X0123456789abcdef_l16u; 0X0123456789abcdeful32; 0X0123456789abcdefl64u;171 +0X0123456789abcdef_l8; +0X0123456789abcdef_l16; +0X0123456789abcdefl32; +0X0123456789abcdefl64; +0X0123456789abcdef_ul8; +0X0123456789abcdef_l16u; +0X0123456789abcdeful32; +0X0123456789abcdefl64u;172 -0X0123456789abcdef_l8; -0X0123456789abcdef_l16; -0X0123456789abcdefl32; -0X0123456789abcdefl64; -0X0123456789abcdef_ul8; -0X0123456789abcdef_l16u; -0X0123456789abcdeful32; -0X0123456789abcdefl64u;173 174 0X0123456789ABCDEF_l8; 0X0123456789ABCDEF_l16; 0X0123456789ABCDEFl32; 0X0123456789ABCDEFl64; 0X0123456789ABCDEF_ul8; 0X0123456789ABCDEF_l16u; 0X0123456789ABCDEFul32; 0X0123456789ABCDEFl64u;175 +0X0123456789ABCDEF_l8; +0X0123456789ABCDEF_l16; +0X0123456789ABCDEFl32; +0X0123456789ABCDEFl64; +0X0123456789ABCDEF_ul8; +0X0123456789ABCDEF_l16u; +0X0123456789ABCDEFul32; +0X0123456789ABCDEFl64u;176 -0X0123456789ABCDEF_l8; -0X0123456789ABCDEF_l16; -0X0123456789ABCDEFl32; -0X0123456789ABCDEFl64; -0X0123456789ABCDEF_ul8; -0X0123456789ABCDEF_l16u; -0X0123456789ABCDEFul32; -0X0123456789ABCDEFl64u;177 178 // floating179 0123456789.l32; 0123456789.l64; 0123456789.l80; 0123456789.l128;180 +0123456789.l32; +0123456789.l64; +0123456789.l80; +0123456789.l128;181 -0123456789.l32; -0123456789.l64; -0123456789.l80; -0123456789.l128;182 183 0123456789.e09L32; 0123456789.e09L64; 0123456789.e09L80; 0123456789.e09L128;184 +0123456789.e+09L32; +0123456789.e+09L64; +0123456789.e+09L80; +0123456789.e+09L128;185 -0123456789.e-09L32; -0123456789.e-09L64; -0123456789.e-09L80; -0123456789.e-09L128;186 187 .0123456789e09L32; .0123456789e09L64; .0123456789e09L80; .0123456789e09L128;188 +.0123456789E+09L32; +.0123456789E+09L64; +.0123456789E+09L80; +.0123456789E+09L128;189 -.0123456789E-09L32; -.0123456789E-09L64; -.0123456789E-09L80; -.0123456789E-09L128;190 191 0123456789.0123456789L32; 0123456789.0123456789L64; 0123456789.0123456789L80; 0123456789.0123456789L128;192 +0123456789.0123456789E09L32; +0123456789.0123456789E09L64; +0123456789.0123456789E09L80; +0123456789.0123456789E09L128;193 -0123456789.0123456789E+09L32; -0123456789.0123456789E+09L64; -0123456789.0123456789E+09L80; -0123456789.0123456789E+09L128;194 0123456789.0123456789E-09L32; 0123456789.0123456789E-09L64; 0123456789.0123456789E-09L80; 0123456789.0123456789E-09L128;195 196 0x0123456789.p09l32; 0x0123456789.p09l64; 0x0123456789.p09l80; 0x0123456789.p09l128;197 +0x0123456789.p09l32; +0x0123456789.p09l64; +0x0123456789.p09l80; +0x0123456789.p09l128;198 -0x0123456789.p09l32; -0x0123456789.p09l64; -0x0123456789.p09l80; -0x0123456789.p09l128;199 200 0x0123456789.p+09l32; 0x0123456789.p+09L64; 0x0123456789.p+09L80; 0x0123456789.p+09L128;201 +0x0123456789.p-09l32; +0x0123456789.p-09L64; +0x0123456789.p-09L80; +0x0123456789.p-09L128;202 -0x.0123456789p09l32; -0x.0123456789p09L64; -0x.0123456789p09L80; -0x.0123456789p09L128;203 204 // char, short, int suffix overloading205 206 150 f( 'a' ); 207 151 f( 20_hh ); -
src/tests/sched-ext-parse.c
r6840e7c rb96ec83 1 //----------------------------------------------------------------------------------------2 //----------------------------------------------------------------------------------------3 //4 // DEPRECATED TEST5 // DIFFERS BETWEEN DEBUG AND RELEASE6 //7 //----------------------------------------------------------------------------------------8 //----------------------------------------------------------------------------------------9 10 1 #include <monitor> 11 2 -
src/tests/sched-int-barge.c
r6840e7c rb96ec83 1 //----------------------------------------------------------------------------------------2 //----------------------------------------------------------------------------------------3 //4 // DEPRECATED TEST5 //6 //----------------------------------------------------------------------------------------7 //----------------------------------------------------------------------------------------8 9 1 #include <fstream> 10 2 #include <kernel> -
src/tests/sched-int-block.c
r6840e7c rb96ec83 1 //---------------------------------------------------------2 // Barging test3 // Ensures that no barging can occur between :4 // - the frontend of the signal_block and the signaled thread5 // - the signaled threadand the backend of the signal_block6 //---------------------------------------------------------7 8 9 1 #include <fstream> 10 2 #include <kernel> -
src/tests/sched-int-wait.c
r6840e7c rb96ec83 1 //---------------------------------------------------------2 // Multi wait test3 // Ensures that no deadlock from waiting/signalling conditions4 //---------------------------------------------------------5 6 7 1 #include <fstream> 8 2 #include <kernel>
Note:
See TracChangeset
for help on using the changeset viewer.