Changeset 3d5701e


Ignore:
Timestamp:
Feb 25, 2020, 1:17:33 PM (6 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
7dc2e015
Parents:
9fb8f01 (diff), dd9e1ca (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

resolve conflict

Files:
75 added
11 deleted
267 edited
25 moved

Legend:

Unmodified
Added
Removed
  • .gitignore

    r9fb8f01 r3d5701e  
    2121.deps
    2222.dirstamp
    23 bin
    24 lib
    25 include
    26 share
    27 build
     23/bin
     24/lib
     25/include
     26/share
     27/build
    2828*.class
    2929
  • Jenkins/FullBuild

    r9fb8f01 r3d5701e  
    1717
    1818                                parallel (
     19                                        clang_x86: { trigger_build( 'gcc-8',   'x86' ) },
     20                                        gcc_5_x86: { trigger_build( 'gcc-7',   'x86' ) },
     21                                        gcc_6_x86: { trigger_build( 'gcc-6',   'x86' ) },
     22                                        gcc_9_x64: { trigger_build( 'gcc-9',   'x64' ) },
     23                                        gcc_8_x64: { trigger_build( 'gcc-8',   'x64' ) },
     24                                        gcc_7_x64: { trigger_build( 'gcc-7',   'x64' ) },
    1925                                        gcc_6_x64: { trigger_build( 'gcc-6',   'x64' ) },
    20                                         gcc_6_x86: { trigger_build( 'gcc-6',   'x86' ) },
    2126                                        gcc_5_x64: { trigger_build( 'gcc-5',   'x64' ) },
    22                                         gcc_5_x86: { trigger_build( 'gcc-5',   'x86' ) },
    2327                                        clang_x64: { trigger_build( 'clang',   'x64' ) },
    24                                         clang_x86: { trigger_build( 'clang',   'x86' ) },
    2528                                )
    2629                        }
  • Jenkinsfile

    r9fb8f01 r3d5701e  
    102102
    103103                echo GitLogMessage()
     104
     105                // This is a complete hack but it solves problems with automake thinking it needs to regenerate makefiles
     106                // We fudged automake/missing to handle that but automake stills bakes prints inside the makefiles
     107                // and these cause more problems.
     108                sh 'find . -name Makefile.in -exec touch {} +'
    104109        }
    105110}
     
    155160
    156161def test() {
    157         build_stage('Test: short', !Settings.RunAllTests) {
     162        try {
     163                build_stage('Test: short', !Settings.RunAllTests) {
     164                        dir (BuildDir) {
     165                                //Run the tests from the tests directory
     166                                sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
     167                        }
     168                }
     169
     170                build_stage('Test: full', Settings.RunAllTests) {
     171                        dir (BuildDir) {
     172                                        //Run the tests from the tests directory
     173                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
     174                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
     175                        }
     176                }
     177        }
     178        catch (Exception err) {
     179                echo "Archiving core dumps"
    158180                dir (BuildDir) {
    159                         //Run the tests from the tests directory
    160                         sh 'make --no-print-directory -C tests'
    161                 }
    162         }
    163 
    164         build_stage('Test: full', Settings.RunAllTests) {
    165                 dir (BuildDir) {
    166                         //Run the tests from the tests directory
    167                         sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes'
    168                         sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no '
    169                 }
     181                        archiveArtifacts artifacts: "tests/crashes/**/*", fingerprint: true
     182                }
     183                throw err
    170184        }
    171185}
     
    201215
    202216                //Then publish the results
    203                 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'       , groupCompile    , false, 'Compilation')
    204                 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff'  , groupCompile    , true , 'Compilation (relative)')
    205                 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch'     , groupConcurrency, false, 'Context Switching')
    206                 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff', groupConcurrency, true , 'Context Switching (relative)')
    207                 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'         , groupConcurrency, false, 'Mutual Exclusion')
    208                 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff'    , groupConcurrency, true , 'Mutual Exclusion (relative)')
    209                 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal'        , groupConcurrency, false, 'Internal and External Scheduling')
    210                 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal.diff'   , groupConcurrency, true , 'Internal and External Scheduling (relative)')
     217                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'        , groupCompile    , false, 'Compilation')
     218                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff'   , groupCompile    , true , 'Compilation (relative)')
     219                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch'      , groupConcurrency, false, 'Context Switching')
     220                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff' , groupConcurrency, true , 'Context Switching (relative)')
     221                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'          , groupConcurrency, false, 'Mutual Exclusion')
     222                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff'     , groupConcurrency, true , 'Mutual Exclusion (relative)')
     223                do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling'     , groupConcurrency, false, 'Internal and External Scheduling')
     224                do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling.diff', groupConcurrency, true , 'Internal and External Scheduling (relative)')
    211225        }
    212226}
     
    215229//Routine responsible of sending the email notification once the build is completed
    216230//===========================================================================================================
     231@NonCPS
     232def SplitLines(String text) {
     233        def list = []
     234
     235        text.eachLine {
     236                list += it
     237        }
     238
     239        return list
     240}
     241
    217242def GitLogMessage() {
    218243        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
    219244
    220         sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
    221 
    222         def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
    223         def gitLog    = readFile("${BuildDir}/GIT_LOG")
    224         def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
     245        def oldRef = Settings.GitOldRef
     246        def newRef = Settings.GitNewRef
     247
     248        def revText = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim()
     249        def revList = SplitLines( revText )
     250
     251        def gitUpdate = ""
     252        revList.each { rev ->
     253                def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
     254                gitUpdate = gitUpdate + "       via  ${rev} (${type})"
     255        }
     256
     257        def rev = oldRef
     258        def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
     259        gitUpdate = gitUpdate + "      from  ${rev} (${type})"
     260
     261        def gitLog    = sh(returnStdout: true, script: "git rev-list --format=short ${oldRef}...${newRef}").trim()
     262
     263        def gitDiff   = sh(returnStdout: true, script: "git diff --stat --color ${newRef} ${oldRef}").trim()
     264        gitDiff = gitDiff.replace('[32m', '<span style="color: #00AA00;">')
     265        gitDiff = gitDiff.replace('[31m', '<span style="color: #AA0000;">')
     266        gitDiff = gitDiff.replace('[m', '</span>')
    225267
    226268        return """
     
    321363        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
    322364                switch( param.Compiler ) {
     365                        case 'gcc-9':
     366                                this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9')
     367                        break
     368                        case 'gcc-8':
     369                                this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8')
     370                        break
     371                        case 'gcc-7':
     372                                this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7')
     373                        break
    323374                        case 'gcc-6':
    324375                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
     
    331382                        break
    332383                        case 'clang':
    333                                 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
     384                                this.Compiler = new CC_Desc('clang', 'clang++-6.0', 'gcc-6')
    334385                        break
    335386                        default :
     
    393444                                        description: 'Which compiler to use',                                   \
    394445                                        name: 'Compiler',                                                                       \
    395                                         choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
    396                                         defaultValue: 'gcc-6',                                                          \
     446                                        choices: 'gcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang',                                   \
     447                                        defaultValue: 'gcc-8',                                                          \
    397448                                ],                                                                                              \
    398449                                [$class: 'ChoiceParameterDefinition',                                           \
  • Makefile.in

    r9fb8f01 r3d5701e  
    264264CCDEPMODE = @CCDEPMODE@
    265265CFACC = @CFACC@
     266CFACC_INSTALL = @CFACC_INSTALL@
    266267CFACPP = @CFACPP@
    267268CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    294295FGREP = @FGREP@
    295296GREP = @GREP@
     297HAS_DISTCC = @HAS_DISTCC@
    296298HOST_FLAGS = @HOST_FLAGS@
    297299INSTALL = @INSTALL@
  • benchmark/Makefile.am

    r9fb8f01 r3d5701e  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Jul 29 18:02:19 2019
    14 ## Update Count     : 54
     13## Last Modified On : Sat Jan 25 09:20:44 2020
     14## Update Count     : 255
    1515###############################################################################
    1616
     
    2222
    2323AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror
    24 AM_CFAFLAGS = -quiet -nodebug -in-tree
     24AM_CFAFLAGS = -quiet -nodebug
    2525AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
    2626
     
    2828BENCH_V_CFA = $(__bench_v_CFA_$(__quiet))
    2929BENCH_V_CXX = $(__bench_v_CXX_$(__quiet))
     30BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    3031BENCH_V_GOC = $(__bench_v_GOC_$(__quiet))
     32BENCH_V_PY = $(__bench_v_PY_$(__quiet))
     33BENCH_V_RUSTC = $(__bench_v_RUSTC_$(__quiet))
     34BENCH_V_NODEJS = $(__bench_v_NODEJS_$(__quiet))
    3135BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    32 BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    3336
    3437__quiet = verbose
     
    3639__bench_v_CFA_quiet = @
    3740__bench_v_CXX_quiet = @
     41__bench_v_UPP_quiet = @
    3842__bench_v_GOC_quiet = @
     43__bench_v_RUSTC_quiet = @
    3944__bench_v_JAVAC_quiet = @
    40 __bench_v_UPP_quiet = @
    4145__bench_v_CC_verbose = $(AM_V_CC)
    4246__bench_v_CFA_verbose = $(AM_V_CFA)
    4347__bench_v_CXX_verbose = $(AM_V_CXX)
     48__bench_v_UPP_verbose = $(AM_V_UPP)
    4449__bench_v_GOC_verbose = $(AM_V_GOC)
     50__bench_v_PY_verbose = $(AM_V_PY)
     51__bench_v_RUSTC_verbose = $(AM_V_RUST)
     52__bench_v_NODEJS_verbose = $(AM_V_NODEJS)
    4553__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    46 __bench_v_UPP_verbose = $(AM_V_UPP)
    4754
    4855
     
    5158STATS    = ${abs_top_srcdir}/tools/stat.py
    5259# NEED AT LEAST 4 DATA VALUES FOR BENCHMARKS BECAUSE THE MAX AND MIN VALUES ARE REMOVED
    53 repeats  = 5 # 31 for benchmarks
     60repeats  = 13 # 31 for benchmarks
    5461arch     = x64
    5562skipcompile = no
     
    6269
    6370dummyC.c:
    64         @echo "int main() { return 0; }" > ${@}
     71        echo "int main() { return 0; }" > ${@}
    6572
    6673dummyCXX.cpp:
    67         @echo "int main() { return 0; }" > ${@}
    68 
     74        echo "int main() { return 0; }" > ${@}
     75
     76.SILENT:                # do not print recipe
    6977.NOTPARALLEL:
    70 .PHONY: compile.csv ctxswitch.csv mutex.csv signal.csv
    71 
    72 ## =========================================================================================================
    73 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT)
     78.PHONY: jenkins cleancsv
     79
     80## =========================================================================================================
     81
     82all : basic$(EXEEXT) ctxswitch$(EXEEXT) mutex$(EXEEXT) schedint$(EXEEXT) schedext$(EXEEXT) creation$(EXEEXT)
     83
     84basic_loop_DURATION = 15000000000
     85basic_function_DURATION = 10000000000
     86basic_tls_fetch_add_DURATION = 10000000000
     87basic_DURATION = 250000000
     88
     89ctxswitch_pthread_DURATION = 25000000
     90ctxswitch_rust_thread_DURATION = $(ctxswitch_pthread_DURATION)
     91ctxswitch_cfa_generator_DURATION = 5000000000
     92ctxswitch_nodejs_await_DURATION = 5000000
     93ctxswitch_DURATION = 100000000
     94
     95#mutex_java_DURATION = 10000000
     96mutex_DURATION = 50000000
     97
     98schedint_pthread_DURATION = 1000000
     99schedint_java_DURATION = $(schedint_pthread_DURATION)
     100schedint_rust_DURATION = $(schedint_pthread_DURATION)
     101schedint_DURATION = 10000000
     102
     103schedext_DURATION = 10000000
     104
     105creation_pthread_DURATION = 250000
     106creation_rust_thread_DURATION = ${creation_pthread_DURATION}
     107creation_java_thread_DURATION = ${creation_pthread_DURATION}
     108creation_cfa_coroutine_DURATION = 100000000
     109creation_cfa_coroutine_eager_DURATION = 10000000
     110creation_upp_coroutine_DURATION = ${creation_cfa_coroutine_eager_DURATION}
     111creation_cfa_thread_DURATION = 10000000
     112creation_upp_thread_DURATION = ${creation_cfa_thread_DURATION}
     113creation_DURATION = 10000000
    74114
    75115%.run : %$(EXEEXT) ${REPEAT}
    76         @rm -f .result.log
    77         @echo "------------------------------------------------------"
    78         @echo $<
    79         @${REPEAT} ${repeats} ./a.out | tee -a .result.log
    80         @${STATS} .result.log
    81         @echo "------------------------------------------------------"
    82         @rm -f a.out .result.log *.class
     116        rm -f .result.log
     117        echo "------------------------------------------------------"
     118        echo $<
     119        ${REPEAT} ${repeats} -- ./a.out\
     120                $(if ${$(subst -,_,$(basename $@))_DURATION},\
     121                        ${$(subst -,_,$(basename $@))_DURATION},\
     122                        ${$(firstword $(subst -, ,$(basename $@)))_DURATION}) | tee -a .result.log
     123        ${STATS} .result.log
     124        echo "------------------------------------------------------"
     125        rm -f a.out .result.log *.class
     126
     127#       ${REPEAT} ${repeats} -- /usr/bin/time -f "%Uu %Ss %Er %Mkb" ./a.out
    83128
    84129%.runquiet :
    85         @+make $(basename $@) CFLAGS="-w" __quiet=quiet
    86         @taskset -c 1 ./a.out
    87         @rm -f a.out
     130        +make $(basename $@) CFLAGS="-w" __quiet=quiet
     131        taskset -c 1 ./a.out
     132        rm -f a.out
    88133
    89134%.make :
    90         @printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@))
    91         @+/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1
     135        printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@))
     136        +/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1
    92137
    93138${REPEAT} :
    94         @+make -C ${abs_top_builddir}/tools repeat
     139        +make -C ${abs_top_builddir}/tools repeat
    95140
    96141## =========================================================================================================
     
    98143FIX_NEW_LINES = cat $@ | tr "\n" "\t" | sed -r 's/\t,/,/' | tr "\t" "\n" > $@
    99144
    100 jenkins$(EXEEXT):
     145cleancsv:
     146        rm -f compile.csv basic.csv ctxswitch.csv mutex.csv scheduling.csv
     147
     148jenkins$(EXEEXT): cleancsv
    101149@DOifskipcompile@
    102         @+make compile.csv
    103         @-+make compile.diff.csv
     150        +make compile.csv
     151        -+make compile.diff.csv
    104152@DOendif@
    105         @+make ctxswitch.csv
    106         @-+make ctxswitch.diff.csv
    107         @+make mutex.csv
    108         @-+make mutex.diff.csv
    109         @+make signal.csv
    110         @-+make signal.diff.csv
     153        +make ctxswitch.csv
     154        -+make ctxswitch.diff.csv
     155        +make mutex.csv
     156        -+make mutex.diff.csv
     157        +make scheduling.csv
     158        -+make scheduling.diff.csv
    111159@DOifskipcompile@
    112160        cat compile.csv
     
    117165        cat mutex.csv
    118166        -cat mutex.diff.csv
    119         cat signal.csv
    120         -cat signal.diff.csv
     167        cat scheduling.csv
     168        -cat scheduling.diff.csv
    121169
    122170compile.csv:
    123         @echo "array,attributes,empty,expression,io,monitor,operators,typeof" > $@
    124         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-array.make >> $@
    125         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-attributes.make >> $@
    126         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-empty.make >> $@
    127         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-expression.make >> $@
    128         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-io.make >> $@
    129         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-monitor.make >> $@
    130         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-operators.make >> $@
    131         @+make TIME_FORMAT='%e' PRINT_FORMAT='' compile-typeof.make >> $@
    132         @$(srcdir)/fixcsv.sh $@
     171        echo "building $@"
     172        echo "array,attributes,empty,expression,io,monitor,operators,typeof" > $@
     173        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-array.make >> $@
     174        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-attributes.make >> $@
     175        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-empty.make >> $@
     176        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-expression.make >> $@
     177        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-io.make >> $@
     178        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-monitor.make >> $@
     179        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-operators.make >> $@
     180        +make TIME_FORMAT='%e' PRINT_FORMAT='' compile-typeof.make >> $@
     181        $(srcdir)/fixcsv.sh $@
    133182
    134183ctxswitch.csv:
    135         @echo "generator,coroutine,thread" > $@
    136         @+make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
    137         @+make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
    138         @+make ctxswitch-cfa_thread.runquiet >> $@
    139         @$(srcdir)/fixcsv.sh $@
     184        echo "building $@"
     185        echo "generator,coroutine,thread" > $@
     186        +make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     187        +make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
     188        +make ctxswitch-cfa_thread.runquiet >> $@
     189        $(srcdir)/fixcsv.sh $@
    140190
    141191mutex.csv:
    142         @echo "1-monitor,2-monitor" > $@
    143         @+make mutex-cfa1.runquiet >> $@ && echo -n ',' >> $@
    144         @+make mutex-cfa2.runquiet >> $@
    145         @$(srcdir)/fixcsv.sh $@
    146 
    147 signal.csv:
    148         @echo "signal-1,signal-2,waitfor-1,waitfor-2" > $@
    149         @+make signal-cfa1.runquiet >> $@ && echo -n ',' >> $@
    150         @+make signal-cfa2.runquiet >> $@ && echo -n ',' >> $@
    151         @+make waitfor-cfa1.runquiet >> $@ && echo -n ',' >> $@
    152         @+make waitfor-cfa2.runquiet >> $@
    153         @$(srcdir)/fixcsv.sh $@
     192        echo "building $@"
     193        echo "1-monitor,2-monitor" > $@
     194        +make mutex-cfa1.runquiet >> $@ && echo -n ',' >> $@
     195        +make mutex-cfa2.runquiet >> $@
     196        $(srcdir)/fixcsv.sh $@
     197
     198scheduling.csv:
     199        echo "building $@"
     200        echo "schedint-1,schedint-2,schedext-1,schedext-2" > $@
     201        +make schedint-cfa1.runquiet >> $@ && echo -n ',' >> $@
     202        +make schedint-cfa2.runquiet >> $@ && echo -n ',' >> $@
     203        +make schedext-cfa1.runquiet >> $@ && echo -n ',' >> $@
     204        +make schedext-cfa2.runquiet >> $@
     205        $(srcdir)/fixcsv.sh $@
    154206
    155207%.diff.csv: %.csv
    156         @test -e $(srcdir)/baselines/$(arch)/$< || (echo "Error : Missing baseline for ${<}" && false)
    157         @$(srcdir)/baselines/calc.py $(srcdir)/baselines/$(arch)/$(<) $(<) > $@
    158 
    159 
    160 ## =========================================================================================================
    161 loop$(EXEEXT):
    162         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=5000000000 $(srcdir)/loop.c
    163 
    164 function$(EXEEXT):
    165         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=5000000000 $(srcdir)/function.c
    166 
    167 fetch_add$(EXEEXT):
    168         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
    169 
    170 ttst_lock$(EXEEXT):
    171         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/ttst_lock.c
    172 
    173 tls-fetch_add$(EXEEXT):
    174         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
    175 
    176 ## =========================================================================================================
    177 CTXSWITCH_DEPEND  =                 \
    178         loop.run                                \
    179         function.run                    \
    180         fetch_add.run                   \
    181         ttst_lock.run                   \
    182         tls-fetch_add.run                       \
    183         ctxswitch-pthread.run           \
     208        test -e $(srcdir)/baselines/$(arch)/$< || (echo "Error : Missing baseline for ${<}" && false)
     209        $(srcdir)/baselines/calc.py $(srcdir)/baselines/$(arch)/$(<) $(<) > $@
     210
     211## =========================================================================================================
     212
     213BASIC_DEPEND  =                                 \
     214        basic-loop.run                          \
     215        basic-function.run                      \
     216        basic-fetch_add.run                     \
     217        basic-ttst_lock.run                     \
     218        basic-tls-fetch_add.run
     219
     220basic-loop$(EXEEXT):
     221        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/loop.c
     222
     223basic-function$(EXEEXT):
     224        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/function.c
     225
     226basic-fetch_add$(EXEEXT):
     227        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/fetch_add.c
     228
     229basic-ttst_lock$(EXEEXT):
     230        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/ttst_lock.c
     231
     232basic-tls-fetch_add$(EXEEXT):
     233        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/tls_fetch_add.c
     234
     235basic$(EXEEXT): $(BASIC_DEPEND)
     236
     237## =========================================================================================================
     238
     239CTXSWITCH_DEPEND  =                     \
    184240        ctxswitch-cfa_generator.run     \
    185241        ctxswitch-cfa_coroutine.run     \
     
    188244        ctxswitch-upp_coroutine.run     \
    189245        ctxswitch-upp_thread.run        \
    190         ctxswitch-goroutine.run         \
    191         ctxswitch-java_thread.run
    192 
     246        ctxswitch-python_coroutine.run  \
     247        ctxswitch-nodejs_coroutine.run  \
     248        ctxswitch-nodejs_await.run      \
     249        ctxswitch-goroutine_thread.run  \
     250        ctxswitch-rust_thread.run       \
     251        ctxswitch-nodejs_coroutine.run  \
     252        ctxswitch-java_thread.run       \
     253        ctxswitch-pthread.run
    193254
    194255if WITH_LIBFIBRE
    195 CTXSWITCH_DEPEND  +=           \
    196         ctxswitch-kos_fibre.run  \
     256CTXSWITCH_DEPEND  +=                    \
     257        ctxswitch-kos_fibre.run         \
    197258        ctxswitch-kos_fibre2.run
    198 
    199259
    200260ctxswitch-kos_fibre$(EXEEXT):
     
    207267ctxswitch$(EXEEXT): $(CTXSWITCH_DEPEND)
    208268
    209 ctxswitch-pthread$(EXEEXT):
    210         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c
    211 
    212269ctxswitch-cfa_generator$(EXEEXT):
    213         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_gen.cfa
     270        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_gen.cfa
    214271
    215272ctxswitch-cfa_coroutine$(EXEEXT):
    216         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_cor.cfa
     273        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_cor.cfa
    217274
    218275ctxswitch-cfa_thread$(EXEEXT):
    219         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd.cfa
     276        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_thrd.cfa
    220277
    221278ctxswitch-cfa_thread2$(EXEEXT):
    222         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd2.cfa
     279        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_thrd2.cfa
    223280
    224281ctxswitch-upp_coroutine$(EXEEXT):
    225         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_cor.cc
     282        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/ctxswitch/upp_cor.cc
    226283
    227284ctxswitch-upp_thread$(EXEEXT):
    228         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_thrd.cc
    229 
    230 ctxswitch-goroutine$(EXEEXT):
     285        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/ctxswitch/upp_thrd.cc
     286
     287ctxswitch-python_coroutine$(EXEEXT):
     288        $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     289        echo "python3.7 $(srcdir)/ctxswitch/python_cor.py" >> a.out
     290        chmod a+x a.out
     291
     292ctxswitch-nodejs_coroutine$(EXEEXT):
     293        $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     294        echo "nodejs $(srcdir)/ctxswitch/node_cor.js" >> a.out
     295        chmod a+x a.out
     296
     297ctxswitch-nodejs_await$(EXEEXT):
     298        $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     299        echo "nodejs $(srcdir)/ctxswitch/node_await.js" >> a.out
     300        chmod a+x a.out
     301
     302ctxswitch-goroutine_thread$(EXEEXT):
    231303        $(BENCH_V_GOC)go build -o a.out $(srcdir)/ctxswitch/goroutine.go
     304
     305ctxswitch-rust_thread$(EXEEXT):
     306        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/ctxswitch/rust_thrd.rs
    232307
    233308ctxswitch-java_thread$(EXEEXT):
    234309        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/ctxswitch/JavaThread.java
    235         @echo "#!/bin/sh" > a.out
    236         @echo "java JavaThread" >> a.out
    237         @chmod a+x a.out
    238 
    239 ## =========================================================================================================
    240 mutex$(EXEEXT) :\
    241         loop.run                        \
    242         function.run            \
    243         fetch_add.run           \
    244         mutex-pthread_lock.run  \
    245         mutex-upp.run           \
     310        echo "#!/bin/sh" > a.out
     311        echo "java JavaThread" >> a.out
     312        chmod a+x a.out
     313
     314ctxswitch-pthread$(EXEEXT):
     315        $(BENCH_V_CC)$(COMPILE) $(srcdir)/ctxswitch/pthreads.c
     316
     317## =========================================================================================================
     318
     319mutex$(EXEEXT) :                \
    246320        mutex-cfa1.run          \
    247321        mutex-cfa2.run          \
    248322        mutex-cfa4.run          \
    249         mutex-java_thread.run
    250 
    251 mutex-pthread_lock$(EXEEXT):
    252         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/mutex/pthreads.c
     323        mutex-upp.run           \
     324        mutex-go.run            \
     325        mutex-rust.run          \
     326        mutex-java.run          \
     327        mutex-pthread.run
     328
     329mutex-pthread$(EXEEXT):
     330        $(BENCH_V_CC)$(COMPILE) $(srcdir)/mutex/pthreads.c
     331
     332mutex-cfa1$(EXEEXT):
     333        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/mutex/cfa1.cfa
     334
     335mutex-cfa2$(EXEEXT):
     336        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/mutex/cfa2.cfa
     337
     338mutex-cfa4$(EXEEXT):
     339        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/mutex/cfa4.cfa
    253340
    254341mutex-upp$(EXEEXT):
    255         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/mutex/upp.cc
    256 
    257 mutex-cfa1$(EXEEXT):
    258         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=5000000  $(srcdir)/mutex/cfa1.cfa
    259 
    260 mutex-cfa2$(EXEEXT):
    261         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=5000000  $(srcdir)/mutex/cfa2.cfa
    262 
    263 mutex-cfa4$(EXEEXT):
    264         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=5000000  $(srcdir)/mutex/cfa4.cfa
    265 
    266 mutex-java_thread$(EXEEXT):
     342        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/mutex/upp.cc
     343
     344mutex-go$(EXEEXT):
     345        $(BENCH_V_GOC)go build -o a.out $(srcdir)/mutex/goroutine.go
     346
     347mutex-rust$(EXEEXT):
     348        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/mutex/rust.rs
     349
     350mutex-java$(EXEEXT):
    267351        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/mutex/JavaThread.java
    268         @echo "#!/bin/sh" > a.out
    269         @echo "java JavaThread" >> a.out
    270         @chmod a+x a.out
    271 
    272 ## =========================================================================================================
    273 signal$(EXEEXT) :\
    274         signal-pthread_cond.run \
    275         signal-upp.run          \
    276         signal-cfa1.run         \
    277         signal-cfa2.run         \
    278         signal-cfa4.run         \
    279         signal-java_thread.run
    280 
    281 signal-pthread_cond$(EXEEXT):
    282         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=500000  $(srcdir)/schedint/pthreads.c
    283 
    284 signal-upp$(EXEEXT):
    285         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=5000000 $(srcdir)/schedint/upp.cc
    286 
    287 signal-cfa1$(EXEEXT):
    288         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedint/cfa1.cfa
    289 
    290 signal-cfa2$(EXEEXT):
    291         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedint/cfa2.cfa
    292 
    293 signal-cfa4$(EXEEXT):
    294         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedint/cfa4.cfa
    295 
    296 signal-java_thread$(EXEEXT):
     352        echo "#!/bin/sh" > a.out
     353        echo "java JavaThread" >> a.out
     354        chmod a+x a.out
     355
     356## =========================================================================================================
     357
     358schedint$(EXEEXT) :             \
     359        schedint-cfa1.run       \
     360        schedint-cfa2.run       \
     361        schedint-cfa4.run       \
     362        schedint-upp.run        \
     363        schedint-rust.run       \
     364        schedint-java.run       \
     365        schedint-pthread.run
     366
     367schedint-cfa1$(EXEEXT):
     368        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedint/cfa1.cfa
     369
     370schedint-cfa2$(EXEEXT):
     371        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedint/cfa2.cfa
     372
     373schedint-cfa4$(EXEEXT):
     374        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedint/cfa4.cfa
     375
     376schedint-upp$(EXEEXT):
     377        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/schedint/upp.cc
     378
     379schedint-rust$(EXEEXT):
     380        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/schedint/rust.rs
     381
     382schedint-java$(EXEEXT):
    297383        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/schedint/JavaThread.java
    298         @echo "#!/bin/sh" > a.out
    299         @echo "java JavaThread" >> a.out
    300         @chmod a+x a.out
    301 
    302 
    303 ## =========================================================================================================
    304 waitfor$(EXEEXT) :\
    305         waitfor-upp.run         \
    306         waitfor-cfa1.run                \
    307         waitfor-cfa2.run                \
    308         waitfor-cfa4.run
    309 
    310 waitfor-upp$(EXEEXT):
    311         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=5000000 $(srcdir)/schedext/upp.cc
    312 
    313 waitfor-cfa1$(EXEEXT):
    314         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedext/cfa1.cfa
    315 
    316 waitfor-cfa2$(EXEEXT):
    317         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedext/cfa2.cfa
    318 
    319 waitfor-cfa4$(EXEEXT):
    320         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedext/cfa4.cfa
    321 
    322 ## =========================================================================================================
    323 creation$(EXEEXT) :\
    324         creation-pthread.run                    \
     384        echo "#!/bin/sh" > a.out
     385        echo "java JavaThread" >> a.out
     386        chmod a+x a.out
     387
     388schedint-pthread$(EXEEXT):
     389        $(BENCH_V_CC)$(COMPILE) $(srcdir)/schedint/pthreads.c
     390
     391## =========================================================================================================
     392
     393schedext$(EXEEXT) :             \
     394        schedext-cfa1.run       \
     395        schedext-cfa2.run       \
     396        schedext-cfa4.run       \
     397        schedext-upp.run        \
     398        schedext-goroutine.run
     399
     400schedext-cfa1$(EXEEXT):
     401        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedext/cfa1.cfa
     402
     403schedext-cfa2$(EXEEXT):
     404        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedext/cfa2.cfa
     405
     406schedext-cfa4$(EXEEXT):
     407        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedext/cfa4.cfa
     408
     409schedext-upp$(EXEEXT):
     410        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/schedext/upp.cc
     411
     412schedext-goroutine$(EXEEXT):
     413        $(BENCH_V_GOC)go build -o a.out $(srcdir)/schedext/goroutine.go
     414
     415
     416## =========================================================================================================
     417
     418creation$(EXEEXT) :                             \
     419        creation-cfa_generator.run              \
    325420        creation-cfa_coroutine.run              \
    326421        creation-cfa_coroutine_eager.run        \
     
    328423        creation-upp_coroutine.run              \
    329424        creation-upp_thread.run                 \
    330         creation-goroutine.run                  \
    331         creation-java_thread.run
     425        creation-python_coroutine.run           \
     426        creation-nodejs_coroutine.run           \
     427        creation-goroutine_thread.run           \
     428        creation-rust_thread.run                \
     429        creation-java_thread.run                \
     430        creation-pthread.run
     431
     432creation-cfa_generator$(EXEEXT):
     433        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_gen.cfa
    332434
    333435creation-cfa_coroutine$(EXEEXT):
    334         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=10000000 $(srcdir)/creation/cfa_cor.cfa
     436        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_cor.cfa
    335437
    336438creation-cfa_coroutine_eager$(EXEEXT):
    337         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=10000000 $(srcdir)/creation/cfa_cor.cfa  -DEAGER
     439        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_cor.cfa  -DEAGER
    338440
    339441creation-cfa_thread$(EXEEXT):
    340         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=10000000 $(srcdir)/creation/cfa_thrd.cfa
     442        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_thrd.cfa
    341443
    342444creation-upp_coroutine$(EXEEXT):
    343         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/creation/upp_cor.cc
     445        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/creation/upp_cor.cc
    344446
    345447creation-upp_thread$(EXEEXT):
    346         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/creation/upp_thrd.cc
    347 
    348 creation-pthread$(EXEEXT):
    349         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=250000   $(srcdir)/creation/pthreads.c
    350 
    351 creation-goroutine$(EXEEXT):
     448        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/creation/upp_thrd.cc
     449
     450creation-python_coroutine$(EXEEXT):
     451        $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     452        echo "python3.7 $(srcdir)/creation/python_cor.py" >> a.out
     453        chmod a+x a.out
     454
     455creation-nodejs_coroutine$(EXEEXT):
     456        $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     457        echo "nodejs $(srcdir)/creation/node_cor.js" >> a.out
     458        chmod a+x a.out
     459
     460creation-goroutine_thread$(EXEEXT):
    352461        $(BENCH_V_GOC)go build -o a.out $(srcdir)/creation/goroutine.go
     462
     463creation-rust_thread$(EXEEXT):
     464        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/creation/rust_thrd.rs
    353465
    354466creation-java_thread$(EXEEXT):
    355467        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/creation/JavaThread.java
    356         @echo "#!/bin/sh" > a.out
    357         @echo "java JavaThread" >> a.out
    358         @chmod a+x a.out
    359 
    360 ## =========================================================================================================
    361 
    362 compile$(EXEEXT) :\
     468        echo "#!/bin/sh" > a.out
     469        echo "java JavaThread" >> a.out
     470        chmod a+x a.out
     471
     472creation-pthread$(EXEEXT):
     473        $(BENCH_V_CC)$(COMPILE) $(srcdir)/creation/pthreads.c
     474
     475## =========================================================================================================
     476
     477compile$(EXEEXT) :              \
    363478        compile-array.make      \
    364479        compile-attributes.make \
     
    370485        compile-typeof.make
    371486
    372 
    373487testdir = $(top_srcdir)/tests
    374488
    375489compile-array$(EXEEXT):
    376         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/array.cfa
     490        $(CFACOMPILE) -fsyntax-only -w $(testdir)/array.cfa
    377491
    378492compile-attributes$(EXEEXT):
    379         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/attributes.cfa
     493        $(CFACOMPILE) -fsyntax-only -w $(testdir)/attributes.cfa
    380494
    381495compile-empty$(EXEEXT):
    382         @$(CFACOMPILE) -fsyntax-only -w $(srcdir)/compile/empty.cfa
     496        $(CFACOMPILE) -fsyntax-only -w $(srcdir)/compile/empty.cfa
    383497
    384498compile-expression$(EXEEXT):
    385         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/expression.cfa
     499        $(CFACOMPILE) -fsyntax-only -w $(testdir)/expression.cfa
    386500
    387501compile-io$(EXEEXT):
    388         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/io1.cfa
     502        $(CFACOMPILE) -fsyntax-only -w $(testdir)/io1.cfa
    389503
    390504compile-monitor$(EXEEXT):
    391         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/monitor.cfa
     505        $(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/monitor.cfa
    392506
    393507compile-operators$(EXEEXT):
    394         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/operators.cfa
     508        $(CFACOMPILE) -fsyntax-only -w $(testdir)/operators.cfa
    395509
    396510compile-thread$(EXEEXT):
    397         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/thread.cfa
     511        $(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/thread.cfa
    398512
    399513compile-typeof$(EXEEXT):
    400         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa
     514        $(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa
     515
     516## =========================================================================================================
     517
     518size$(EXEEXT) : size-cfa.runquiet
     519
     520size-cfa$(EXEEXT):
     521        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/size/size.cfa
  • benchmark/Makefile.in

    r9fb8f01 r3d5701e  
    9393EXTRA_PROGRAMS = dummy$(EXEEXT)
    9494@WITH_LIBFIBRE_TRUE@am__append_1 = \
    95 @WITH_LIBFIBRE_TRUE@    ctxswitch-kos_fibre.run  \
     95@WITH_LIBFIBRE_TRUE@    ctxswitch-kos_fibre.run         \
    9696@WITH_LIBFIBRE_TRUE@    ctxswitch-kos_fibre2.run
    9797
     
    214214CCDEPMODE = @CCDEPMODE@
    215215CFACC = @CFACC@
     216CFACC_INSTALL = @CFACC_INSTALL@
    216217CFACPP = @CFACPP@
    217218CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    244245FGREP = @FGREP@
    245246GREP = @GREP@
     247HAS_DISTCC = @HAS_DISTCC@
    246248HOST_FLAGS = @HOST_FLAGS@
    247249INSTALL = @INSTALL@
     
    350352LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
    351353        $(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \
    352         $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \
    353         $(AM_CFLAGS) $(CFLAGS)
     354        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(AM_CFLAGS) $(CFAFLAGS) $(CFLAGS)
    354355
    355356AM_V_CFA = $(am__v_CFA_@AM_V@)
     
    357358am__v_CFA_0 = @echo "  CFA     " $@;
    358359am__v_CFA_1 =
    359 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
    360 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
    361 am__v_JAVAC_0 = @echo "  JAVAC   " $@;
    362 am__v_JAVAC_1 =
    363 AM_V_GOC = $(am__v_GOC_@AM_V@)
    364 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
    365 am__v_GOC_0 = @echo "  GOC     " $@;
    366 am__v_GOC_1 =
    367360UPPCC = u++
    368361UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
     
    371364am__v_UPP_0 = @echo "  UPP     " $@;
    372365am__v_UPP_1 =
     366AM_V_GOC = $(am__v_GOC_@AM_V@)
     367am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
     368am__v_GOC_0 = @echo "  GOC     " $@;
     369am__v_GOC_1 =
     370AM_V_PY = $(am__v_PY_@AM_V@)
     371am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
     372am__v_PY_0 = @echo "  PYTHON  " $@;
     373am__v_PY_1 =
     374AM_V_RUST = $(am__v_RUST_@AM_V@)
     375am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
     376am__v_RUST_0 = @echo "  RUST    " $@;
     377am__v_RUST_1 =
     378AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
     379am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
     380am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     381am__v_NODEJS_1 =
     382AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     383am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
     384am__v_JAVAC_0 = @echo "  JAVAC   " $@;
     385am__v_JAVAC_1 =
    373386
    374387# applies to both programs
    375388AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror
    376 AM_CFAFLAGS = -quiet -nodebug -in-tree
     389AM_CFAFLAGS = -quiet -nodebug
    377390AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
    378391BENCH_V_CC = $(__bench_v_CC_$(__quiet))
    379392BENCH_V_CFA = $(__bench_v_CFA_$(__quiet))
    380393BENCH_V_CXX = $(__bench_v_CXX_$(__quiet))
     394BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    381395BENCH_V_GOC = $(__bench_v_GOC_$(__quiet))
     396BENCH_V_PY = $(__bench_v_PY_$(__quiet))
     397BENCH_V_RUSTC = $(__bench_v_RUSTC_$(__quiet))
     398BENCH_V_NODEJS = $(__bench_v_NODEJS_$(__quiet))
    382399BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    383 BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    384400__quiet = verbose
    385401__bench_v_CC_quiet = @
    386402__bench_v_CFA_quiet = @
    387403__bench_v_CXX_quiet = @
     404__bench_v_UPP_quiet = @
    388405__bench_v_GOC_quiet = @
     406__bench_v_RUSTC_quiet = @
    389407__bench_v_JAVAC_quiet = @
    390 __bench_v_UPP_quiet = @
    391408__bench_v_CC_verbose = $(AM_V_CC)
    392409__bench_v_CFA_verbose = $(AM_V_CFA)
    393410__bench_v_CXX_verbose = $(AM_V_CXX)
     411__bench_v_UPP_verbose = $(AM_V_UPP)
    394412__bench_v_GOC_verbose = $(AM_V_GOC)
     413__bench_v_PY_verbose = $(AM_V_PY)
     414__bench_v_RUSTC_verbose = $(AM_V_RUST)
     415__bench_v_NODEJS_verbose = $(AM_V_NODEJS)
    395416__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    396 __bench_v_UPP_verbose = $(AM_V_UPP)
    397417TOOLSDIR = ${abs_top_builddir}/tools/
    398418REPEAT = ${abs_top_builddir}/tools/repeat
    399419STATS = ${abs_top_srcdir}/tools/stat.py
    400420# NEED AT LEAST 4 DATA VALUES FOR BENCHMARKS BECAUSE THE MAX AND MIN VALUES ARE REMOVED
    401 repeats = 5 # 31 for benchmarks
     421repeats = 13 # 31 for benchmarks
    402422arch = x64
    403423skipcompile = no
     
    405425PRINT_FORMAT = %20s: #Comments needed for spacing
    406426dummy_SOURCES = dummyC.c dummyCXX.cpp
     427basic_loop_DURATION = 15000000000
     428basic_function_DURATION = 10000000000
     429basic_tls_fetch_add_DURATION = 10000000000
     430basic_DURATION = 250000000
     431ctxswitch_pthread_DURATION = 25000000
     432ctxswitch_rust_thread_DURATION = $(ctxswitch_pthread_DURATION)
     433ctxswitch_cfa_generator_DURATION = 5000000000
     434ctxswitch_nodejs_await_DURATION = 5000000
     435ctxswitch_DURATION = 100000000
     436
     437#mutex_java_DURATION = 10000000
     438mutex_DURATION = 50000000
     439schedint_pthread_DURATION = 1000000
     440schedint_java_DURATION = $(schedint_pthread_DURATION)
     441schedint_rust_DURATION = $(schedint_pthread_DURATION)
     442schedint_DURATION = 10000000
     443schedext_DURATION = 10000000
     444creation_pthread_DURATION = 250000
     445creation_rust_thread_DURATION = ${creation_pthread_DURATION}
     446creation_java_thread_DURATION = ${creation_pthread_DURATION}
     447creation_cfa_coroutine_DURATION = 100000000
     448creation_cfa_coroutine_eager_DURATION = 10000000
     449creation_upp_coroutine_DURATION = ${creation_cfa_coroutine_eager_DURATION}
     450creation_cfa_thread_DURATION = 10000000
     451creation_upp_thread_DURATION = ${creation_cfa_thread_DURATION}
     452creation_DURATION = 10000000
    407453FIX_NEW_LINES = cat $@ | tr "\n" "\t" | sed -r 's/\t,/,/' | tr "\t" "\n" > $@
    408 CTXSWITCH_DEPEND = loop.run function.run fetch_add.run ttst_lock.run \
    409         tls-fetch_add.run ctxswitch-pthread.run \
    410         ctxswitch-cfa_generator.run ctxswitch-cfa_coroutine.run \
    411         ctxswitch-cfa_thread.run ctxswitch-cfa_thread2.run \
    412         ctxswitch-upp_coroutine.run ctxswitch-upp_thread.run \
    413         ctxswitch-goroutine.run ctxswitch-java_thread.run \
    414         $(am__append_1)
     454BASIC_DEPEND = \
     455        basic-loop.run                          \
     456        basic-function.run                      \
     457        basic-fetch_add.run                     \
     458        basic-ttst_lock.run                     \
     459        basic-tls-fetch_add.run
     460
     461CTXSWITCH_DEPEND = ctxswitch-cfa_generator.run \
     462        ctxswitch-cfa_coroutine.run ctxswitch-cfa_thread.run \
     463        ctxswitch-cfa_thread2.run ctxswitch-upp_coroutine.run \
     464        ctxswitch-upp_thread.run ctxswitch-python_coroutine.run \
     465        ctxswitch-nodejs_coroutine.run ctxswitch-nodejs_await.run \
     466        ctxswitch-goroutine_thread.run ctxswitch-rust_thread.run \
     467        ctxswitch-nodejs_coroutine.run ctxswitch-java_thread.run \
     468        ctxswitch-pthread.run $(am__append_1)
    415469testdir = $(top_srcdir)/tests
    416470all: all-am
     
    731785
    732786dummyC.c:
    733         @echo "int main() { return 0; }" > ${@}
     787        echo "int main() { return 0; }" > ${@}
    734788
    735789dummyCXX.cpp:
    736         @echo "int main() { return 0; }" > ${@}
    737 
     790        echo "int main() { return 0; }" > ${@}
     791
     792.SILENT:                # do not print recipe
    738793.NOTPARALLEL:
    739 .PHONY: compile.csv ctxswitch.csv mutex.csv signal.csv
    740 
    741 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT)
     794.PHONY: jenkins cleancsv
     795
     796all : basic$(EXEEXT) ctxswitch$(EXEEXT) mutex$(EXEEXT) schedint$(EXEEXT) schedext$(EXEEXT) creation$(EXEEXT)
    742797
    743798%.run : %$(EXEEXT) ${REPEAT}
    744         @rm -f .result.log
    745         @echo "------------------------------------------------------"
    746         @echo $<
    747         @${REPEAT} ${repeats} ./a.out | tee -a .result.log
    748         @${STATS} .result.log
    749         @echo "------------------------------------------------------"
    750         @rm -f a.out .result.log *.class
     799        rm -f .result.log
     800        echo "------------------------------------------------------"
     801        echo $<
     802        ${REPEAT} ${repeats} -- ./a.out\
     803                $(if ${$(subst -,_,$(basename $@))_DURATION},\
     804                        ${$(subst -,_,$(basename $@))_DURATION},\
     805                        ${$(firstword $(subst -, ,$(basename $@)))_DURATION}) | tee -a .result.log
     806        ${STATS} .result.log
     807        echo "------------------------------------------------------"
     808        rm -f a.out .result.log *.class
     809
     810#       ${REPEAT} ${repeats} -- /usr/bin/time -f "%Uu %Ss %Er %Mkb" ./a.out
    751811
    752812%.runquiet :
    753         @+make $(basename $@) CFLAGS="-w" __quiet=quiet
    754         @taskset -c 1 ./a.out
    755         @rm -f a.out
     813        +make $(basename $@) CFLAGS="-w" __quiet=quiet
     814        taskset -c 1 ./a.out
     815        rm -f a.out
    756816
    757817%.make :
    758         @printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@))
    759         @+/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1
     818        printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@))
     819        +/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1
    760820
    761821${REPEAT} :
    762         @+make -C ${abs_top_builddir}/tools repeat
    763 
    764 jenkins$(EXEEXT):
     822        +make -C ${abs_top_builddir}/tools repeat
     823
     824cleancsv:
     825        rm -f compile.csv basic.csv ctxswitch.csv mutex.csv scheduling.csv
     826
     827jenkins$(EXEEXT): cleancsv
    765828@DOifskipcompile@
    766         @+make compile.csv
    767         @-+make compile.diff.csv
     829        +make compile.csv
     830        -+make compile.diff.csv
    768831@DOendif@
    769         @+make ctxswitch.csv
    770         @-+make ctxswitch.diff.csv
    771         @+make mutex.csv
    772         @-+make mutex.diff.csv
    773         @+make signal.csv
    774         @-+make signal.diff.csv
     832        +make ctxswitch.csv
     833        -+make ctxswitch.diff.csv
     834        +make mutex.csv
     835        -+make mutex.diff.csv
     836        +make scheduling.csv
     837        -+make scheduling.diff.csv
    775838@DOifskipcompile@
    776839        cat compile.csv
     
    781844        cat mutex.csv
    782845        -cat mutex.diff.csv
    783         cat signal.csv
    784         -cat signal.diff.csv
     846        cat scheduling.csv
     847        -cat scheduling.diff.csv
    785848
    786849compile.csv:
    787         @echo "array,attributes,empty,expression,io,monitor,operators,typeof" > $@
    788         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-array.make >> $@
    789         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-attributes.make >> $@
    790         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-empty.make >> $@
    791         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-expression.make >> $@
    792         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-io.make >> $@
    793         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-monitor.make >> $@
    794         @+make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-operators.make >> $@
    795         @+make TIME_FORMAT='%e' PRINT_FORMAT='' compile-typeof.make >> $@
    796         @$(srcdir)/fixcsv.sh $@
     850        echo "building $@"
     851        echo "array,attributes,empty,expression,io,monitor,operators,typeof" > $@
     852        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-array.make >> $@
     853        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-attributes.make >> $@
     854        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-empty.make >> $@
     855        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-expression.make >> $@
     856        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-io.make >> $@
     857        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-monitor.make >> $@
     858        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-operators.make >> $@
     859        +make TIME_FORMAT='%e' PRINT_FORMAT='' compile-typeof.make >> $@
     860        $(srcdir)/fixcsv.sh $@
    797861
    798862ctxswitch.csv:
    799         @echo "generator,coroutine,thread" > $@
    800         @+make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
    801         @+make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
    802         @+make ctxswitch-cfa_thread.runquiet >> $@
    803         @$(srcdir)/fixcsv.sh $@
     863        echo "building $@"
     864        echo "generator,coroutine,thread" > $@
     865        +make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     866        +make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
     867        +make ctxswitch-cfa_thread.runquiet >> $@
     868        $(srcdir)/fixcsv.sh $@
    804869
    805870mutex.csv:
    806         @echo "1-monitor,2-monitor" > $@
    807         @+make mutex-cfa1.runquiet >> $@ && echo -n ',' >> $@
    808         @+make mutex-cfa2.runquiet >> $@
    809         @$(srcdir)/fixcsv.sh $@
    810 
    811 signal.csv:
    812         @echo "signal-1,signal-2,waitfor-1,waitfor-2" > $@
    813         @+make signal-cfa1.runquiet >> $@ && echo -n ',' >> $@
    814         @+make signal-cfa2.runquiet >> $@ && echo -n ',' >> $@
    815         @+make waitfor-cfa1.runquiet >> $@ && echo -n ',' >> $@
    816         @+make waitfor-cfa2.runquiet >> $@
    817         @$(srcdir)/fixcsv.sh $@
     871        echo "building $@"
     872        echo "1-monitor,2-monitor" > $@
     873        +make mutex-cfa1.runquiet >> $@ && echo -n ',' >> $@
     874        +make mutex-cfa2.runquiet >> $@
     875        $(srcdir)/fixcsv.sh $@
     876
     877scheduling.csv:
     878        echo "building $@"
     879        echo "schedint-1,schedint-2,schedext-1,schedext-2" > $@
     880        +make schedint-cfa1.runquiet >> $@ && echo -n ',' >> $@
     881        +make schedint-cfa2.runquiet >> $@ && echo -n ',' >> $@
     882        +make schedext-cfa1.runquiet >> $@ && echo -n ',' >> $@
     883        +make schedext-cfa2.runquiet >> $@
     884        $(srcdir)/fixcsv.sh $@
    818885
    819886%.diff.csv: %.csv
    820         @test -e $(srcdir)/baselines/$(arch)/$< || (echo "Error : Missing baseline for ${<}" && false)
    821         @$(srcdir)/baselines/calc.py $(srcdir)/baselines/$(arch)/$(<) $(<) > $@
    822 
    823 loop$(EXEEXT):
    824         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=5000000000 $(srcdir)/loop.c
    825 
    826 function$(EXEEXT):
    827         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=5000000000 $(srcdir)/function.c
    828 
    829 fetch_add$(EXEEXT):
    830         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
    831 
    832 ttst_lock$(EXEEXT):
    833         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/ttst_lock.c
    834 
    835 tls-fetch_add$(EXEEXT):
    836         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
     887        test -e $(srcdir)/baselines/$(arch)/$< || (echo "Error : Missing baseline for ${<}" && false)
     888        $(srcdir)/baselines/calc.py $(srcdir)/baselines/$(arch)/$(<) $(<) > $@
     889
     890basic-loop$(EXEEXT):
     891        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/loop.c
     892
     893basic-function$(EXEEXT):
     894        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/function.c
     895
     896basic-fetch_add$(EXEEXT):
     897        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/fetch_add.c
     898
     899basic-ttst_lock$(EXEEXT):
     900        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/ttst_lock.c
     901
     902basic-tls-fetch_add$(EXEEXT):
     903        $(BENCH_V_CC)$(COMPILE) $(srcdir)/basic/tls_fetch_add.c
     904
     905basic$(EXEEXT): $(BASIC_DEPEND)
    837906
    838907@WITH_LIBFIBRE_TRUE@ctxswitch-kos_fibre$(EXEEXT):
     
    844913ctxswitch$(EXEEXT): $(CTXSWITCH_DEPEND)
    845914
    846 ctxswitch-pthread$(EXEEXT):
    847         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c
    848 
    849915ctxswitch-cfa_generator$(EXEEXT):
    850         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_gen.cfa
     916        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_gen.cfa
    851917
    852918ctxswitch-cfa_coroutine$(EXEEXT):
    853         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_cor.cfa
     919        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_cor.cfa
    854920
    855921ctxswitch-cfa_thread$(EXEEXT):
    856         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd.cfa
     922        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_thrd.cfa
    857923
    858924ctxswitch-cfa_thread2$(EXEEXT):
    859         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd2.cfa
     925        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/ctxswitch/cfa_thrd2.cfa
    860926
    861927ctxswitch-upp_coroutine$(EXEEXT):
    862         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_cor.cc
     928        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/ctxswitch/upp_cor.cc
    863929
    864930ctxswitch-upp_thread$(EXEEXT):
    865         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_thrd.cc
    866 
    867 ctxswitch-goroutine$(EXEEXT):
     931        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/ctxswitch/upp_thrd.cc
     932
     933ctxswitch-python_coroutine$(EXEEXT):
     934        $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     935        echo "python3.7 $(srcdir)/ctxswitch/python_cor.py" >> a.out
     936        chmod a+x a.out
     937
     938ctxswitch-nodejs_coroutine$(EXEEXT):
     939        $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     940        echo "nodejs $(srcdir)/ctxswitch/node_cor.js" >> a.out
     941        chmod a+x a.out
     942
     943ctxswitch-nodejs_await$(EXEEXT):
     944        $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     945        echo "nodejs $(srcdir)/ctxswitch/node_await.js" >> a.out
     946        chmod a+x a.out
     947
     948ctxswitch-goroutine_thread$(EXEEXT):
    868949        $(BENCH_V_GOC)go build -o a.out $(srcdir)/ctxswitch/goroutine.go
     950
     951ctxswitch-rust_thread$(EXEEXT):
     952        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/ctxswitch/rust_thrd.rs
    869953
    870954ctxswitch-java_thread$(EXEEXT):
    871955        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/ctxswitch/JavaThread.java
    872         @echo "#!/bin/sh" > a.out
    873         @echo "java JavaThread" >> a.out
    874         @chmod a+x a.out
    875 
    876 mutex$(EXEEXT) :\
    877         loop.run                        \
    878         function.run            \
    879         fetch_add.run           \
    880         mutex-pthread_lock.run  \
    881         mutex-upp.run           \
     956        echo "#!/bin/sh" > a.out
     957        echo "java JavaThread" >> a.out
     958        chmod a+x a.out
     959
     960ctxswitch-pthread$(EXEEXT):
     961        $(BENCH_V_CC)$(COMPILE) $(srcdir)/ctxswitch/pthreads.c
     962
     963mutex$(EXEEXT) :                \
    882964        mutex-cfa1.run          \
    883965        mutex-cfa2.run          \
    884966        mutex-cfa4.run          \
    885         mutex-java_thread.run
    886 
    887 mutex-pthread_lock$(EXEEXT):
    888         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/mutex/pthreads.c
     967        mutex-upp.run           \
     968        mutex-go.run            \
     969        mutex-rust.run          \
     970        mutex-java.run          \
     971        mutex-pthread.run
     972
     973mutex-pthread$(EXEEXT):
     974        $(BENCH_V_CC)$(COMPILE) $(srcdir)/mutex/pthreads.c
     975
     976mutex-cfa1$(EXEEXT):
     977        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/mutex/cfa1.cfa
     978
     979mutex-cfa2$(EXEEXT):
     980        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/mutex/cfa2.cfa
     981
     982mutex-cfa4$(EXEEXT):
     983        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/mutex/cfa4.cfa
    889984
    890985mutex-upp$(EXEEXT):
    891         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/mutex/upp.cc
    892 
    893 mutex-cfa1$(EXEEXT):
    894         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=5000000  $(srcdir)/mutex/cfa1.cfa
    895 
    896 mutex-cfa2$(EXEEXT):
    897         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=5000000  $(srcdir)/mutex/cfa2.cfa
    898 
    899 mutex-cfa4$(EXEEXT):
    900         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=5000000  $(srcdir)/mutex/cfa4.cfa
    901 
    902 mutex-java_thread$(EXEEXT):
     986        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/mutex/upp.cc
     987
     988mutex-go$(EXEEXT):
     989        $(BENCH_V_GOC)go build -o a.out $(srcdir)/mutex/goroutine.go
     990
     991mutex-rust$(EXEEXT):
     992        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/mutex/rust.rs
     993
     994mutex-java$(EXEEXT):
    903995        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/mutex/JavaThread.java
    904         @echo "#!/bin/sh" > a.out
    905         @echo "java JavaThread" >> a.out
    906         @chmod a+x a.out
    907 
    908 signal$(EXEEXT) :\
    909         signal-pthread_cond.run \
    910         signal-upp.run          \
    911         signal-cfa1.run         \
    912         signal-cfa2.run         \
    913         signal-cfa4.run         \
    914         signal-java_thread.run
    915 
    916 signal-pthread_cond$(EXEEXT):
    917         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=500000  $(srcdir)/schedint/pthreads.c
    918 
    919 signal-upp$(EXEEXT):
    920         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=5000000 $(srcdir)/schedint/upp.cc
    921 
    922 signal-cfa1$(EXEEXT):
    923         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedint/cfa1.cfa
    924 
    925 signal-cfa2$(EXEEXT):
    926         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedint/cfa2.cfa
    927 
    928 signal-cfa4$(EXEEXT):
    929         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedint/cfa4.cfa
    930 
    931 signal-java_thread$(EXEEXT):
     996        echo "#!/bin/sh" > a.out
     997        echo "java JavaThread" >> a.out
     998        chmod a+x a.out
     999
     1000schedint$(EXEEXT) :             \
     1001        schedint-cfa1.run       \
     1002        schedint-cfa2.run       \
     1003        schedint-cfa4.run       \
     1004        schedint-upp.run        \
     1005        schedint-rust.run       \
     1006        schedint-java.run       \
     1007        schedint-pthread.run
     1008
     1009schedint-cfa1$(EXEEXT):
     1010        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedint/cfa1.cfa
     1011
     1012schedint-cfa2$(EXEEXT):
     1013        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedint/cfa2.cfa
     1014
     1015schedint-cfa4$(EXEEXT):
     1016        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedint/cfa4.cfa
     1017
     1018schedint-upp$(EXEEXT):
     1019        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/schedint/upp.cc
     1020
     1021schedint-rust$(EXEEXT):
     1022        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/schedint/rust.rs
     1023
     1024schedint-java$(EXEEXT):
    9321025        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/schedint/JavaThread.java
    933         @echo "#!/bin/sh" > a.out
    934         @echo "java JavaThread" >> a.out
    935         @chmod a+x a.out
    936 
    937 waitfor$(EXEEXT) :\
    938         waitfor-upp.run         \
    939         waitfor-cfa1.run                \
    940         waitfor-cfa2.run                \
    941         waitfor-cfa4.run
    942 
    943 waitfor-upp$(EXEEXT):
    944         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=5000000 $(srcdir)/schedext/upp.cc
    945 
    946 waitfor-cfa1$(EXEEXT):
    947         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedext/cfa1.cfa
    948 
    949 waitfor-cfa2$(EXEEXT):
    950         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedext/cfa2.cfa
    951 
    952 waitfor-cfa4$(EXEEXT):
    953         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=500000  $(srcdir)/schedext/cfa4.cfa
    954 
    955 creation$(EXEEXT) :\
    956         creation-pthread.run                    \
     1026        echo "#!/bin/sh" > a.out
     1027        echo "java JavaThread" >> a.out
     1028        chmod a+x a.out
     1029
     1030schedint-pthread$(EXEEXT):
     1031        $(BENCH_V_CC)$(COMPILE) $(srcdir)/schedint/pthreads.c
     1032
     1033schedext$(EXEEXT) :             \
     1034        schedext-cfa1.run       \
     1035        schedext-cfa2.run       \
     1036        schedext-cfa4.run       \
     1037        schedext-upp.run        \
     1038        schedext-goroutine.run
     1039
     1040schedext-cfa1$(EXEEXT):
     1041        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedext/cfa1.cfa
     1042
     1043schedext-cfa2$(EXEEXT):
     1044        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedext/cfa2.cfa
     1045
     1046schedext-cfa4$(EXEEXT):
     1047        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/schedext/cfa4.cfa
     1048
     1049schedext-upp$(EXEEXT):
     1050        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/schedext/upp.cc
     1051
     1052schedext-goroutine$(EXEEXT):
     1053        $(BENCH_V_GOC)go build -o a.out $(srcdir)/schedext/goroutine.go
     1054
     1055creation$(EXEEXT) :                             \
     1056        creation-cfa_generator.run              \
    9571057        creation-cfa_coroutine.run              \
    9581058        creation-cfa_coroutine_eager.run        \
     
    9601060        creation-upp_coroutine.run              \
    9611061        creation-upp_thread.run                 \
    962         creation-goroutine.run                  \
    963         creation-java_thread.run
     1062        creation-python_coroutine.run           \
     1063        creation-nodejs_coroutine.run           \
     1064        creation-goroutine_thread.run           \
     1065        creation-rust_thread.run                \
     1066        creation-java_thread.run                \
     1067        creation-pthread.run
     1068
     1069creation-cfa_generator$(EXEEXT):
     1070        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_gen.cfa
    9641071
    9651072creation-cfa_coroutine$(EXEEXT):
    966         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=10000000 $(srcdir)/creation/cfa_cor.cfa
     1073        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_cor.cfa
    9671074
    9681075creation-cfa_coroutine_eager$(EXEEXT):
    969         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=10000000 $(srcdir)/creation/cfa_cor.cfa  -DEAGER
     1076        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_cor.cfa  -DEAGER
    9701077
    9711078creation-cfa_thread$(EXEEXT):
    972         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=10000000 $(srcdir)/creation/cfa_thrd.cfa
     1079        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/creation/cfa_thrd.cfa
    9731080
    9741081creation-upp_coroutine$(EXEEXT):
    975         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/creation/upp_cor.cc
     1082        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/creation/upp_cor.cc
    9761083
    9771084creation-upp_thread$(EXEEXT):
    978         $(BENCH_V_UPP)$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/creation/upp_thrd.cc
    979 
    980 creation-pthread$(EXEEXT):
    981         $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=250000   $(srcdir)/creation/pthreads.c
    982 
    983 creation-goroutine$(EXEEXT):
     1085        $(BENCH_V_UPP)$(UPPCOMPILE) $(srcdir)/creation/upp_thrd.cc
     1086
     1087creation-python_coroutine$(EXEEXT):
     1088        $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     1089        echo "python3.7 $(srcdir)/creation/python_cor.py" >> a.out
     1090        chmod a+x a.out
     1091
     1092creation-nodejs_coroutine$(EXEEXT):
     1093        $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     1094        echo "nodejs $(srcdir)/creation/node_cor.js" >> a.out
     1095        chmod a+x a.out
     1096
     1097creation-goroutine_thread$(EXEEXT):
    9841098        $(BENCH_V_GOC)go build -o a.out $(srcdir)/creation/goroutine.go
     1099
     1100creation-rust_thread$(EXEEXT):
     1101        $(BENCH_V_RUSTC)rustc -C opt-level=3 -o a.out $(srcdir)/creation/rust_thrd.rs
    9851102
    9861103creation-java_thread$(EXEEXT):
    9871104        $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/creation/JavaThread.java
    988         @echo "#!/bin/sh" > a.out
    989         @echo "java JavaThread" >> a.out
    990         @chmod a+x a.out
    991 
    992 compile$(EXEEXT) :\
     1105        echo "#!/bin/sh" > a.out
     1106        echo "java JavaThread" >> a.out
     1107        chmod a+x a.out
     1108
     1109creation-pthread$(EXEEXT):
     1110        $(BENCH_V_CC)$(COMPILE) $(srcdir)/creation/pthreads.c
     1111
     1112compile$(EXEEXT) :              \
    9931113        compile-array.make      \
    9941114        compile-attributes.make \
     
    10011121
    10021122compile-array$(EXEEXT):
    1003         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/array.cfa
     1123        $(CFACOMPILE) -fsyntax-only -w $(testdir)/array.cfa
    10041124
    10051125compile-attributes$(EXEEXT):
    1006         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/attributes.cfa
     1126        $(CFACOMPILE) -fsyntax-only -w $(testdir)/attributes.cfa
    10071127
    10081128compile-empty$(EXEEXT):
    1009         @$(CFACOMPILE) -fsyntax-only -w $(srcdir)/compile/empty.cfa
     1129        $(CFACOMPILE) -fsyntax-only -w $(srcdir)/compile/empty.cfa
    10101130
    10111131compile-expression$(EXEEXT):
    1012         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/expression.cfa
     1132        $(CFACOMPILE) -fsyntax-only -w $(testdir)/expression.cfa
    10131133
    10141134compile-io$(EXEEXT):
    1015         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/io1.cfa
     1135        $(CFACOMPILE) -fsyntax-only -w $(testdir)/io1.cfa
    10161136
    10171137compile-monitor$(EXEEXT):
    1018         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/monitor.cfa
     1138        $(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/monitor.cfa
    10191139
    10201140compile-operators$(EXEEXT):
    1021         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/operators.cfa
     1141        $(CFACOMPILE) -fsyntax-only -w $(testdir)/operators.cfa
    10221142
    10231143compile-thread$(EXEEXT):
    1024         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/thread.cfa
     1144        $(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/thread.cfa
    10251145
    10261146compile-typeof$(EXEEXT):
    1027         @$(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa
     1147        $(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa
     1148
     1149size$(EXEEXT) : size-cfa.runquiet
     1150
     1151size-cfa$(EXEEXT):
     1152        $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/size/size.cfa
    10281153
    10291154# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • benchmark/baselines/x64/schedint.csv

    r9fb8f01 r3d5701e  
    1 waitfor-2,signal-1,signal-2,waitfor-1
     1schedext-2,schedint-1,schedint-2,schedext-1
    22393.69606249999987,325.99158333333327,409.01025000000004,319.90975000000003
  • benchmark/baselines/x86/schedint.csv

    r9fb8f01 r3d5701e  
    1 signal-2,waitfor-1,waitfor-2,signal-1
     1schedint-2,schedext-1,schedext-2,schedint-1
    22532.5297959183672,413.3084897959184,506.7579591836735,423.78826530612247
  • benchmark/basic/tls_fetch_add.c

    r9fb8f01 r3d5701e  
    33
    44#include "bench.h"
     5
     6// Does not do a fetch & add. It mimics the cfa protocol to disable interrupts locally, by writing true or false to a
     7// thread_local Boolean. This means the entire protocol is just to "mov" instructions making it extremely cheap.
    58
    69#define thread_local _Thread_local
     
    1619}
    1720
    18 int main(int argc, char* argv[]) {
     21int main( int argc, char * argv[] ) {
     22        BENCH_START()
    1923        BENCH(
    20                 for (size_t i = 0; i < n; i++) {
     24                for (size_t i = 0; i < times; i++) {
    2125                        do_call();
    2226                },
    2327                result
    2428        )
     29        printf( "%g\n", result );
     30}
    2531
    26         printf("%g\n", result);
    27 }
     32// Local Variables: //
     33// tab-width: 4 //
     34// End: //
  • benchmark/basic/ttst_lock.c

    r9fb8f01 r3d5701e  
    33
    44#include "bench.h"
     5
     6// Does a "lock xchg" on entry but a simple "mov" on exit => cheaper as 0 contention. While it has much more code, the
     7// bulk is never run.
    58
    69#define CALIGN __attribute__(( aligned (CACHE_ALIGN) ))
     
    3538}
    3639
    37 int main(int argc, char* argv[]) {
     40int main( int argc, char * argv[] ) {
     41        BENCH_START()
    3842        BENCH(
    39                 for (size_t i = 0; i < n; i++) {
     43                for (size_t i = 0; i < times; i++) {
    4044                        do_call();
    4145                },
    4246                result
    43                 )
    44 
    45                 printf("%g\n", result);
     47        )
     48        printf( "%g\n", result );
    4649}
    4750
  • benchmark/bench.h

    r9fb8f01 r3d5701e  
    55#endif
    66        #include <stdlib.h>
    7         #include <unistd.h>                                     // sysconf
     7        #include <stdint.h>                             // uint64_t
     8        #include <unistd.h>                             // sysconf
    89#if ! defined(__cforall)
    910        #include <time.h>
     
    1516
    1617
    17 static inline unsigned long long int bench_time() {
    18     struct timespec ts;
    19     clock_gettime(
    20 #if defined( __linux__ )
    21          CLOCK_THREAD_CPUTIME_ID,
    22 #elif defined( __freebsd__ )
    23          CLOCK_PROF,
    24 #elif defined( __solaris__ )
    25          CLOCK_HIGHRES,
    26 #else
    27     #error uC++ : internal error, unsupported architecture
    28 #endif
    29          &ts );
    30     return 1000000000LL * ts.tv_sec + ts.tv_nsec;
    31 } // Time
     18static inline uint64_t bench_time() {
     19        struct timespec ts;
     20        clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts );
     21        return 1000000000LL * ts.tv_sec + ts.tv_nsec;
     22} // bench_time
    3223
    3324#ifndef BENCH_N
    34 #define BENCH_N 500 //10000000
     25#define BENCH_N 10000000
    3526#endif
    3627
     28size_t times = BENCH_N;
     29
     30#define BENCH_START()                           \
     31        if ( argc > 2 ) exit( EXIT_FAILURE );   \
     32        if ( argc == 2 ) {                      \
     33                times = atoi( argv[1] );        \
     34        }
     35
    3736#define BENCH(statement, output)                \
    38         size_t n = BENCH_N;                     \
    39         if( argc > 2 ) return 1;                \
    40         if( argc == 2 ) {                               \
    41                 n = atoi(argv[1]);              \
    42         }                                               \
    43         long long int StartTime, EndTime;       \
     37        uint64_t StartTime, EndTime;            \
    4438        StartTime = bench_time();               \
    45         statement;                                      \
     39        statement;                              \
    4640        EndTime = bench_time();                 \
    47         double output =         \
    48             (double)( EndTime - StartTime ) / n;
     41        double output = (double)( EndTime - StartTime ) / times;
     42
    4943
    5044#if defined(__cforall)
     
    5347}
    5448#endif
     49#if defined(__U_CPLUSPLUS__)
     50unsigned int uDefaultPreemption() {
     51        return 0;
     52}
     53#endif
  • benchmark/creation/JavaThread.java

    r9fb8f01 r3d5701e  
    2626        static int x = 2;
    2727
    28         static private final int NoOfTimes = Integer.parseInt("10000") ;
     28        static private int times = Integer.parseInt("10000") ;
    2929
    3030        public static class MyThread extends Thread {
     
    3333        }
    3434        public static void helper() throws InterruptedException {
    35                 for(int i = 1; i <= NoOfTimes; i += 1) {
     35                for(int i = 1; i <= times; i += 1) {
    3636                        MyThread m = new MyThread();
    3737                        x = nextRandom( x );
     
    4444                helper();
    4545                long end = System.nanoTime();
    46                 System.out.println( (end - start) / NoOfTimes );
     46                System.out.println( (end - start) / times );
    4747        }
    4848        public static void main(String[] args) throws InterruptedException {
    49                 for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
     49                if ( args.length > 2 ) System.exit( 1 );
     50                if ( args.length == 2 ) { times = Integer.parseInt(args[1]); }
     51
     52                for (int i = Integer.parseInt("5"); --i >= 0 ; ) {
    5053                        InnerMain();
    51                         Thread.sleep(2000);     // 2 seconds
     54                        Thread.sleep(2000);             // 2 seconds
    5255                        x = nextRandom(x);
    5356                }
     
    5558        }
    5659}
     60
     61// Local Variables: //
     62// tab-width: 4 //
     63// End: //
  • benchmark/creation/cfa_cor.cfa

    r9fb8f01 r3d5701e  
    55
    66coroutine MyCoroutine {};
    7 void ?{} (MyCoroutine & this) {
     7void ?{}( MyCoroutine & this ) {
    88#ifdef EAGER
    9         resume(this);
     9        resume( this );
    1010#endif
    1111}
    12 void main(MyCoroutine &) {}
     12void main( MyCoroutine & ) {}
    1313
    14 int main(int argc, char* argv[]) {
     14int main( int argc, char * argv[] ) {
     15        BENCH_START()
    1516        BENCH(
    16                 for ( i; n ) {
    17                         MyCoroutine m;
     17                for ( times ) {
     18                        MyCoroutine c;
    1819                },
    1920                result
    2021        )
     22        printf( "%g\n", result );
     23}
    2124
    22         printf("%g\n", result);
    23 }
     25// Local Variables: //
     26// tab-width: 4 //
     27// End: //
  • benchmark/creation/cfa_thrd.cfa

    r9fb8f01 r3d5701e  
    77void main(MyThread &) {}
    88
    9 int main(int argc, char* argv[]) {
     9int main( int argc, char * argv[] ) {
     10        BENCH_START()
    1011        BENCH(
    11                 for ( i; n ) {
     12                for ( times ) {
    1213                        MyThread m;
    1314                },
    1415                result
    1516        )
     17        printf( "%g\n", result );
     18}
    1619
    17         printf("%g\n", result);
    18 }
     20// Local Variables: //
     21// tab-width: 4 //
     22// End: //
  • benchmark/creation/goroutine.go

    r9fb8f01 r3d5701e  
    22
    33import (
    4     "fmt"
    5     "time"
     4        "fmt"
     5        "time"
     6        "os"
     7        "strconv"
    68)
    79
     
    1719
    1820func main() {
    19         const NoOfTimes = 500000
     21        var times int = 10000000
     22        if len( os.Args ) > 2 { os.Exit( 1 ) }
     23        if len( os.Args ) == 2 { times, _ = strconv.Atoi(os.Args[1]) }
     24
    2025        start := time.Now()
    21         for i := 1; i <= NoOfTimes; i += 1 {
     26        for i := 1; i <= times; i += 1 {
    2227                go noop()               // creation
     28                <- shake                // wait for completion
    2329        }
    2430        end := time.Now()
    25         fmt.Printf("%d\n", end.Sub(start) / time.Duration(NoOfTimes))
    26         <- shake
     31        fmt.Printf( "%d\n", end.Sub(start) / time.Duration(times) )
    2732}
     33
     34// Local Variables: //
     35// tab-width: 4 //
     36// End: //
  • benchmark/creation/pthreads.c

    r9fb8f01 r3d5701e  
    44#include "bench.h"
    55
    6 static void *foo(void *arg) {
     6static void * foo(void *arg) {
    77    return arg;
    88}
    99
    10 int main(int argc, char* argv[]) {
     10int main( int argc, char * argv[] ) {
     11        BENCH_START()
    1112        BENCH(
    12                 for (size_t i = 0; i < n; i++) {
     13                for (size_t i = 0; i < times; i++) {
    1314                        pthread_t thread;
    1415                        if (pthread_create(&thread, NULL, foo, NULL) < 0) {
     
    1617                                return 1;
    1718                        }
    18 
    1919                        if (pthread_join( thread, NULL) < 0) {
    2020                                perror( "failure" );
     
    2424                result
    2525        )
     26        printf( "%g\n", result );
     27}
    2628
    27         printf("%g\n", result);
    28 }
     29// Local Variables: //
     30// tab-width: 4 //
     31// End: //
  • benchmark/creation/upp_cor.cc

    r9fb8f01 r3d5701e  
    55_Coroutine MyCor {
    66        void main() {}
     7  public:
     8        MyCor() { resume(); }
    79};
    810
    9 int main(int argc, char* argv[]) {
     11int main( int argc, char * argv[] ) {
     12        BENCH_START()
    1013        BENCH(
    11                 for (size_t i = 0; i < n; i++) {
     14                for (size_t i = 0; i < times; i++) {
    1215                        MyCor m;
    1316                },
    1417                result
    1518        )
     19        printf( "%g\n", result );
     20}
    1621
    17         printf("%g\n", result);
    18 }
     22// Local Variables: //
     23// tab-width: 4 //
     24// End: //
  • benchmark/creation/upp_thrd.cc

    r9fb8f01 r3d5701e  
    77};
    88
    9 int main(int argc, char* argv[]) {
     9int main( int argc, char * argv[] ) {
     10        BENCH_START()
    1011        BENCH(
    11                 for (size_t i = 0; i < n; i++) {
     12                for (size_t i = 0; i < times; i++) {
    1213                        MyThread m;
    1314                },
    1415                result
    1516        )
     17        printf( "%g\n", result );
     18}
    1619
    17         printf("%g\n", result);
    18 }
     20// Local Variables: //
     21// tab-width: 4 //
     22// End: //
  • benchmark/ctxswitch/JavaThread.java

    r9fb8f01 r3d5701e  
    2626        static int x = 2;
    2727
    28         static private final int NoOfTimes = Integer.parseInt("1000000") ;
     28        static private int times = Integer.parseInt("100000");
    2929
    3030        public static void helper() {
    31                 for(int i = 1; i <= NoOfTimes; i += 1) {
     31                for(int i = 1; i <= times; i += 1) {
    3232                        Thread.yield();
    3333                }
     
    3737                helper();
    3838                long end = System.nanoTime();
    39                 System.out.println( (end - start) / NoOfTimes );
     39                System.out.println( (end - start) / times );
    4040        }
    4141        public static void main(String[] args) throws InterruptedException {
    42                 for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
     42                if ( args.length > 2 ) System.exit( 1 );
     43                if ( args.length == 2 ) { times = Integer.parseInt(args[1]); }
     44
     45                for (int i = Integer.parseInt("5"); --i >= 0 ; ) {
    4346                        InnerMain();
    44                         Thread.sleep(2000);     // 2 seconds
     47                        Thread.sleep(2000);     // 2 seconds
    4548                        x = nextRandom(x);
    4649                }
     
    4851        }
    4952}
     53
     54// Local Variables: //
     55// tab-width: 4 //
     56// End: //
  • benchmark/ctxswitch/cfa_cor.cfa

    r9fb8f01 r3d5701e  
    44#include "bench.h"
    55
    6 coroutine GreatSuspender {};
    7 
    8 void ?{}( GreatSuspender & this ) {
    9         prime(this);
    10 }
    11 
    12 void main( __attribute__((unused)) GreatSuspender & this ) {
    13         while( true ) {
     6coroutine C {} c;
     7void main( __attribute__((unused)) C & ) {
     8        while () {
    149                suspend();
    1510        }
    1611}
    17 
    18 int main(int argc, char* argv[]) {
    19         GreatSuspender s;
    20 
     12int main( int argc, char * argv[] ) {
     13        BENCH_START()
    2114        BENCH(
    22                 for ( i; n ) {
    23                         resume( s );
     15                for ( times ) {
     16                        resume( c );
    2417                },
    2518                result
    2619        )
     20        printf( "%g\n", result );
     21}
    2722
    28         printf("%g\n", result);
    29 }
     23// Local Variables: //
     24// tab-width: 4 //
     25// End: //
  • benchmark/ctxswitch/cfa_cor_then.cfa

    r9fb8f01 r3d5701e  
    66void noOp(void) {}
    77
    8 coroutine GreatSuspender {};
     8coroutine C {} c;
    99
    10 void ?{}( GreatSuspender & this ) {
     10void ?{}( C & this ) {
    1111        prime(this);
    1212}
    1313
    14 void main( __attribute__((unused)) GreatSuspender & this ) {
    15         while( true ) {
     14void main( __attribute__((unused)) C & this ) {
     15        while () {
    1616                suspend_then(noOp);
    1717        }
    1818}
    1919
    20 int main(int argc, char* argv[]) {
    21         GreatSuspender s;
    22 
     20int main( int argc, char * argv[] ) {
     21        BENCH_START()
    2322        BENCH(
    24                 for ( i; n ) {
    25                         resume( s );
     23                for ( times ) {
     24                        resume( c );
    2625                },
    2726                result
    2827        )
     28        printf( "%g\n", result );
     29}
    2930
    30         printf("%g\n", result);
    31 }
     31// Local Variables: //
     32// tab-width: 4 //
     33// End: //
  • benchmark/ctxswitch/cfa_gen.cfa

    r9fb8f01 r3d5701e  
    33typedef struct {
    44        void * next;
    5 } GreatSuspender;
     5} C;
    66
    7 void comain( GreatSuspender * this ) {
    8     if ( __builtin_expect(this->next != 0, 1) ) goto *(this->next);
    9     this->next = &&s1;
     7void comain( C * c ) {
     8        if ( __builtin_expect(c->next != 0, 1) ) goto *(c->next);
     9        c->next = &&s1;
    1010        for () {
    11             return;
     11                return;
    1212          s1: ;
    1313        }
    1414}
    1515
    16 int main(int argc, char* argv[]) {
    17     GreatSuspender s = { 0 };
    18 
     16int main( int argc, char * argv[] ) {
     17        BENCH_START()
     18        C c = { 0 };
    1919        BENCH(
    20                 for ( i; n ) {
    21                         comain( &s );
     20                for ( times ) {
     21                        comain( &c );
    2222                },
    2323                result
    2424        )
     25        printf( "%g\n", result );
     26}
    2527
    26         printf("%g\n", result);
    27 }
     28// Local Variables: //
     29// tab-width: 4 //
     30// End: //
  • benchmark/ctxswitch/cfa_thrd.cfa

    r9fb8f01 r3d5701e  
    33#include "bench.h"
    44
    5 int main(int argc, char* argv[]) {
     5int main( int argc, char * argv[] ) {
     6        BENCH_START()
    67        BENCH(
    7                 for ( i; n ) {
     8                for ( times ) {
    89                        yield();
    910                },
    1011                result
    1112        )
     13        printf( "%g\n", result );
     14}
    1215
    13         printf("%g\n", result);
    14 }
     16// Local Variables: //
     17// tab-width: 4 //
     18// End: //
  • benchmark/ctxswitch/cfa_thrd2.cfa

    r9fb8f01 r3d5701e  
    88
    99void main(__attribute__((unused)) Fibre & this) {
    10         while(!done) {
     10        while ( ! done ) {
    1111                yield();
    1212        }
    1313}
    1414
    15 int main(int argc, char* argv[]) {
     15int main( int argc, char * argv[] ) {
     16        BENCH_START()
    1617        Fibre f1;
    1718        BENCH(
    18                 for ( i; n ) {
     19                for ( times ) {
    1920                        yield();
    2021                },
    2122                result
    2223        )
     24        printf( "%g\n", result );
     25        done = true;
     26}
    2327
    24         printf("%g\n", result);
    25         done = true;
    26         return 0;
    27 }
     28// Local Variables: //
     29// tab-width: 4 //
     30// End: //
  • benchmark/ctxswitch/goroutine.go

    r9fb8f01 r3d5701e  
    22
    33import (
    4     "fmt"
    5     "runtime"
    6     "time"
     4        "fmt"
     5        "time"
     6        "os"
     7        "strconv"
     8        "runtime"
    79)
    810
     
    2830
    2931func main() {
    30         const NoOfTimes = 10000000
    31         go ContextSwitch( NoOfTimes )           // context switch
     32        var times int = 10000000
     33        if len( os.Args ) > 2 { os.Exit( 1 ) }
     34        if len( os.Args ) == 2 { times, _ = strconv.Atoi(os.Args[1]) }
     35        go ContextSwitch( times )               // context switch
    3236        <- shake
    3337}
     38
     39// Local Variables: //
     40// tab-width: 4 //
     41// End: //
  • benchmark/ctxswitch/kos_fibre.cpp

    r9fb8f01 r3d5701e  
    33#include "bench.h"
    44
    5 int main(int argc, char* argv[]) {
     5int main( int argc, char * argv[] ) {
     6        BENCH_START()
    67        BENCH(
    7                 for (size_t i = 0; i < n; i++) {
     8                for (size_t i = 0; i < times; i++) {
    89                        Fibre::yield();
    910                },
    1011                result
    1112        )
    12         printf("%g\n", result);
    13         return 0;
     13        printf( "%g\n", result );
    1414}
     15
     16// Local Variables: //
     17// tab-width: 4 //
     18// End: //
  • benchmark/ctxswitch/kos_fibre2.cpp

    r9fb8f01 r3d5701e  
    1111}
    1212
    13 int main(int argc, char* argv[]) {
     13int main( int argc, char * argv[] ) {
     14        BENCH_START()
    1415        Fibre* f1 = (new Fibre)->run(f1main);
    1516        BENCH(
    16                 for (size_t i = 0; i < n; i++) {
     17                for (size_t i = 0; i < times; i++) {
    1718                        Fibre::yield();
    1819                },
    1920                result
    2021        )
    21         printf("%g\n", result);
     22        printf( "%g\n", result );
    2223        done = true;
    2324        Fibre::yield();
    2425        f1->join();
    25         return 0;
    2626}
     27
     28// Local Variables: //
     29// tab-width: 4 //
     30// End: //
  • benchmark/ctxswitch/pthreads.c

    r9fb8f01 r3d5701e  
    66#include "bench.h"
    77
    8 int main(int argc, char* argv[]) {
     8int main( int argc, char * argv[] ) {
     9        BENCH_START()
    910        BENCH(
    10                 for (size_t i = 0; i < n; i++) {
     11                for (size_t i = 0; i < times; i++) {
    1112                        sched_yield();
    1213                },
    1314                result
    1415        )
    15 
    16         printf("%g\n", result);
     16        printf( "%g\n", result );
    1717}
  • benchmark/ctxswitch/upp_cor.cc

    r9fb8f01 r3d5701e  
    33#include "bench.h"
    44
    5 _Coroutine GreatSuspender {
    6 public:
    7         GreatSuspender() {
    8                 resume();
    9         }
    10 
    11         void do_resume() {
    12                 resume();
    13         }
    14 private:
     5_Coroutine C {
    156        void main() {
    167                while( true ) {
     
    189                }
    1910        }
    20 };
    21 
    22 int main(int argc, char* argv[]) {
    23         GreatSuspender s;
    24 
     11  public:
     12        void do_resume() {
     13                resume();
     14        }
     15} c;
     16int main( int argc, char * argv[] ) {
     17        BENCH_START()
    2518        BENCH(
    26                 for (size_t i = 0; i < n; i++) {
    27                         s.do_resume();
     19                for (size_t i = 0; i < times; i++) {
     20                        c.do_resume();
    2821                },
    2922                result
    3023        )
     24        printf( "%g\n", result );
     25}
    3126
    32         printf("%g\n", result);
    33 }
     27// Local Variables: //
     28// tab-width: 4 //
     29// End: //
  • benchmark/ctxswitch/upp_thrd.cc

    r9fb8f01 r3d5701e  
    33#include "bench.h"
    44
    5 int main(int argc, char* argv[]) {
     5int main( int argc, char * argv[] ) {
     6        BENCH_START()
    67        BENCH(
    7                 for (size_t i = 0; i < n; i++) {
     8                for (size_t i = 0; i < times; i++) {
    89                        uThisTask().yield();
    910                },
    1011                result
    1112        )
     13        printf( "%g\n", result );
     14}
    1215
    13         printf("%g\n", result);
    14 }
     16// Local Variables: //
     17// tab-width: 4 //
     18// End: //
  • benchmark/mutex/JavaThread.java

    r9fb8f01 r3d5701e  
    2626        static int x = 2;
    2727
    28         static private final int NoOfTimes = Integer.parseInt("100000000") ;
     28        static private int times = Integer.parseInt("100000000");
    2929
    3030        public synchronized void noop() {
     
    3535                // Inhibit biased locking ...
    3636                x = (j.hashCode() ^ System.identityHashCode(j)) | 1 ;     
    37                 for(int i = 1; i <= NoOfTimes; i += 1) {
     37                for(int i = 1; i <= times; i += 1) {
    3838                        x = nextRandom(x);
    3939                        j.noop();
     
    4444                helper();
    4545                long end = System.nanoTime();
    46                 System.out.println( (end - start) / NoOfTimes );
     46                System.out.println( (end - start) / times );
    4747        }
    4848        public static void main(String[] args) throws InterruptedException {
     49                if ( args.length > 2 ) System.exit( 1 );
     50                if ( args.length == 2 ) { times = Integer.parseInt(args[1]); }
     51
    4952                for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
    5053                        InnerMain();
     
    5558        }
    5659}
     60
     61// Local Variables: //
     62// tab-width: 4 //
     63// End: //
  • benchmark/mutex/cfa1.cfa

    r9fb8f01 r3d5701e  
    44#include "bench.h"
    55
    6 monitor M {};
    7 void __attribute__((noinline)) call( M & mutex m ) {}
     6monitor M {} m1;
     7void __attribute__((noinline)) call( M & mutex p1 ) {}
    88
    9 int main(int argc, char* argv[]) {
    10         M m;
     9int main( int argc, char * argv[] ) {
     10        BENCH_START()
    1111        BENCH(
    12                 for ( i; n ) {
    13                         call(m);
     12                for ( times ) {
     13                        call( m1 );
    1414                },
    1515                result
    1616        )
     17        printf( "%g\n", result );
     18}
    1719
    18         printf("%g\n", result);
    19 }
     20// Local Variables: //
     21// tab-width: 4 //
     22// End: //
  • benchmark/mutex/cfa2.cfa

    r9fb8f01 r3d5701e  
    44#include "bench.h"
    55
    6 monitor M {};
    7 void __attribute__((noinline)) call( M & mutex m1, M & mutex m2 ) {}
     6monitor M {} m1, m2;
    87
    9 int main(int argc, char* argv[]) {
    10         M m1, m2;
     8void __attribute__((noinline)) call( M & mutex p1, M & mutex p2 ) {}
     9
     10int main( int argc, char * argv[] ) {
     11        BENCH_START()
    1112        BENCH(
    12                 for ( i; n ) {
    13                         call(m1, m2);
     13                for ( times ) {
     14                        call( m1, m2 );
    1415                },
    1516                result
    1617        )
     18        printf( "%g\n", result );
     19}
    1720
    18         printf("%g\n", result);
    19 }
     21// Local Variables: //
     22// tab-width: 4 //
     23// End: //
  • benchmark/mutex/cfa4.cfa

    r9fb8f01 r3d5701e  
    55
    66
    7 monitor M {};
    8 void __attribute__((noinline)) call( M & mutex m1, M & mutex m2, M & mutex m3, M & mutex m4 ) {}
     7monitor M {} m1, m2, m3, m4;
     8void __attribute__((noinline)) call( M & mutex p1, M & mutex p2, M & mutex p3, M & mutex p4 ) {}
    99
    10 int main(int argc, char* argv[]) {
    11         M m1, m2, m3, m4;
     10int main( int argc, char * argv[] ) {
     11        BENCH_START()
    1212        BENCH(
    13                 for ( i; n ) {
    14                         call(m1, m2, m3, m4);
     13                for ( times ) {
     14                        call( m1, m2, m3, m4 );
    1515                },
    1616                result
    1717        )
     18        printf( "%g\n", result );
     19}
    1820
    19         printf("%g\n", result);
    20 }
     21// Local Variables: //
     22// tab-width: 4 //
     23// End: //
  • benchmark/mutex/pthreads.c

    r9fb8f01 r3d5701e  
    77
    88void __attribute__((noinline)) call() {
    9          pthread_mutex_lock  (&mutex);
    10          pthread_mutex_unlock(&mutex);
     9         pthread_mutex_lock( &mutex );
     10         pthread_mutex_unlock( &mutex );
    1111}
    12 
    13 int main(int argc, char* argv[]) {
     12int main( int argc, char * argv[] ) {
     13        BENCH_START()
    1414        BENCH(
    15                 for (size_t i = 0; i < n; i++) {
     15                for ( size_t i = 0; i < times; i++ ) {
    1616                        call();
    1717                },
    1818                result
    1919        )
     20        printf( "%g\n", result );
     21}
    2022
    21         printf("%g\n", result);
    22 }
     23// Local Variables: //
     24// tab-width: 4 //
     25// End: //
  • benchmark/mutex/upp.cc

    r9fb8f01 r3d5701e  
    88};
    99
    10 int main(int argc, char* argv[]) {
     10int main( int argc, char * argv[] ) {
     11        BENCH_START()
    1112        MyMonitor m;
    1213        BENCH(
    13                 for (size_t i = 0; i < n; i++) {
     14                for ( size_t i = 0; i < times; i++ ) {
    1415                        m.call();
    1516                },
    1617                result
    1718        )
     19        printf( "%g\n", result );
     20}
    1821
    19         printf("%g\n", result);
    20 }
     22// Local Variables: //
     23// tab-width: 4 //
     24// End: //
  • benchmark/schedext/cfa1.cfa

    r9fb8f01 r3d5701e  
    44#include <stdio.h>
    55
    6 #include "bench.h"
     6#include "../bench.h"
    77
    8 int argc;
    9 char** argv;
    10 volatile int go = 0;
     8monitor M {} m1;
    119
    12 monitor M {};
    13 M m1;
    14 
    15 void __attribute__((noinline)) call( M & mutex a1 ) {}
    16 
    17 int  __attribute__((noinline)) wait( M & mutex a1 ) {
    18         go = 1;
    19         BENCH(
    20                 for ( i; n ) {
    21                         waitfor(call, a1);
    22                 },
    23                 result
    24         )
    25 
    26         printf("%g\n", result);
    27         go = 0;
    28         return 0;
     10void __attribute__((noinline)) call( M & mutex p1 ) {}
     11void __attribute__((noinline)) wait( M & mutex p1 ) {
     12        for ( times ) {
     13                waitfor( call : p1 );
     14        }
    2915}
    3016
    3117thread T {};
    32 void ^?{}( T & mutex this ) {}
    3318void main( T & ) {
    34         while(go == 0) { yield(); }
    35         while(go == 1) { call(m1); }
    36 
     19        BENCH(
     20                for ( times ) { call( m1 ); },
     21                result
     22        )
     23        printf( "%g\n", result );
    3724}
    3825
    39 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     26int main( int argc, char * argv[] ) {
     27        BENCH_START()
    4028        T t;
    41         return wait(m1);
     29        wait( m1 );
    4230}
     31
     32// Local Variables: //
     33// tab-width: 4 //
     34// End: //
  • benchmark/schedext/cfa2.cfa

    r9fb8f01 r3d5701e  
    44#include <stdio.h>
    55
    6 #include "bench.h"
     6#include "../bench.h"
    77
    8 int argc;
    9 char** argv;
    10 volatile int go = 0;
     8monitor M {} m1, m2;
    119
    12 monitor M {};
    13 M m1, m2;
    14 
    15 void __attribute__((noinline)) call( M & mutex a1, M & mutex a2 ) {}
    16 
    17 int  __attribute__((noinline)) wait( M & mutex a1, M & mutex a2 ) {
    18         go = 1;
     10void __attribute__((noinline)) call( M & mutex p1, M & mutex p2 ) {}
     11void __attribute__((noinline)) wait( M & mutex p1, M & mutex p2 ) {
     12        for ( times ) {
     13                waitfor( call : p1, p2 );
     14        }
     15}
     16thread T {};
     17void main( T & ) {
    1918        BENCH(
    20                 for ( i; n ) {
    21                         waitfor(call, a1, a2);
     19                for ( times ) {
     20                        call( m1, m2 );
    2221                },
    2322                result
    2423        )
    25 
    26         printf("%g\n", result);
    27         go = 0;
    28         return 0;
     24        printf( "%g\n", result );
    2925}
    3026
    31 thread T {};
    32 void ^?{}( T & mutex this ) {}
    33 void main( T & ) {
    34         while(go == 0) { yield(); }
    35         while(go == 1) { call(m1, m2); }
    36 
     27int main( int argc, char * argv[] ) {
     28        BENCH_START()
     29        T t;
     30        wait( m1, m2 );
    3731}
    3832
    39 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    40         T t;
    41         return wait(m1, m2);
    42 }
     33// Local Variables: //
     34// tab-width: 4 //
     35// End: //
  • benchmark/schedext/cfa4.cfa

    r9fb8f01 r3d5701e  
    44#include <stdio.h>
    55
    6 #include "bench.h"
     6#include "../bench.h"
    77
    8 int argc;
    9 char** argv;
    10 volatile int go = 0;
     8monitor M {} m1, m2, m3, m4;
    119
    12 monitor M {};
    13 M m1, m2, m3, m4;
    14 
    15 void __attribute__((noinline)) call( M & mutex a1, M & mutex a2, M & mutex a3, M & mutex a4 ) {}
    16 
    17 int  __attribute__((noinline)) wait( M & mutex a1, M & mutex a2, M & mutex a3, M & mutex a4 ) {
    18         go = 1;
     10void __attribute__((noinline)) call( M & mutex p1, M & mutex p2, M & mutex p3, M & mutex p4 ) {}
     11void __attribute__((noinline)) wait( M & mutex p1, M & mutex p2, M & mutex p3, M & mutex p4 ) {
     12        for ( times ) {
     13                waitfor( call : p1, p2, p3, p4 );
     14        }
     15}
     16thread T {};
     17void main( T & ) {
    1918        BENCH(
    20                 for ( i; n ) {
    21                         waitfor(call, a1, a2, a3, a4);
     19                for ( times ) {
     20                        call( m1, m2, m3, m4 );
    2221                },
    2322                result
    2423        )
    25 
    26         printf("%g\n", result);
    27         go = 0;
    28         return 0;
     24        printf( "%g\n", result );
    2925}
    3026
    31 thread T {};
    32 void ^?{}( T & mutex this ) {}
    33 void main( T & ) {
    34         while(go == 0) { yield(); }
    35         while(go == 1) { call(m1, m2, m3, m4); }
    36 
     27int main( int argc, char * argv[] ) {
     28        BENCH_START()
     29        T t;
     30        wait( m1, m2, m3, m4 );
    3731}
    3832
    39 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    40         T t;
    41         return wait(m1, m2, m3, m4);
    42 }
     33// Local Variables: //
     34// tab-width: 4 //
     35// End: //
  • benchmark/schedext/upp.cc

    r9fb8f01 r3d5701e  
    33#include "bench.h"
    44
    5 int argc;
    6 char** argv;
    7 volatile int go = 0;
    8 
    95_Monitor M {
    106public:
    117        void __attribute__((noinline)) call() {}
     8        void __attribute__((noinline)) wait() {
     9                for ( size_t i = 0; i < times; i++ ) {
     10                        _Accept(call);
     11                }
     12        }
     13} m;
    1214
    13         int __attribute__((noinline)) wait() {
    14                 go = 1;
     15_Task T {
     16        void main() {
    1517                BENCH(
    16                         for (size_t i = 0; i < n; i++) {
    17                                 _Accept(call);
     18                        for ( size_t i = 0; i < times; i++ ) {
     19                                m.call();
    1820                        },
    1921                        result
    2022                )
    21 
    22                 printf("%g\n", result);
    23                 go = 0;
    24                 return 0;
     23                printf( "%g\n", result );
    2524        }
    2625};
    2726
    28 M m;
     27int main( int argc, char * argv[] ) {
     28        BENCH_START()
     29        T t;
     30        m.wait();
     31}
    2932
    30 _Task T {
    31         void main() {
    32                 while(go == 0) { yield(); }
    33                 while(go == 1) { m.call(); }
    34 
    35         }
    36 };
    37 
    38 int main(int margc, char* margv[]) {
    39         argc = margc;
    40         argv = margv;
    41         T t;
    42         return m.wait();
    43 }
     33// Local Variables: //
     34// tab-width: 4 //
     35// End: //
  • benchmark/schedint/JavaThread.java

    r9fb8f01 r3d5701e  
    4949        static int x = 2;
    5050
    51         static private final int NoOfTimes = Integer.parseInt("1000000") ;
     51        static private int times = Integer.parseInt("1000000");
    5252
    5353        public static void helper( Monitor m ) throws InterruptedException {
    54                 for(int i = 1; i <= NoOfTimes; i += 1) {
     54                for(int i = 1; i <= times; i += 1) {
    5555                        m.wait();               // relase monitor lock
    5656                        m.next = true;
     
    6363                synchronized(m) {
    6464                        s.start();
    65                         while( !Monitor.go ) {
     65                        while( ! Monitor.go ) { // waiter must start first
    6666                                Thread.yield();
    6767                        }
     
    7272                Monitor.go = false;
    7373                s.join();
    74                 System.out.println( (end - start) / NoOfTimes);
     74                System.out.println( (end - start) / times);
    7575        }
    7676        public static void main(String[] args) throws InterruptedException {
     77                if ( args.length > 2 ) System.exit( 1 );
     78                if ( args.length == 2 ) { times = Integer.parseInt(args[1]); }
     79
    7780                for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
    7881                        InnerMain();
     
    8386        }
    8487}
     88
     89// Local Variables: //
     90// tab-width: 4 //
     91// End: //
  • benchmark/schedint/cfa1.cfa

    r9fb8f01 r3d5701e  
    44#include <stdio.h>
    55
    6 #include "bench.h"
     6#include "../bench.h"
    77
    8 int argc;
    9 char** argv;
    108volatile int go = 0;
    119
    1210condition c;
    13 monitor M {};
    14 M m1;
     11monitor M {} m1;
    1512
    16 void __attribute__((noinline)) call( M & mutex a1 ) {
    17         signal(c);
     13void __attribute__((noinline)) call( M & mutex p1 ) {
     14        signal( c );
    1815}
    19 
    20 int  __attribute__((noinline)) wait( M & mutex a1 ) {
     16void __attribute__((noinline)) wait( M & mutex p1 ) {
    2117        go = 1;
    22         BENCH(
    23                 for ( i; n ) {
    24                         wait(c);
    25                 },
    26                 result
    27         )
    28 
    29         printf("%g\n", result);
    30         go = 0;
    31         return 0;
     18        for ( times ) {
     19                wait( c );
     20        }
    3221}
    3322
    3423thread T {};
    35 void ^?{}( T & mutex ) {}
    3624void main( T & ) {
    37         while(go == 0) { yield(); }
    38         while(go == 1) { call(m1); }
    39 
     25        while ( go == 0 ) { yield(); } // waiter must start first
     26        BENCH(
     27                for ( times ) { call( m1 ); },
     28                result
     29        )
     30        printf( "%g\n", result );
    4031}
    4132
    42 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     33int main( int argc, char * argv[] ) {
     34        BENCH_START()
    4335        T t;
    44         return wait(m1);
     36        wait( m1 );
    4537}
     38
     39// Local Variables: //
     40// tab-width: 4 //
     41// End: //
  • benchmark/schedint/cfa2.cfa

    r9fb8f01 r3d5701e  
    44#include <stdio.h>
    55
    6 #include "bench.h"
     6#include "../bench.h"
    77
    8 int argc;
    9 char** argv;
    108volatile int go = 0;
    119
    1210condition c;
    13 monitor M {};
    14 M m1, m2;
     11monitor M {} m1, m2;
    1512
    16 void __attribute__((noinline)) call( M & mutex a1, M & mutex a2 ) {
    17         signal(c);
     13void __attribute__((noinline)) call( M & mutex p1, M & mutex p2 ) {
     14        signal( c );
    1815}
    19 
    20 int  __attribute__((noinline)) wait( M & mutex a1, M & mutex a2 ) {
     16void __attribute__((noinline)) wait( M & mutex p1, M & mutex p2 ) {
    2117        go = 1;
    22         BENCH(
    23                 for ( i; n ) {
    24                         wait(c);
    25                 },
    26                 result
    27         )
    28 
    29         printf("%g\n", result);
    30         go = 0;
    31         return 0;
     18        for ( times ) {
     19                wait( c );
     20        }
    3221}
    3322
    3423thread T {};
    35 void ^?{}( T & mutex this ) {}
    3624void main( T & ) {
    37         while(go == 0) { yield(); }
    38         while(go == 1) { call(m1, m2); }
    39 
     25        while ( go == 0 ) { yield(); } // waiter must start first
     26        BENCH(
     27                for ( times ) { call( m1, m2 ); },
     28                result
     29        )
     30        printf( "%g\n", result );
    4031}
    4132
    42 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     33int main( int argc, char * argv[] ) {
     34        BENCH_START()
    4335        T t;
    44         return wait(m1, m2);
     36        wait( m1, m2 );
    4537}
     38
     39// Local Variables: //
     40// tab-width: 4 //
     41// End: //
  • benchmark/schedint/cfa4.cfa

    r9fb8f01 r3d5701e  
    44#include <stdio.h>
    55
    6 #include "bench.h"
     6#include "../bench.h"
    77
    8 int argc;
    9 char** argv;
    108volatile int go = 0;
    119
    1210condition c;
    13 monitor M {};
    14 M m1, m2, m3, m4;
     11monitor M {} m1, m2, m3, m4;
    1512
    16 void __attribute__((noinline)) call( M & mutex a1, M & mutex a2, M & mutex a3, M & mutex a4 ) {
    17         signal(c);
     13void __attribute__((noinline)) call( M & mutex p1, M & mutex p2, M & mutex p3, M & mutex p4 ) {
     14        signal( c );
    1815}
    19 
    20 int  __attribute__((noinline)) wait( M & mutex a1, M & mutex a2, M & mutex a3, M & mutex a4 ) {
     16void __attribute__((noinline)) wait( M & mutex p1, M & mutex p2, M & mutex p3, M & mutex p4 ) {
    2117        go = 1;
    22         BENCH(
    23                 for ( i; n ) {
    24                         wait(c);
    25                 },
    26                 result
    27         )
    28 
    29         printf("%g\n", result);
    30         go = 0;
    31         return 0;
     18        for ( times ) {
     19                wait( c );
     20        }
    3221}
    3322
    3423thread T {};
    35 void ^?{}( T & mutex this ) {}
    3624void main( T & ) {
    37         while(go == 0) { yield(); }
    38         while(go == 1) { call(m1, m2, m3, m4); }
    39 
     25        while ( go == 0 ) { yield(); } // waiter must start first
     26        BENCH(
     27                for ( times ) { call( m1, m2, m3, m4 ); },
     28                result
     29        )
     30        printf( "%g\n", result );
    4031}
    4132
    42 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     33int main( int argc, char * argv[] ) {
     34        BENCH_START()
    4335        T t;
    44         return wait(m1, m2, m3, m4);
     36        wait( m1, m2, m3, m4 );
    4537}
     38
     39// Local Variables: //
     40// tab-width: 4 //
     41// End: //
  • benchmark/schedint/pthreads.c

    r9fb8f01 r3d5701e  
    44#include "bench.h"
    55
    6 int argc;
    7 char** argv;
    86volatile int go = 0;
    97
     8pthread_mutex_t m;
    109pthread_cond_t c;
    11 pthread_mutex_t m;
    1210
    1311void __attribute__((noinline)) call() {
    14         pthread_mutex_lock(&m);
    15         pthread_cond_signal(&c);
    16         pthread_mutex_unlock(&m);
     12        pthread_mutex_lock( &m );
     13        pthread_cond_signal( &c );
     14        pthread_mutex_unlock( &m );
    1715}
    1816
    19 int __attribute__((noinline)) wait() {
     17void __attribute__((noinline)) wait() {
    2018        pthread_mutex_lock(&m);
    2119        go = 1;
     20        for ( size_t i = 0; i < times; i++ ) {
     21                pthread_cond_wait( &c, &m );
     22        }
     23        go = 0;
     24        pthread_mutex_unlock( &m );
     25}
     26
     27void * thread_main( __attribute__((unused)) void * arg ) {
     28        while ( go == 0 ) { sched_yield(); } // waiter must start first
     29        // barging for lock acquire => may not execute N times
    2230        BENCH(
    23                 for (size_t i = 0; i < n; i++) {
    24                         pthread_cond_wait(&c, &m);
    25                 },
     31                while ( go == 1 ) { call(); },
    2632                result
    2733        )
    28 
    29         printf("%g\n", result);
    30         go = 0;
    31         pthread_mutex_unlock(&m);
    32         return 0;
    33 }
    34 
    35 void* thread_main(__attribute__((unused)) void * arg ) {
    36         while(go == 0) { sched_yield(); }
    37         while(go == 1) { call(); }
     34        printf( "%g\n", result );
    3835        return NULL;
    3936}
    4037
    41 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     38int main( int argc, char * argv[] ) {
     39        BENCH_START()
    4240        pthread_t thread;
    43         if (pthread_create(&thread, NULL, thread_main, NULL) < 0) {
     41        if ( pthread_create( &thread, NULL, thread_main, NULL ) < 0 ) {
    4442                perror( "failure" );
    4543                return 1;
    4644        }
    4745        wait();
    48         if (pthread_join( thread, NULL) < 0) {
     46        if ( pthread_join( thread, NULL ) < 0 ) {
    4947                perror( "failure" );
    5048                return 1;
    5149        }
    52         return 0;
    5350}
     51
     52// Local Variables: //
     53// tab-width: 4 //
     54// End: //
  • benchmark/schedint/upp.cc

    r9fb8f01 r3d5701e  
    33#include "bench.h"
    44
    5 int argc;
    6 char** argv;
    75volatile int go = 0;
    86
     
    1311                cond.signal();
    1412        }
     13        void __attribute__((noinline)) wait() {
     14                go = 1;
     15                for ( size_t i = 0; i < times; i++ ) {
     16                        cond.wait();
     17                }
     18        }
     19} m;
    1520
    16         int __attribute__((noinline)) wait() {
    17                 go = 1;
     21_Task T {
     22        void main() {
     23                while ( go == 0 ) { yield(); } // waiter must start first
    1824                BENCH(
    19                         for (size_t i = 0; i < n; i++) {
    20                                 cond.wait();
     25                        for ( size_t i = 0; i < times; i++ ) {
     26                                m.call();
    2127                        },
    2228                        result
    2329                )
    24 
    25                 printf("%g\n", result);
    26                 go = 0;
    27                 return 0;
     30                printf( "%g\n", result );
    2831        }
    2932};
    3033
    31 M m;
     34int main( int argc, char * argv[] ) {
     35        BENCH_START()
     36        T t;
     37        m.wait();
     38}
    3239
    33 _Task T {
    34         void main() {
    35                 while(go == 0) { yield(); }
    36                 while(go == 1) { m.call(); }
    37 
    38         }
    39 };
    40 
    41 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    42         T t;
    43         return m.wait();
    44 }
     40// Local Variables: //
     41// tab-width: 4 //
     42// End: //
  • configure

    r9fb8f01 r3d5701e  
    663663ac_ct_DUMPBIN
    664664DUMPBIN
    665 LD
    666665FGREP
    667666EGREP
     
    701700LDFLAGS
    702701CXXFLAGS
    703 CXX
    704702CFA_FLAGS
    705703LIBCFA_TARGET_MAKEFILES
     
    717715BUILD_IN_TREE_FLAGS
    718716CFACPP
     717CFACC_INSTALL
    719718CFACC
    720719DRIVER_DIR
     
    723722CFA_INCDIR
    724723CFA_PREFIX
     724HAS_DISTCC
     725LD
     726CXX
     727ENABLE_DISTCC_FALSE
     728ENABLE_DISTCC_TRUE
    725729DOendif
    726730DOifskipcompile
     
    797801enable_silent_rules
    798802with_cfa_name
     803enable_distcc
    799804with_target_hosts
    800805enable_gprofiler
     
    14591464  --enable-silent-rules   less verbose build output (undo: "make V=1")
    14601465  --disable-silent-rules  verbose build output (undo: "make V=0")
     1466  --enable-distcc     whether or not to enable distributed compilation
    14611467  --enable-gprofiler     whether or not to enable gprofiler tools (if available)
    14621468  --enable-demangler     whether or not to build the demangler (executable and library)
     
    31843190
    31853191#==============================================================================
     3192# distcc support
     3193
     3194# Check whether --enable-distcc was given.
     3195if test "${enable_distcc+set}" = set; then :
     3196  enableval=$enable_distcc; enable_distcc=$enableval
     3197else
     3198  enable_distcc=no
     3199fi
     3200
     3201
     3202 if test x$enable_distcc = xyes; then
     3203  ENABLE_DISTCC_TRUE=
     3204  ENABLE_DISTCC_FALSE='#'
     3205else
     3206  ENABLE_DISTCC_TRUE='#'
     3207  ENABLE_DISTCC_FALSE=
     3208fi
     3209
     3210HAS_DISTCC="False"
     3211
     3212if test x$enable_distcc = xyes; then
     3213        CXX="distcc ${CXX}"
     3214        LD="distcc ${LD} -lstdc++"
     3215        HAS_DISTCC="True"
     3216        echo "Enabling distributed builds"
     3217fi
     3218
     3219
     3220
     3221
     3222
     3223#==============================================================================
    31863224# Installation paths
    31873225
     
    32663304DRIVER_DIR=${TOP_BUILDDIR}driver/
    32673305CFACC=${DRIVER_DIR}cfa
     3306CFACC_INSTALL=${CFA_BINDIR}${CFA_NAME}
    32683307CFACPP=${DRIVER_DIR}cfa-cpp
     3308
    32693309
    32703310
     
    1701717057fi
    1701817058
     17059if test -z "${ENABLE_DISTCC_TRUE}" && test -z "${ENABLE_DISTCC_FALSE}"; then
     17060  as_fn_error $? "conditional \"ENABLE_DISTCC\" was never defined.
     17061Usually this means the macro was only invoked conditionally." "$LINENO" 5
     17062fi
    1701917063if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
    1702017064  as_fn_error $? "conditional \"AMDEP\" was never defined.
  • configure.ac

    r9fb8f01 r3d5701e  
    5858
    5959#==============================================================================
     60# distcc support
     61
     62AC_ARG_ENABLE(distcc,
     63        [  --enable-distcc     whether or not to enable distributed compilation],
     64        enable_distcc=$enableval, enable_distcc=no)
     65
     66AM_CONDITIONAL([ENABLE_DISTCC], [test x$enable_distcc = xyes])
     67HAS_DISTCC="False"
     68
     69if test x$enable_distcc = xyes; then
     70        CXX="distcc ${CXX}"
     71        LD="distcc ${LD} -lstdc++"
     72        HAS_DISTCC="True"
     73        echo "Enabling distributed builds"
     74fi
     75
     76AC_SUBST(CXX)
     77AC_SUBST(LD)
     78AC_SUBST(HAS_DISTCC)
     79
     80#==============================================================================
    6081# Installation paths
    6182M4CFA_PARSE_PREFIX
     
    7293DRIVER_DIR=${TOP_BUILDDIR}driver/
    7394CFACC=${DRIVER_DIR}cfa
     95CFACC_INSTALL=${CFA_BINDIR}${CFA_NAME}
    7496CFACPP=${DRIVER_DIR}cfa-cpp
    7597AC_SUBST(DRIVER_DIR)
    7698AC_SUBST(CFACC)
     99AC_SUBST(CFACC_INSTALL)
    77100AC_SUBST(CFACPP)
    78101
  • doc/papers/concurrency/Paper.tex

    r9fb8f01 r3d5701e  
    239239\lstMakeShortInline@%
    240240
     241\newcommand{\commenttd}[1]{{\color{red}{Thierry : #1}}}
     242
    241243\let\OLDthebibliography\thebibliography
    242244\renewcommand\thebibliography[1]{
     
    11631165% }
    11641166% int main() {
    1165 % 
     1167%
    11661168%       for ( int i = 0; i < 10; i += 1 ) {
    11671169%               printf( "%d\n", fib() );
     
    18341836                if ( random() % 3 ) transfer( b1, b2, 7 );
    18351837        }
    1836 }   
     1838}
    18371839int main() {
    18381840        `Person p1 = { b1, b2 }, p2 = { b2, b1 };`
     
    18641866                if ( random() % 3 ) transfer( b1, b2, 7 );
    18651867        }
    1866 }   
     1868}
    18671869int main() {
    18681870        `thread p1(person, ref(b1), ref(b2)), p2(person, ref(b2), ref(b1));`
     
    27392741% \section{Parallelism}
    27402742% \label{s:Parallelism}
    2741 % 
     2743%
    27422744% Historically, computer performance was about processor speeds.
    27432745% However, with heat dissipation being a direct consequence of speed increase, parallelism is the new source for increased performance~\cite{Sutter05, Sutter05b}.
     
    27462748% However, kernel threads are better as an implementation tool because of complexity and higher cost.
    27472749% Therefore, different abstractions are often layered onto kernel threads to simplify them, \eg pthreads.
    2748 % 
    2749 % 
     2750%
     2751%
    27502752% \subsection{User Threads}
    2751 % 
     2753%
    27522754% A direct improvement on kernel threads is user threads, \eg Erlang~\cite{Erlang} and \uC~\cite{uC++book}.
    27532755% This approach provides an interface that matches the language paradigms, gives more control over concurrency by the language runtime, and an abstract (and portable) interface to the underlying kernel threads across operating systems.
     
    27552757% Like kernel threads, user threads support preemption, which maximizes nondeterminism, but increases the potential for concurrency errors: race, livelock, starvation, and deadlock.
    27562758% \CFA adopts user-threads to provide more flexibility and a low-cost mechanism to build any other concurrency approach, \eg thread pools and actors~\cite{Actors}.
    2757 % 
     2759%
    27582760% A variant of user thread is \newterm{fibres}, which removes preemption, \eg Go~\cite{Go} @goroutine@s.
    27592761% Like functional programming, which removes mutation and its associated problems, removing preemption from concurrency reduces nondeterminism, making race and deadlock errors more difficult to generate.
  • driver/Makefile.in

    r9fb8f01 r3d5701e  
    201201CCDEPMODE = @CCDEPMODE@
    202202CFACC = @CFACC@
     203CFACC_INSTALL = @CFACC_INSTALL@
    203204CFACPP = @CFACPP@
    204205CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    231232FGREP = @FGREP@
    232233GREP = @GREP@
     234HAS_DISTCC = @HAS_DISTCC@
    233235HOST_FLAGS = @HOST_FLAGS@
    234236INSTALL = @INSTALL@
  • driver/cc1.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Fri Aug 26 14:23:51 2005
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 23 15:06:27 2019
    13 // Update Count     : 371
     12// Last Modified On : Sun Oct 20 08:14:33 2019
     13// Update Count     : 385
    1414//
    1515
     
    3333
    3434
    35 static string installlibdir( CFA_LIBDIR );                              // fixed location of cc1 and cfa-cpp commands when installed
    36 static string compiler_path( CFA_BACKEND_CC );                  // path/name of C compiler
     35static string compiler_path( CFA_BACKEND_CC );                  // C compiler path/name
    3736static bool CFA_flag = false;                                                   // -CFA flag
    3837static bool save_temps = false;                                                 // -save-temps flag
    3938static string o_file;
     39static string bprefix;
    4040
    4141
     
    5858
    5959
    60 static string __CFA_FLAGPREFIX__( "__CFA_FLAG" );
     60static string __CFA_FLAGPREFIX__( "__CFA_FLAG" );               // "N__=" suffix
    6161
    6262static void checkEnv1( const char * args[], int & nargs ) { // stage 1
     
    7070
    7171                if ( prefix( arg, __CFA_FLAGPREFIX__ ) ) {
    72                         string val( arg.substr( __CFA_FLAGPREFIX__.size() + 4 ) );
     72                        string val( arg.substr( arg.find_first_of( "=" ) + 1 ) );
    7373                        if ( prefix( val, "-compiler=" ) ) {
    7474                                compiler_path = val.substr( 10 );
     
    8989
    9090                if ( prefix( arg, __CFA_FLAGPREFIX__ ) ) {
    91                         string val( arg.substr( __CFA_FLAGPREFIX__.size() + 4 ) );
     91                        string val( arg.substr( arg.find_first_of( "=" ) + 1 ) );
    9292                        if ( prefix( val, "-compiler=" ) ) {
    9393                                compiler_path = val.substr( 10 );
     
    9898                        } else if ( prefix( val, "-o=" ) ) {            // output file for -CFA
    9999                                o_file = val.substr( 3 );
    100                         } else {
    101                                 args[nargs++] = ( *new string( arg.substr( __CFA_FLAGPREFIX__.size() + 4 ) ) ).c_str();
     100                        } else if ( prefix( val, "-B=" ) ) {            // location of cfa-cpp
     101                                bprefix = val.substr( 3 );
     102                        } else {                                                                        // normal flag for cfa-cpp
     103                                args[nargs++] = ( *new string( arg.substr( arg.find_first_of( "=" ) + 1 ) ) ).c_str();
    102104                        } // if
    103105                } // if
     
    106108
    107109
    108 static char tmpname[] = P_tmpdir "/CFAXXXXXX.i";
     110static char tmpname[] = P_tmpdir "/CFAXXXXXX.ifa";
    109111static int tmpfilefd = -1;
    110112static bool startrm = false;
     
    291293
    292294                execvp( args[0], (char * const *)args );                // should not return
    293                 perror( "CC1 Translator error: stage 1, execvp" );
     295                perror( "CC1 Translator error: stage 1 cpp, execvp" );
     296                cerr << " invoked " << args[0] << endl;
    294297                exit( EXIT_FAILURE );
    295298        } // if
     
    332335        #endif // __DEBUG_H__
    333336
     337        enum {
     338                Color_Auto   = 0,
     339                Color_Always = 1,
     340                Color_Never  = 2,
     341        } color_arg = Color_Auto;
     342
     343        const char * color_names[3] = { "--colors=auto", "--colors=always", "--colors=never" };
     344
    334345        // process all the arguments
    335346
     
    338349                if ( prefix( arg, "-" ) ) {
    339350                        // strip inappropriate flags
     351
     352                        if ( prefix( arg, "-fdiagnostics-color=" ) ) {
     353                                string choice = arg.substr(20);
     354                                     if(choice == "always") color_arg = Color_Always;
     355                                else if(choice == "never" ) color_arg = Color_Never;
     356                                else if(choice == "auto"  ) color_arg = Color_Auto;
     357                        } else if ( arg == "-fno-diagnostics-color" ) {
     358                                color_arg = Color_Auto;
     359                        }
    340360
    341361                        if ( arg == "-quiet" || arg == "-version" || arg == "-fpreprocessed" ||
     
    411431                        } // if
    412432                } else {
    413                         tmpfilefd = mkstemps( tmpname, 2 );
     433                        tmpfilefd = mkstemps( tmpname, 4 );
    414434                        if ( tmpfilefd == -1 ) {
    415435                                perror( "CC1 Translator error: stage 2, mkstemp" );
     
    427447
    428448        if ( fork() == 0 ) {                                                            // child runs CFA
    429                 cargs[0] = ( *new string( installlibdir + "cfa-cpp" ) ).c_str();
    430 
     449                cargs[0] = ( *new string( bprefix + "cfa-cpp" ) ).c_str();
    431450                cargs[ncargs++] = cpp_in;
    432451
     
    438457                        cargs[ncargs++] = cfa_cpp_out.c_str();
    439458                } // if
    440                 cargs[ncargs] = nullptr;                                                        // terminate argument list
     459
     460                cargs[ncargs++] = color_names[color_arg];
     461
     462                cargs[ncargs] = nullptr;                                                // terminate argument list
    441463
    442464                #ifdef __DEBUG_H__
     
    448470
    449471                execvp( cargs[0], (char * const *)cargs );              // should not return
    450                 perror( "CC1 Translator error: stage 2, execvp" );
     472                perror( "CC1 Translator error: stage 2 cfa-cpp, execvp" );
     473                cerr << " invoked " << cargs[0] << endl;
    451474                exit( EXIT_FAILURE );
    452475        } // if
     
    484507                args[0] = compiler_path.c_str();
    485508                args[nargs++] = "-S";                                                   // only compile and put assembler output in specified file
    486                 if ( save_temps ) {                                                             // make gcc accept .ifa suffix
    487                         args[nargs++] = "-x";
    488                         args[nargs++] = "cpp-output";
    489                 } // if
     509                args[nargs++] = "-x";
     510                args[nargs++] = "cpp-output";
     511
    490512                args[nargs++] = cfa_cpp_out.c_str();
    491513                args[nargs] = nullptr;                                                  // terminate argument list
     
    500522
    501523                execvp( args[0], (char * const *)args );                // should not return
    502                 perror( "CC1 Translator error: stage 2, execvp" );
     524                perror( "CC1 Translator error: stage 2 cc1, execvp" );
     525                cerr << " invoked " << args[0] << endl;
    503526                exit( EXIT_FAILURE );                                                   // tell gcc not to go any further
    504527        } // if
    505528
    506529        wait( &code );                                                                          // wait for child to finish
     530        rmtmpfile();                                                                            // remove tmpname
    507531
    508532        if ( WIFSIGNALED(code) ) {                                                      // child failed ?
    509                 rmtmpfile();                                                                    // remove tmpname
    510533                cerr << "CC1 Translator error: stage 2, child failed " << WTERMSIG(code) << endl;
    511534                exit( EXIT_FAILURE );
     
    516539        #endif // __DEBUG_H__
    517540
    518         rmtmpfile();                                                                            // remove tmpname
    519541        exit( WEXITSTATUS( code ) );                                            // stop regardless of success or failure
    520542} // Stage2
  • driver/cfa.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 23 16:27:07 2019
    13 // Update Count     : 411
     12// Last Modified On : Fri Jan 31 16:48:03 2020
     13// Update Count     : 421
    1414//
    1515
    1616#include <iostream>
    17 #include <cstdio>                                                                               // perror
    18 #include <cstdlib>                                                                              // putenv, exit
    19 #include <unistd.h>                                                                             // execvp
    20 #include <string>                                                                               // STL version
    21 #include <string.h>                                                                             // strcmp
    22 #include <algorithm>                                                                    // find
     17#include <cstdio>      // perror
     18#include <cstdlib>     // putenv, exit
     19#include <climits>     // PATH_MAX
     20#include <unistd.h>    // execvp
     21#include <string>      // STL version
     22#include <string.h>    // strcmp
     23#include <algorithm>   // find
    2324
    2425#include <sys/types.h>
     
    3334using std::to_string;
    3435
    35 //#define __DEBUG_H__
    36 
     36// #define __DEBUG_H__
     37
     38// "N__=" suffix
     39static string __CFA_FLAGPREFIX__( "__CFA_FLAG" );
    3740
    3841void Putenv( char * argv[], string arg ) {
    39         static int flags = 0;                                                           // environment variables must have unique names
    40 
    41         if ( putenv( (char *)( *new string( string( "__CFA_FLAG" + to_string( flags++ ) + "__=" ) + arg ) ).c_str() ) ) {
     42        // environment variables must have unique names
     43        static int flags = 0;
     44
     45        if ( putenv( (char *)( *new string( string( __CFA_FLAGPREFIX__ + to_string( flags++ ) + "__=" ) + arg ) ).c_str() ) ) {
    4246                cerr << argv[0] << " error, cannot set environment variable." << endl;
    4347                exit( EXIT_FAILURE );
     
    4549} // Putenv
    4650
    47 
    48 bool prefix( const string & arg, const string & pre ) { // check if string has prefix
     51// check if string has prefix
     52bool prefix( const string & arg, const string & pre ) {
    4953        return arg.substr( 0, pre.size() ) == pre;
    5054} // prefix
    5155
    52 bool suffix( const string & arg ) {                                             // check if string has suffix
     56inline bool ends_with(const string & str, const string & sfix) {
     57        if (sfix.size() > str.size()) return false;
     58        return std::equal(str.rbegin(), str.rbegin() + sfix.size(), sfix.rbegin(), sfix.rend());
     59}
     60
     61// check if string has suffix
     62bool suffix( const string & arg ) {
    5363        enum { NumSuffixes = 3 };
    5464        static const string suffixes[NumSuffixes] = { "cfa", "hfa", "ifa" };
     
    6474    struct stat info;
    6575    if ( stat( path.c_str(), &info ) != 0 ) return false;
    66     if ( info.st_mode & S_IFDIR ) return true;
    67         return false;
     76        return (info.st_mode & S_IFDIR) != 0;
    6877} // dirExists
     78
     79static inline string dir(const string & path) {
     80        return path.substr(0, path.find_last_of('/'));
     81}
     82
     83// Different path modes
     84enum PathMode {
     85        Installed,     // cfa is installed, use prefix
     86        BuildTree,     // cfa is in the tree, use source and build tree
     87        Distributed    // cfa is distributed, use build tree for includes and executable directory for .cfs
     88};
     89
     90// Get path mode from /proc
     91PathMode FromProc() {
     92        std::string abspath;
     93        abspath.resize(PATH_MAX);
     94
     95        // get executable path from /proc/self/exe
     96        ssize_t size = readlink("/proc/self/exe", const_cast<char*>(abspath.c_str()), abspath.size());
     97        if(size <= 0) {
     98                std::cerr << "Error could not evaluate absolute path from /proc/self/exe" << std::endl;
     99                std::cerr << "Failed with " << std::strerror(errno) << std::endl;
     100                std::exit(1);
     101        }
     102
     103        // Trim extra characters
     104        abspath.resize(size);
     105
     106        // Are we installed
     107        if(abspath.rfind(CFA_BINDIR  , 0) == 0) { return Installed; }
     108
     109        // Is this the build tree
     110        if(abspath.rfind(TOP_BUILDDIR, 0) == 0) { return BuildTree; }
     111
     112        // Does this look like distcc
     113        if(abspath.find("/.cfadistcc/") != std::string::npos) { return Distributed; }
     114
     115        // None of the above? Give up since we don't know where the prelude or include directories are
     116        std::cerr << "Cannot find required files from excutable path " << abspath << std::endl;
     117        std::exit(1);
     118}
    69119
    70120
     
    82132        string heading;                                                                         // banner printed at start of cfa compilation
    83133        string arg;                                                                                     // current command-line argument during command-line parsing
    84         string Bprefix;                                                                         // path where gcc looks for compiler command steps
     134        string bprefix;                                                                         // path where gcc looks for compiler steps
    85135        string langstd;                                                                         // language standard
    86136
     
    103153        bool m32 = false;                                                                       // -m32 flag
    104154        bool m64 = false;                                                                       // -m64 flag
    105         bool intree = false;                                                            // build in tree
     155        bool compiling_libs = false;
    106156        int o_file = 0;                                                                         // -o filename position
     157
     158        PathMode path = FromProc();
    107159
    108160        const char *args[argc + 100];                                           // cfa command line values, plus some space for additional flags
     
    135187                        } else if ( arg == "-XCFA" ) {                          // CFA pass through
    136188                                i += 1;
     189                                if ( i == argc ) continue;                              // next argument available ?
    137190                                Putenv( argv, argv[i] );
    138191
     
    159212                        } else if ( arg == "-no-include-stdhdr" ) {
    160213                                noincstd_flag = true;                                   // strip the no-include-stdhdr flag
    161                         } else if ( arg == "-in-tree" ) {
    162                                 intree = true;
     214                        } else if ( arg == "-cfalib") {
     215                                compiling_libs = true;
    163216                        } else if ( arg == "-compiler" ) {
    164217                                // use the user specified compiler
     
    211264                                } // if
    212265                        } else if ( prefix( arg, "-B" ) ) {
    213                                 Bprefix = arg.substr(2);                                // strip the -B flag
    214                                 args[nargs++] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
     266                                bprefix = arg.substr(2);                                // strip the -B flag
    215267                        } else if ( arg == "-c" || arg == "-S" || arg == "-E" || arg == "-M" || arg == "-MM" ) {
    216268                                args[nargs++] = argv[i];                                // pass argument along
     
    263315        // -E flag stops at cc1 stage 1, so cfa-cpp in cc1 stage 2 is never executed.
    264316        if ( cpp_flag && CFA_flag ) {
    265                 cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
    266                 exit( EXIT_FAILURE );
     317                CFA_flag = false;
     318                cerr << argv[0] << " warning, both -E and -CFA flags specified, using -E and ignoring -CFA." << endl;
    267319        } // if
    268320
    269321        // add the CFA include-library paths, which allow direct access to header files without directory qualification
    270         if ( ! intree ) {
     322        string libbase;
     323        switch(path) {
     324        case Installed:
    271325                args[nargs++] = "-I" CFA_INCDIR;
    272                 if ( ! noincstd_flag ) {                                                // do not use during build
     326                // do not use during build
     327                if ( ! noincstd_flag ) {
    273328                        args[nargs++] = "-I" CFA_INCDIR "stdhdr";
    274329                } // if
    275330                args[nargs++] = "-I" CFA_INCDIR "concurrency";
    276331                args[nargs++] = "-I" CFA_INCDIR "containers";
    277         } else {
     332                libbase = CFA_LIBDIR;
     333                break;
     334        case BuildTree:
     335        case Distributed:
    278336                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src";
    279                 if ( ! noincstd_flag ) {                                                // do not use during build
     337                // do not use during build
     338                if ( ! noincstd_flag ) {
    280339                        args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/stdhdr";
    281340                } // if
    282341                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/concurrency";
    283342                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/containers";
     343
     344                libbase = TOP_BUILDDIR "libcfa/";
     345
     346                break;
    284347        } // if
    285348
     
    288351        args[nargs++] = "stdbool.h";
    289352
    290         string libbase;
    291         if ( ! intree ) {
    292                 libbase = CFA_LIBDIR;
    293         } else {
    294                 libbase = TOP_BUILDDIR "libcfa/";
     353        if( compiling_libs ) {
    295354                Putenv( argv, "-t" );
    296355        } // if
     
    305364        } // if
    306365
    307         string libdir( libbase + arch + "-" + (nolib ? "nolib" : (debug ? "debug": "nodebug")) );
    308         if ( ! dirExists( libdir ) ) {
    309                 cerr << argv[0] << " internal error, cannot find prelude directory " << libdir << endl;
    310                 exit( EXIT_FAILURE );
    311         } // if
     366        const char * config = nolib ? "nolib" : (debug ? "debug": "nodebug");
     367        string libdir = libbase + arch + "-" + config;
     368
     369        if (path != Distributed) {
     370                if ( ! nolib && ! dirExists( libdir ) ) {
     371                        cerr << argv[0] << " internal error, configuration " << config << " not installed." << endl;
     372                        cerr << "Was looking for " << libdir << endl;
     373                        for(int i = 1; i < argc; i++) {
     374                                cerr << argv[i] << " ";
     375                        }
     376                        cerr << endl;
     377                        libdir = libbase + arch + "-" + "nolib";
     378                } // if
     379
     380                if ( ! dirExists( libdir ) ) {
     381                        cerr << argv[0] << " internal error, cannot find prelude directory." << endl;
     382                        cerr << "Was looking for " << libdir << endl;
     383                        exit( EXIT_FAILURE );
     384                } // if
     385        } // if
     386
     387        switch(path) {
     388        case Installed   : Putenv( argv, "--prelude-dir=" + libdir ); break;
     389        case BuildTree   : Putenv( argv, "--prelude-dir=" + libdir + "/prelude" ); break;
     390        case Distributed : Putenv( argv, "--prelude-dir=" + dir(argv[0]) ); break;
     391        }
    312392
    313393        for ( int i = 0; i < nlibs; i += 1 ) {                          // copy non-user libraries after all user libraries
     
    322402                args[nargs++] = "-Xlinker";
    323403                args[nargs++] = "--undefined=__cfaabi_appready_startup";
    324 
    325                 // include the cfa library in case it's needed
    326                 args[nargs++] = ( *new string( string("-L" ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
    327                 args[nargs++] = ( *new string( string("-Wl,-rpath," ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
     404                args[nargs++] = "-z";
     405                args[nargs++] = "execstack";
     406
     407                // include the cfa library in case it is needed
     408                args[nargs++] = ( *new string( string("-L" ) + libdir + (path != Installed ? "/src/.libs" : "")) ).c_str();
     409                args[nargs++] = ( *new string( string("-Wl,-rpath," ) + libdir + (path != Installed ? "/src/.libs" : "")) ).c_str();
    328410                args[nargs++] = "-Wl,--push-state,--as-needed";
    329411                args[nargs++] = "-lcfathread";
    330412                args[nargs++] = "-Wl,--pop-state";
     413                args[nargs++] = "-Wl,--push-state,--no-as-needed";
    331414                args[nargs++] = "-lcfa";
    332                 args[nargs++] = "-lpthread";
     415                args[nargs++] = "-Wl,--pop-state";
     416                args[nargs++] = "-pthread";
    333417                args[nargs++] = "-ldl";
    334418                args[nargs++] = "-lrt";
     
    361445        } // if
    362446
    363         Putenv( argv, "--prelude-dir=" + libdir + (intree ? "/prelude" : "") );
    364 
    365447        if ( debug ) {
    366448                heading += " (debug)";
     
    370452        } // if
    371453
    372         if ( Bprefix.length() == 0 ) {
    373                 Bprefix = ! intree ? installlibdir : srcdriverdir;
    374                 if ( Bprefix[Bprefix.length() - 1] != '/' ) Bprefix += '/';
    375                 args[nargs++] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
     454        if ( bprefix.length() == 0 ) {
     455                switch(path) {
     456                case Installed   : bprefix = installlibdir; break;
     457                case BuildTree   : bprefix = srcdriverdir ; break;
     458                case Distributed : bprefix = dir(argv[0]) ; break;
     459                }
     460                if ( bprefix[bprefix.length() - 1] != '/' ) bprefix += '/';
     461                Putenv( argv, string("-B=") + bprefix );
    376462        } // if
    377463
     
    401487                args[nargs++] = "-fgnu89-inline";
    402488                args[nargs++] = "-D__int8_t_defined";                   // prevent gcc type-size attributes
    403                 args[nargs++] = ( *new string( string("-B") + Bprefix ) ).c_str();
     489                args[nargs++] = ( *new string( string("-B") + bprefix ) ).c_str();
    404490        } else {
    405491                cerr << argv[0] << " error, compiler \"" << compiler_name << "\" unsupported." << endl;
     
    415501                cerr << " \"" << args[i] << "\"" << endl;
    416502        } // for
     503        cerr << endl;
    417504        #endif // __DEBUG_H__
    418505
    419506        if ( ! quiet ) {
    420507                cerr << "CFA " << "Version " << Version << heading << endl;
    421 
    422508                if ( help ) {
    423509                        cerr <<
  • libcfa/Makefile.in

    r9fb8f01 r3d5701e  
    231231CFACC = @CFACC@
    232232CFACPP = @CFACPP@
     233CFADIR_HASH = @CFADIR_HASH@
    233234CFA_BINDIR = @CFA_BINDIR@
    234235CFA_INCDIR = @CFA_INCDIR@
     
    274275LIPO = @LIPO@
    275276LN_S = @LN_S@
     277LOCAL_CC1 = @LOCAL_CC1@
     278LOCAL_CFACC = @LOCAL_CFACC@
    276279LTLIBOBJS = @LTLIBOBJS@
    277280LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
  • libcfa/automake/missing

    • Property mode changed from 120000 to 100644
    r9fb8f01 r3d5701e  
    1 /usr/share/automake-1.15/missing
     1#! /bin/sh
     2# Tdelisle : having the Makefiles.in automatically regenerated causes problems
     3#            when using multiple versions of automake, even if only on end user machines
     4#            therefore I am disabling that feature by commenting this script
     5exit 0
  • libcfa/configure

    r9fb8f01 r3d5701e  
    707707CONFIG_CFLAGS
    708708ARCH_FLAGS
     709CFADIR_HASH
     710LOCAL_CC1
     711LOCAL_CFACC
    709712CFACPP
    710713CFACC
     714ENABLE_DISTCC_FALSE
     715ENABLE_DISTCC_TRUE
    711716CFA_VERSION
    712717DRIVER_DIR
     
    783788enable_option_checking
    784789enable_silent_rules
     790enable_distcc
    785791with_cfa_name
    786792enable_shared
     
    14451451  --enable-silent-rules   less verbose build output (undo: "make V=1")
    14461452  --disable-silent-rules  verbose build output (undo: "make V=0")
     1453  --enable-distcc     whether or not to enable distributed compilation
    14471454  --enable-shared[=PKGS]  build shared libraries [default=yes]
    14481455  --enable-static[=PKGS]  build static libraries [default=yes]
     
    29412948
    29422949
    2943 CFACC=${DRIVER_DIR}cfa
     2950# Check whether --enable-distcc was given.
     2951if test "${enable_distcc+set}" = set; then :
     2952  enableval=$enable_distcc; enable_distcc=$enableval
     2953else
     2954  enable_distcc=no
     2955fi
     2956
     2957
     2958echo -n "checking for distributated build... "
     2959if test x$enable_distcc = xno; then
     2960        CFACC=${DRIVER_DIR}cfa
     2961        echo "no"
     2962else
     2963        tools="$(readlink -m $ac_confdir/)/../tools/build"
     2964        config=$(basename $(readlink -f .))
     2965        echo "$tools/distcc_hash $config"
     2966        CFADIR_HASH=$($tools/distcc_hash $config)
     2967        CFACC="distcc ~/.cfadistcc/${CFADIR_HASH}/cfa"
     2968        echo "yes (hash=${CFADIR_HASH})"
     2969fi
    29442970CFACPP=${DRIVER_DIR}cfa-cpp
     2971LOCAL_CFACC=${DRIVER_DIR}cfa
     2972LOCAL_CC1=${DRIVER_DIR}cc1
     2973
     2974 if test x$enable_distcc = xyes; then
     2975  ENABLE_DISTCC_TRUE=
     2976  ENABLE_DISTCC_FALSE='#'
     2977else
     2978  ENABLE_DISTCC_TRUE='#'
     2979  ENABLE_DISTCC_FALSE=
     2980fi
     2981
     2982
     2983
     2984
     2985
    29452986
    29462987
     
    29593000case $CONFIGURATION in
    29603001        "debug"   )
    2961                 CONFIG_CFLAGS="-Og -g"
     3002                CONFIG_CFLAGS="-O0 -g"
    29623003                CONFIG_CFAFLAGS="-debug"
    29633004                CONFIG_BUILDLIB="yes"
     
    1698217023fi
    1698317024
     17025if test -z "${ENABLE_DISTCC_TRUE}" && test -z "${ENABLE_DISTCC_FALSE}"; then
     17026  as_fn_error $? "conditional \"ENABLE_DISTCC\" was never defined.
     17027Usually this means the macro was only invoked conditionally." "$LINENO" 5
     17028fi
    1698417029if test -z "${BUILDLIB_TRUE}" && test -z "${BUILDLIB_FALSE}"; then
    1698517030  as_fn_error $? "conditional \"BUILDLIB\" was never defined.
  • libcfa/configure.ac

    r9fb8f01 r3d5701e  
    2727AC_ARG_VAR(CFA_VERSION, [The long version of cfa])
    2828
    29 CFACC=${DRIVER_DIR}cfa
     29AC_ARG_ENABLE(distcc,
     30        [  --enable-distcc     whether or not to enable distributed compilation],
     31        enable_distcc=$enableval, enable_distcc=no)
     32
     33echo -n "checking for distributated build... "
     34if test x$enable_distcc = xno; then
     35        CFACC=${DRIVER_DIR}cfa
     36        echo "no"
     37else
     38        tools="$(readlink -m $ac_confdir/)/../tools/build"
     39        config=$(basename $(readlink -f .))
     40        echo "$tools/distcc_hash $config"
     41        CFADIR_HASH=$($tools/distcc_hash $config)
     42        CFACC="distcc ~/.cfadistcc/${CFADIR_HASH}/cfa"
     43        echo "yes (hash=${CFADIR_HASH})"
     44fi
    3045CFACPP=${DRIVER_DIR}cfa-cpp
     46LOCAL_CFACC=${DRIVER_DIR}cfa
     47LOCAL_CC1=${DRIVER_DIR}cc1
     48
     49AM_CONDITIONAL([ENABLE_DISTCC], [test x$enable_distcc = xyes])
     50
    3151AC_SUBST(CFACC)
    3252AC_SUBST(CFACPP)
     53AC_SUBST(LOCAL_CFACC)
     54AC_SUBST(LOCAL_CC1)
     55AC_SUBST(CFADIR_HASH)
    3356AC_SUBST(CFA_VERSION)
    3457
     
    4568case $CONFIGURATION in
    4669        "debug"   )
    47                 CONFIG_CFLAGS="-Og -g"
     70                CONFIG_CFLAGS="-O0 -g"
    4871                CONFIG_CFAFLAGS="-debug"
    4972                CONFIG_BUILDLIB="yes"
  • libcfa/prelude/Makefile.am

    r9fb8f01 r3d5701e  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Wed Dec 14 15:00:35 2016
    14 ## Update Count     : 205
     13## Last Modified On : Mon Feb  3 21:27:18 2020
     14## Update Count     : 208
    1515###############################################################################
    1616
     
    2323cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c
    2424
    25 CC = @CFACC@
     25CC = @LOCAL_CFACC@
    2626AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@
    2727AM_CFAFLAGS = @CONFIG_CFAFLAGS@
     
    3636extras.cf : ${srcdir}/extras.regx ${srcdir}/extras.c
    3737        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -f ${srcdir}/extras.regx > extras.cf
     38        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -zo -f ${srcdir}/extras.regx2 | tr '\0' '\n' >> extras.cf
    3839
    3940# create forward declarations for gcc builtins
     
    5455
    5556# create forward declarations for cfa builtins
    56 builtins.cf : builtins.c ${CC}
     57builtins.cf : builtins.c @LOCAL_CFACC@
    5758        ${AM_V_GEN}gcc ${AM_CFLAGS} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po -D__cforall
    5859        ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
     
    6869MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cfa
    6970MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
     71
     72if ENABLE_DISTCC
     73distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh
     74        ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
     75        @echo "Dummy file to track distribution to remote hosts" > ${@}
     76
     77all: all-am distribution
     78endif ENABLE_DISTCC
  • libcfa/prelude/Makefile.in

    r9fb8f01 r3d5701e  
    1 # Makefile.in generated by automake 1.15 from Makefile.am.
     1# Makefile.in generated by automake 1.16.1 from Makefile.am.
    22# @configure_input@
    33
    4 # Copyright (C) 1994-2014 Free Software Foundation, Inc.
     4# Copyright (C) 1994-2018 Free Software Foundation, Inc.
    55
    66# This Makefile.in is free software; the Free Software Foundation
     
    167167AUTOMAKE = @AUTOMAKE@
    168168AWK = @AWK@
    169 CC = @CFACC@
     169CC = @LOCAL_CFACC@
    170170CCAS = @CCAS@
    171171CCASDEPMODE = @CCASDEPMODE@
     
    174174CFACC = @CFACC@
    175175CFACPP = @CFACPP@
     176CFADIR_HASH = @CFADIR_HASH@
    176177CFA_BINDIR = @CFA_BINDIR@
    177178CFA_INCDIR = @CFA_INCDIR@
     
    217218LIPO = @LIPO@
    218219LN_S = @LN_S@
     220LOCAL_CC1 = @LOCAL_CC1@
     221LOCAL_CFACC = @LOCAL_CFACC@
    219222LTLIBOBJS = @LTLIBOBJS@
    220223LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
     
    328331            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
    329332          *) \
    330             echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
    331             cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
     333            echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
     334            cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
    332335        esac;
    333336
     
    374377
    375378
    376 distdir: $(DISTFILES)
     379distdir: $(BUILT_SOURCES)
     380        $(MAKE) $(AM_MAKEFLAGS) distdir-am
     381
     382distdir-am: $(DISTFILES)
    377383        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
    378384        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
     
    537543extras.cf : ${srcdir}/extras.regx ${srcdir}/extras.c
    538544        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -f ${srcdir}/extras.regx > extras.cf
     545        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -zo -f ${srcdir}/extras.regx2 | tr '\0' '\n' >> extras.cf
    539546
    540547# create forward declarations for gcc builtins
     
    555562
    556563# create forward declarations for cfa builtins
    557 builtins.cf : builtins.c ${CC}
     564builtins.cf : builtins.c @LOCAL_CFACC@
    558565        ${AM_V_GEN}gcc ${AM_CFLAGS} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po -D__cforall
    559566        ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
     
    566573maintainer-clean-local :
    567574        rm -rf $(DEPDIR)
     575
     576@ENABLE_DISTCC_TRUE@distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh
     577@ENABLE_DISTCC_TRUE@    ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
     578@ENABLE_DISTCC_TRUE@    @echo "Dummy file to track distribution to remote hosts" > ${@}
     579
     580@ENABLE_DISTCC_TRUE@all: all-am distribution
    568581
    569582# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • libcfa/prelude/builtins.c

    r9fb8f01 r3d5701e  
    1010// Created On       : Fri Jul 21 16:21:03 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun 25 18:06:52 2019
    13 // Update Count     : 97
     12// Last Modified On : Thu Nov 21 16:31:39 2019
     13// Update Count     : 101
    1414//
    1515
     
    6969
    7070// universal typed pointer constant
    71 // Compiler issue: there is a problem with anonymous types that do not have a size.
    72 static inline forall( dtype DT | sized(DT) ) DT * intptr( uintptr_t addr ) { return (DT *)addr; }
     71static inline forall( dtype DT ) DT * intptr( uintptr_t addr ) { return (DT *)addr; }
    7372
    7473// exponentiation operator implementation
  • libcfa/prelude/extras.regx

    r9fb8f01 r3d5701e  
    1919typedef.* uint32_t;
    2020typedef.* uint64_t;
     21typedef.* __uint_least16_t;
     22typedef.* __uint_least32_t;
    2123typedef.* char16_t;
    2224typedef.* char32_t;
    2325typedef.* wchar_t;
    24 extern.*\*malloc\(.*\).*
    25 extern.* free\(.*\).*
    26 extern.* exit\(.*\).*
    27 extern.* atexit\(.*\).*
    28 extern.* abort\(.*\).*
    29 extern.* printf\(.*\).*
  • libcfa/prelude/prototypes.awk

    r9fb8f01 r3d5701e  
    1010# Created On       : Sat May 16 07:57:37 2015
    1111# Last Modified By : Peter A. Buhr
    12 # Last Modified On : Thu Jun  6 20:46:28 2019
    13 # Update Count     : 34
     12# Last Modified On : Sat Feb  8 09:46:58 2020
     13# Update Count     : 36
    1414#
    1515
     
    1717
    1818BEGIN {
    19   FS = "[( )]"
     19        FS = "[( )]"
    2020        # order so string search is longest string
    2121        i=-1
     
    8484
    8585/BT_FN/ {
    86         for (i = 1; i <= NF; i++) {
    87           if( match($i, "BT_FN") != 0 ) {
    88                 prototypes[$i] = $i
    89           }
     86        for (i = 1; i <= NF; i += 1 ) {
     87                if ( match($i, "BT_FN") != 0 ) {
     88                        prototypes[$i] = $i
     89                }
    9090        }
    91   }
     91}
    9292
    9393END {
     
    103103
    104104        for ( prototype in prototypes ) {
    105           # printf( "//\"%s\"\n", prototype )
    106           if ( index( "BT_LAST", prototype ) == 1 ) {
    107                 continue
    108           } # if
     105                # printf( "//\"%s\"\n", prototype )
     106                if ( index( "BT_LAST", prototype ) == 1 ) {
     107                        continue
     108                } # if
    109109
    110           printf( "#define %s(NAME) FUNC_SIMPLE(", prototype )
     110                printf( "#define %s(NAME) FUNC_SIMPLE(", prototype )
    111111
    112           if ( sub( "BT_FN_", "", prototype ) == 0 ) {
    113                 printf( "\n********** BAD MACRO NAME \"%s\" **********\n", prototype )
    114                 exit 0
    115           } # if
     112                if ( sub( "BT_FN_", "", prototype ) == 0 ) {
     113                        printf( "\n********** BAD MACRO NAME \"%s\" **********\n", prototype )
     114                        exit 0
     115                } # if
    116116
    117           # generate function return type as macro
    118           for ( t = 0; t < N; t += 1 ) {                                        # find longest match
    119                 type = types[t];
    120                 if ( index( prototype, type ) == 1 ) {          # found match
    121                   printf( "BT_%s, NAME", type )
    122                   sub( type, "", prototype )
    123                   break;
     117                # generate function return type as macro
     118                for ( t = 0; t < N; t += 1 ) {                                  # find longest match
     119                        type = types[t];
     120                        if ( index( prototype, type ) == 1 ) {          # found match
     121                                printf( "BT_%s, NAME", type )
     122                                sub( type, "", prototype )
     123                                break;
     124                        } # if
     125                } # for
     126
     127                # generate function parameter types as macro
     128                if ( index( prototype, "VAR" ) != 2 ) {                 # C-style empty parameters ?
     129                        for ( p = 0; length( prototype ) > 0; p += 1 ) { # until all parameters types are removed
     130                                sub( "_", "", prototype)                                # remove "_"
     131                                printf( ", ", type )
     132                                temp = prototype
     133                                for ( t = 0; t < N; t += 1 ) {                  # find longest match
     134                                        type = types[t];
     135                                        if ( index( prototype, type ) == 1 ) { # found match
     136                                                printf( "BT_%s", type )
     137                                                sub( type, "", prototype )
     138                                                break;
     139                                        } # if
     140                                } # for
     141                                if ( temp == prototype ) {                              # no match found for parameter in macro table
     142                                        printf( "\n********** MISSING TYPE \"%s\" **********\n", prototype )
     143                                        exit 0
     144                                } # if
     145                        } # for
    124146                } # if
    125           } # for
    126 
    127           # generate function parameter types as macro
    128           if ( index( prototype, "VAR" ) != 2 ) {                       # C-style empty parameters ?
    129                 for ( p = 0; length( prototype ) > 0; p += 1 ) { # until all parameters types are removed
    130                   sub( "_", "", prototype)                              # remove "_"
    131                   printf( ", ", type )
    132                   temp = prototype
    133                   for ( t = 0; t < N; t += 1 ) {                        # find longest match
    134                         type = types[t];
    135                         if ( index( prototype, type ) == 1 ) { # found match
    136                           printf( "BT_%s", type )
    137                           sub( type, "", prototype )
    138                           break;
    139                         } # if
    140                   } # for
    141                   if ( temp == prototype ) {                            # no match found for parameter in macro table
    142                         printf( "\n********** MISSING TYPE \"%s\" **********\n", prototype )
    143                         exit 0
    144                   } # if
    145                 } # for
    146           } # if
    147           printf( ")\n" )
     147                printf( ")\n" )
    148148        } # for
    149149
  • libcfa/prelude/sync-builtins.cf

    r9fb8f01 r3d5701e  
    11char __sync_fetch_and_add(volatile char *, char,...);
    2 char __sync_fetch_and_add_1(volatile char *, char,...);
    32signed char __sync_fetch_and_add(volatile signed char *, signed char,...);
    4 signed char __sync_fetch_and_add_1(volatile signed char *, signed char,...);
    53unsigned char __sync_fetch_and_add(volatile unsigned char *, unsigned char,...);
    6 unsigned char __sync_fetch_and_add_1(volatile unsigned char *, unsigned char,...);
    74signed short __sync_fetch_and_add(volatile signed short *, signed short,...);
    8 signed short __sync_fetch_and_add_2(volatile signed short *, signed short,...);
    95unsigned short __sync_fetch_and_add(volatile unsigned short *, unsigned short,...);
    10 unsigned short __sync_fetch_and_add_2(volatile unsigned short *, unsigned short,...);
    116signed int __sync_fetch_and_add(volatile signed int *, signed int,...);
    12 signed int __sync_fetch_and_add_4(volatile signed int *, signed int,...);
    137unsigned int __sync_fetch_and_add(volatile unsigned int *, unsigned int,...);
    14 unsigned int __sync_fetch_and_add_4(volatile unsigned int *, unsigned int,...);
     8signed long int __sync_fetch_and_add(volatile signed long int *, signed long int,...);
     9unsigned long int __sync_fetch_and_add(volatile unsigned long int *, unsigned long int,...);
    1510signed long long int __sync_fetch_and_add(volatile signed long long int *, signed long long int,...);
    16 signed long long int __sync_fetch_and_add_8(volatile signed long long int *, signed long long int,...);
    1711unsigned long long int __sync_fetch_and_add(volatile unsigned long long int *, unsigned long long int,...);
    18 unsigned long long int __sync_fetch_and_add_8(volatile unsigned long long int *, unsigned long long int,...);
    1912#if defined(__SIZEOF_INT128__)
    2013signed __int128 __sync_fetch_and_add(volatile signed __int128 *, signed __int128,...);
    21 signed __int128 __sync_fetch_and_add_16(volatile signed __int128 *, signed __int128,...);
    2214unsigned __int128 __sync_fetch_and_add(volatile unsigned __int128 *, unsigned __int128,...);
    23 unsigned __int128 __sync_fetch_and_add_16(volatile unsigned __int128 *, unsigned __int128,...);
    2415#endif
    2516
    2617char __sync_fetch_and_sub(volatile char *, char,...);
    27 char __sync_fetch_and_sub_1(volatile char *, char,...);
    2818signed char __sync_fetch_and_sub(volatile signed char *, signed char,...);
    29 signed char __sync_fetch_and_sub_1(volatile signed char *, signed char,...);
    3019unsigned char __sync_fetch_and_sub(volatile unsigned char *, unsigned char,...);
    31 unsigned char __sync_fetch_and_sub_1(volatile unsigned char *, unsigned char,...);
    3220signed short __sync_fetch_and_sub(volatile signed short *, signed short,...);
    33 signed short __sync_fetch_and_sub_2(volatile signed short *, signed short,...);
    3421unsigned short __sync_fetch_and_sub(volatile unsigned short *, unsigned short,...);
    35 unsigned short __sync_fetch_and_sub_2(volatile unsigned short *, unsigned short,...);
    3622signed int __sync_fetch_and_sub(volatile signed int *, signed int,...);
    37 signed int __sync_fetch_and_sub_4(volatile signed int *, signed int,...);
    3823unsigned int __sync_fetch_and_sub(volatile unsigned int *, unsigned int,...);
    39 unsigned int __sync_fetch_and_sub_4(volatile unsigned int *, unsigned int,...);
     24signed long int __sync_fetch_and_sub(volatile signed long int *, signed long int,...);
     25unsigned long int __sync_fetch_and_sub(volatile unsigned long int *, unsigned long int,...);
    4026signed long long int __sync_fetch_and_sub(volatile signed long long int *, signed long long int,...);
    41 signed long long int __sync_fetch_and_sub_8(volatile signed long long int *, signed long long int,...);
    4227unsigned long long int __sync_fetch_and_sub(volatile unsigned long long int *, unsigned long long int,...);
    43 unsigned long long int __sync_fetch_and_sub_8(volatile unsigned long long int *, unsigned long long int,...);
    4428#if defined(__SIZEOF_INT128__)
    4529signed __int128 __sync_fetch_and_sub(volatile signed __int128 *, signed __int128,...);
    46 signed __int128 __sync_fetch_and_sub_16(volatile signed __int128 *, signed __int128,...);
    4730unsigned __int128 __sync_fetch_and_sub(volatile unsigned __int128 *, unsigned __int128,...);
    48 unsigned __int128 __sync_fetch_and_sub_16(volatile unsigned __int128 *, unsigned __int128,...);
    4931#endif
    5032
    5133char __sync_fetch_and_or(volatile char *, char,...);
    52 char __sync_fetch_and_or_1(volatile char *, char,...);
    5334signed char __sync_fetch_and_or(volatile signed char *, signed char,...);
    54 signed char __sync_fetch_and_or_1(volatile signed char *, signed char,...);
    5535unsigned char __sync_fetch_and_or(volatile unsigned char *, unsigned char,...);
    56 unsigned char __sync_fetch_and_or_1(volatile unsigned char *, unsigned char,...);
    5736signed short __sync_fetch_and_or(volatile signed short *, signed short,...);
    58 signed short __sync_fetch_and_or_2(volatile signed short *, signed short,...);
    5937unsigned short __sync_fetch_and_or(volatile unsigned short *, unsigned short,...);
    60 unsigned short __sync_fetch_and_or_2(volatile unsigned short *, unsigned short,...);
    6138signed int __sync_fetch_and_or(volatile signed int *, signed int,...);
    62 signed int __sync_fetch_and_or_4(volatile signed int *, signed int,...);
    6339unsigned int __sync_fetch_and_or(volatile unsigned int *, unsigned int,...);
    64 unsigned int __sync_fetch_and_or_4(volatile unsigned int *, unsigned int,...);
     40signed long int __sync_fetch_and_or(volatile signed long int *, signed long int,...);
     41unsigned long int __sync_fetch_and_or(volatile unsigned long int *, unsigned long int,...);
    6542signed long long int __sync_fetch_and_or(volatile signed long long int *, signed long long int,...);
    66 signed long long int __sync_fetch_and_or_8(volatile signed long long int *, signed long long int,...);
    6743unsigned long long int __sync_fetch_and_or(volatile unsigned long long int *, unsigned long long int,...);
    68 unsigned long long int __sync_fetch_and_or_8(volatile unsigned long long int *, unsigned long long int,...);
    6944#if defined(__SIZEOF_INT128__)
    7045signed __int128 __sync_fetch_and_or(volatile signed __int128 *, signed __int128,...);
    71 signed __int128 __sync_fetch_and_or_16(volatile signed __int128 *, signed __int128,...);
    7246unsigned __int128 __sync_fetch_and_or(volatile unsigned __int128 *, unsigned __int128,...);
    73 unsigned __int128 __sync_fetch_and_or_16(volatile unsigned __int128 *, unsigned __int128,...);
    7447#endif
    7548
    7649char __sync_fetch_and_and(volatile char *, char,...);
    77 char __sync_fetch_and_and_1(volatile char *, char,...);
    7850signed char __sync_fetch_and_and(volatile signed char *, signed char,...);
    79 signed char __sync_fetch_and_and_1(volatile signed char *, signed char,...);
    8051unsigned char __sync_fetch_and_and(volatile unsigned char *, unsigned char,...);
    81 unsigned char __sync_fetch_and_and_1(volatile unsigned char *, unsigned char,...);
    8252signed short __sync_fetch_and_and(volatile signed short *, signed short,...);
    83 signed short __sync_fetch_and_and_2(volatile signed short *, signed short,...);
    8453unsigned short __sync_fetch_and_and(volatile unsigned short *, unsigned short,...);
    85 unsigned short __sync_fetch_and_and_2(volatile unsigned short *, unsigned short,...);
    8654signed int __sync_fetch_and_and(volatile signed int *, signed int,...);
    87 signed int __sync_fetch_and_and_4(volatile signed int *, signed int,...);
    8855unsigned int __sync_fetch_and_and(volatile unsigned int *, unsigned int,...);
    89 unsigned int __sync_fetch_and_and_4(volatile unsigned int *, unsigned int,...);
     56signed long int __sync_fetch_and_and(volatile signed long int *, signed long int,...);
     57unsigned long int __sync_fetch_and_and(volatile unsigned long int *, unsigned long int,...);
    9058signed long long int __sync_fetch_and_and(volatile signed long long int *, signed long long int,...);
    91 signed long long int __sync_fetch_and_and_8(volatile signed long long int *, signed long long int,...);
    9259unsigned long long int __sync_fetch_and_and(volatile unsigned long long int *, unsigned long long int,...);
    93 unsigned long long int __sync_fetch_and_and_8(volatile unsigned long long int *, unsigned long long int,...);
    9460#if defined(__SIZEOF_INT128__)
    9561signed __int128 __sync_fetch_and_and(volatile signed __int128 *, signed __int128,...);
    96 signed __int128 __sync_fetch_and_and_16(volatile signed __int128 *, signed __int128,...);
    9762unsigned __int128 __sync_fetch_and_and(volatile unsigned __int128 *, unsigned __int128,...);
    98 unsigned __int128 __sync_fetch_and_and_16(volatile unsigned __int128 *, unsigned __int128,...);
    9963#endif
    10064
    10165char __sync_fetch_and_xor(volatile char *, char,...);
    102 char __sync_fetch_and_xor_1(volatile char *, char,...);
    10366signed char __sync_fetch_and_xor(volatile signed char *, signed char,...);
    104 signed char __sync_fetch_and_xor_1(volatile signed char *, signed char,...);
    10567unsigned char __sync_fetch_and_xor(volatile unsigned char *, unsigned char,...);
    106 unsigned char __sync_fetch_and_xor_1(volatile unsigned char *, unsigned char,...);
    10768signed short __sync_fetch_and_xor(volatile signed short *, signed short,...);
    108 signed short __sync_fetch_and_xor_2(volatile signed short *, signed short,...);
    10969unsigned short __sync_fetch_and_xor(volatile unsigned short *, unsigned short,...);
    110 unsigned short __sync_fetch_and_xor_2(volatile unsigned short *, unsigned short,...);
    11170signed int __sync_fetch_and_xor(volatile signed int *, signed int,...);
    112 signed int __sync_fetch_and_xor_4(volatile signed int *, signed int,...);
    11371unsigned int __sync_fetch_and_xor(volatile unsigned int *, unsigned int,...);
    114 unsigned int __sync_fetch_and_xor_4(volatile unsigned int *, unsigned int,...);
     72signed long int __sync_fetch_and_xor(volatile signed long int *, signed long int,...);
     73unsigned long int __sync_fetch_and_xor(volatile unsigned long int *, unsigned long int,...);
    11574signed long long int __sync_fetch_and_xor(volatile signed long long int *, signed long long int,...);
    116 signed long long int __sync_fetch_and_xor_8(volatile signed long long int *, signed long long int,...);
    11775unsigned long long int __sync_fetch_and_xor(volatile unsigned long long int *, unsigned long long int,...);
    118 unsigned long long int __sync_fetch_and_xor_8(volatile unsigned long long int *, unsigned long long int,...);
    11976#if defined(__SIZEOF_INT128__)
    12077signed __int128 __sync_fetch_and_xor(volatile signed __int128 *, signed __int128,...);
    121 signed __int128 __sync_fetch_and_xor_16(volatile signed __int128 *, signed __int128,...);
    12278unsigned __int128 __sync_fetch_and_xor(volatile unsigned __int128 *, unsigned __int128,...);
    123 unsigned __int128 __sync_fetch_and_xor_16(volatile unsigned __int128 *, unsigned __int128,...);
    12479#endif
    12580
    12681char __sync_fetch_and_nand(volatile char *, char,...);
    127 char __sync_fetch_and_nand_1(volatile char *, char,...);
    12882signed char __sync_fetch_and_nand(volatile signed char *, signed char,...);
    129 signed char __sync_fetch_and_nand_1(volatile signed char *, signed char,...);
    13083unsigned char __sync_fetch_and_nand(volatile unsigned char *, unsigned char,...);
    131 unsigned char __sync_fetch_and_nand_1(volatile unsigned char *, unsigned char,...);
    13284signed short __sync_fetch_and_nand(volatile signed short *, signed short,...);
    133 signed short __sync_fetch_and_nand_2(volatile signed short *, signed short,...);
    13485unsigned short __sync_fetch_and_nand(volatile unsigned short *, unsigned short,...);
    135 unsigned short __sync_fetch_and_nand_2(volatile unsigned short *, unsigned short,...);
    13686signed int __sync_fetch_and_nand(volatile signed int *, signed int,...);
    137 signed int __sync_fetch_and_nand_4(volatile signed int *, signed int,...);
    13887unsigned int __sync_fetch_and_nand(volatile unsigned int *, unsigned int,...);
    139 unsigned int __sync_fetch_and_nand_4(volatile unsigned int *, unsigned int,...);
     88signed long int __sync_fetch_and_nand(volatile signed long int *, signed long int,...);
     89unsigned long int __sync_fetch_and_nand(volatile unsigned long int *, unsigned long int,...);
    14090signed long long int __sync_fetch_and_nand(volatile signed long long int *, signed long long int,...);
    141 signed long long int __sync_fetch_and_nand_8(volatile signed long long int *, signed long long int,...);
    14291unsigned long long int __sync_fetch_and_nand(volatile unsigned long long int *, unsigned long long int,...);
    143 unsigned long long int __sync_fetch_and_nand_8(volatile unsigned long long int *, unsigned long long int,...);
    14492#if defined(__SIZEOF_INT128__)
    14593signed __int128 __sync_fetch_and_nand(volatile signed __int128 *, signed __int128,...);
    146 signed __int128 __sync_fetch_and_nand_16(volatile signed __int128 *, signed __int128,...);
    14794unsigned __int128 __sync_fetch_and_nand(volatile unsigned __int128 *, unsigned __int128,...);
    148 unsigned __int128 __sync_fetch_and_nand_16(volatile unsigned __int128 *, unsigned __int128,...);
    14995#endif
    15096
    15197char __sync_add_and_fetch(volatile char *, char,...);
    152 char __sync_add_and_fetch_1(volatile char *, char,...);
    15398signed char __sync_add_and_fetch(volatile signed char *, signed char,...);
    154 signed char __sync_add_and_fetch_1(volatile signed char *, signed char,...);
    15599unsigned char __sync_add_and_fetch(volatile unsigned char *, unsigned char,...);
    156 unsigned char __sync_add_and_fetch_1(volatile unsigned char *, unsigned char,...);
    157100signed short __sync_add_and_fetch(volatile signed short *, signed short,...);
    158 signed short __sync_add_and_fetch_2(volatile signed short *, signed short,...);
    159101unsigned short __sync_add_and_fetch(volatile unsigned short *, unsigned short,...);
    160 unsigned short __sync_add_and_fetch_2(volatile unsigned short *, unsigned short,...);
    161102signed int __sync_add_and_fetch(volatile signed int *, signed int,...);
    162 signed int __sync_add_and_fetch_4(volatile signed int *, signed int,...);
    163103signed int __sync_add_and_fetch(volatile signed int *, signed int,...);
    164 signed int __sync_add_and_fetch_4(volatile signed int *, signed int,...);
     104signed long int __sync_add_and_fetch(volatile signed long int *, signed long int,...);
     105unsigned long int __sync_add_and_fetch(volatile unsigned long int *, unsigned long int,...);
    165106signed long long int __sync_add_and_fetch(volatile signed long long int *, signed long long int,...);
    166 signed long long int __sync_add_and_fetch_8(volatile signed long long int *, signed long long int,...);
    167107unsigned long long int __sync_add_and_fetch(volatile unsigned long long int *, unsigned long long int,...);
    168 unsigned long long int __sync_add_and_fetch_8(volatile unsigned long long int *, unsigned long long int,...);
    169108#if defined(__SIZEOF_INT128__)
    170109signed __int128 __sync_add_and_fetch(volatile signed __int128 *, signed __int128,...);
    171 signed __int128 __sync_add_and_fetch_16(volatile signed __int128 *, signed __int128,...);
    172110unsigned __int128 __sync_add_and_fetch(volatile unsigned __int128 *, unsigned __int128,...);
    173 unsigned __int128 __sync_add_and_fetch_16(volatile unsigned __int128 *, unsigned __int128,...);
    174111#endif
    175112
    176113char __sync_sub_and_fetch(volatile char *, char,...);
    177 char __sync_sub_and_fetch_1(volatile char *, char,...);
    178114signed char __sync_sub_and_fetch(volatile signed char *, signed char,...);
    179 signed char __sync_sub_and_fetch_1(volatile signed char *, signed char,...);
    180115unsigned char __sync_sub_and_fetch(volatile unsigned char *, unsigned char,...);
    181 unsigned char __sync_sub_and_fetch_1(volatile unsigned char *, unsigned char,...);
    182116signed short __sync_sub_and_fetch(volatile signed short *, signed short,...);
    183 signed short __sync_sub_and_fetch_2(volatile signed short *, signed short,...);
    184117unsigned short __sync_sub_and_fetch(volatile unsigned short *, unsigned short,...);
    185 unsigned short __sync_sub_and_fetch_2(volatile unsigned short *, unsigned short,...);
    186118signed int __sync_sub_and_fetch(volatile signed int *, signed int,...);
    187 signed int __sync_sub_and_fetch_4(volatile signed int *, signed int,...);
    188119unsigned int __sync_sub_and_fetch(volatile unsigned int *, unsigned int,...);
    189 unsigned int __sync_sub_and_fetch_4(volatile unsigned int *, unsigned int,...);
     120signed long int __sync_sub_and_fetch(volatile signed long int *, signed long int,...);
     121unsigned long int __sync_sub_and_fetch(volatile unsigned long int *, unsigned long int,...);
    190122signed long long int __sync_sub_and_fetch(volatile signed long long int *, signed long long int,...);
    191 signed long long int __sync_sub_and_fetch_8(volatile signed long long int *, signed long long int,...);
    192123unsigned long long int __sync_sub_and_fetch(volatile unsigned long long int *, unsigned long long int,...);
    193 unsigned long long int __sync_sub_and_fetch_8(volatile unsigned long long int *, unsigned long long int,...);
    194124#if defined(__SIZEOF_INT128__)
    195125signed __int128 __sync_sub_and_fetch(volatile signed __int128 *, signed __int128,...);
    196 signed __int128 __sync_sub_and_fetch_16(volatile signed __int128 *, signed __int128,...);
    197126unsigned __int128 __sync_sub_and_fetch(volatile unsigned __int128 *, unsigned __int128,...);
    198 unsigned __int128 __sync_sub_and_fetch_16(volatile unsigned __int128 *, unsigned __int128,...);
    199127#endif
    200128
    201129char __sync_or_and_fetch(volatile char *, char,...);
    202 char __sync_or_and_fetch_1(volatile char *, char,...);
    203130signed char __sync_or_and_fetch(volatile signed char *, signed char,...);
    204 signed char __sync_or_and_fetch_1(volatile signed char *, signed char,...);
    205131unsigned char __sync_or_and_fetch(volatile unsigned char *, unsigned char,...);
    206 unsigned char __sync_or_and_fetch_1(volatile unsigned char *, unsigned char,...);
    207132signed short __sync_or_and_fetch(volatile signed short *, signed short,...);
    208 signed short __sync_or_and_fetch_2(volatile signed short *, signed short,...);
    209133unsigned short __sync_or_and_fetch(volatile unsigned short *, unsigned short,...);
    210 unsigned short __sync_or_and_fetch_2(volatile unsigned short *, unsigned short,...);
    211134signed int __sync_or_and_fetch(volatile signed int *, signed int,...);
    212 signed int __sync_or_and_fetch_4(volatile signed int *, signed int,...);
    213135unsigned int __sync_or_and_fetch(volatile unsigned int *, unsigned int,...);
    214 unsigned int __sync_or_and_fetch_4(volatile unsigned int *, unsigned int,...);
     136signed long int __sync_or_and_fetch(volatile signed long int *, signed long int,...);
     137unsigned long int __sync_or_and_fetch(volatile unsigned long int *, unsigned long int,...);
    215138signed long long int __sync_or_and_fetch(volatile signed long long int *, signed long long int,...);
    216 signed long long int __sync_or_and_fetch_8(volatile signed long long int *, signed long long int,...);
    217139unsigned long long int __sync_or_and_fetch(volatile unsigned long long int *, unsigned long long int,...);
    218 unsigned long long int __sync_or_and_fetch_8(volatile unsigned long long int *, unsigned long long int,...);
    219140#if defined(__SIZEOF_INT128__)
    220141signed __int128 __sync_or_and_fetch(volatile signed __int128 *, signed __int128,...);
    221 signed __int128 __sync_or_and_fetch_16(volatile signed __int128 *, signed __int128,...);
    222142unsigned __int128 __sync_or_and_fetch(volatile unsigned __int128 *, unsigned __int128,...);
    223 unsigned __int128 __sync_or_and_fetch_16(volatile unsigned __int128 *, unsigned __int128,...);
    224143#endif
    225144
    226145char __sync_and_and_fetch(volatile char *, char,...);
    227 char __sync_and_and_fetch_1(volatile char *, char,...);
    228146signed char __sync_and_and_fetch(volatile signed char *, signed char,...);
    229 signed char __sync_and_and_fetch_1(volatile signed char *, signed char,...);
    230147unsigned char __sync_and_and_fetch(volatile unsigned char *, unsigned char,...);
    231 unsigned char __sync_and_and_fetch_1(volatile unsigned char *, unsigned char,...);
    232148signed short __sync_and_and_fetch(volatile signed short *, signed short,...);
    233 signed short __sync_and_and_fetch_2(volatile signed short *, signed short,...);
    234149unsigned short __sync_and_and_fetch(volatile unsigned short *, unsigned short,...);
    235 unsigned short __sync_and_and_fetch_2(volatile unsigned short *, unsigned short,...);
    236150signed int __sync_and_and_fetch(volatile signed int *, signed int,...);
    237 signed int __sync_and_and_fetch_4(volatile signed int *, signed int,...);
    238151unsigned int __sync_and_and_fetch(volatile unsigned int *, unsigned int,...);
    239 unsigned int __sync_and_and_fetch_4(volatile unsigned int *, unsigned int,...);
     152signed long int __sync_and_and_fetch(volatile signed long int *, signed long int,...);
     153unsigned long int __sync_and_and_fetch(volatile unsigned long int *, unsigned long int,...);
    240154signed long long int __sync_and_and_fetch(volatile signed long long int *, signed long long int,...);
    241 signed long long int __sync_and_and_fetch_8(volatile signed long long int *, signed long long int,...);
    242155unsigned long long int __sync_and_and_fetch(volatile unsigned long long int *, unsigned long long int,...);
    243 unsigned long long int __sync_and_and_fetch_8(volatile unsigned long long int *, unsigned long long int,...);
    244156#if defined(__SIZEOF_INT128__)
    245157signed __int128 __sync_and_and_fetch(volatile signed __int128 *, signed __int128,...);
    246 signed __int128 __sync_and_and_fetch_16(volatile signed __int128 *, signed __int128,...);
    247158unsigned __int128 __sync_and_and_fetch(volatile unsigned __int128 *, unsigned __int128,...);
    248 unsigned __int128 __sync_and_and_fetch_16(volatile unsigned __int128 *, unsigned __int128,...);
    249159#endif
    250160
    251161char __sync_xor_and_fetch(volatile char *, char,...);
    252 char __sync_xor_and_fetch_1(volatile char *, char,...);
    253162signed char __sync_xor_and_fetch(volatile signed char *, signed char,...);
    254 signed char __sync_xor_and_fetch_1(volatile signed char *, signed char,...);
    255163unsigned char __sync_xor_and_fetch(volatile unsigned char *, unsigned char,...);
    256 unsigned char __sync_xor_and_fetch_1(volatile unsigned char *, unsigned char,...);
    257164signed short __sync_xor_and_fetch(volatile signed short *, signed short,...);
    258 signed short __sync_xor_and_fetch_2(volatile signed short *, signed short,...);
    259165unsigned short __sync_xor_and_fetch(volatile unsigned short *, unsigned short,...);
    260 unsigned short __sync_xor_and_fetch_2(volatile unsigned short *, unsigned short,...);
    261166signed int __sync_xor_and_fetch(volatile signed int *, signed int,...);
    262 signed int __sync_xor_and_fetch_4(volatile signed int *, signed int,...);
    263167unsigned int __sync_xor_and_fetch(volatile unsigned int *, unsigned int,...);
    264 unsigned int __sync_xor_and_fetch_4(volatile unsigned int *, unsigned int,...);
     168signed long int __sync_xor_and_fetch(volatile signed long int *, signed long int,...);
     169unsigned long int __sync_xor_and_fetch(volatile unsigned long int *, unsigned long int,...);
    265170signed long long int __sync_xor_and_fetch(volatile signed long long int *, signed long long int,...);
    266 signed long long int __sync_xor_and_fetch_8(volatile signed long long int *, signed long long int,...);
    267171unsigned long long int __sync_xor_and_fetch(volatile unsigned long long int *, unsigned long long int,...);
    268 unsigned long long int __sync_xor_and_fetch_8(volatile unsigned long long int *, unsigned long long int,...);
    269172#if defined(__SIZEOF_INT128__)
    270173signed __int128 __sync_xor_and_fetch(volatile signed __int128 *, signed __int128,...);
    271 signed __int128 __sync_xor_and_fetch_16(volatile signed __int128 *, signed __int128,...);
    272174unsigned __int128 __sync_xor_and_fetch(volatile unsigned __int128 *, unsigned __int128,...);
    273 unsigned __int128 __sync_xor_and_fetch_16(volatile unsigned __int128 *, unsigned __int128,...);
    274175#endif
    275176
    276177char __sync_nand_and_fetch(volatile char *, char,...);
    277 char __sync_nand_and_fetch_1(volatile char *, char,...);
    278178signed char __sync_nand_and_fetch(volatile signed char *, signed char,...);
    279 signed char __sync_nand_and_fetch_1(volatile signed char *, signed char,...);
    280179unsigned char __sync_nand_and_fetch(volatile unsigned char *, unsigned char,...);
    281 unsigned char __sync_nand_and_fetch_1(volatile unsigned char *, unsigned char,...);
    282180signed short __sync_nand_and_fetch(volatile signed short *, signed short,...);
    283 signed short __sync_nand_and_fetch_2(volatile signed short *, signed short,...);
    284181unsigned short __sync_nand_and_fetch(volatile unsigned short *, unsigned short,...);
    285 unsigned short __sync_nand_and_fetch_2(volatile unsigned short *, unsigned short,...);
    286182signed int __sync_nand_and_fetch(volatile signed int *, signed int,...);
    287 signed int __sync_nand_and_fetch_4(volatile signed int *, signed int,...);
    288183unsigned int __sync_nand_and_fetch(volatile unsigned int *, unsigned int,...);
    289 unsigned int __sync_nand_and_fetch_4(volatile unsigned int *, unsigned int,...);
     184signed long int __sync_nand_and_fetch(volatile signed long int *, signed long int,...);
     185unsigned long int __sync_nand_and_fetch(volatile unsigned long int *, unsigned long int,...);
    290186signed long long int __sync_nand_and_fetch(volatile signed long long int *, signed long long int,...);
    291 signed long long int __sync_nand_and_fetch_8(volatile signed long long int *, signed long long int,...);
    292187unsigned long long int __sync_nand_and_fetch(volatile unsigned long long int *, unsigned long long int,...);
    293 unsigned long long int __sync_nand_and_fetch_8(volatile unsigned long long int *, unsigned long long int,...);
    294188#if defined(__SIZEOF_INT128__)
    295189signed __int128 __sync_nand_and_fetch(volatile signed __int128 *, signed __int128,...);
    296 signed __int128 __sync_nand_and_fetch_16(volatile signed __int128 *, signed __int128,...);
    297190unsigned __int128 __sync_nand_and_fetch(volatile unsigned __int128 *, unsigned __int128,...);
    298 unsigned __int128 __sync_nand_and_fetch_16(volatile unsigned __int128 *, unsigned __int128,...);
    299191#endif
    300192
    301193_Bool __sync_bool_compare_and_swap(volatile char *, char, char,...);
    302 _Bool __sync_bool_compare_and_swap_1(volatile char *, char, char,...);
    303194_Bool __sync_bool_compare_and_swap(volatile signed char *, signed char, signed char,...);
    304 _Bool __sync_bool_compare_and_swap_1(volatile signed char *, signed char, signed char,...);
    305195_Bool __sync_bool_compare_and_swap(volatile unsigned char *, unsigned char, unsigned char,...);
    306 _Bool __sync_bool_compare_and_swap_1(volatile unsigned char *, unsigned char, unsigned char,...);
    307196_Bool __sync_bool_compare_and_swap(volatile short *, signed short, signed short,...);
    308 _Bool __sync_bool_compare_and_swap_2(volatile short *, signed short, signed short,...);
    309197_Bool __sync_bool_compare_and_swap(volatile short *, unsigned short, unsigned short,...);
    310 _Bool __sync_bool_compare_and_swap_2(volatile short *, unsigned short, unsigned short,...);
    311198_Bool __sync_bool_compare_and_swap(volatile signed int *, signed int, signed int,...);
    312 _Bool __sync_bool_compare_and_swap_4(volatile signed int *, signed int, signed int,...);
    313199_Bool __sync_bool_compare_and_swap(volatile unsigned int *, unsigned int, unsigned int,...);
    314 _Bool __sync_bool_compare_and_swap_4(volatile unsigned int *, unsigned int, unsigned int,...);
     200_Bool __sync_bool_compare_and_swap(volatile signed long int *, signed long int, signed long int,...);
     201_Bool __sync_bool_compare_and_swap(volatile unsigned long int *, unsigned long int, unsigned long int,...);
    315202_Bool __sync_bool_compare_and_swap(volatile signed long long int *, signed long long int, signed long long int,...);
    316 _Bool __sync_bool_compare_and_swap_8(volatile signed long long int *, signed long long int, signed long long int,...);
    317203_Bool __sync_bool_compare_and_swap(volatile unsigned long long int *, unsigned long long int, unsigned long long int,...);
    318 _Bool __sync_bool_compare_and_swap_8(volatile unsigned long long int *, unsigned long long int, unsigned long long int,...);
    319204#if defined(__SIZEOF_INT128__)
    320205_Bool __sync_bool_compare_and_swap(volatile signed __int128 *, signed __int128, signed __int128,...);
    321 _Bool __sync_bool_compare_and_swap_16(volatile signed __int128 *, signed __int128, signed __int128,...);
    322206_Bool __sync_bool_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...);
    323 _Bool __sync_bool_compare_and_swap_16(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...);
    324207#endif
    325208forall(dtype T) _Bool __sync_bool_compare_and_swap(T * volatile *, T *, T*, ...);
    326209
    327210char __sync_val_compare_and_swap(volatile char *, char, char,...);
    328 char __sync_val_compare_and_swap_1(volatile char *, char, char,...);
    329211signed char __sync_val_compare_and_swap(volatile signed char *, signed char, signed char,...);
    330 signed char __sync_val_compare_and_swap_1(volatile signed char *, signed char, signed char,...);
    331212unsigned char __sync_val_compare_and_swap(volatile unsigned char *, unsigned char, unsigned char,...);
    332 unsigned char __sync_val_compare_and_swap_1(volatile unsigned char *, unsigned char, unsigned char,...);
    333213signed short __sync_val_compare_and_swap(volatile signed short *, signed short, signed short,...);
    334 signed short __sync_val_compare_and_swap_2(volatile signed short *, signed short, signed short,...);
    335214unsigned short __sync_val_compare_and_swap(volatile unsigned short *, unsigned short, unsigned short,...);
    336 unsigned short __sync_val_compare_and_swap_2(volatile unsigned short *, unsigned short, unsigned short,...);
    337215signed int __sync_val_compare_and_swap(volatile signed int *, signed int, signed int,...);
    338 signed int __sync_val_compare_and_swap_4(volatile signed int *, signed int, signed int,...);
    339216unsigned int __sync_val_compare_and_swap(volatile unsigned int *, unsigned int, unsigned int,...);
    340 unsigned int __sync_val_compare_and_swap_4(volatile unsigned int *, unsigned int, unsigned int,...);
     217signed long int __sync_val_compare_and_swap(volatile signed long int *, signed long int, signed long int,...);
     218unsigned long int __sync_val_compare_and_swap(volatile unsigned long int *, unsigned long int, unsigned long int,...);
    341219signed long long int __sync_val_compare_and_swap(volatile signed long long int *, signed long long int, signed long long int,...);
    342 signed long long int __sync_val_compare_and_swap_8(volatile signed long long int *, signed long long int, signed long long int,...);
    343220unsigned long long int __sync_val_compare_and_swap(volatile unsigned long long int *, unsigned long long int, unsigned long long int,...);
    344 unsigned long long int __sync_val_compare_and_swap_8(volatile unsigned long long int *, unsigned long long int, unsigned long long int,...);
    345221#if defined(__SIZEOF_INT128__)
    346222signed __int128 __sync_val_compare_and_swap(volatile signed __int128 *, signed __int128, signed __int128,...);
    347 signed __int128 __sync_val_compare_and_swap_16(volatile signed __int128 *, signed __int128, signed __int128,...);
    348223unsigned __int128 __sync_val_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...);
    349 unsigned __int128 __sync_val_compare_and_swap_16(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...);
    350224#endif
    351225forall(dtype T) T * __sync_val_compare_and_swap(T * volatile *, T *, T*,...);
    352226
    353227char __sync_lock_test_and_set(volatile char *, char,...);
    354 char __sync_lock_test_and_set_1(volatile char *, char,...);
    355228signed char __sync_lock_test_and_set(volatile signed char *, signed char,...);
    356 signed char __sync_lock_test_and_set_1(volatile signed char *, signed char,...);
    357229unsigned char __sync_lock_test_and_set(volatile unsigned char *, unsigned char,...);
    358 unsigned char __sync_lock_test_and_set_1(volatile unsigned char *, unsigned char,...);
    359230signed short __sync_lock_test_and_set(volatile signed short *, signed short,...);
    360 signed short __sync_lock_test_and_set_2(volatile signed short *, signed short,...);
    361231unsigned short __sync_lock_test_and_set(volatile unsigned short *, unsigned short,...);
    362 unsigned short __sync_lock_test_and_set_2(volatile unsigned short *, unsigned short,...);
    363232signed int __sync_lock_test_and_set(volatile signed int *, signed int,...);
    364 signed int __sync_lock_test_and_set_4(volatile signed int *, signed int,...);
    365233unsigned int __sync_lock_test_and_set(volatile unsigned int *, unsigned int,...);
    366 unsigned int __sync_lock_test_and_set_4(volatile unsigned int *, unsigned int,...);
     234signed long int __sync_lock_test_and_set(volatile signed long int *, signed long int,...);
     235unsigned long int __sync_lock_test_and_set(volatile unsigned long int *, unsigned long int,...);
    367236signed long long int __sync_lock_test_and_set(volatile signed long long int *, signed long long int,...);
    368 signed long long int __sync_lock_test_and_set_8(volatile signed long long int *, signed long long int,...);
    369237unsigned long long int __sync_lock_test_and_set(volatile unsigned long long int *, unsigned long long int,...);
    370 unsigned long long int __sync_lock_test_and_set_8(volatile unsigned long long int *, unsigned long long int,...);
    371238#if defined(__SIZEOF_INT128__)
    372239signed __int128 __sync_lock_test_and_set(volatile signed __int128 *, signed __int128,...);
    373 signed __int128 __sync_lock_test_and_set_16(volatile signed __int128 *, signed __int128,...);
    374240unsigned __int128 __sync_lock_test_and_set(volatile unsigned __int128 *, unsigned __int128,...);
    375 unsigned __int128 __sync_lock_test_and_set_16(volatile unsigned __int128 *, unsigned __int128,...);
    376241#endif
    377242
    378243void __sync_lock_release(volatile char *,...);
    379 void __sync_lock_release_1(volatile char *,...);
    380244void __sync_lock_release(volatile signed char *,...);
    381 void __sync_lock_release_1(volatile signed char *,...);
    382245void __sync_lock_release(volatile unsigned char *,...);
    383 void __sync_lock_release_1(volatile unsigned char *,...);
    384246void __sync_lock_release(volatile signed short *,...);
    385 void __sync_lock_release_2(volatile signed short *,...);
    386247void __sync_lock_release(volatile unsigned short *,...);
    387 void __sync_lock_release_2(volatile unsigned short *,...);
    388248void __sync_lock_release(volatile signed int *,...);
    389 void __sync_lock_release_4(volatile signed int *,...);
    390249void __sync_lock_release(volatile unsigned int *,...);
    391 void __sync_lock_release_4(volatile unsigned int *,...);
     250void __sync_lock_release(volatile signed long int *,...);
     251void __sync_lock_release(volatile unsigned long int *,...);
    392252void __sync_lock_release(volatile signed long long int *,...);
    393 void __sync_lock_release_8(volatile signed long long int *,...);
    394253void __sync_lock_release(volatile unsigned long long int *,...);
    395 void __sync_lock_release_8(volatile unsigned long long int *,...);
    396254#if defined(__SIZEOF_INT128__)
    397255void __sync_lock_release(volatile signed __int128 *,...);
    398 void __sync_lock_release_16(volatile signed __int128 *,...);
    399256void __sync_lock_release(volatile unsigned __int128 *,...);
    400 void __sync_lock_release_16(volatile unsigned __int128 *,...);
    401257#endif
    402258
     
    414270_Bool __atomic_test_and_set(volatile signed int *, int);
    415271_Bool __atomic_test_and_set(volatile unsigned int *, int);
     272_Bool __atomic_test_and_set(volatile signed long int *, int);
     273_Bool __atomic_test_and_set(volatile unsigned long int *, int);
    416274_Bool __atomic_test_and_set(volatile signed long long int *, int);
    417275_Bool __atomic_test_and_set(volatile unsigned long long int *, int);
     
    429287void __atomic_clear(volatile signed int *, int);
    430288void __atomic_clear(volatile unsigned int *, int);
     289void __atomic_clear(volatile signed long int *, int);
     290void __atomic_clear(volatile unsigned long int *, int);
    431291void __atomic_clear(volatile signed long long int *, int);
    432292void __atomic_clear(volatile unsigned long long int *, int);
     
    436296#endif
    437297
     298_Bool __atomic_exchange_n(volatile _Bool *, _Bool, int);
     299void __atomic_exchange(volatile _Bool *, volatile _Bool *, volatile _Bool *, int);
    438300char __atomic_exchange_n(volatile char *, char, int);
    439 char __atomic_exchange_1(volatile char *, char, int);
    440301void __atomic_exchange(volatile char *, volatile char *, volatile char *, int);
    441302signed char __atomic_exchange_n(volatile signed char *, signed char, int);
    442 signed char __atomic_exchange_1(volatile signed char *, signed char, int);
    443303void __atomic_exchange(volatile signed char *, volatile signed char *, volatile signed char *, int);
    444304unsigned char __atomic_exchange_n(volatile unsigned char *, unsigned char, int);
    445 unsigned char __atomic_exchange_1(volatile unsigned char *, unsigned char, int);
    446305void __atomic_exchange(volatile unsigned char *, volatile unsigned char *, volatile unsigned char *, int);
    447306signed short __atomic_exchange_n(volatile signed short *, signed short, int);
    448 signed short __atomic_exchange_2(volatile signed short *, signed short, int);
    449307void __atomic_exchange(volatile signed short *, volatile signed short *, volatile signed short *, int);
    450308unsigned short __atomic_exchange_n(volatile unsigned short *, unsigned short, int);
    451 unsigned short __atomic_exchange_2(volatile unsigned short *, unsigned short, int);
    452309void __atomic_exchange(volatile unsigned short *, volatile unsigned short *, volatile unsigned short *, int);
    453310signed int __atomic_exchange_n(volatile signed int *, signed int, int);
    454 signed int __atomic_exchange_4(volatile signed int *, signed int, int);
    455311void __atomic_exchange(volatile signed int *, volatile signed int *, volatile signed int *, int);
    456312unsigned int __atomic_exchange_n(volatile unsigned int *, unsigned int, int);
    457 unsigned int __atomic_exchange_4(volatile unsigned int *, unsigned int, int);
    458313void __atomic_exchange(volatile unsigned int *, volatile unsigned int *, volatile unsigned int *, int);
     314signed long int __atomic_exchange_n(volatile signed long int *, signed long int, int);
     315void __atomic_exchange(volatile signed long int *, volatile signed long int *, volatile signed long int *, int);
     316unsigned long int __atomic_exchange_n(volatile unsigned long int *, unsigned long int, int);
     317void __atomic_exchange(volatile unsigned long int *, volatile unsigned long int *, volatile unsigned long int *, int);
    459318signed long long int __atomic_exchange_n(volatile signed long long int *, signed long long int, int);
    460 signed long long int __atomic_exchange_8(volatile signed long long int *, signed long long int, int);
    461319void __atomic_exchange(volatile signed long long int *, volatile signed long long int *, volatile signed long long int *, int);
    462320unsigned long long int __atomic_exchange_n(volatile unsigned long long int *, unsigned long long int, int);
    463 unsigned long long int __atomic_exchange_8(volatile unsigned long long int *, unsigned long long int, int);
    464321void __atomic_exchange(volatile unsigned long long int *, volatile unsigned long long int *, volatile unsigned long long int *, int);
    465322#if defined(__SIZEOF_INT128__)
    466323signed __int128 __atomic_exchange_n(volatile signed __int128 *, signed __int128, int);
    467 signed __int128 __atomic_exchange_16(volatile signed __int128 *, signed __int128, int);
    468324void __atomic_exchange(volatile signed __int128 *, volatile signed __int128 *, volatile signed __int128 *, int);
    469325unsigned __int128 __atomic_exchange_n(volatile unsigned __int128 *, unsigned __int128, int);
    470 unsigned __int128 __atomic_exchange_16(volatile unsigned __int128 *, unsigned __int128, int);
    471326void __atomic_exchange(volatile unsigned __int128 *, volatile unsigned __int128 *, volatile unsigned __int128 *, int);
    472327#endif
     
    477332void __atomic_load(const volatile _Bool *, volatile _Bool *, int);
    478333char __atomic_load_n(const volatile char *, int);
    479 char __atomic_load_1(const volatile char *, int);
    480334void __atomic_load(const volatile char *, volatile char *, int);
    481335signed char __atomic_load_n(const volatile signed char *, int);
    482 signed char __atomic_load_1(const volatile signed char *, int);
    483336void __atomic_load(const volatile signed char *, volatile signed char *, int);
    484337unsigned char __atomic_load_n(const volatile unsigned char *, int);
    485 unsigned char __atomic_load_1(const volatile unsigned char *, int);
    486338void __atomic_load(const volatile unsigned char *, volatile unsigned char *, int);
    487339signed short __atomic_load_n(const volatile signed short *, int);
    488 signed short __atomic_load_2(const volatile signed short *, int);
    489340void __atomic_load(const volatile signed short *, volatile signed short *, int);
    490341unsigned short __atomic_load_n(const volatile unsigned short *, int);
    491 unsigned short __atomic_load_2(const volatile unsigned short *, int);
    492342void __atomic_load(const volatile unsigned short *, volatile unsigned short *, int);
    493343signed int __atomic_load_n(const volatile signed int *, int);
    494 signed int __atomic_load_4(const volatile signed int *, int);
    495344void __atomic_load(const volatile signed int *, volatile signed int *, int);
    496345unsigned int __atomic_load_n(const volatile unsigned int *, int);
    497 unsigned int __atomic_load_4(const volatile unsigned int *, int);
    498346void __atomic_load(const volatile unsigned int *, volatile unsigned int *, int);
     347signed long int __atomic_load_n(const volatile signed long int *, int);
     348void __atomic_load(const volatile signed long int *, volatile signed long int *, int);
     349unsigned long int __atomic_load_n(const volatile unsigned long int *, int);
     350void __atomic_load(const volatile unsigned long int *, volatile unsigned long int *, int);
    499351signed long long int __atomic_load_n(const volatile signed long long int *, int);
    500 signed long long int __atomic_load_8(const volatile signed long long int *, int);
    501352void __atomic_load(const volatile signed long long int *, volatile signed long long int *, int);
    502353unsigned long long int __atomic_load_n(const volatile unsigned long long int *, int);
    503 unsigned long long int __atomic_load_8(const volatile unsigned long long int *, int);
    504354void __atomic_load(const volatile unsigned long long int *, volatile unsigned long long int *, int);
    505355#if defined(__SIZEOF_INT128__)
    506356signed __int128 __atomic_load_n(const volatile signed __int128 *, int);
    507 signed __int128 __atomic_load_16(const volatile signed __int128 *, int);
    508357void __atomic_load(const volatile signed __int128 *, volatile signed __int128 *, int);
    509358unsigned __int128 __atomic_load_n(const volatile unsigned __int128 *, int);
    510 unsigned __int128 __atomic_load_16(const volatile unsigned __int128 *, int);
    511359void __atomic_load(const volatile unsigned __int128 *, volatile unsigned __int128 *, int);
    512360#endif
     
    515363
    516364_Bool __atomic_compare_exchange_n(volatile char *, char *, char, _Bool, int, int);
    517 _Bool __atomic_compare_exchange_1(volatile char *, char *, char, _Bool, int, int);
    518365_Bool __atomic_compare_exchange  (volatile char *, char *, char *, _Bool, int, int);
    519366_Bool __atomic_compare_exchange_n(volatile signed char *, signed char *, signed char, _Bool, int, int);
    520 _Bool __atomic_compare_exchange_1(volatile signed char *, signed char *, signed char, _Bool, int, int);
    521367_Bool __atomic_compare_exchange  (volatile signed char *, signed char *, signed char *, _Bool, int, int);
    522368_Bool __atomic_compare_exchange_n(volatile unsigned char *, unsigned char *, unsigned char, _Bool, int, int);
    523 _Bool __atomic_compare_exchange_1(volatile unsigned char *, unsigned char *, unsigned char, _Bool, int, int);
    524369_Bool __atomic_compare_exchange  (volatile unsigned char *, unsigned char *, unsigned char *, _Bool, int, int);
    525370_Bool __atomic_compare_exchange_n(volatile signed short *, signed short *, signed short, _Bool, int, int);
    526 _Bool __atomic_compare_exchange_2(volatile signed short *, signed short *, signed short, _Bool, int, int);
    527371_Bool __atomic_compare_exchange  (volatile signed short *, signed short *, signed short *, _Bool, int, int);
    528372_Bool __atomic_compare_exchange_n(volatile unsigned short *, unsigned short *, unsigned short, _Bool, int, int);
    529 _Bool __atomic_compare_exchange_2(volatile unsigned short *, unsigned short *, unsigned short, _Bool, int, int);
    530373_Bool __atomic_compare_exchange  (volatile unsigned short *, unsigned short *, unsigned short *, _Bool, int, int);
    531374_Bool __atomic_compare_exchange_n(volatile signed int *, signed int *, signed int, _Bool, int, int);
    532 _Bool __atomic_compare_exchange_4(volatile signed int *, signed int *, signed int, _Bool, int, int);
    533375_Bool __atomic_compare_exchange  (volatile signed int *, signed int *, signed int *, _Bool, int, int);
    534376_Bool __atomic_compare_exchange_n(volatile unsigned int *, unsigned int *, unsigned int, _Bool, int, int);
    535 _Bool __atomic_compare_exchange_4(volatile unsigned int *, unsigned int *, unsigned int, _Bool, int, int);
    536377_Bool __atomic_compare_exchange  (volatile unsigned int *, unsigned int *, unsigned int *, _Bool, int, int);
     378_Bool __atomic_compare_exchange_n(volatile signed long int *, signed long int *, signed long int, _Bool, int, int);
     379_Bool __atomic_compare_exchange  (volatile signed long int *, signed long int *, signed long int *, _Bool, int, int);
     380_Bool __atomic_compare_exchange_n(volatile unsigned long int *, unsigned long int *, unsigned long int, _Bool, int, int);
     381_Bool __atomic_compare_exchange  (volatile unsigned long int *, unsigned long int *, unsigned long int *, _Bool, int, int);
    537382_Bool __atomic_compare_exchange_n(volatile signed long long int *, signed long long int *, signed long long int, _Bool, int, int);
    538 _Bool __atomic_compare_exchange_8(volatile signed long long int *, signed long long int *, signed long long int, _Bool, int, int);
    539383_Bool __atomic_compare_exchange  (volatile signed long long int *, signed long long int *, signed long long int *, _Bool, int, int);
    540384_Bool __atomic_compare_exchange_n(volatile unsigned long long int *, unsigned long long int *, unsigned long long int, _Bool, int, int);
    541 _Bool __atomic_compare_exchange_8(volatile unsigned long long int *, unsigned long long int *, unsigned long long int, _Bool, int, int);
    542385_Bool __atomic_compare_exchange  (volatile unsigned long long int *, unsigned long long int *, unsigned long long int *, _Bool, int, int);
    543386#if defined(__SIZEOF_INT128__)
    544387_Bool __atomic_compare_exchange_n (volatile signed __int128 *, signed __int128 *, signed __int128, _Bool, int, int);
    545 _Bool __atomic_compare_exchange_16(volatile signed __int128 *, signed __int128 *, signed __int128, _Bool, int, int);
    546388_Bool __atomic_compare_exchange   (volatile signed __int128 *, signed __int128 *, signed __int128 *, _Bool, int, int);
    547389_Bool __atomic_compare_exchange_n (volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128, _Bool, int, int);
    548 _Bool __atomic_compare_exchange_16(volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128, _Bool, int, int);
    549390_Bool __atomic_compare_exchange   (volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128 *, _Bool, int, int);
    550391#endif
     
    555396void __atomic_store(volatile _Bool *, _Bool *, int);
    556397void __atomic_store_n(volatile char *, char, int);
    557 void __atomic_store_1(volatile char *, char, int);
    558398void __atomic_store(volatile char *, char *, int);
    559399void __atomic_store_n(volatile signed char *, signed char, int);
    560 void __atomic_store_1(volatile signed char *, signed char, int);
    561400void __atomic_store(volatile signed char *, signed char *, int);
    562401void __atomic_store_n(volatile unsigned char *, unsigned char, int);
    563 void __atomic_store_1(volatile unsigned char *, unsigned char, int);
    564402void __atomic_store(volatile unsigned char *, unsigned char *, int);
    565403void __atomic_store_n(volatile signed short *, signed short, int);
    566 void __atomic_store_2(volatile signed short *, signed short, int);
    567404void __atomic_store(volatile signed short *, signed short *, int);
    568405void __atomic_store_n(volatile unsigned short *, unsigned short, int);
    569 void __atomic_store_2(volatile unsigned short *, unsigned short, int);
    570406void __atomic_store(volatile unsigned short *, unsigned short *, int);
    571407void __atomic_store_n(volatile signed int *, signed int, int);
    572 void __atomic_store_4(volatile signed int *, signed int, int);
    573408void __atomic_store(volatile signed int *, signed int *, int);
    574409void __atomic_store_n(volatile unsigned int *, unsigned int, int);
    575 void __atomic_store_4(volatile unsigned int *, unsigned int, int);
    576410void __atomic_store(volatile unsigned int *, unsigned int *, int);
     411void __atomic_store_n(volatile signed long int *, signed long int, int);
     412void __atomic_store(volatile signed long int *, signed long int *, int);
     413void __atomic_store_n(volatile unsigned long int *, unsigned long int, int);
     414void __atomic_store(volatile unsigned long int *, unsigned long int *, int);
    577415void __atomic_store_n(volatile signed long long int *, signed long long int, int);
    578 void __atomic_store_8(volatile signed long long int *, signed long long int, int);
    579416void __atomic_store(volatile signed long long int *, signed long long int *, int);
    580417void __atomic_store_n(volatile unsigned long long int *, unsigned long long int, int);
    581 void __atomic_store_8(volatile unsigned long long int *, unsigned long long int, int);
    582418void __atomic_store(volatile unsigned long long int *, unsigned long long int *, int);
    583419#if defined(__SIZEOF_INT128__)
    584420void __atomic_store_n(volatile signed __int128 *, signed __int128, int);
    585 void __atomic_store_16(volatile signed __int128 *, signed __int128, int);
    586421void __atomic_store(volatile signed __int128 *, signed __int128 *, int);
    587422void __atomic_store_n(volatile unsigned __int128 *, unsigned __int128, int);
    588 void __atomic_store_16(volatile unsigned __int128 *, unsigned __int128, int);
    589423void __atomic_store(volatile unsigned __int128 *, unsigned __int128 *, int);
    590424#endif
     
    593427
    594428char __atomic_add_fetch  (volatile char *, char, int);
    595 char __atomic_add_fetch_1(volatile char *, char, int);
    596429signed char __atomic_add_fetch  (volatile signed char *, signed char, int);
    597 signed char __atomic_add_fetch_1(volatile signed char *, signed char, int);
    598430unsigned char __atomic_add_fetch  (volatile unsigned char *, unsigned char, int);
    599 unsigned char __atomic_add_fetch_1(volatile unsigned char *, unsigned char, int);
    600431signed short __atomic_add_fetch  (volatile signed short *, signed short, int);
    601 signed short __atomic_add_fetch_2(volatile signed short *, signed short, int);
    602432unsigned short __atomic_add_fetch  (volatile unsigned short *, unsigned short, int);
    603 unsigned short __atomic_add_fetch_2(volatile unsigned short *, unsigned short, int);
    604433signed int __atomic_add_fetch  (volatile signed int *, signed int, int);
    605 signed int __atomic_add_fetch_4(volatile signed int *, signed int, int);
    606434unsigned int __atomic_add_fetch  (volatile unsigned int *, unsigned int, int);
    607 unsigned int __atomic_add_fetch_4(volatile unsigned int *, unsigned int, int);
     435signed long int __atomic_add_fetch  (volatile signed long int *, signed long int, int);
     436unsigned long int __atomic_add_fetch  (volatile unsigned long int *, unsigned long int, int);
    608437signed long long int __atomic_add_fetch  (volatile signed long long int *, signed long long int, int);
    609 signed long long int __atomic_add_fetch_8(volatile signed long long int *, signed long long int, int);
    610438unsigned long long int __atomic_add_fetch  (volatile unsigned long long int *, unsigned long long int, int);
    611 unsigned long long int __atomic_add_fetch_8(volatile unsigned long long int *, unsigned long long int, int);
    612439#if defined(__SIZEOF_INT128__)
    613440signed __int128 __atomic_add_fetch   (volatile signed __int128 *, signed __int128, int);
    614 signed __int128 __atomic_add_fetch_16(volatile signed __int128 *, signed __int128, int);
    615441unsigned __int128 __atomic_add_fetch   (volatile unsigned __int128 *, unsigned __int128, int);
    616 unsigned __int128 __atomic_add_fetch_16(volatile unsigned __int128 *, unsigned __int128, int);
    617442#endif
    618443
    619444char __atomic_sub_fetch  (volatile char *, char, int);
    620 char __atomic_sub_fetch_1(volatile char *, char, int);
    621445signed char __atomic_sub_fetch  (volatile signed char *, signed char, int);
    622 signed char __atomic_sub_fetch_1(volatile signed char *, signed char, int);
    623446unsigned char __atomic_sub_fetch  (volatile unsigned char *, unsigned char, int);
    624 unsigned char __atomic_sub_fetch_1(volatile unsigned char *, unsigned char, int);
    625447signed short __atomic_sub_fetch  (volatile signed short *, signed short, int);
    626 signed short __atomic_sub_fetch_2(volatile signed short *, signed short, int);
    627448unsigned short __atomic_sub_fetch  (volatile unsigned short *, unsigned short, int);
    628 unsigned short __atomic_sub_fetch_2(volatile unsigned short *, unsigned short, int);
    629449signed int __atomic_sub_fetch  (volatile signed int *, signed int, int);
    630 signed int __atomic_sub_fetch_4(volatile signed int *, signed int, int);
    631450unsigned int __atomic_sub_fetch  (volatile unsigned int *, unsigned int, int);
    632 unsigned int __atomic_sub_fetch_4(volatile unsigned int *, unsigned int, int);
     451signed long long int __atomic_sub_fetch  (volatile signed long int *, signed long int, int);
     452unsigned long long int __atomic_sub_fetch  (volatile unsigned long int *, unsigned long int, int);
    633453signed long long int __atomic_sub_fetch  (volatile signed long long int *, signed long long int, int);
    634 signed long long int __atomic_sub_fetch_8(volatile signed long long int *, signed long long int, int);
    635454unsigned long long int __atomic_sub_fetch  (volatile unsigned long long int *, unsigned long long int, int);
    636 unsigned long long int __atomic_sub_fetch_8(volatile unsigned long long int *, unsigned long long int, int);
    637455#if defined(__SIZEOF_INT128__)
    638456signed __int128 __atomic_sub_fetch   (volatile signed __int128 *, signed __int128, int);
    639 signed __int128 __atomic_sub_fetch_16(volatile signed __int128 *, signed __int128, int);
    640457unsigned __int128 __atomic_sub_fetch   (volatile unsigned __int128 *, unsigned __int128, int);
    641 unsigned __int128 __atomic_sub_fetch_16(volatile unsigned __int128 *, unsigned __int128, int);
    642458#endif
    643459
    644460char __atomic_and_fetch  (volatile char *, char, int);
    645 char __atomic_and_fetch_1(volatile char *, char, int);
    646461signed char __atomic_and_fetch  (volatile signed char *, signed char, int);
    647 signed char __atomic_and_fetch_1(volatile signed char *, signed char, int);
    648462unsigned char __atomic_and_fetch  (volatile unsigned char *, unsigned char, int);
    649 unsigned char __atomic_and_fetch_1(volatile unsigned char *, unsigned char, int);
    650463signed short __atomic_and_fetch  (volatile signed short *, signed short, int);
    651 signed short __atomic_and_fetch_2(volatile signed short *, signed short, int);
    652464unsigned short __atomic_and_fetch  (volatile unsigned short *, unsigned short, int);
    653 unsigned short __atomic_and_fetch_2(volatile unsigned short *, unsigned short, int);
    654465signed int __atomic_and_fetch  (volatile signed int *, signed int, int);
    655 signed int __atomic_and_fetch_4(volatile signed int *, signed int, int);
    656466unsigned int __atomic_and_fetch  (volatile unsigned int *, unsigned int, int);
    657 unsigned int __atomic_and_fetch_4(volatile unsigned int *, unsigned int, int);
     467signed long int __atomic_and_fetch  (volatile signed long int *, signed long int, int);
     468unsigned long int __atomic_and_fetch  (volatile unsigned long int *, unsigned long int, int);
    658469signed long long int __atomic_and_fetch  (volatile signed long long int *, signed long long int, int);
    659 signed long long int __atomic_and_fetch_8(volatile signed long long int *, signed long long int, int);
    660470unsigned long long int __atomic_and_fetch  (volatile unsigned long long int *, unsigned long long int, int);
    661 unsigned long long int __atomic_and_fetch_8(volatile unsigned long long int *, unsigned long long int, int);
    662471#if defined(__SIZEOF_INT128__)
    663472signed __int128 __atomic_and_fetch   (volatile signed __int128 *, signed __int128, int);
    664 signed __int128 __atomic_and_fetch_16(volatile signed __int128 *, signed __int128, int);
    665473unsigned __int128 __atomic_and_fetch   (volatile unsigned __int128 *, unsigned __int128, int);
    666 unsigned __int128 __atomic_and_fetch_16(volatile unsigned __int128 *, unsigned __int128, int);
    667474#endif
    668475
    669476char __atomic_nand_fetch  (volatile char *, char, int);
    670 char __atomic_nand_fetch_1(volatile char *, char, int);
    671477signed char __atomic_nand_fetch  (volatile signed char *, signed char, int);
    672 signed char __atomic_nand_fetch_1(volatile signed char *, signed char, int);
    673478unsigned char __atomic_nand_fetch  (volatile unsigned char *, unsigned char, int);
    674 unsigned char __atomic_nand_fetch_1(volatile unsigned char *, unsigned char, int);
    675479signed short __atomic_nand_fetch  (volatile signed short *, signed short, int);
    676 signed short __atomic_nand_fetch_2(volatile signed short *, signed short, int);
    677480unsigned short __atomic_nand_fetch  (volatile unsigned short *, unsigned short, int);
    678 unsigned short __atomic_nand_fetch_2(volatile unsigned short *, unsigned short, int);
    679481signed int __atomic_nand_fetch  (volatile signed int *, signed int, int);
    680 signed int __atomic_nand_fetch_4(volatile signed int *, signed int, int);
    681482unsigned int __atomic_nand_fetch  (volatile unsigned int *, unsigned int, int);
    682 unsigned int __atomic_nand_fetch_4(volatile unsigned int *, unsigned int, int);
     483signed long int __atomic_nand_fetch  (volatile signed long int *, signed long int, int);
     484unsigned long int __atomic_nand_fetch  (volatile unsigned long int *, unsigned long int, int);
    683485signed long long int __atomic_nand_fetch  (volatile signed long long int *, signed long long int, int);
    684 signed long long int __atomic_nand_fetch_8(volatile signed long long int *, signed long long int, int);
    685486unsigned long long int __atomic_nand_fetch  (volatile unsigned long long int *, unsigned long long int, int);
    686 unsigned long long int __atomic_nand_fetch_8(volatile unsigned long long int *, unsigned long long int, int);
    687487#if defined(__SIZEOF_INT128__)
    688488signed __int128 __atomic_nand_fetch   (volatile signed __int128 *, signed __int128, int);
    689 signed __int128 __atomic_nand_fetch_16(volatile signed __int128 *, signed __int128, int);
    690489unsigned __int128 __atomic_nand_fetch   (volatile unsigned __int128 *, unsigned __int128, int);
    691 unsigned __int128 __atomic_nand_fetch_16(volatile unsigned __int128 *, unsigned __int128, int);
    692490#endif
    693491
    694492char __atomic_xor_fetch  (volatile char *, char, int);
    695 char __atomic_xor_fetch_1(volatile char *, char, int);
    696493signed char __atomic_xor_fetch  (volatile signed char *, signed char, int);
    697 signed char __atomic_xor_fetch_1(volatile signed char *, signed char, int);
    698494unsigned char __atomic_xor_fetch  (volatile unsigned char *, unsigned char, int);
    699 unsigned char __atomic_xor_fetch_1(volatile unsigned char *, unsigned char, int);
    700495signed short __atomic_xor_fetch  (volatile signed short *, signed short, int);
    701 signed short __atomic_xor_fetch_2(volatile signed short *, signed short, int);
    702496unsigned short __atomic_xor_fetch  (volatile unsigned short *, unsigned short, int);
    703 unsigned short __atomic_xor_fetch_2(volatile unsigned short *, unsigned short, int);
    704497signed int __atomic_xor_fetch  (volatile signed int *, signed int, int);
    705 signed int __atomic_xor_fetch_4(volatile signed int *, signed int, int);
    706498unsigned int __atomic_xor_fetch  (volatile unsigned int *, unsigned int, int);
    707 unsigned int __atomic_xor_fetch_4(volatile unsigned int *, unsigned int, int);
     499signed long int __atomic_xor_fetch  (volatile signed long int *, signed long int, int);
     500unsigned long int __atomic_xor_fetch  (volatile unsigned long int *, unsigned long int, int);
    708501signed long long int __atomic_xor_fetch  (volatile signed long long int *, signed long long int, int);
    709 signed long long int __atomic_xor_fetch_8(volatile signed long long int *, signed long long int, int);
    710502unsigned long long int __atomic_xor_fetch  (volatile unsigned long long int *, unsigned long long int, int);
    711 unsigned long long int __atomic_xor_fetch_8(volatile unsigned long long int *, unsigned long long int, int);
    712503#if defined(__SIZEOF_INT128__)
    713504signed __int128 __atomic_xor_fetch   (volatile signed __int128 *, signed __int128, int);
    714 signed __int128 __atomic_xor_fetch_16(volatile signed __int128 *, signed __int128, int);
    715505unsigned __int128 __atomic_xor_fetch   (volatile unsigned __int128 *, unsigned __int128, int);
    716 unsigned __int128 __atomic_xor_fetch_16(volatile unsigned __int128 *, unsigned __int128, int);
    717506#endif
    718507
    719508char __atomic_or_fetch  (volatile char *, char, int);
    720 char __atomic_or_fetch_1(volatile char *, char, int);
    721509signed char __atomic_or_fetch  (volatile signed char *, signed char, int);
    722 signed char __atomic_or_fetch_1(volatile signed char *, signed char, int);
    723510unsigned char __atomic_or_fetch  (volatile unsigned char *, unsigned char, int);
    724 unsigned char __atomic_or_fetch_1(volatile unsigned char *, unsigned char, int);
    725511signed short __atomic_or_fetch  (volatile signed short *, signed short, int);
    726 signed short __atomic_or_fetch_2(volatile signed short *, signed short, int);
    727512unsigned short __atomic_or_fetch  (volatile unsigned short *, unsigned short, int);
    728 unsigned short __atomic_or_fetch_2(volatile unsigned short *, unsigned short, int);
    729513signed int __atomic_or_fetch  (volatile signed int *, signed int, int);
    730 signed int __atomic_or_fetch_4(volatile signed int *, signed int, int);
    731514unsigned int __atomic_or_fetch  (volatile unsigned int *, unsigned int, int);
    732 unsigned int __atomic_or_fetch_4(volatile unsigned int *, unsigned int, int);
     515signed long int __atomic_or_fetch  (volatile signed long int *, signed long int, int);
     516unsigned long int __atomic_or_fetch  (volatile unsigned long int *, unsigned long int, int);
    733517signed long long int __atomic_or_fetch  (volatile signed long long int *, signed long long int, int);
    734 signed long long int __atomic_or_fetch_8(volatile signed long long int *, signed long long int, int);
    735518unsigned long long int __atomic_or_fetch  (volatile unsigned long long int *, unsigned long long int, int);
    736 unsigned long long int __atomic_or_fetch_8(volatile unsigned long long int *, unsigned long long int, int);
    737519#if defined(__SIZEOF_INT128__)
    738520signed __int128 __atomic_or_fetch   (volatile signed __int128 *, signed __int128, int);
    739 signed __int128 __atomic_or_fetch_16(volatile signed __int128 *, signed __int128, int);
    740521unsigned __int128 __atomic_or_fetch   (volatile unsigned __int128 *, unsigned __int128, int);
    741 unsigned __int128 __atomic_or_fetch_16(volatile unsigned __int128 *, unsigned __int128, int);
    742522#endif
    743523
    744524char __atomic_fetch_add  (volatile char *, char, int);
    745 char __atomic_fetch_add_1(volatile char *, char, int);
    746525signed char __atomic_fetch_add  (volatile signed char *, signed char, int);
    747 signed char __atomic_fetch_add_1(volatile signed char *, signed char, int);
    748526unsigned char __atomic_fetch_add  (volatile unsigned char *, unsigned char, int);
    749 unsigned char __atomic_fetch_add_1(volatile unsigned char *, unsigned char, int);
    750527signed short __atomic_fetch_add  (volatile signed short *, signed short, int);
    751 signed short __atomic_fetch_add_2(volatile signed short *, signed short, int);
    752528unsigned short __atomic_fetch_add  (volatile unsigned short *, unsigned short, int);
    753 unsigned short __atomic_fetch_add_2(volatile unsigned short *, unsigned short, int);
    754529signed int __atomic_fetch_add  (volatile signed int *, signed int, int);
    755 signed int __atomic_fetch_add_4(volatile signed int *, signed int, int);
    756530unsigned int __atomic_fetch_add  (volatile unsigned int *, unsigned int, int);
    757 unsigned int __atomic_fetch_add_4(volatile unsigned int *, unsigned int, int);
     531signed long int __atomic_fetch_add  (volatile signed long int *, signed long int, int);
     532unsigned long int __atomic_fetch_add  (volatile unsigned long int *, unsigned long int, int);
    758533signed long long int __atomic_fetch_add  (volatile signed long long int *, signed long long int, int);
    759 signed long long int __atomic_fetch_add_8(volatile signed long long int *, signed long long int, int);
    760534unsigned long long int __atomic_fetch_add  (volatile unsigned long long int *, unsigned long long int, int);
    761 unsigned long long int __atomic_fetch_add_8(volatile unsigned long long int *, unsigned long long int, int);
    762535#if defined(__SIZEOF_INT128__)
    763536signed __int128 __atomic_fetch_add   (volatile signed __int128 *, signed __int128, int);
    764 signed __int128 __atomic_fetch_add_16(volatile signed __int128 *, signed __int128, int);
    765537unsigned __int128 __atomic_fetch_add   (volatile unsigned __int128 *, unsigned __int128, int);
    766 unsigned __int128 __atomic_fetch_add_16(volatile unsigned __int128 *, unsigned __int128, int);
    767538#endif
    768539
    769540char __atomic_fetch_sub  (volatile char *, char, int);
    770 char __atomic_fetch_sub_1(volatile char *, char, int);
    771541signed char __atomic_fetch_sub  (volatile signed char *, signed char, int);
    772 signed char __atomic_fetch_sub_1(volatile signed char *, signed char, int);
    773542unsigned char __atomic_fetch_sub  (volatile unsigned char *, unsigned char, int);
    774 unsigned char __atomic_fetch_sub_1(volatile unsigned char *, unsigned char, int);
    775543signed short __atomic_fetch_sub  (volatile signed short *, signed short, int);
    776 signed short __atomic_fetch_sub_2(volatile signed short *, signed short, int);
    777544unsigned short __atomic_fetch_sub  (volatile unsigned short *, unsigned short, int);
    778 unsigned short __atomic_fetch_sub_2(volatile unsigned short *, unsigned short, int);
    779545signed int __atomic_fetch_sub  (volatile signed int *, signed int, int);
    780 signed int __atomic_fetch_sub_4(volatile signed int *, signed int, int);
    781546unsigned int __atomic_fetch_sub  (volatile unsigned int *, unsigned int, int);
    782 unsigned int __atomic_fetch_sub_4(volatile unsigned int *, unsigned int, int);
     547signed long int __atomic_fetch_sub  (volatile signed long int *, signed long int, int);
     548unsigned long int __atomic_fetch_sub  (volatile unsigned long int *, unsigned long int, int);
    783549signed long long int __atomic_fetch_sub  (volatile signed long long int *, signed long long int, int);
    784 signed long long int __atomic_fetch_sub_8(volatile signed long long int *, signed long long int, int);
    785550unsigned long long int __atomic_fetch_sub  (volatile unsigned long long int *, unsigned long long int, int);
    786 unsigned long long int __atomic_fetch_sub_8(volatile unsigned long long int *, unsigned long long int, int);
    787551#if defined(__SIZEOF_INT128__)
    788552signed __int128 __atomic_fetch_sub   (volatile signed  __int128 *, signed __int128, int);
    789 signed __int128 __atomic_fetch_sub_16(volatile signed  __int128 *, signed __int128, int);
    790553unsigned __int128 __atomic_fetch_sub   (volatile unsigned  __int128 *, unsigned __int128, int);
    791 unsigned __int128 __atomic_fetch_sub_16(volatile unsigned  __int128 *, unsigned __int128, int);
    792554#endif
    793555
    794556char __atomic_fetch_and  (volatile char *, char, int);
    795 char __atomic_fetch_and_1(volatile char *, char, int);
    796557signed char __atomic_fetch_and  (volatile signed char *, signed char, int);
    797 signed char __atomic_fetch_and_1(volatile signed char *, signed char, int);
    798558unsigned char __atomic_fetch_and  (volatile unsigned char *, unsigned char, int);
    799 unsigned char __atomic_fetch_and_1(volatile unsigned char *, unsigned char, int);
    800559signed short __atomic_fetch_and  (volatile signed short *, signed short, int);
    801 signed short __atomic_fetch_and_2(volatile signed short *, signed short, int);
    802560unsigned short __atomic_fetch_and  (volatile unsigned short *, unsigned short, int);
    803 unsigned short __atomic_fetch_and_2(volatile unsigned short *, unsigned short, int);
    804561signed int __atomic_fetch_and  (volatile signed int *, signed int, int);
    805 signed int __atomic_fetch_and_4(volatile signed int *, signed int, int);
    806562unsigned int __atomic_fetch_and  (volatile unsigned int *, unsigned int, int);
    807 unsigned int __atomic_fetch_and_4(volatile unsigned int *, unsigned int, int);
     563signed long int __atomic_fetch_and  (volatile signed long int *, signed long int, int);
     564unsigned long int __atomic_fetch_and  (volatile unsigned long int *, unsigned long int, int);
    808565signed long long int __atomic_fetch_and  (volatile signed long long int *, signed long long int, int);
    809 signed long long int __atomic_fetch_and_8(volatile signed long long int *, signed long long int, int);
    810566unsigned long long int __atomic_fetch_and  (volatile unsigned long long int *, unsigned long long int, int);
    811 unsigned long long int __atomic_fetch_and_8(volatile unsigned long long int *, unsigned long long int, int);
    812567#if defined(__SIZEOF_INT128__)
    813568signed __int128 __atomic_fetch_and   (volatile signed __int128 *, signed __int128, int);
    814 signed __int128 __atomic_fetch_and_16(volatile signed __int128 *, signed __int128, int);
    815569unsigned __int128 __atomic_fetch_and   (volatile unsigned __int128 *, unsigned __int128, int);
    816 unsigned __int128 __atomic_fetch_and_16(volatile unsigned __int128 *, unsigned __int128, int);
    817570#endif
    818571
    819572char __atomic_fetch_nand  (volatile char *, char, int);
    820 char __atomic_fetch_nand_1(volatile char *, char, int);
    821573signed char __atomic_fetch_nand  (volatile signed char *, signed char, int);
    822 signed char __atomic_fetch_nand_1(volatile signed char *, signed char, int);
    823574unsigned char __atomic_fetch_nand  (volatile unsigned char *, unsigned char, int);
    824 unsigned char __atomic_fetch_nand_1(volatile unsigned char *, unsigned char, int);
    825575signed short __atomic_fetch_nand  (volatile signed short *, signed short, int);
    826 signed short __atomic_fetch_nand_2(volatile signed short *, signed short, int);
    827576unsigned short __atomic_fetch_nand  (volatile unsigned short *, unsigned short, int);
    828 unsigned short __atomic_fetch_nand_2(volatile unsigned short *, unsigned short, int);
    829577signed int __atomic_fetch_nand  (volatile signed int *, signed int, int);
    830 signed int __atomic_fetch_nand_4(volatile signed int *, signed int, int);
    831578unsigned int __atomic_fetch_nand  (volatile unsigned int *, unsigned int, int);
    832 unsigned int __atomic_fetch_nand_4(volatile unsigned int *, unsigned int, int);
     579signed long int __atomic_fetch_nand  (volatile signed long int *, signed long int, int);
     580unsigned long int __atomic_fetch_nand  (volatile unsigned long int *, unsigned long int, int);
    833581signed long long int __atomic_fetch_nand  (volatile signed long long int *, signed long long int, int);
    834 signed long long int __atomic_fetch_nand_8(volatile signed long long int *, signed long long int, int);
    835582unsigned long long int __atomic_fetch_nand  (volatile unsigned long long int *, unsigned long long int, int);
    836 unsigned long long int __atomic_fetch_nand_8(volatile unsigned long long int *, unsigned long long int, int);
    837583#if defined(__SIZEOF_INT128__)
    838584signed __int128 __atomic_fetch_nand   (volatile signed __int128 *, signed __int128, int);
    839 signed __int128 __atomic_fetch_nand_16(volatile signed __int128 *, signed __int128, int);
    840585unsigned __int128 __atomic_fetch_nand   (volatile unsigned __int128 *, unsigned __int128, int);
    841 unsigned __int128 __atomic_fetch_nand_16(volatile unsigned __int128 *, unsigned __int128, int);
    842586#endif
    843587
    844588char __atomic_fetch_xor  (volatile char *, char, int);
    845 char __atomic_fetch_xor_1(volatile char *, char, int);
    846589signed char __atomic_fetch_xor  (volatile signed char *, signed char, int);
    847 signed char __atomic_fetch_xor_1(volatile signed char *, signed char, int);
    848590unsigned char __atomic_fetch_xor  (volatile unsigned char *, unsigned char, int);
    849 unsigned char __atomic_fetch_xor_1(volatile unsigned char *, unsigned char, int);
    850591signed short __atomic_fetch_xor  (volatile signed short *, signed short, int);
    851 signed short __atomic_fetch_xor_2(volatile signed short *, signed short, int);
    852592unsigned short __atomic_fetch_xor  (volatile unsigned short *, unsigned short, int);
    853 unsigned short __atomic_fetch_xor_2(volatile unsigned short *, unsigned short, int);
    854593signed int __atomic_fetch_xor  (volatile signed int *, signed int, int);
    855 signed int __atomic_fetch_xor_4(volatile signed int *, signed int, int);
    856594unsigned int __atomic_fetch_xor  (volatile unsigned int *, unsigned int, int);
    857 unsigned int __atomic_fetch_xor_4(volatile unsigned int *, unsigned int, int);
     595signed long int __atomic_fetch_xor  (volatile signed long int *, signed long int, int);
     596unsigned long int __atomic_fetch_xor  (volatile unsigned long int *, unsigned long int, int);
    858597signed long long int __atomic_fetch_xor  (volatile signed long long int *, signed long long int, int);
    859 signed long long int __atomic_fetch_xor_8(volatile signed long long int *, signed long long int, int);
    860598unsigned long long int __atomic_fetch_xor  (volatile unsigned long long int *, unsigned long long int, int);
    861 unsigned long long int __atomic_fetch_xor_8(volatile unsigned long long int *, unsigned long long int, int);
    862599#if defined(__SIZEOF_INT128__)
    863600signed __int128 __atomic_fetch_xor   (volatile signed __int128 *, signed __int128, int);
    864 signed __int128 __atomic_fetch_xor_16(volatile signed __int128 *, signed __int128, int);
    865601unsigned __int128 __atomic_fetch_xor   (volatile unsigned __int128 *, unsigned __int128, int);
    866 unsigned __int128 __atomic_fetch_xor_16(volatile unsigned __int128 *, unsigned __int128, int);
    867602#endif
    868603
    869604char __atomic_fetch_or  (volatile char *, char, int);
    870 char __atomic_fetch_or_1(volatile char *, char, int);
    871605signed char __atomic_fetch_or  (volatile signed char *, signed char, int);
    872 signed char __atomic_fetch_or_1(volatile signed char *, signed char, int);
    873606unsigned char __atomic_fetch_or  (volatile unsigned char *, unsigned char, int);
    874 unsigned char __atomic_fetch_or_1(volatile unsigned char *, unsigned char, int);
    875607signed short __atomic_fetch_or  (volatile signed short *, signed short, int);
    876 signed short __atomic_fetch_or_2(volatile signed short *, signed short, int);
    877608unsigned short __atomic_fetch_or  (volatile unsigned short *, unsigned short, int);
    878 unsigned short __atomic_fetch_or_2(volatile unsigned short *, unsigned short, int);
    879609signed int __atomic_fetch_or  (volatile signed int *, signed int, int);
    880 signed int __atomic_fetch_or_4(volatile signed int *, signed int, int);
    881610unsigned int __atomic_fetch_or  (volatile unsigned int *, unsigned int, int);
    882 unsigned int __atomic_fetch_or_4(volatile unsigned int *, unsigned int, int);
     611signed long int __atomic_fetch_or  (volatile signed long int *, signed long int, int);
     612unsigned long int __atomic_fetch_or  (volatile unsigned long int *, unsigned long int, int);
    883613signed long long int __atomic_fetch_or  (volatile signed long long int *, signed long long int, int);
    884 signed long long int __atomic_fetch_or_8(volatile signed long long int *, signed long long int, int);
    885614unsigned long long int __atomic_fetch_or  (volatile unsigned long long int *, unsigned long long int, int);
    886 unsigned long long int __atomic_fetch_or_8(volatile unsigned long long int *, unsigned long long int, int);
    887615#if defined(__SIZEOF_INT128__)
    888616signed __int128 __atomic_fetch_or   (volatile signed __int128 *, signed __int128, int);
    889 signed __int128 __atomic_fetch_or_16(volatile signed __int128 *, signed __int128, int);
    890617unsigned __int128 __atomic_fetch_or   (volatile unsigned __int128 *, unsigned __int128, int);
    891 unsigned __int128 __atomic_fetch_or_16(volatile unsigned __int128 *, unsigned __int128, int);
    892618#endif
    893619
  • libcfa/src/Makefile.am

    r9fb8f01 r3d5701e  
    3232# use -no-include-stdhdr to prevent rebuild cycles
    3333# The built sources must not depend on the installed headers
    34 AM_CFAFLAGS = -quiet -in-tree -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
    35 AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@
     34AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
     35AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC -pthread @ARCH_FLAGS@ @CONFIG_CFLAGS@
    3636AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@
    3737CFACC = @CFACC@
     
    6464# add dependency of cfa files
    6565libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(libsrc))))
    66 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     66$(libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
    6767
    6868thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
    69 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     69$(thread_libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
    7070
    7171
     
    8686
    8787
    88 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
    89         ${AM_V_GEN}$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
     88if ENABLE_DISTCC
    9089
    91 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
     90../prelude/distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ ../prelude/gcc-builtins.cf ../prelude/builtins.cf ../prelude/extras.cf ../prelude/prelude.cfa ../prelude/bootloader.c $(srcdir)/../../tools/build/push2dist.sh
     91        @+make -C ../prelude distribution
     92
     93prelude.o prelude.lo $(libobjs) $(thread_libobjs) : ../prelude/distribution
     94
     95endif ENABLE_DISTCC
     96
     97prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
     98        ${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@}
     99
     100prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
    92101        ${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
    93         $(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
    94 
     102        $(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@}
    95103
    96104#----------------------------------------------------------------------------------------------------------------
  • libcfa/src/Makefile.in

    r9fb8f01 r3d5701e  
    284284CFACC = @CFACC@
    285285CFACPP = @CFACPP@
     286CFADIR_HASH = @CFADIR_HASH@
    286287CFA_BINDIR = @CFA_BINDIR@
    287288CFA_INCDIR = @CFA_INCDIR@
     
    327328LIPO = @LIPO@
    328329LN_S = @LN_S@
     330LOCAL_CC1 = @LOCAL_CC1@
     331LOCAL_CFACC = @LOCAL_CFACC@
    329332LTLIBOBJS = @LTLIBOBJS@
    330333LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
     
    413416LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
    414417        $(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \
    415         $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \
    416         $(AM_CFLAGS) $(CFLAGS)
     418        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(AM_CFLAGS) $(CFAFLAGS) $(CFLAGS)
    417419
    418420AM_V_CFA = $(am__v_CFA_@AM_V@)
     
    420422am__v_CFA_0 = @echo "  CFA     " $@;
    421423am__v_CFA_1 =
    422 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
    423 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
    424 am__v_JAVAC_0 = @echo "  JAVAC   " $@;
    425 am__v_JAVAC_1 =
    426 AM_V_GOC = $(am__v_GOC_@AM_V@)
    427 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
    428 am__v_GOC_0 = @echo "  GOC     " $@;
    429 am__v_GOC_1 =
    430424UPPCC = u++
    431425UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
     
    434428am__v_UPP_0 = @echo "  UPP     " $@;
    435429am__v_UPP_1 =
     430AM_V_GOC = $(am__v_GOC_@AM_V@)
     431am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
     432am__v_GOC_0 = @echo "  GOC     " $@;
     433am__v_GOC_1 =
     434AM_V_RUST = $(am__v_RUST_@AM_V@)
     435am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
     436am__v_RUST_0 = @echo "  RUST     " $@;
     437am__v_RUST_1 =
     438AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
     439am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
     440am__v_NODEJS_0 = @echo "  NODEJS     " $@;
     441am__v_NODEJS_1 =
     442AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     443am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
     444am__v_JAVAC_0 = @echo "  JAVAC   " $@;
     445am__v_JAVAC_1 =
    436446lib_LTLIBRARIES = libcfa.la libcfathread.la
    437447gdbwaittarget = ""
     
    441451# use -no-include-stdhdr to prevent rebuild cycles
    442452# The built sources must not depend on the installed headers
    443 AM_CFAFLAGS = -quiet -in-tree -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
    444 AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@
     453AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
     454AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC -pthread @ARCH_FLAGS@ @CONFIG_CFLAGS@
    445455AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@
    446456@BUILDLIB_FALSE@headers_nosrc =
     
    937947        $(LTCFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
    938948        $(am__mv) $$depbase.Tpo $$depbase.Plo
    939 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    940 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     949$(libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
     950$(thread_libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
    941951
    942952-include $(libdeps)
     
    944954-include $(thread_libdeps)
    945955
    946 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
    947         ${AM_V_GEN}$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
    948 
    949 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
     956@ENABLE_DISTCC_TRUE@../prelude/distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ ../prelude/gcc-builtins.cf ../prelude/builtins.cf ../prelude/extras.cf ../prelude/prelude.cfa ../prelude/bootloader.c $(srcdir)/../../tools/build/push2dist.sh
     957@ENABLE_DISTCC_TRUE@    @+make -C ../prelude distribution
     958
     959@ENABLE_DISTCC_TRUE@prelude.o prelude.lo $(libobjs) $(thread_libobjs) : ../prelude/distribution
     960
     961prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
     962        ${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@}
     963
     964prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
    950965        ${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
    951         $(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
     966        $(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@}
    952967
    953968#----------------------------------------------------------------------------------------------------------------
  • libcfa/src/assert.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 20 15:10:26 2017
    13 // Update Count     : 2
     12// Last Modified On : Tue Feb  4 13:00:18 2020
     13// Update Count     : 6
    1414//
    1515
     
    1717#include <stdarg.h>                                                             // varargs
    1818#include <stdio.h>                                                              // fprintf
     19#include <unistd.h>                                                             // STDERR_FILENO
    1920#include "bits/debug.hfa"
    2021
     
    2526
    2627        // called by macro assert in assert.h
    27         void __assert_fail( const char *assertion, const char *file, unsigned int line, const char *function ) {
    28                 __cfaabi_dbg_bits_print_safe( CFA_ASSERT_FMT ".\n", assertion, __progname, function, line, file );
     28        void __assert_fail( const char assertion[], const char file[], unsigned int line, const char function[] ) {
     29                __cfaabi_bits_print_safe( STDERR_FILENO, CFA_ASSERT_FMT ".\n", assertion, __progname, function, line, file );
    2930                abort();
    3031        }
    3132
    3233        // called by macro assertf
    33         void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) {
    34                 __cfaabi_dbg_bits_acquire();
    35                 __cfaabi_dbg_bits_print_nolock( CFA_ASSERT_FMT ": ", assertion, __progname, function, line, file );
     34        void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) {
     35                __cfaabi_bits_acquire();
     36                __cfaabi_bits_print_nolock( STDERR_FILENO, CFA_ASSERT_FMT ": ", assertion, __progname, function, line, file );
    3637
    3738                va_list args;
    3839                va_start( args, fmt );
    39                 __cfaabi_dbg_bits_print_vararg( fmt, args );
     40                __cfaabi_bits_print_vararg( STDERR_FILENO, fmt, args );
    4041                va_end( args );
    4142
    42                 __cfaabi_dbg_bits_print_nolock( "\n" );
    43                 __cfaabi_dbg_bits_release();
     43                __cfaabi_bits_print_nolock( STDERR_FILENO, "\n" );
     44                __cfaabi_bits_release();
    4445                abort();
    4546        }
  • libcfa/src/bits/align.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 23:05:35 2017
    13 // Update Count     : 2
     12// Last Modified On : Sat Nov 16 18:58:22 2019
     13// Update Count     : 3
    1414//
    1515// This  library is free  software; you  can redistribute  it and/or  modify it
     
    3333
    3434// Minimum size used to align memory boundaries for memory allocations.
    35 #define libAlign() (sizeof(double))
     35//#define libAlign() (sizeof(double))
     36// gcc-7 uses xmms instructions, which require 16 byte alignment.
     37#define libAlign() (16)
    3638
    3739// Check for power of 2
  • libcfa/src/bits/containers.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Oct 31 16:38:50 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 26 08:52:20 2019
    13 // Update Count     : 4
     12// Last Modified On : Wed Jan 15 07:42:35 2020
     13// Update Count     : 28
    1414
    1515#pragma once
     
    4444
    4545        forall(dtype T | sized(T))
    46         static inline T& ?[?]( __small_array(T) & this, __lock_size_t idx) {
     46        static inline T & ?[?]( __small_array(T) & this, __lock_size_t idx ) {
    4747                return ((typeof(this.data))this.data)[idx];
    4848        }
    4949
    5050        forall(dtype T | sized(T))
    51         static inline T& ?[?]( const __small_array(T) & this, __lock_size_t idx) {
     51        static inline T & ?[?]( const __small_array(T) & this, __lock_size_t idx ) {
    5252                return ((typeof(this.data))this.data)[idx];
    5353        }
    5454
     55        forall(dtype T)
     56        static inline T * begin( const __small_array(T) & this ) {
     57                return ((typeof(this.data))this.data);
     58        }
     59
    5560        forall(dtype T | sized(T))
    56         static inline T* begin( const __small_array(T) & this ) {
    57                 return ((typeof(this.data))this.data);
    58         }
    59 
    60         forall(dtype T | sized(T))
    61         static inline T* end( const __small_array(T) & this ) {
     61        static inline T * end( const __small_array(T) & this ) {
    6262                return ((typeof(this.data))this.data) + this.size;
    6363        }
     
    7070#ifdef __cforall
    7171        trait is_node(dtype T) {
    72                 T*& get_next( T& );
     72                T *& get_next( T & );
    7373        };
    7474#endif
     
    9797        forall(dtype T)
    9898        static inline void ?{}( __stack(T) & this ) {
    99                 (this.top){ NULL };
    100         }
    101 
    102         forall(dtype T | is_node(T) | sized(T))
    103         static inline void push( __stack(T) & this, T * val ) {
    104                 verify( !get_next( *val ) );
    105                 get_next( *val ) = this.top;
    106                 this.top = val;
    107         }
    108 
    109         forall(dtype T | is_node(T) | sized(T))
    110         static inline T * pop( __stack(T) & this ) {
    111                 T * top = this.top;
    112                 if( top ) {
    113                         this.top = get_next( *top );
    114                         get_next( *top ) = NULL;
    115                 }
    116                 return top;
    117         }
    118 
    119         forall(dtype T | is_node(T))
    120         static inline int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
    121                 return this.top != 0;
     99                (this.top){ 0p };
     100        }
     101
     102        static inline forall( dtype T | is_node(T) ) {
     103                void push( __stack(T) & this, T * val ) {
     104                        verify( !get_next( *val ) );
     105                        get_next( *val ) = this.top;
     106                        this.top = val;
     107                }
     108
     109                T * pop( __stack(T) & this ) {
     110                        T * top = this.top;
     111                        if( top ) {
     112                                this.top = get_next( *top );
     113                                get_next( *top ) = 0p;
     114                        }
     115                        return top;
     116                }
     117
     118                int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
     119                        return this.top != 0;
     120                }
    122121        }
    123122#endif
     
    145144
    146145#ifdef __cforall
    147 
    148         forall(dtype T)
    149         static inline void ?{}( __queue(T) & this ) with( this ) {
    150                 head{ NULL };
    151                 tail{ &head };
    152         }
    153 
    154         forall(dtype T | is_node(T) | sized(T))
    155         static inline void append( __queue(T) & this, T * val ) with( this ) {
    156                 verify(tail != NULL);
    157                 *tail = val;
    158                 tail = &get_next( *val );
    159         }
    160 
    161         forall(dtype T | is_node(T) | sized(T))
    162         static inline T * pop_head( __queue(T) & this ) {
    163                 T * head = this.head;
    164                 if( head ) {
    165                         this.head = get_next( *head );
    166                         if( !get_next( *head ) ) {
    167                                 this.tail = &this.head;
    168                         }
    169                         get_next( *head ) = NULL;
    170                 }
    171                 return head;
    172         }
    173 
    174         forall(dtype T | is_node(T) | sized(T))
    175         static inline T * remove( __queue(T) & this, T ** it ) with( this ) {
    176                 T * val = *it;
    177                 verify( val );
    178 
    179                 (*it) = get_next( *val );
    180 
    181                 if( tail == &get_next( *val ) ) {
    182                         tail = it;
    183                 }
    184 
    185                 get_next( *val ) = NULL;
    186 
    187                 verify( (head == NULL) == (&head == tail) );
    188                 verify( *tail == NULL );
    189                 return val;
    190         }
    191 
    192         forall(dtype T | is_node(T))
    193         static inline int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
    194                 return this.head != 0;
     146        static inline forall( dtype T | is_node(T) ) {
     147                void ?{}( __queue(T) & this ) with( this ) {
     148                        head{ 1p };
     149                        tail{ &head };
     150                        verify(*tail == 1p);
     151                }
     152
     153                void append( __queue(T) & this, T * val ) with( this ) {
     154                        verify(tail != 0p);
     155                        verify(*tail == 1p);
     156                        *tail = val;
     157                        tail = &get_next( *val );
     158                        *tail = 1p;
     159                }
     160
     161                T * pop_head( __queue(T) & this ) {
     162                        verify(*this.tail == 1p);
     163                        T * head = this.head;
     164                        if( head != 1p ) {
     165                                this.head = get_next( *head );
     166                                if( get_next( *head ) == 1p ) {
     167                                        this.tail = &this.head;
     168                                }
     169                                get_next( *head ) = 0p;
     170                                verify(*this.tail == 1p);
     171                                return head;
     172                        }
     173                        verify(*this.tail == 1p);
     174                        return 0p;
     175                }
     176
     177                T * remove( __queue(T) & this, T ** it ) with( this ) {
     178                        T * val = *it;
     179                        verify( val );
     180
     181                        (*it) = get_next( *val );
     182
     183                        if( tail == &get_next( *val ) ) {
     184                                tail = it;
     185                        }
     186
     187                        get_next( *val ) = 0p;
     188
     189                        verify( (head == 1p) == (&head == tail) );
     190                        verify( *tail == 1p );
     191                        return val;
     192                }
     193
     194                int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
     195                        return this.head != 0;
     196                }
    195197        }
    196198#endif
     
    223225
    224226#ifdef __cforall
    225 
    226         forall(dtype T | sized(T))
     227        forall(dtype T )
    227228        static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
    228                 this.head{ NULL };
     229                this.head{ 0p };
    229230                this.__get = __get;
    230231        }
     
    232233        #define next 0
    233234        #define prev 1
    234         forall(dtype T | sized(T))
    235         static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
    236                 verify(__get);
    237                 if ( head ) {
    238                         __get( node ).next = head;
    239                         __get( node ).prev = __get( *head ).prev;
    240                         // inserted node must be consistent before it is seen
     235        static inline forall(dtype T) {
     236                void push_front( __dllist(T) & this, T & node ) with( this ) {
     237                        verify(__get);
     238                        if ( head ) {
     239                                __get( node ).next = head;
     240                                __get( node ).prev = __get( *head ).prev;
     241                                // inserted node must be consistent before it is seen
     242                                // prevent code movement across barrier
     243                                asm( "" : : : "memory" );
     244                                __get( *head ).prev = &node;
     245                                T & _prev = *__get( node ).prev;
     246                                __get( _prev ).next = &node;
     247                        } else {
     248                                __get( node ).next = &node;
     249                                __get( node ).prev = &node;
     250                        }
     251
    241252                        // prevent code movement across barrier
    242253                        asm( "" : : : "memory" );
    243                         __get( *head ).prev = &node;
    244                         T & _prev = *__get( node ).prev;
    245                         __get( _prev ).next = &node;
    246                 }
    247                 else {
    248                         __get( node ).next = &node;
    249                         __get( node ).prev = &node;
    250                 }
    251 
    252                 // prevent code movement across barrier
    253                 asm( "" : : : "memory" );
    254                 head = &node;
    255         }
    256 
    257         forall(dtype T | sized(T))
    258         static inline void remove( __dllist(T) & this, T & node ) with( this ) {
    259                 verify(__get);
    260                 if ( &node == head ) {
    261                         if ( __get( *head ).next == head ) {
    262                                 head = NULL;
    263                         }
    264                         else {
    265                                 head = __get( *head ).next;
    266                         }
    267                 }
    268                 __get( *__get( node ).next ).prev = __get( node ).prev;
    269                 __get( *__get( node ).prev ).next = __get( node ).next;
    270                 __get( node ).next = NULL;
    271                 __get( node ).prev = NULL;
    272         }
    273 
    274         forall(dtype T | sized(T))
    275         static inline int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
    276                 return this.head != 0;
     254                        head = &node;
     255                }
     256
     257                void remove( __dllist(T) & this, T & node ) with( this ) {
     258                        verify(__get);
     259                        if ( &node == head ) {
     260                                if ( __get( *head ).next == head ) {
     261                                        head = 0p;
     262                                } else {
     263                                        head = __get( *head ).next;
     264                                }
     265                        }
     266                        __get( *__get( node ).next ).prev = __get( node ).prev;
     267                        __get( *__get( node ).prev ).next = __get( node ).next;
     268                        __get( node ).next = 0p;
     269                        __get( node ).prev = 0p;
     270                }
     271
     272                int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
     273                        return this.head != 0;
     274                }
    277275        }
    278276        #undef next
     
    286284
    287285#endif
     286
     287// Local Variables: //
     288// tab-width: 4 //
     289// End: //
  • libcfa/src/bits/debug.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu Mar 30 12:30:01 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 14 22:17:35 2019
    13 // Update Count     : 4
     12// Last Modified On : Tue Feb  4 13:03:16 2020
     13// Update Count     : 11
    1414//
    1515
     
    2727
    2828extern "C" {
    29 
    30         void __cfaabi_dbg_bits_write( const char *in_buffer, int len ) {
     29        void __cfaabi_bits_write( int fd, const char in_buffer[], int len ) {
    3130                // ensure all data is written
    3231                for ( int count = 0, retcode; count < len; count += retcode ) {
     
    3433
    3534                        for ( ;; ) {
    36                                 retcode = write( STDERR_FILENO, in_buffer, len - count );
     35                                retcode = write( fd, in_buffer, len - count );
    3736
    3837                                // not a timer interrupt ?
     
    4443        }
    4544
    46         void __cfaabi_dbg_bits_acquire() __attribute__((__weak__)) {}
    47         void __cfaabi_dbg_bits_release() __attribute__((__weak__)) {}
     45        void __cfaabi_bits_acquire() __attribute__((__weak__)) {}
     46        void __cfaabi_bits_release() __attribute__((__weak__)) {}
    4847
    49         void __cfaabi_dbg_bits_print_safe  ( const char fmt[], ... ) __attribute__(( format(printf, 1, 2) )) {
     48        void __cfaabi_bits_print_safe  ( int fd, const char fmt[], ... ) __attribute__(( format(printf, 2, 3) )) {
    5049                va_list args;
    5150
    5251                va_start( args, fmt );
    53                 __cfaabi_dbg_bits_acquire();
     52                __cfaabi_bits_acquire();
    5453
    5554                int len = vsnprintf( buffer, buffer_size, fmt, args );
    56                 __cfaabi_dbg_bits_write( buffer, len );
     55                __cfaabi_bits_write( fd, buffer, len );
    5756
    58                 __cfaabi_dbg_bits_release();
     57                __cfaabi_bits_release();
    5958                va_end( args );
    6059        }
    6160
    62         void __cfaabi_dbg_bits_print_nolock( const char fmt[], ... ) __attribute__(( format(printf, 1, 2) )) {
     61        void __cfaabi_bits_print_nolock( int fd, const char fmt[], ... ) __attribute__(( format(printf, 2, 3) )) {
    6362                va_list args;
    6463
     
    6665
    6766                int len = vsnprintf( buffer, buffer_size, fmt, args );
    68                 __cfaabi_dbg_bits_write( buffer, len );
     67                __cfaabi_bits_write( fd, buffer, len );
    6968
    7069                va_end( args );
    7170        }
    7271
    73         void __cfaabi_dbg_bits_print_vararg( const char fmt[], va_list args ) {
     72        void __cfaabi_bits_print_vararg( int fd, const char fmt[], va_list args ) {
    7473                int len = vsnprintf( buffer, buffer_size, fmt, args );
    75                 __cfaabi_dbg_bits_write( buffer, len );
     74                __cfaabi_bits_write( fd, buffer, len );
    7675        }
    7776
    78         void __cfaabi_dbg_bits_print_buffer( char in_buffer[], int in_buffer_size, const char fmt[], ... ) __attribute__(( format(printf, 3, 4) )) {
     77        void __cfaabi_bits_print_buffer( int fd, char in_buffer[], int in_buffer_size, const char fmt[], ... ) __attribute__(( format(printf, 4, 5) )) {
    7978                va_list args;
    8079
     
    8281
    8382                int len = vsnprintf( in_buffer, in_buffer_size, fmt, args );
    84                 __cfaabi_dbg_bits_write( in_buffer, len );
     83                __cfaabi_bits_write( fd, in_buffer, len );
    8584
    8685                va_end( args );
  • libcfa/src/bits/debug.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  8 12:35:19 2018
    13 // Update Count     : 2
     12// Last Modified On : Tue Feb  4 12:29:21 2020
     13// Update Count     : 9
    1414//
    1515
     
    2121        #define __cfaabi_dbg_ctx __PRETTY_FUNCTION__
    2222        #define __cfaabi_dbg_ctx2 , __PRETTY_FUNCTION__
    23         #define __cfaabi_dbg_ctx_param const char * caller
    24         #define __cfaabi_dbg_ctx_param2 , const char * caller
     23        #define __cfaabi_dbg_ctx_param const char caller[]
     24        #define __cfaabi_dbg_ctx_param2 , const char caller[]
    2525#else
    2626        #define __cfaabi_dbg_debug_do(...)
     
    3838        #include <stdio.h>
    3939
    40       extern void __cfaabi_dbg_bits_write( const char *buffer, int len );
    41       extern void __cfaabi_dbg_bits_acquire();
    42       extern void __cfaabi_dbg_bits_release();
    43       extern void __cfaabi_dbg_bits_print_safe  ( const char fmt[], ... ) __attribute__(( format(printf, 1, 2) ));
    44       extern void __cfaabi_dbg_bits_print_nolock( const char fmt[], ... ) __attribute__(( format(printf, 1, 2) ));
    45       extern void __cfaabi_dbg_bits_print_vararg( const char fmt[], va_list arg );
    46       extern void __cfaabi_dbg_bits_print_buffer( char buffer[], int buffer_size, const char fmt[], ... ) __attribute__(( format(printf, 3, 4) ));
     40        extern void __cfaabi_bits_write( int fd, const char buffer[], int len );
     41        extern void __cfaabi_bits_acquire();
     42        extern void __cfaabi_bits_release();
     43        extern void __cfaabi_bits_print_safe  ( int fd, const char fmt[], ... ) __attribute__(( format(printf, 2, 3) ));
     44        extern void __cfaabi_bits_print_nolock( int fd, const char fmt[], ... ) __attribute__(( format(printf, 2, 3) ));
     45        extern void __cfaabi_bits_print_vararg( int fd, const char fmt[], va_list arg );
     46        extern void __cfaabi_bits_print_buffer( int fd, char buffer[], int buffer_size, const char fmt[], ... ) __attribute__(( format(printf, 4, 5) ));
    4747#ifdef __cforall
    4848}
     
    5050
    5151#ifdef __CFA_DEBUG_PRINT__
    52         #define __cfaabi_dbg_write( buffer, len )         __cfaabi_dbg_bits_write( buffer, len )
    53         #define __cfaabi_dbg_acquire()                    __cfaabi_dbg_bits_acquire()
    54         #define __cfaabi_dbg_release()                    __cfaabi_dbg_bits_release()
    55         #define __cfaabi_dbg_print_safe(...)              __cfaabi_dbg_bits_print_safe   (__VA_ARGS__)
    56         #define __cfaabi_dbg_print_nolock(...)            __cfaabi_dbg_bits_print_nolock (__VA_ARGS__)
    57         #define __cfaabi_dbg_print_buffer(...)            __cfaabi_dbg_bits_print_buffer (__VA_ARGS__)
    58         #define __cfaabi_dbg_print_buffer_decl(...)       char __dbg_text[256]; int __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __cfaabi_dbg_bits_write( __dbg_text, __dbg_len );
    59         #define __cfaabi_dbg_print_buffer_local(...)      __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __cfaabi_dbg_bits_write( __dbg_text, __dbg_len );
     52        #define __cfaabi_dbg_write( buffer, len )         __cfaabi_bits_write( STDERR_FILENO, buffer, len )
     53        #define __cfaabi_dbg_acquire()                    __cfaabi_bits_acquire()
     54        #define __cfaabi_dbg_release()                    __cfaabi_bits_release()
     55        #define __cfaabi_dbg_print_safe(...)              __cfaabi_bits_print_safe   (__VA_ARGS__)
     56        #define __cfaabi_dbg_print_nolock(...)            __cfaabi_bits_print_nolock (__VA_ARGS__)
     57        #define __cfaabi_dbg_print_buffer(...)            __cfaabi_bits_print_buffer (__VA_ARGS__)
     58        #define __cfaabi_dbg_print_buffer_decl(...)       char __dbg_text[256]; int __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __cfaabi_bits_write( __dbg_text, __dbg_len );
     59        #define __cfaabi_dbg_print_buffer_local(...)      __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __cfaabi_dbg_write( __dbg_text, __dbg_len );
    6060#else
    6161        #define __cfaabi_dbg_write(...)               ((void)0)
  • libcfa/src/bits/defs.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu Nov  9 13:24:10 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  8 16:22:41 2018
    13 // Update Count     : 8
     12// Last Modified On : Tue Jan 28 22:38:27 2020
     13// Update Count     : 9
    1414//
    1515
     
    3434
    3535#ifdef __cforall
    36 void abort ( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     36void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     37void abort( bool signalAbort, const char fmt[], ... ) __attribute__ (( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    3738extern "C" {
    3839#endif
     
    4748#define OPTIONAL_THREAD __attribute__((weak))
    4849#endif
     50
     51static inline long long rdtscl(void) {
     52    unsigned int lo, hi;
     53    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
     54    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
     55}
  • libcfa/src/bits/locks.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Oct 31 15:14:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 11 15:42:24 2018
    13 // Update Count     : 10
     12// Last Modified On : Tue Feb  4 13:03:19 2020
     13// Update Count     : 11
    1414//
    1515
     
    5454
    5555                #ifdef __CFA_DEBUG__
    56                         void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name);
     56                        void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]);
    5757                #else
    5858                        #define __cfaabi_dbg_record(x, y)
    5959                #endif
    6060        }
    61 
    62         extern void yield( unsigned int );
    6361
    6462        static inline void ?{}( __spinlock_t & this ) {
     
    6866        // Lock the spinlock, return false if already acquired
    6967        static inline bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
     68                disable_interrupts();
    7069                bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);
    7170                if( result ) {
    72                         disable_interrupts();
    7371                        __cfaabi_dbg_record( this, caller );
     72                } else {
     73                        enable_interrupts_noPoll();
    7474                }
    7575                return result;
     
    8383                #endif
    8484
     85                disable_interrupts();
    8586                for ( unsigned int i = 1;; i += 1 ) {
    8687                        if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break;
     
    9899                        #endif
    99100                }
    100                 disable_interrupts();
    101101                __cfaabi_dbg_record( this, caller );
    102102        }
    103103
    104104        static inline void unlock( __spinlock_t & this ) {
     105                __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    105106                enable_interrupts_noPoll();
    106                 __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    107107        }
    108108
  • libcfa/src/bits/signal.hfa

    r9fb8f01 r3d5701e  
    3737
    3838        act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
     39        sigemptyset( &act.sa_mask );
     40        sigaddset( &act.sa_mask, SIGALRM );             // disabled during signal handler
     41        sigaddset( &act.sa_mask, SIGUSR1 );
     42        sigaddset( &act.sa_mask, SIGSEGV );
     43        sigaddset( &act.sa_mask, SIGBUS );
     44        sigaddset( &act.sa_mask, SIGILL );
     45        sigaddset( &act.sa_mask, SIGFPE );
     46        sigaddset( &act.sa_mask, SIGHUP );              // revert to default on second delivery
     47        sigaddset( &act.sa_mask, SIGTERM );
     48        sigaddset( &act.sa_mask, SIGINT );
    3949        act.sa_flags = flags;
    4050
    41         if ( sigaction( sig, &act, NULL ) == -1 ) {
     51        if ( sigaction( sig, &act, 0p ) == -1 ) {
    4252                __cfaabi_dbg_print_buffer_decl(
    4353                        " __cfaabi_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
     
    4555                );
    4656                _exit( EXIT_FAILURE );
    47         }
     57        } // if
    4858}
    49 
    50 // Sigaction wrapper : restore default handler
    51 static void __cfaabi_sigdefault( int sig ) {
    52         struct sigaction act;
    53 
    54         act.sa_handler = SIG_DFL;
    55         act.sa_flags = 0;
    56         sigemptyset( &act.sa_mask );
    57 
    58         if ( sigaction( sig, &act, NULL ) == -1 ) {
    59                 __cfaabi_dbg_print_buffer_decl(
    60                         " __cfaabi_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
    61                         sig, errno, strerror( errno )
    62                 );
    63                 _exit( EXIT_FAILURE );
    64         }
    65 }
  • libcfa/src/clock.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu Apr 12 14:36:06 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 13 21:21:13 2019
    13 // Update Count     : 8
     12// Last Modified On : Mon Jan  6 12:49:58 2020
     13// Update Count     : 9
    1414//
    1515
    1616#include <time.hfa>
    17 
    1817
    1918//######################### C time #########################
     
    2625static inline tm * localtime_r( time_t tp, tm * result ) { return localtime_r( &tp, result ); }
    2726
    28 
    2927//######################### Clock #########################
    3028
    3129struct Clock {                                                                                  // private
    3230        Duration offset;                                                                        // for virtual clock: contains offset from real-time
    33         int clocktype;                                                                          // implementation only -1 (virtual), CLOCK_REALTIME
    3431};
    3532
    3633static inline {
    37         void resetClock( Clock & clk ) with( clk ) {
    38                 clocktype = CLOCK_REALTIME_COARSE;
    39         } // Clock::resetClock
    40 
    4134        void resetClock( Clock & clk, Duration adj ) with( clk ) {
    42                 clocktype = -1;
    4335                offset = adj + __timezone`s;                                    // timezone (global) is (UTC - local time) in seconds
    4436        } // resetClock
    4537
    46         void ?{}( Clock & clk ) { resetClock( clk ); }
    4738        void ?{}( Clock & clk, Duration adj ) { resetClock( clk, adj ); }
    4839
     
    8980                return ret;
    9081        } // getTime
     82
     83        Time getCPUTime() {
     84                timespec ts;
     85                clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts );
     86                return (Time){ ts };
     87    } // getCPUTime
    9188} // distribution
    9289
  • libcfa/src/concurrency/CtxSwitch-arm.S

    r9fb8f01 r3d5701e  
    1313        .text
    1414        .align  2
    15         .global CtxSwitch
    16         .type   CtxSwitch, %function
     15        .global __cfactx_switch
     16        .type   __cfactx_switch, %function
    1717
    18 CtxSwitch:
     18__cfactx_switch:
    1919        @ save callee-saved registers: r4-r8, r10, r11, r13(sp) (plus r9 depending on platform specification)
    2020        @ I've seen reference to 31 registers on 64-bit, if this is the case, more need to be saved
     
    5252        mov r15, r14
    5353        #endif // R9_SPECIAL
    54        
     54
    5555        .text
    5656        .align  2
    57         .global CtxInvokeStub
    58         .type   CtxInvokeStub, %function
     57        .global __cfactx_invoke_stub
     58        .type   __cfactx_invoke_stub, %function
    5959
    60 CtxInvokeStub:
     60__cfactx_invoke_stub:
    6161        ldmfd r13!, {r0-r1}
    6262        mov r15, r1
  • libcfa/src/concurrency/CtxSwitch-i386.S

    r9fb8f01 r3d5701e  
    4343        .text
    4444        .align 2
    45         .globl CtxSwitch
    46         .type  CtxSwitch, @function
    47 CtxSwitch:
     45        .globl __cfactx_switch
     46        .type  __cfactx_switch, @function
     47__cfactx_switch:
    4848
    4949        // Copy the "from" context argument from the stack to register eax
     
    8383
    8484        ret
    85         .size  CtxSwitch, .-CtxSwitch
     85        .size  __cfactx_switch, .-__cfactx_switch
    8686
    8787// Local Variables: //
  • libcfa/src/concurrency/CtxSwitch-x86_64.S

    r9fb8f01 r3d5701e  
    4444        .text
    4545        .align 2
    46         .globl CtxSwitch
    47         .type  CtxSwitch, @function
    48 CtxSwitch:
     46        .globl __cfactx_switch
     47        .type  __cfactx_switch, @function
     48__cfactx_switch:
    4949
    5050        // Save volatile registers on the stack.
     
    7777
    7878        ret
    79         .size  CtxSwitch, .-CtxSwitch
     79        .size  __cfactx_switch, .-__cfactx_switch
    8080
    8181//-----------------------------------------------------------------------------
     
    8383        .text
    8484        .align 2
    85         .globl CtxInvokeStub
    86         .type    CtxInvokeStub, @function
    87 CtxInvokeStub:
     85        .globl __cfactx_invoke_stub
     86        .type    __cfactx_invoke_stub, @function
     87__cfactx_invoke_stub:
    8888        movq %rbx, %rdi
    89         jmp *%r12
    90         .size  CtxInvokeStub, .-CtxInvokeStub
     89        movq %r12, %rsi
     90        jmp *%r13
     91        .size  __cfactx_invoke_stub, .-__cfactx_invoke_stub
    9192
    9293// Local Variables: //
  • libcfa/src/concurrency/alarm.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Fri Jun 2 11:31:25 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri May 25 06:25:47 2018
    13 // Update Count     : 67
     12// Last Modified On : Sun Jan  5 08:41:36 2020
     13// Update Count     : 69
    1414//
    1515
     
    3939
    4040void __kernel_set_timer( Duration alarm ) {
    41         verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%jins)", alarm.tv);
    42         setitimer( ITIMER_REAL, &(itimerval){ alarm }, NULL );
     41        verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%jins)", alarm`ns);
     42        setitimer( ITIMER_REAL, &(itimerval){ alarm }, 0p );
    4343}
    4444
     
    4747//=============================================================================================
    4848
    49 void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period ) with( this ) {
     49void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period ) with( this ) {
    5050        this.thrd = thrd;
    5151        this.alarm = alarm;
     
    113113                        this->tail = &this->head;
    114114                }
    115                 head->next = NULL;
     115                head->next = 0p;
    116116        }
    117117        verify( validate( this ) );
     
    127127                this->tail = it;
    128128        }
    129         n->next = NULL;
     129        n->next = 0p;
    130130
    131131        verify( validate( this ) );
  • libcfa/src/concurrency/alarm.hfa

    r9fb8f01 r3d5701e  
    2323#include "time.hfa"
    2424
    25 struct thread_desc;
     25struct $thread;
    2626struct processor;
    2727
     
    4343
    4444        union {
    45                 thread_desc * thrd;     // thrd who created event
     45                $thread * thrd; // thrd who created event
    4646                processor * proc;               // proc who created event
    4747        };
     
    5353typedef alarm_node_t ** __alarm_it_t;
    5454
    55 void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period );
     55void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period );
    5656void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period );
    5757void ^?{}( alarm_node_t & this );
  • libcfa/src/concurrency/coroutine.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 17:20:57 2018
    13 // Update Count     : 9
     12// Last Modified On : Tue Feb  4 12:29:25 2020
     13// Update Count     : 16
    1414//
    1515
     
    3737
    3838extern "C" {
    39         void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__));
     39        void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct $coroutine *) __attribute__ ((__noreturn__));
    4040        static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) __attribute__ ((__noreturn__));
    4141        static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) {
     
    8989}
    9090
    91 void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize ) with( this ) {
    92         (this.context){NULL, NULL};
     91void ?{}( $coroutine & this, const char name[], void * storage, size_t storageSize ) with( this ) {
     92        (this.context){0p, 0p};
    9393        (this.stack){storage, storageSize};
    9494        this.name = name;
    9595        state = Start;
    96         starter = NULL;
    97         last = NULL;
    98         cancellation = NULL;
    99 }
    100 
    101 void ^?{}(coroutine_desc& this) {
     96        starter = 0p;
     97        last = 0p;
     98        cancellation = 0p;
     99}
     100
     101void ^?{}($coroutine& this) {
    102102        if(this.state != Halted && this.state != Start && this.state != Primed) {
    103                 coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    104                 coroutine_desc * dst = &this;
     103                $coroutine * src = TL_GET( this_thread )->curr_cor;
     104                $coroutine * dst = &this;
    105105
    106106                struct _Unwind_Exception storage;
     
    115115                }
    116116
    117                 CoroutineCtxSwitch( src, dst );
     117                $ctx_switch( src, dst );
    118118        }
    119119}
     
    123123forall(dtype T | is_coroutine(T))
    124124void prime(T& cor) {
    125         coroutine_desc* this = get_coroutine(cor);
     125        $coroutine* this = get_coroutine(cor);
    126126        assert(this->state == Start);
    127127
     
    131131
    132132[void *, size_t] __stack_alloc( size_t storageSize ) {
    133         static const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
     133        const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
    134134        assert(__page_size != 0l);
    135135        size_t size = libCeiling( storageSize, 16 ) + stack_data_size;
     
    157157
    158158void __stack_prepare( __stack_info_t * this, size_t create_size ) {
    159         static const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
     159        const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
    160160        bool userStack;
    161161        void * storage;
     
    187187// is not inline (We can't inline Cforall in C)
    188188extern "C" {
    189         void __suspend_internal(void) {
    190                 suspend();
    191         }
    192 
    193         void __leave_coroutine( coroutine_desc * src ) {
    194                 coroutine_desc * starter = src->cancellation != 0 ? src->last : src->starter;
     189        void __cfactx_cor_leave( struct $coroutine * src ) {
     190                $coroutine * starter = src->cancellation != 0 ? src->last : src->starter;
    195191
    196192                src->state = Halted;
     
    205201                        src->name, src, starter->name, starter );
    206202
    207                 CoroutineCtxSwitch( src, starter );
     203                $ctx_switch( src, starter );
     204        }
     205
     206        struct $coroutine * __cfactx_cor_finish(void) {
     207                struct $coroutine * cor = kernelTLS.this_thread->curr_cor;
     208
     209                if(cor->state == Primed) {
     210                        suspend();
     211                }
     212
     213                cor->state = Active;
     214
     215                return cor;
    208216        }
    209217}
  • libcfa/src/concurrency/coroutine.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 17:49:39 2019
    13 // Update Count     : 9
     12// Last Modified On : Tue Feb  4 12:29:26 2020
     13// Update Count     : 11
    1414//
    1515
     
    2525trait is_coroutine(dtype T) {
    2626      void main(T & this);
    27       coroutine_desc * get_coroutine(T & this);
     27      $coroutine * get_coroutine(T & this);
    2828};
    2929
    30 #define DECL_COROUTINE(X) static inline coroutine_desc* get_coroutine(X& this) { return &this.__cor; } void main(X& this)
     30#define DECL_COROUTINE(X) static inline $coroutine* get_coroutine(X& this) { return &this.__cor; } void main(X& this)
    3131
    3232//-----------------------------------------------------------------------------
     
    3535// void ^?{}( coStack_t & this );
    3636
    37 void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize );
    38 void ^?{}( coroutine_desc & this );
     37void  ?{}( $coroutine & this, const char name[], void * storage, size_t storageSize );
     38void ^?{}( $coroutine & this );
    3939
    40 static inline void ?{}( coroutine_desc & this)                                       { this{ "Anonymous Coroutine", NULL, 0 }; }
    41 static inline void ?{}( coroutine_desc & this, size_t stackSize)                     { this{ "Anonymous Coroutine", NULL, stackSize }; }
    42 static inline void ?{}( coroutine_desc & this, void * storage, size_t storageSize )  { this{ "Anonymous Coroutine", storage, storageSize }; }
    43 static inline void ?{}( coroutine_desc & this, const char * name)                    { this{ name, NULL, 0 }; }
    44 static inline void ?{}( coroutine_desc & this, const char * name, size_t stackSize ) { this{ name, NULL, stackSize }; }
     40static inline void ?{}( $coroutine & this)                                       { this{ "Anonymous Coroutine", 0p, 0 }; }
     41static inline void ?{}( $coroutine & this, size_t stackSize)                     { this{ "Anonymous Coroutine", 0p, stackSize }; }
     42static inline void ?{}( $coroutine & this, void * storage, size_t storageSize )  { this{ "Anonymous Coroutine", storage, storageSize }; }
     43static inline void ?{}( $coroutine & this, const char name[])                    { this{ name, 0p, 0 }; }
     44static inline void ?{}( $coroutine & this, const char name[], size_t stackSize ) { this{ name, 0p, stackSize }; }
    4545
    4646//-----------------------------------------------------------------------------
     
    5454void prime(T & cor);
    5555
    56 static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
     56static inline struct $coroutine * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
    5757
    5858//-----------------------------------------------------------------------------
     
    6161// Start coroutine routines
    6262extern "C" {
    63       forall(dtype T | is_coroutine(T))
    64       void CtxInvokeCoroutine(T * this);
     63        void __cfactx_invoke_coroutine(void (*main)(void *), void * this);
    6564
    66       forall(dtype T | is_coroutine(T))
    67       void CtxStart(T * this, void ( *invoke)(T *));
     65        forall(dtype T)
     66        void __cfactx_start(void (*main)(T &), struct $coroutine * cor, T & this, void (*invoke)(void (*main)(void *), void *));
    6867
    69         extern void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__));
     68        extern void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct $coroutine *) __attribute__ ((__noreturn__));
    7069
    71         extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch");
     70        extern void __cfactx_switch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("__cfactx_switch");
    7271}
    7372
    7473// Private wrappers for context switch and stack creation
    7574// Wrapper for co
    76 static inline void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
     75static inline void $ctx_switch( $coroutine * src, $coroutine * dst ) __attribute__((nonnull (1, 2))) {
    7776        // set state of current coroutine to inactive
    7877        src->state = src->state == Halted ? Halted : Inactive;
     
    8382        // context switch to specified coroutine
    8483        verify( dst->context.SP );
    85         CtxSwitch( &src->context, &dst->context );
    86         // when CtxSwitch returns we are back in the src coroutine
     84        __cfactx_switch( &src->context, &dst->context );
     85        // when __cfactx_switch returns we are back in the src coroutine
    8786
    8887        // set state of new coroutine to active
    8988        src->state = Active;
    9089
    91         if( unlikely(src->cancellation != NULL) ) {
    92                 _CtxCoroutine_Unwind(src->cancellation, src);
     90        if( unlikely(src->cancellation != 0p) ) {
     91                __cfactx_coroutine_unwind(src->cancellation, src);
    9392        }
    9493}
     
    103102        // will also migrate which means this value will
    104103        // stay in syn with the TLS
    105         coroutine_desc * src = TL_GET( this_thread )->curr_cor;
     104        $coroutine * src = TL_GET( this_thread )->curr_cor;
    106105
    107106        assertf( src->last != 0,
     
    114113                src->name, src, src->last->name, src->last );
    115114
    116         CoroutineCtxSwitch( src, src->last );
     115        $ctx_switch( src, src->last );
    117116}
    118117
     
    125124        // will also migrate which means this value will
    126125        // stay in syn with the TLS
    127         coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    128         coroutine_desc * dst = get_coroutine(cor);
     126        $coroutine * src = TL_GET( this_thread )->curr_cor;
     127        $coroutine * dst = get_coroutine(cor);
    129128
    130         if( unlikely(dst->context.SP == NULL) ) {
     129        if( unlikely(dst->context.SP == 0p) ) {
     130                TL_GET( this_thread )->curr_cor = dst;
    131131                __stack_prepare(&dst->stack, 65000);
    132                 CtxStart(&cor, CtxInvokeCoroutine);
     132                __cfactx_start(main, dst, cor, __cfactx_invoke_coroutine);
     133                TL_GET( this_thread )->curr_cor = src;
    133134        }
    134135
     
    146147
    147148        // always done for performance testing
    148         CoroutineCtxSwitch( src, dst );
     149        $ctx_switch( src, dst );
    149150
    150151        return cor;
    151152}
    152153
    153 static inline void resume(coroutine_desc * dst) {
     154static inline void resume( $coroutine * dst ) __attribute__((nonnull (1))) {
    154155        // optimization : read TLS once and reuse it
    155156        // Safety note: this is preemption safe since if
     
    157158        // will also migrate which means this value will
    158159        // stay in syn with the TLS
    159         coroutine_desc * src = TL_GET( this_thread )->curr_cor;
     160        $coroutine * src = TL_GET( this_thread )->curr_cor;
    160161
    161162        // not resuming self ?
     
    171172
    172173        // always done for performance testing
    173         CoroutineCtxSwitch( src, dst );
     174        $ctx_switch( src, dst );
    174175}
    175176
  • libcfa/src/concurrency/invoke.c

    r9fb8f01 r3d5701e  
    2929// Called from the kernel when starting a coroutine or task so must switch back to user mode.
    3030
    31 extern void __suspend_internal(void);
    32 extern void __leave_coroutine( struct coroutine_desc * );
    33 extern void __finish_creation( struct thread_desc * );
    34 extern void __leave_thread_monitor( struct thread_desc * this );
     31extern struct $coroutine * __cfactx_cor_finish(void);
     32extern void __cfactx_cor_leave ( struct $coroutine * );
     33extern void __cfactx_thrd_leave();
     34
    3535extern void disable_interrupts() OPTIONAL_THREAD;
    3636extern void enable_interrupts( __cfaabi_dbg_ctx_param );
    3737
    38 void CtxInvokeCoroutine(
     38void __cfactx_invoke_coroutine(
    3939        void (*main)(void *),
    40         struct coroutine_desc *(*get_coroutine)(void *),
    4140        void *this
    4241) {
    43         struct coroutine_desc* cor = get_coroutine( this );
     42        // Finish setting up the coroutine by setting its state
     43        struct $coroutine * cor = __cfactx_cor_finish();
    4444
    45         if(cor->state == Primed) {
    46                 __suspend_internal();
    47         }
    48 
    49         cor->state = Active;
    50 
     45        // Call the main of the coroutine
    5146        main( this );
    5247
    5348        //Final suspend, should never return
    54         __leave_coroutine( cor );
     49        __cfactx_cor_leave( cor );
    5550        __cabi_abort( "Resumed dead coroutine" );
    5651}
    5752
    58 static _Unwind_Reason_Code _CtxCoroutine_UnwindStop(
     53static _Unwind_Reason_Code __cfactx_coroutine_unwindstop(
    5954        __attribute((__unused__)) int version,
    6055        _Unwind_Action actions,
     
    6762                // We finished unwinding the coroutine,
    6863                // leave it
    69                 __leave_coroutine( param );
     64                __cfactx_cor_leave( param );
    7065                __cabi_abort( "Resumed dead coroutine" );
    7166        }
     
    7570}
    7671
    77 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) __attribute__ ((__noreturn__));
    78 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) {
    79         _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, cor );
     72void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct $coroutine * cor) __attribute__ ((__noreturn__));
     73void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct $coroutine * cor) {
     74        _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, __cfactx_coroutine_unwindstop, cor );
    8075        printf("UNWIND ERROR %d after force unwind\n", ret);
    8176        abort();
    8277}
    8378
    84 void CtxInvokeThread(
    85         void (*dtor)(void *),
     79void __cfactx_invoke_thread(
    8680        void (*main)(void *),
    87         struct thread_desc *(*get_thread)(void *),
    8881        void *this
    8982) {
    90         // Fetch the thread handle from the user defined thread structure
    91         struct thread_desc* thrd = get_thread( this );
    92 
    93         // First suspend, once the thread arrives here,
    94         // the function pointer to main can be invalidated without risk
    95         __finish_creation( thrd );
    96 
    9783        // Officially start the thread by enabling preemption
    9884        enable_interrupts( __cfaabi_dbg_ctx );
     
    10894        // The order of these 4 operations is very important
    10995        //Final suspend, should never return
    110         __leave_thread_monitor( thrd );
     96        __cfactx_thrd_leave();
    11197        __cabi_abort( "Resumed dead thread" );
    11298}
    11399
    114 
    115 void CtxStart(
     100void __cfactx_start(
    116101        void (*main)(void *),
    117         struct coroutine_desc *(*get_coroutine)(void *),
     102        struct $coroutine * cor,
    118103        void *this,
    119104        void (*invoke)(void *)
    120105) {
    121         struct coroutine_desc * cor = get_coroutine( this );
    122106        struct __stack_t * stack = cor->stack.storage;
    123107
     
    138122
    139123        fs->dummyReturn = NULL;
    140         fs->argument[0] = this;     // argument to invoke
     124        fs->argument[0] = main;     // argument to invoke
     125        fs->argument[1] = this;     // argument to invoke
    141126        fs->rturn = invoke;
    142127
     
    155140
    156141        fs->dummyReturn = NULL;
    157         fs->rturn = CtxInvokeStub;
    158         fs->fixedRegisters[0] = this;
    159         fs->fixedRegisters[1] = invoke;
     142        fs->rturn = __cfactx_invoke_stub;
     143        fs->fixedRegisters[0] = main;
     144        fs->fixedRegisters[1] = this;
     145        fs->fixedRegisters[2] = invoke;
    160146
    161147#elif defined( __ARM_ARCH )
    162 
     148#error ARM needs to be upgrade to use to parameters like X86/X64 (A.K.A. : I broke this and do not know how to fix it)
    163149        struct FakeStack {
    164150                float fpRegs[16];                       // floating point registers
     
    172158        struct FakeStack *fs = (struct FakeStack *)cor->context.SP;
    173159
    174         fs->intRegs[8] = CtxInvokeStub;
     160        fs->intRegs[8] = __cfactx_invoke_stub;
    175161        fs->arg[0] = this;
    176162        fs->arg[1] = invoke;
  • libcfa/src/concurrency/invoke.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun 22 18:19:13 2019
    13 // Update Count     : 40
     12// Last Modified On : Thu Dec  5 16:26:03 2019
     13// Update Count     : 44
    1414//
    1515
     
    4646        #ifdef __cforall
    4747        extern "Cforall" {
    48                 extern thread_local struct KernelThreadData {
    49                         struct thread_desc    * volatile this_thread;
     48                extern __attribute__((aligned(128))) thread_local struct KernelThreadData {
     49                        struct $thread    * volatile this_thread;
    5050                        struct processor      * volatile this_processor;
    5151
     
    5555                                volatile bool in_progress;
    5656                        } preemption_state;
     57
     58                        uint32_t rand_seed;
    5759                } kernelTLS __attribute__ ((tls_model ( "initial-exec" )));
    5860        }
     
    9092        };
    9193
    92         enum coroutine_state { Halted, Start, Inactive, Active, Primed };
    93 
    94         struct coroutine_desc {
    95                 // context that is switch during a CtxSwitch
     94        enum coroutine_state { Halted, Start, Primed, Inactive, Active, Rerun };
     95        enum __Preemption_Reason { __NO_PREEMPTION, __ALARM_PREEMPTION, __POLL_PREEMPTION, __MANUAL_PREEMPTION };
     96
     97        struct $coroutine {
     98                // context that is switch during a __cfactx_switch
    9699                struct __stack_context_t context;
    97100
     
    106109
    107110                // first coroutine to resume this one
    108                 struct coroutine_desc * starter;
     111                struct $coroutine * starter;
    109112
    110113                // last coroutine to resume this one
    111                 struct coroutine_desc * last;
     114                struct $coroutine * last;
    112115
    113116                // If non-null stack must be unwound with this exception
     
    125128        };
    126129
    127         struct monitor_desc {
     130        struct $monitor {
    128131                // spinlock to protect internal data
    129132                struct __spinlock_t lock;
    130133
    131134                // current owner of the monitor
    132                 struct thread_desc * owner;
     135                struct $thread * owner;
    133136
    134137                // queue of threads that are blocked waiting for the monitor
    135                 __queue_t(struct thread_desc) entry_queue;
     138                __queue_t(struct $thread) entry_queue;
    136139
    137140                // stack of conditions to run next once we exit the monitor
     
    150153        struct __monitor_group_t {
    151154                // currently held monitors
    152                 __cfa_anonymous_object( __small_array_t(monitor_desc*) );
     155                __cfa_anonymous_object( __small_array_t($monitor*) );
    153156
    154157                // last function that acquired monitors
     
    156159        };
    157160
    158         struct thread_desc {
     161        struct $thread {
    159162                // Core threading fields
    160                 // context that is switch during a CtxSwitch
     163                // context that is switch during a __cfactx_switch
    161164                struct __stack_context_t context;
    162165
    163166                // current execution status for coroutine
    164                 enum coroutine_state state;
     167                volatile int state;
     168                enum __Preemption_Reason preempted;
    165169
    166170                //SKULLDUGGERY errno is not save in the thread data structure because returnToKernel appears to be the only function to require saving and restoring it
    167171
    168172                // coroutine body used to store context
    169                 struct coroutine_desc  self_cor;
     173                struct $coroutine  self_cor;
    170174
    171175                // current active context
    172                 struct coroutine_desc * curr_cor;
     176                struct $coroutine * curr_cor;
    173177
    174178                // monitor body used for mutual exclusion
    175                 struct monitor_desc    self_mon;
     179                struct $monitor    self_mon;
    176180
    177181                // pointer to monitor with sufficient lifetime for current monitors
    178                 struct monitor_desc *  self_mon_p;
     182                struct $monitor *  self_mon_p;
    179183
    180184                // pointer to the cluster on which the thread is running
     
    186190                // Link lists fields
    187191                // instrusive link field for threads
    188                 struct thread_desc * next;
     192                struct $thread * next;
    189193
    190194                struct {
    191                         struct thread_desc * next;
    192                         struct thread_desc * prev;
     195                        struct $thread * next;
     196                        struct $thread * prev;
    193197                } node;
    194198        };
     
    196200        #ifdef __cforall
    197201        extern "Cforall" {
    198                 static inline thread_desc *& get_next( thread_desc & this ) {
     202                static inline $thread *& get_next( $thread & this ) __attribute__((const)) {
    199203                        return this.next;
    200204                }
    201205
    202                 static inline [thread_desc *&, thread_desc *& ] __get( thread_desc & this ) {
     206                static inline [$thread *&, $thread *& ] __get( $thread & this ) __attribute__((const)) {
    203207                        return this.node.[next, prev];
    204208                }
    205209
    206210                static inline void ?{}(__monitor_group_t & this) {
    207                         (this.data){NULL};
     211                        (this.data){0p};
    208212                        (this.size){0};
    209213                        (this.func){NULL};
    210214                }
    211215
    212                 static inline void ?{}(__monitor_group_t & this, struct monitor_desc ** data, __lock_size_t size, fptr_t func) {
     216                static inline void ?{}(__monitor_group_t & this, struct $monitor ** data, __lock_size_t size, fptr_t func) {
    213217                        (this.data){data};
    214218                        (this.size){size};
     
    216220                }
    217221
    218                 static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
     222                static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) __attribute__((const)) {
    219223                        if( (lhs.data != 0) != (rhs.data != 0) ) return false;
    220224                        if( lhs.size != rhs.size ) return false;
     
    250254
    251255        // assembler routines that performs the context switch
    252         extern void CtxInvokeStub( void );
    253         extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch");
     256        extern void __cfactx_invoke_stub( void );
     257        extern void __cfactx_switch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("__cfactx_switch");
    254258        // void CtxStore ( void * this ) asm ("CtxStore");
    255259        // void CtxRet   ( void * dst  ) asm ("CtxRet");
  • libcfa/src/concurrency/kernel.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 20 17:21:23 2019
    13 // Update Count     : 25
     12// Last Modified On : Tue Feb  4 13:03:15 2020
     13// Update Count     : 58
    1414//
    1515
     
    2626#include <signal.h>
    2727#include <unistd.h>
     28#include <limits.h>                                                                             // PTHREAD_STACK_MIN
     29#include <sys/mman.h>                                                                   // mprotect
    2830}
    2931
     
    4042//-----------------------------------------------------------------------------
    4143// Some assembly required
    42 #if   defined( __i386 )
     44#if defined( __i386 )
    4345        #define CtxGet( ctx )        \
    4446                __asm__ volatile (     \
     
    108110//-----------------------------------------------------------------------------
    109111//Start and stop routine for the kernel, declared first to make sure they run first
    110 static void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
    111 static void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
     112static void __kernel_startup (void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     113static void __kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    112114
    113115//-----------------------------------------------------------------------------
     
    115117KERNEL_STORAGE(cluster,         mainCluster);
    116118KERNEL_STORAGE(processor,       mainProcessor);
    117 KERNEL_STORAGE(thread_desc,     mainThread);
     119KERNEL_STORAGE($thread, mainThread);
    118120KERNEL_STORAGE(__stack_t,       mainThreadCtx);
    119121
    120122cluster     * mainCluster;
    121123processor   * mainProcessor;
    122 thread_desc * mainThread;
     124$thread * mainThread;
    123125
    124126extern "C" {
    125 struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters;
     127        struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters;
    126128}
    127129
     
    131133// Global state
    132134thread_local struct KernelThreadData kernelTLS __attribute__ ((tls_model ( "initial-exec" ))) = {
     135        NULL,                                                                                           // cannot use 0p
    133136        NULL,
    134         NULL,
    135         { 1, false, false }
     137        { 1, false, false },
     138        6u //this should be seeded better but due to a bug calling rdtsc doesn't work
    136139};
    137140
     
    139142// Struct to steal stack
    140143struct current_stack_info_t {
    141         __stack_t * storage;            // pointer to stack object
    142         void *base;                             // base of stack
    143         void *limit;                    // stack grows towards stack limit
    144         void *context;                  // address of cfa_context_t
     144        __stack_t * storage;                                                            // pointer to stack object
     145        void * base;                                                                            // base of stack
     146        void * limit;                                                                           // stack grows towards stack limit
     147        void * context;                                                                         // address of cfa_context_t
    145148};
    146149
     
    161164// Main thread construction
    162165
    163 void ?{}( coroutine_desc & this, current_stack_info_t * info) with( this ) {
     166void ?{}( $coroutine & this, current_stack_info_t * info) with( this ) {
    164167        stack.storage = info->storage;
    165168        with(*stack.storage) {
     
    171174        name = "Main Thread";
    172175        state = Start;
    173         starter = NULL;
    174         last = NULL;
    175         cancellation = NULL;
    176 }
    177 
    178 void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) {
     176        starter = 0p;
     177        last = 0p;
     178        cancellation = 0p;
     179}
     180
     181void ?{}( $thread & this, current_stack_info_t * info) with( this ) {
    179182        state = Start;
    180183        self_cor{ info };
     
    184187        self_mon.recursion = 1;
    185188        self_mon_p = &self_mon;
    186         next = NULL;
    187 
    188         node.next = NULL;
    189         node.prev = NULL;
     189        next = 0p;
     190
     191        node.next = 0p;
     192        node.prev = 0p;
    190193        doregister(curr_cluster, this);
    191194
     
    205208}
    206209
    207 static void start(processor * this);
    208 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
     210static void * __invoke_processor(void * arg);
     211
     212void ?{}(processor & this, const char name[], cluster & cltr) with( this ) {
    209213        this.name = name;
    210214        this.cltr = &cltr;
    211215        terminated{ 0 };
     216        destroyer = 0p;
    212217        do_terminate = false;
    213         preemption_alarm = NULL;
     218        preemption_alarm = 0p;
    214219        pending_preemption = false;
    215220        runner.proc = &this;
     
    217222        idleLock{};
    218223
    219         start( &this );
     224        __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", &this);
     225
     226        this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
     227
     228        __cfaabi_dbg_print_safe("Kernel : core %p started\n", &this);
    220229}
    221230
     
    231240        }
    232241
    233         pthread_join( kernel_thread, NULL );
    234 }
    235 
    236 void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) {
     242        pthread_join( kernel_thread, 0p );
     243        free( this.stack );
     244}
     245
     246void ?{}(cluster & this, const char name[], Duration preemption_rate) with( this ) {
    237247        this.name = name;
    238248        this.preemption_rate = preemption_rate;
     
    254264// Kernel Scheduling logic
    255265//=============================================================================================
    256 static void runThread(processor * this, thread_desc * dst);
    257 static void finishRunning(processor * this);
    258 static void halt(processor * this);
     266static $thread * __next_thread(cluster * this);
     267static void __run_thread(processor * this, $thread * dst);
     268static void __halt(processor * this);
    259269
    260270//Main of the processor contexts
    261271void main(processorCtx_t & runner) {
     272        // Because of a bug, we couldn't initialized the seed on construction
     273        // Do it here
     274        kernelTLS.rand_seed ^= rdtscl();
     275
    262276        processor * this = runner.proc;
    263277        verify(this);
     
    273287                __cfaabi_dbg_print_safe("Kernel : core %p started\n", this);
    274288
    275                 thread_desc * readyThread = NULL;
    276                 for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ )
    277                 {
    278                         readyThread = nextThread( this->cltr );
    279 
    280                         if(readyThread)
    281                         {
    282                                 verify( ! kernelTLS.preemption_state.enabled );
    283 
    284                                 runThread(this, readyThread);
    285 
    286                                 verify( ! kernelTLS.preemption_state.enabled );
    287 
    288                                 //Some actions need to be taken from the kernel
    289                                 finishRunning(this);
     289                $thread * readyThread = 0p;
     290                for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ ) {
     291                        readyThread = __next_thread( this->cltr );
     292
     293                        if(readyThread) {
     294                                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     295                                /* paranoid */ verifyf( readyThread->state == Inactive || readyThread->state == Start || readyThread->preempted != __NO_PREEMPTION, "state : %d, preempted %d\n", readyThread->state, readyThread->preempted);
     296                                /* paranoid */ verifyf( readyThread->next == 0p, "Expected null got %p", readyThread->next );
     297
     298                                __run_thread(this, readyThread);
     299
     300                                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    290301
    291302                                spin_count = 0;
    292                         }
    293                         else
    294                         {
     303                        } else {
    295304                                // spin(this, &spin_count);
    296                                 halt(this);
     305                                __halt(this);
    297306                        }
    298307                }
     
    314323// runThread runs a thread by context switching
    315324// from the processor coroutine to the target thread
    316 static void runThread(processor * this, thread_desc * thrd_dst) {
    317         coroutine_desc * proc_cor = get_coroutine(this->runner);
    318 
    319         // Reset the terminating actions here
    320         this->finish.action_code = No_Action;
     325static void __run_thread(processor * this, $thread * thrd_dst) {
     326        $coroutine * proc_cor = get_coroutine(this->runner);
    321327
    322328        // Update global state
    323329        kernelTLS.this_thread = thrd_dst;
    324330
    325         // set state of processor coroutine to inactive and the thread to active
    326         proc_cor->state = proc_cor->state == Halted ? Halted : Inactive;
    327         thrd_dst->state = Active;
    328 
    329         // set context switch to the thread that the processor is executing
    330         verify( thrd_dst->context.SP );
    331         CtxSwitch( &proc_cor->context, &thrd_dst->context );
    332         // when CtxSwitch returns we are back in the processor coroutine
    333 
    334         // set state of processor coroutine to active and the thread to inactive
    335         thrd_dst->state = thrd_dst->state == Halted ? Halted : Inactive;
     331        // set state of processor coroutine to inactive
     332        verify(proc_cor->state == Active);
     333        proc_cor->state = Inactive;
     334
     335        // Actually run the thread
     336        RUNNING:  while(true) {
     337                if(unlikely(thrd_dst->preempted)) {
     338                        thrd_dst->preempted = __NO_PREEMPTION;
     339                        verify(thrd_dst->state == Active || thrd_dst->state == Rerun);
     340                } else {
     341                        verify(thrd_dst->state == Start || thrd_dst->state == Primed || thrd_dst->state == Inactive);
     342                        thrd_dst->state = Active;
     343                }
     344
     345                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     346
     347                // set context switch to the thread that the processor is executing
     348                verify( thrd_dst->context.SP );
     349                __cfactx_switch( &proc_cor->context, &thrd_dst->context );
     350                // when __cfactx_switch returns we are back in the processor coroutine
     351
     352                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     353
     354
     355                // We just finished running a thread, there are a few things that could have happened.
     356                // 1 - Regular case : the thread has blocked and now one has scheduled it yet.
     357                // 2 - Racy case    : the thread has blocked but someone has already tried to schedule it.
     358                // 3 - Polite Racy case : the thread has blocked, someone has already tried to schedule it, but the thread is nice and wants to go through the ready-queue any way
     359                // 4 - Preempted
     360                // In case 1, we may have won a race so we can't write to the state again.
     361                // In case 2, we lost the race so we now own the thread.
     362                // In case 3, we lost the race but can just reschedule the thread.
     363
     364                if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
     365                        // The thread was preempted, reschedule it and reset the flag
     366                        __schedule_thread( thrd_dst );
     367                        break RUNNING;
     368                }
     369
     370                // set state of processor coroutine to active and the thread to inactive
     371                static_assert(sizeof(thrd_dst->state) == sizeof(int));
     372                enum coroutine_state old_state = __atomic_exchange_n(&thrd_dst->state, Inactive, __ATOMIC_SEQ_CST);
     373                switch(old_state) {
     374                        case Halted:
     375                                // The thread has halted, it should never be scheduled/run again, leave it back to Halted and move on
     376                                thrd_dst->state = Halted;
     377
     378                                // We may need to wake someone up here since
     379                                unpark( this->destroyer );
     380                                this->destroyer = 0p;
     381                                break RUNNING;
     382                        case Active:
     383                                // This is case 1, the regular case, nothing more is needed
     384                                break RUNNING;
     385                        case Rerun:
     386                                // This is case 2, the racy case, someone tried to run this thread before it finished blocking
     387                                // In this case, just run it again.
     388                                continue RUNNING;
     389                        default:
     390                                // This makes no sense, something is wrong abort
     391                                abort("Finished running a thread that was Inactive/Start/Primed %d\n", old_state);
     392                }
     393        }
     394
     395        // Just before returning to the processor, set the processor coroutine to active
    336396        proc_cor->state = Active;
    337397}
    338398
    339399// KERNEL_ONLY
    340 static void returnToKernel() {
    341         coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
    342         thread_desc * thrd_src = kernelTLS.this_thread;
    343 
    344         // set state of current coroutine to inactive
    345         thrd_src->state = thrd_src->state == Halted ? Halted : Inactive;
    346         proc_cor->state = Active;
    347         int local_errno = *__volatile_errno();
    348         #if defined( __i386 ) || defined( __x86_64 )
    349                 __x87_store;
    350         #endif
    351 
    352         // set new coroutine that the processor is executing
    353         // and context switch to it
    354         verify( proc_cor->context.SP );
    355         CtxSwitch( &thrd_src->context, &proc_cor->context );
    356 
    357         // set state of new coroutine to active
    358         proc_cor->state = proc_cor->state == Halted ? Halted : Inactive;
    359         thrd_src->state = Active;
    360 
    361         #if defined( __i386 ) || defined( __x86_64 )
    362                 __x87_load;
    363         #endif
    364         *__volatile_errno() = local_errno;
    365 }
    366 
    367 // KERNEL_ONLY
    368 // Once a thread has finished running, some of
    369 // its final actions must be executed from the kernel
    370 static void finishRunning(processor * this) with( this->finish ) {
    371         verify( ! kernelTLS.preemption_state.enabled );
    372         choose( action_code ) {
    373         case No_Action:
    374                 break;
    375         case Release:
    376                 unlock( *lock );
    377         case Schedule:
    378                 ScheduleThread( thrd );
    379         case Release_Schedule:
    380                 unlock( *lock );
    381                 ScheduleThread( thrd );
    382         case Release_Multi:
    383                 for(int i = 0; i < lock_count; i++) {
    384                         unlock( *locks[i] );
    385                 }
    386         case Release_Multi_Schedule:
    387                 for(int i = 0; i < lock_count; i++) {
    388                         unlock( *locks[i] );
    389                 }
    390                 for(int i = 0; i < thrd_count; i++) {
    391                         ScheduleThread( thrds[i] );
    392                 }
    393         case Callback:
    394                 callback();
    395         default:
    396                 abort("KERNEL ERROR: Unexpected action to run after thread");
    397         }
     400void returnToKernel() {
     401        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     402        $coroutine * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
     403        $thread * thrd_src = kernelTLS.this_thread;
     404
     405        // Run the thread on this processor
     406        {
     407                int local_errno = *__volatile_errno();
     408                #if defined( __i386 ) || defined( __x86_64 )
     409                        __x87_store;
     410                #endif
     411                verify( proc_cor->context.SP );
     412                __cfactx_switch( &thrd_src->context, &proc_cor->context );
     413                #if defined( __i386 ) || defined( __x86_64 )
     414                        __x87_load;
     415                #endif
     416                *__volatile_errno() = local_errno;
     417        }
     418
     419        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    398420}
    399421
     
    402424// This is the entry point for processors (kernel threads)
    403425// It effectively constructs a coroutine by stealing the pthread stack
    404 static void * CtxInvokeProcessor(void * arg) {
     426static void * __invoke_processor(void * arg) {
    405427        processor * proc = (processor *) arg;
    406428        kernelTLS.this_processor = proc;
    407         kernelTLS.this_thread    = NULL;
     429        kernelTLS.this_thread    = 0p;
    408430        kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
    409431        // SKULLDUGGERY: We want to create a context for the processor coroutine
     
    418440
    419441        //Set global state
    420         kernelTLS.this_thread    = NULL;
     442        kernelTLS.this_thread = 0p;
    421443
    422444        //We now have a proper context from which to schedule threads
     
    434456        __cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, &proc->runner);
    435457
    436         return NULL;
    437 }
    438 
    439 static void start(processor * this) {
    440         __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", this);
    441 
    442         pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
    443 
    444         __cfaabi_dbg_print_safe("Kernel : core %p started\n", this);
     458        return 0p;
     459}
     460
     461static void Abort( int ret, const char func[] ) {
     462        if ( ret ) {                                                                            // pthread routines return errno values
     463                abort( "%s : internal error, error(%d) %s.", func, ret, strerror( ret ) );
     464        } // if
     465} // Abort
     466
     467void * __create_pthread( pthread_t * pthread, void * (*start)(void *), void * arg ) {
     468        pthread_attr_t attr;
     469
     470        Abort( pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute
     471
     472        size_t stacksize;
     473        // default stack size, normally defined by shell limit
     474        Abort( pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" );
     475        assert( stacksize >= PTHREAD_STACK_MIN );
     476
     477        void * stack;
     478        __cfaabi_dbg_debug_do(
     479                stack = memalign( __page_size, stacksize + __page_size );
     480                // pthread has no mechanism to create the guard page in user supplied stack.
     481                if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
     482                        abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
     483                } // if
     484        );
     485        __cfaabi_dbg_no_debug_do(
     486                stack = malloc( stacksize );
     487        );
     488
     489        Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
     490
     491        Abort( pthread_create( pthread, &attr, start, arg ), "pthread_create" );
     492        return stack;
    445493}
    446494
    447495// KERNEL_ONLY
    448 void kernel_first_resume( processor * this ) {
    449         thread_desc * src = mainThread;
    450         coroutine_desc * dst = get_coroutine(this->runner);
     496static void __kernel_first_resume( processor * this ) {
     497        $thread * src = mainThread;
     498        $coroutine * dst = get_coroutine(this->runner);
    451499
    452500        verify( ! kernelTLS.preemption_state.enabled );
    453501
     502        kernelTLS.this_thread->curr_cor = dst;
    454503        __stack_prepare( &dst->stack, 65000 );
    455         CtxStart(&this->runner, CtxInvokeCoroutine);
     504        __cfactx_start(main, dst, this->runner, __cfactx_invoke_coroutine);
    456505
    457506        verify( ! kernelTLS.preemption_state.enabled );
     
    465514        // context switch to specified coroutine
    466515        verify( dst->context.SP );
    467         CtxSwitch( &src->context, &dst->context );
    468         // when CtxSwitch returns we are back in the src coroutine
     516        __cfactx_switch( &src->context, &dst->context );
     517        // when __cfactx_switch returns we are back in the src coroutine
     518
     519        mainThread->curr_cor = &mainThread->self_cor;
    469520
    470521        // set state of new coroutine to active
     
    475526
    476527// KERNEL_ONLY
    477 void kernel_last_resume( processor * this ) {
    478         coroutine_desc * src = &mainThread->self_cor;
    479         coroutine_desc * dst = get_coroutine(this->runner);
     528static void __kernel_last_resume( processor * this ) {
     529        $coroutine * src = &mainThread->self_cor;
     530        $coroutine * dst = get_coroutine(this->runner);
    480531
    481532        verify( ! kernelTLS.preemption_state.enabled );
     
    484535
    485536        // context switch to the processor
    486         CtxSwitch( &src->context, &dst->context );
     537        __cfactx_switch( &src->context, &dst->context );
    487538}
    488539
    489540//-----------------------------------------------------------------------------
    490541// Scheduler routines
    491 
    492542// KERNEL ONLY
    493 void ScheduleThread( thread_desc * thrd ) {
    494         verify( thrd );
    495         verify( thrd->state != Halted );
    496 
    497         verify( ! kernelTLS.preemption_state.enabled );
    498 
    499         verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    500 
    501         with( *thrd->curr_cluster ) {
    502                 lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    503                 bool was_empty = !(ready_queue != 0);
    504                 append( ready_queue, thrd );
    505                 unlock( ready_queue_lock );
    506 
    507                 if(was_empty) {
    508                         lock      (proc_list_lock __cfaabi_dbg_ctx2);
    509                         if(idles) {
    510                                 wake_fast(idles.head);
    511                         }
    512                         unlock    (proc_list_lock);
     543void __schedule_thread( $thread * thrd ) with( *thrd->curr_cluster ) {
     544        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     545        /* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
     546        /* paranoid */ if( thrd->state == Inactive || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
     547                          "Error inactive thread marked as preempted, state %d, preemption %d\n", thrd->state, thrd->preempted );
     548        /* paranoid */ if( thrd->preempted != __NO_PREEMPTION ) assertf(thrd->state == Active || thrd->state == Rerun,
     549                          "Error preempted thread marked as not currently running, state %d, preemption %d\n", thrd->state, thrd->preempted );
     550        /* paranoid */ #endif
     551        /* paranoid */ verifyf( thrd->next == 0p, "Expected null got %p", thrd->next );
     552
     553        lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
     554        bool was_empty = !(ready_queue != 0);
     555        append( ready_queue, thrd );
     556        unlock( ready_queue_lock );
     557
     558        if(was_empty) {
     559                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     560                if(idles) {
     561                        wake_fast(idles.head);
    513562                }
    514                 else if( struct processor * idle = idles.head ) {
    515                         wake_fast(idle);
    516                 }
    517 
    518         }
    519 
    520         verify( ! kernelTLS.preemption_state.enabled );
     563                unlock    (proc_list_lock);
     564        }
     565        else if( struct processor * idle = idles.head ) {
     566                wake_fast(idle);
     567        }
     568
     569        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    521570}
    522571
    523572// KERNEL ONLY
    524 thread_desc * nextThread(cluster * this) with( *this ) {
    525         verify( ! kernelTLS.preemption_state.enabled );
     573static $thread * __next_thread(cluster * this) with( *this ) {
     574        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     575
    526576        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    527         thread_desc * head = pop_head( ready_queue );
     577        $thread * head = pop_head( ready_queue );
    528578        unlock( ready_queue_lock );
    529         verify( ! kernelTLS.preemption_state.enabled );
     579
     580        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    530581        return head;
    531582}
    532583
    533 void BlockInternal() {
     584void unpark( $thread * thrd ) {
     585        if( !thrd ) return;
     586
    534587        disable_interrupts();
    535         verify( ! kernelTLS.preemption_state.enabled );
     588        static_assert(sizeof(thrd->state) == sizeof(int));
     589        enum coroutine_state old_state = __atomic_exchange_n(&thrd->state, Rerun, __ATOMIC_SEQ_CST);
     590        switch(old_state) {
     591                case Active:
     592                        // Wake won the race, the thread will reschedule/rerun itself
     593                        break;
     594                case Inactive:
     595                        /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
     596
     597                        // Wake lost the race,
     598                        thrd->state = Inactive;
     599                        __schedule_thread( thrd );
     600                        break;
     601                case Rerun:
     602                        abort("More than one thread attempted to schedule thread %p\n", thrd);
     603                        break;
     604                case Halted:
     605                case Start:
     606                case Primed:
     607                default:
     608                        // This makes no sense, something is wrong abort
     609                        abort();
     610        }
     611        enable_interrupts( __cfaabi_dbg_ctx );
     612}
     613
     614void park( void ) {
     615        /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     616        disable_interrupts();
     617        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     618        /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION );
     619
    536620        returnToKernel();
    537         verify( ! kernelTLS.preemption_state.enabled );
     621
     622        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    538623        enable_interrupts( __cfaabi_dbg_ctx );
    539 }
    540 
    541 void BlockInternal( __spinlock_t * lock ) {
     624        /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     625
     626}
     627
     628// KERNEL ONLY
     629void __leave_thread() {
     630        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     631        returnToKernel();
     632        abort();
     633}
     634
     635// KERNEL ONLY
     636bool force_yield( __Preemption_Reason reason ) {
     637        /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    542638        disable_interrupts();
    543         with( *kernelTLS.this_processor ) {
    544                 finish.action_code = Release;
    545                 finish.lock        = lock;
    546         }
    547 
    548         verify( ! kernelTLS.preemption_state.enabled );
    549         returnToKernel();
    550         verify( ! kernelTLS.preemption_state.enabled );
    551 
    552         enable_interrupts( __cfaabi_dbg_ctx );
    553 }
    554 
    555 void BlockInternal( thread_desc * thrd ) {
    556         disable_interrupts();
    557         with( * kernelTLS.this_processor ) {
    558                 finish.action_code = Schedule;
    559                 finish.thrd        = thrd;
    560         }
    561 
    562         verify( ! kernelTLS.preemption_state.enabled );
    563         returnToKernel();
    564         verify( ! kernelTLS.preemption_state.enabled );
    565 
    566         enable_interrupts( __cfaabi_dbg_ctx );
    567 }
    568 
    569 void BlockInternal( __spinlock_t * lock, thread_desc * thrd ) {
    570         assert(thrd);
    571         disable_interrupts();
    572         with( * kernelTLS.this_processor ) {
    573                 finish.action_code = Release_Schedule;
    574                 finish.lock        = lock;
    575                 finish.thrd        = thrd;
    576         }
    577 
    578         verify( ! kernelTLS.preemption_state.enabled );
    579         returnToKernel();
    580         verify( ! kernelTLS.preemption_state.enabled );
    581 
    582         enable_interrupts( __cfaabi_dbg_ctx );
    583 }
    584 
    585 void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    586         disable_interrupts();
    587         with( * kernelTLS.this_processor ) {
    588                 finish.action_code = Release_Multi;
    589                 finish.locks       = locks;
    590                 finish.lock_count  = count;
    591         }
    592 
    593         verify( ! kernelTLS.preemption_state.enabled );
    594         returnToKernel();
    595         verify( ! kernelTLS.preemption_state.enabled );
    596 
    597         enable_interrupts( __cfaabi_dbg_ctx );
    598 }
    599 
    600 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    601         disable_interrupts();
    602         with( *kernelTLS.this_processor ) {
    603                 finish.action_code = Release_Multi_Schedule;
    604                 finish.locks       = locks;
    605                 finish.lock_count  = lock_count;
    606                 finish.thrds       = thrds;
    607                 finish.thrd_count  = thrd_count;
    608         }
    609 
    610         verify( ! kernelTLS.preemption_state.enabled );
    611         returnToKernel();
    612         verify( ! kernelTLS.preemption_state.enabled );
    613 
    614         enable_interrupts( __cfaabi_dbg_ctx );
    615 }
    616 
    617 void BlockInternal(__finish_callback_fptr_t callback) {
    618         disable_interrupts();
    619         with( *kernelTLS.this_processor ) {
    620                 finish.action_code = Callback;
    621                 finish.callback    = callback;
    622         }
    623 
    624         verify( ! kernelTLS.preemption_state.enabled );
    625         returnToKernel();
    626         verify( ! kernelTLS.preemption_state.enabled );
    627 
    628         enable_interrupts( __cfaabi_dbg_ctx );
    629 }
    630 
    631 // KERNEL ONLY
    632 void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    633         verify( ! kernelTLS.preemption_state.enabled );
    634         with( * kernelTLS.this_processor ) {
    635                 finish.action_code = thrd ? Release_Schedule : Release;
    636                 finish.lock        = lock;
    637                 finish.thrd        = thrd;
    638         }
    639 
    640         returnToKernel();
     639        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     640
     641        $thread * thrd = kernelTLS.this_thread;
     642        /* paranoid */ verify(thrd->state == Active || thrd->state == Rerun);
     643
     644        // SKULLDUGGERY: It is possible that we are preempting this thread just before
     645        // it was going to park itself. If that is the case and it is already using the
     646        // intrusive fields then we can't use them to preempt the thread
     647        // If that is the case, abandon the preemption.
     648        bool preempted = false;
     649        if(thrd->next == 0p) {
     650                preempted = true;
     651                thrd->preempted = reason;
     652                returnToKernel();
     653        }
     654
     655        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     656        enable_interrupts_noPoll();
     657        /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     658
     659        return preempted;
    641660}
    642661
     
    646665//-----------------------------------------------------------------------------
    647666// Kernel boot procedures
    648 static void kernel_startup(void) {
     667static void __kernel_startup(void) {
    649668        verify( ! kernelTLS.preemption_state.enabled );
    650669        __cfaabi_dbg_print_safe("Kernel : Starting\n");
     
    664683        // SKULLDUGGERY: the mainThread steals the process main thread
    665684        // which will then be scheduled by the mainProcessor normally
    666         mainThread = (thread_desc *)&storage_mainThread;
     685        mainThread = ($thread *)&storage_mainThread;
    667686        current_stack_info_t info;
    668687        info.storage = (__stack_t*)&storage_mainThreadCtx;
     
    676695        void ?{}(processorCtx_t & this, processor * proc) {
    677696                (this.__cor){ "Processor" };
    678                 this.__cor.starter = NULL;
     697                this.__cor.starter = 0p;
    679698                this.proc = proc;
    680699        }
     
    685704                terminated{ 0 };
    686705                do_terminate = false;
    687                 preemption_alarm = NULL;
     706                preemption_alarm = 0p;
    688707                pending_preemption = false;
    689708                kernel_thread = pthread_self();
     
    707726        // Add the main thread to the ready queue
    708727        // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread
    709         ScheduleThread(mainThread);
     728        __schedule_thread(mainThread);
    710729
    711730        // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX
    712         // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
     731        // context. Hence, the main thread does not begin through __cfactx_invoke_thread, like all other threads. The trick here is that
    713732        // mainThread is on the ready queue when this call is made.
    714         kernel_first_resume( kernelTLS.this_processor );
     733        __kernel_first_resume( kernelTLS.this_processor );
    715734
    716735
     
    724743}
    725744
    726 static void kernel_shutdown(void) {
     745static void __kernel_shutdown(void) {
    727746        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    728747
     
    735754        // which is currently here
    736755        __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);
    737         kernel_last_resume( kernelTLS.this_processor );
     756        __kernel_last_resume( kernelTLS.this_processor );
    738757        mainThread->self_cor.state = Halted;
    739758
     
    761780// Kernel Quiescing
    762781//=============================================================================================
    763 static void halt(processor * this) with( *this ) {
     782static void __halt(processor * this) with( *this ) {
    764783        // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
    765784
     
    803822                sigemptyset( &mask );
    804823                sigaddset( &mask, SIGALRM );            // block SIGALRM signals
    805                 sigsuspend( &mask );                    // block the processor to prevent further damage during abort
    806                 _exit( EXIT_FAILURE );                  // if processor unblocks before it is killed, terminate it
     824                sigaddset( &mask, SIGUSR1 );            // block SIGALRM signals
     825                sigsuspend( &mask );                            // block the processor to prevent further damage during abort
     826                _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    807827        }
    808828        else {
     
    815835
    816836void kernel_abort_msg( void * kernel_data, char * abort_text, int abort_text_size ) {
    817         thread_desc * thrd = kernel_data;
     837        $thread * thrd = kernel_data;
    818838
    819839        if(thrd) {
    820840                int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd );
    821                 __cfaabi_dbg_bits_write( abort_text, len );
     841                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    822842
    823843                if ( &thrd->self_cor != thrd->curr_cor ) {
    824844                        len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", thrd->curr_cor->name, thrd->curr_cor );
    825                         __cfaabi_dbg_bits_write( abort_text, len );
     845                        __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    826846                }
    827847                else {
    828                         __cfaabi_dbg_bits_write( ".\n", 2 );
     848                        __cfaabi_bits_write( STDERR_FILENO, ".\n", 2 );
    829849                }
    830850        }
    831851        else {
    832852                int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" );
    833                 __cfaabi_dbg_bits_write( abort_text, len );
     853                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    834854        }
    835855}
     
    842862
    843863extern "C" {
    844         void __cfaabi_dbg_bits_acquire() {
     864        void __cfaabi_bits_acquire() {
    845865                lock( kernel_debug_lock __cfaabi_dbg_ctx2 );
    846866        }
    847867
    848         void __cfaabi_dbg_bits_release() {
     868        void __cfaabi_bits_release() {
    849869                unlock( kernel_debug_lock );
    850870        }
     
    871891
    872892                // atomically release spin lock and block
    873                 BlockInternal( &lock );
     893                unlock( lock );
     894                park();
    874895        }
    875896        else {
     
    879900
    880901void V(semaphore & this) with( this ) {
    881         thread_desc * thrd = NULL;
     902        $thread * thrd = 0p;
    882903        lock( lock __cfaabi_dbg_ctx2 );
    883904        count += 1;
     
    890911
    891912        // make new owner
    892         WakeThread( thrd );
     913        unpark( thrd );
    893914}
    894915
     
    907928}
    908929
    909 void doregister( cluster * cltr, thread_desc & thrd ) {
     930void doregister( cluster * cltr, $thread & thrd ) {
    910931        lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    911932        cltr->nthreads += 1;
     
    914935}
    915936
    916 void unregister( cluster * cltr, thread_desc & thrd ) {
     937void unregister( cluster * cltr, $thread & thrd ) {
    917938        lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    918939        remove(cltr->threads, thrd );
     
    939960__cfaabi_dbg_debug_do(
    940961        extern "C" {
    941                 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
     962                void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]) {
    942963                        this.prev_name = prev_name;
    943964                        this.prev_thrd = kernelTLS.this_thread;
     
    948969//-----------------------------------------------------------------------------
    949970// Debug
    950 bool threading_enabled(void) {
     971bool threading_enabled(void) __attribute__((const)) {
    951972        return true;
    952973}
  • libcfa/src/concurrency/kernel.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun 22 11:39:17 2019
    13 // Update Count     : 16
     12// Last Modified On : Tue Feb  4 12:29:26 2020
     13// Update Count     : 22
    1414//
    1515
     
    2020#include "invoke.h"
    2121#include "time_t.hfa"
     22#include "coroutine.hfa"
    2223
    2324extern "C" {
     
    3132        __spinlock_t lock;
    3233        int count;
    33         __queue_t(thread_desc) waiting;
     34        __queue_t($thread) waiting;
    3435};
    3536
     
    4344// Processor
    4445extern struct cluster * mainCluster;
    45 
    46 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule, Callback };
    47 
    48 typedef void (*__finish_callback_fptr_t)(void);
    49 
    50 //TODO use union, many of these fields are mutually exclusive (i.e. MULTI vs NOMULTI)
    51 struct FinishAction {
    52         FinishOpCode action_code;
    53         /*
    54         // Union of possible actions
    55         union {
    56                 // Option 1 : locks and threads
    57                 struct {
    58                         // 1 thread or N thread
    59                         union {
    60                                 thread_desc * thrd;
    61                                 struct {
    62                                         thread_desc ** thrds;
    63                                         unsigned short thrd_count;
    64                                 };
    65                         };
    66                         // 1 lock or N lock
    67                         union {
    68                                 __spinlock_t * lock;
    69                                 struct {
    70                                         __spinlock_t ** locks;
    71                                         unsigned short lock_count;
    72                                 };
    73                         };
    74                 };
    75                 // Option 2 : action pointer
    76                 __finish_callback_fptr_t callback;
    77         };
    78         /*/
    79         thread_desc * thrd;
    80         thread_desc ** thrds;
    81         unsigned short thrd_count;
    82         __spinlock_t * lock;
    83         __spinlock_t ** locks;
    84         unsigned short lock_count;
    85         __finish_callback_fptr_t callback;
    86         //*/
    87 };
    88 static inline void ?{}(FinishAction & this) {
    89         this.action_code = No_Action;
    90         this.thrd = NULL;
    91         this.lock = NULL;
    92 }
    93 static inline void ^?{}(FinishAction &) {}
    9446
    9547// Processor
     
    11567        // RunThread data
    11668        // Action to do after a thread is ran
    117         struct FinishAction finish;
     69        $thread * destroyer;
    11870
    11971        // Preemption data
     
    13486        semaphore terminated;
    13587
     88        // pthread Stack
     89        void * stack;
     90
    13691        // Link lists fields
    13792        struct __dbg_node_proc {
     
    146101};
    147102
    148 void  ?{}(processor & this, const char * name, struct cluster & cltr);
     103void  ?{}(processor & this, const char name[], struct cluster & cltr);
    149104void ^?{}(processor & this);
    150105
    151106static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
    152107static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
    153 static inline void  ?{}(processor & this, const char * name) { this{name, *mainCluster }; }
     108static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
    154109
    155 static inline [processor *&, processor *& ] __get( processor & this ) {
    156         return this.node.[next, prev];
    157 }
     110static inline [processor *&, processor *& ] __get( processor & this ) __attribute__((const)) { return this.node.[next, prev]; }
    158111
    159112//-----------------------------------------------------------------------------
     
    164117
    165118        // Ready queue for threads
    166         __queue_t(thread_desc) ready_queue;
     119        __queue_t($thread) ready_queue;
    167120
    168121        // Name of the cluster
     
    180133        // List of threads
    181134        __spinlock_t thread_list_lock;
    182         __dllist_t(struct thread_desc) threads;
     135        __dllist_t(struct $thread) threads;
    183136        unsigned int nthreads;
    184137
     
    191144extern Duration default_preemption();
    192145
    193 void ?{} (cluster & this, const char * name, Duration preemption_rate);
     146void ?{} (cluster & this, const char name[], Duration preemption_rate);
    194147void ^?{}(cluster & this);
    195148
    196149static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
    197150static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
    198 static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
     151static inline void ?{} (cluster & this, const char name[])        { this{name, default_preemption()}; }
    199152
    200 static inline [cluster *&, cluster *& ] __get( cluster & this ) {
    201         return this.node.[next, prev];
    202 }
     153static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
    203154
    204155static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
  • libcfa/src/concurrency/kernel_private.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Feb 13 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 29 14:06:40 2018
    13 // Update Count     : 3
     12// Last Modified On : Sat Nov 30 19:25:02 2019
     13// Update Count     : 8
    1414//
    1515
     
    3131}
    3232
    33 void ScheduleThread( thread_desc * );
    34 static inline void WakeThread( thread_desc * thrd ) {
    35         if( !thrd ) return;
    36 
    37         disable_interrupts();
    38         ScheduleThread( thrd );
    39         enable_interrupts( __cfaabi_dbg_ctx );
    40 }
    41 thread_desc * nextThread(cluster * this);
     33void __schedule_thread( $thread * ) __attribute__((nonnull (1)));
    4234
    4335//Block current thread and release/wake-up the following resources
    44 void BlockInternal(void);
    45 void BlockInternal(__spinlock_t * lock);
    46 void BlockInternal(thread_desc * thrd);
    47 void BlockInternal(__spinlock_t * lock, thread_desc * thrd);
    48 void BlockInternal(__spinlock_t * locks [], unsigned short count);
    49 void BlockInternal(__spinlock_t * locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count);
    50 void BlockInternal(__finish_callback_fptr_t callback);
    51 void LeaveThread(__spinlock_t * lock, thread_desc * thrd);
     36void __leave_thread() __attribute__((noreturn));
    5237
    5338//-----------------------------------------------------------------------------
    5439// Processor
    5540void main(processorCtx_t *);
     41
     42void * __create_pthread( pthread_t *, void * (*)(void *), void * );
    5643
    5744static inline void wake_fast(processor * this) {
     
    8471// Threads
    8572extern "C" {
    86       forall(dtype T | is_thread(T))
    87       void CtxInvokeThread(T * this);
     73      void __cfactx_invoke_thread(void (*main)(void *), void * this);
    8874}
    8975
    90 extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst);
    91 
    9276__cfaabi_dbg_debug_do(
    93         extern void __cfaabi_dbg_thread_register  ( thread_desc * thrd );
    94         extern void __cfaabi_dbg_thread_unregister( thread_desc * thrd );
     77        extern void __cfaabi_dbg_thread_register  ( $thread * thrd );
     78        extern void __cfaabi_dbg_thread_unregister( $thread * thrd );
    9579)
    9680
     
    9983#define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)]
    10084
     85static inline uint32_t __tls_rand() {
     86        kernelTLS.rand_seed ^= kernelTLS.rand_seed << 6;
     87        kernelTLS.rand_seed ^= kernelTLS.rand_seed >> 21;
     88        kernelTLS.rand_seed ^= kernelTLS.rand_seed << 7;
     89        return kernelTLS.rand_seed;
     90}
     91
    10192
    10293void doregister( struct cluster & cltr );
    10394void unregister( struct cluster & cltr );
    10495
    105 void doregister( struct cluster * cltr, struct thread_desc & thrd );
    106 void unregister( struct cluster * cltr, struct thread_desc & thrd );
     96void doregister( struct cluster * cltr, struct $thread & thrd );
     97void unregister( struct cluster * cltr, struct $thread & thrd );
    10798
    10899void doregister( struct cluster * cltr, struct processor * proc );
  • libcfa/src/concurrency/monitor.cfa

    r9fb8f01 r3d5701e  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // monitor_desc.c --
     7// $monitor.c --
    88//
    99// Author           : Thierry Delisle
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 14:30:26 2018
    13 // Update Count     : 9
     12// Last Modified On : Wed Dec  4 07:55:14 2019
     13// Update Count     : 10
    1414//
    1515
     
    2727//-----------------------------------------------------------------------------
    2828// Forward declarations
    29 static inline void set_owner ( monitor_desc * this, thread_desc * owner );
    30 static inline void set_owner ( monitor_desc * storage [], __lock_size_t count, thread_desc * owner );
    31 static inline void set_mask  ( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask );
    32 static inline void reset_mask( monitor_desc * this );
    33 
    34 static inline thread_desc * next_thread( monitor_desc * this );
    35 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors );
     29static inline void __set_owner ( $monitor * this, $thread * owner );
     30static inline void __set_owner ( $monitor * storage [], __lock_size_t count, $thread * owner );
     31static inline void set_mask  ( $monitor * storage [], __lock_size_t count, const __waitfor_mask_t & mask );
     32static inline void reset_mask( $monitor * this );
     33
     34static inline $thread * next_thread( $monitor * this );
     35static inline bool is_accepted( $monitor * this, const __monitor_group_t & monitors );
    3636
    3737static inline void lock_all  ( __spinlock_t * locks [], __lock_size_t count );
    38 static inline void lock_all  ( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count );
     38static inline void lock_all  ( $monitor * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count );
    3939static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count );
    40 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count );
    41 
    42 static inline void save   ( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );
    43 static inline void restore( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );
    44 
    45 static inline void init     ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
    46 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
    47 
    48 static inline thread_desc *        check_condition   ( __condition_criterion_t * );
     40static inline void unlock_all( $monitor * locks [], __lock_size_t count );
     41
     42static inline void save   ( $monitor * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );
     43static inline void restore( $monitor * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );
     44
     45static inline void init     ( __lock_size_t count, $monitor * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
     46static inline void init_push( __lock_size_t count, $monitor * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
     47
     48static inline $thread *        check_condition   ( __condition_criterion_t * );
    4949static inline void                 brand_condition   ( condition & );
    50 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc * monitors [], __lock_size_t count );
     50static inline [$thread *, int] search_entry_queue( const __waitfor_mask_t &, $monitor * monitors [], __lock_size_t count );
    5151
    5252forall(dtype T | sized( T ))
    5353static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val );
    5454static inline __lock_size_t count_max    ( const __waitfor_mask_t & mask );
    55 static inline __lock_size_t aggregate    ( monitor_desc * storage [], const __waitfor_mask_t & mask );
     55static inline __lock_size_t aggregate    ( $monitor * storage [], const __waitfor_mask_t & mask );
    5656
    5757//-----------------------------------------------------------------------------
     
    6868
    6969#define monitor_ctx( mons, cnt )                                /* Define that create the necessary struct for internal/external scheduling operations */ \
    70         monitor_desc ** monitors = mons;                          /* Save the targeted monitors                                                          */ \
     70        $monitor ** monitors = mons;                          /* Save the targeted monitors                                                          */ \
    7171        __lock_size_t count = cnt;                                /* Save the count to a local variable                                                  */ \
    7272        unsigned int recursions[ count ];                         /* Save the current recursion levels to restore them later                             */ \
     
    8080//-----------------------------------------------------------------------------
    8181// Enter/Leave routines
    82 
    83 
    84 extern "C" {
    85         // Enter single monitor
    86         static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
    87                 // Lock the monitor spinlock
    88                 lock( this->lock __cfaabi_dbg_ctx2 );
    89                 // Interrupts disable inside critical section
    90                 thread_desc * thrd = kernelTLS.this_thread;
    91 
    92                 __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
    93 
    94                 if( !this->owner ) {
    95                         // No one has the monitor, just take it
    96                         set_owner( this, thrd );
    97 
    98                         __cfaabi_dbg_print_safe( "Kernel :  mon is free \n" );
    99                 }
    100                 else if( this->owner == thrd) {
    101                         // We already have the monitor, just note how many times we took it
    102                         this->recursion += 1;
    103 
    104                         __cfaabi_dbg_print_safe( "Kernel :  mon already owned \n" );
    105                 }
    106                 else if( is_accepted( this, group) ) {
    107                         // Some one was waiting for us, enter
    108                         set_owner( this, thrd );
    109 
    110                         // Reset mask
    111                         reset_mask( this );
    112 
    113                         __cfaabi_dbg_print_safe( "Kernel :  mon accepts \n" );
    114                 }
    115                 else {
    116                         __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
    117 
    118                         // Some one else has the monitor, wait in line for it
    119                         append( this->entry_queue, thrd );
    120 
    121                         BlockInternal( &this->lock );
    122 
    123                         __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
    124 
    125                         // BlockInternal will unlock spinlock, no need to unlock ourselves
    126                         return;
    127                 }
     82// Enter single monitor
     83static void __enter( $monitor * this, const __monitor_group_t & group ) {
     84        // Lock the monitor spinlock
     85        lock( this->lock __cfaabi_dbg_ctx2 );
     86        // Interrupts disable inside critical section
     87        $thread * thrd = kernelTLS.this_thread;
     88
     89        __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     90
     91        if( !this->owner ) {
     92                // No one has the monitor, just take it
     93                __set_owner( this, thrd );
     94
     95                __cfaabi_dbg_print_safe( "Kernel :  mon is free \n" );
     96        }
     97        else if( this->owner == thrd) {
     98                // We already have the monitor, just note how many times we took it
     99                this->recursion += 1;
     100
     101                __cfaabi_dbg_print_safe( "Kernel :  mon already owned \n" );
     102        }
     103        else if( is_accepted( this, group) ) {
     104                // Some one was waiting for us, enter
     105                __set_owner( this, thrd );
     106
     107                // Reset mask
     108                reset_mask( this );
     109
     110                __cfaabi_dbg_print_safe( "Kernel :  mon accepts \n" );
     111        }
     112        else {
     113                __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
     114
     115                // Some one else has the monitor, wait in line for it
     116                /* paranoid */ verify( thrd->next == 0p );
     117                append( this->entry_queue, thrd );
     118                /* paranoid */ verify( thrd->next == 1p );
     119
     120                unlock( this->lock );
     121                park();
    128122
    129123                __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
    130124
    131                 // Release the lock and leave
     125                /* paranoid */ verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     126                return;
     127        }
     128
     129        __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
     130
     131        /* paranoid */ verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     132        /* paranoid */ verify( this->lock.lock );
     133
     134        // Release the lock and leave
     135        unlock( this->lock );
     136        return;
     137}
     138
     139static void __dtor_enter( $monitor * this, fptr_t func ) {
     140        // Lock the monitor spinlock
     141        lock( this->lock __cfaabi_dbg_ctx2 );
     142        // Interrupts disable inside critical section
     143        $thread * thrd = kernelTLS.this_thread;
     144
     145        __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
     146
     147
     148        if( !this->owner ) {
     149                __cfaabi_dbg_print_safe( "Kernel : Destroying free mon %p\n", this);
     150
     151                // No one has the monitor, just take it
     152                __set_owner( this, thrd );
     153
     154                verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     155
    132156                unlock( this->lock );
    133157                return;
    134158        }
    135 
    136         static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
    137                 // Lock the monitor spinlock
    138                 lock( this->lock __cfaabi_dbg_ctx2 );
    139                 // Interrupts disable inside critical section
    140                 thread_desc * thrd = kernelTLS.this_thread;
    141 
    142                 __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
    143 
    144 
    145                 if( !this->owner ) {
    146                         __cfaabi_dbg_print_safe( "Kernel : Destroying free mon %p\n", this);
    147 
    148                         // No one has the monitor, just take it
    149                         set_owner( this, thrd );
    150 
    151                         unlock( this->lock );
    152                         return;
     159        else if( this->owner == thrd) {
     160                // We already have the monitor... but where about to destroy it so the nesting will fail
     161                // Abort!
     162                abort( "Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.", this, thrd->self_cor.name, thrd );
     163        }
     164
     165        __lock_size_t count = 1;
     166        $monitor ** monitors = &this;
     167        __monitor_group_t group = { &this, 1, func };
     168        if( is_accepted( this, group) ) {
     169                __cfaabi_dbg_print_safe( "Kernel :  mon accepts dtor, block and signal it \n" );
     170
     171                // Wake the thread that is waiting for this
     172                __condition_criterion_t * urgent = pop( this->signal_stack );
     173                /* paranoid */ verify( urgent );
     174
     175                // Reset mask
     176                reset_mask( this );
     177
     178                // Create the node specific to this wait operation
     179                wait_ctx_primed( thrd, 0 )
     180
     181                // Some one else has the monitor, wait for him to finish and then run
     182                unlock( this->lock );
     183
     184                // Release the next thread
     185                /* paranoid */ verifyf( urgent->owner->waiting_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     186                unpark( urgent->owner->waiting_thread );
     187
     188                // Park current thread waiting
     189                park();
     190
     191                // Some one was waiting for us, enter
     192                /* paranoid */ verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     193        }
     194        else {
     195                __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
     196
     197                wait_ctx( thrd, 0 )
     198                this->dtor_node = &waiter;
     199
     200                // Some one else has the monitor, wait in line for it
     201                /* paranoid */ verify( thrd->next == 0p );
     202                append( this->entry_queue, thrd );
     203                /* paranoid */ verify( thrd->next == 1p );
     204                unlock( this->lock );
     205
     206                // Park current thread waiting
     207                park();
     208
     209                /* paranoid */ verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     210                return;
     211        }
     212
     213        __cfaabi_dbg_print_safe( "Kernel : Destroying %p\n", this);
     214
     215}
     216
     217// Leave single monitor
     218void __leave( $monitor * this ) {
     219        // Lock the monitor spinlock
     220        lock( this->lock __cfaabi_dbg_ctx2 );
     221
     222        __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", kernelTLS.this_thread, this, this->owner);
     223
     224        /* paranoid */ verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     225
     226        // Leaving a recursion level, decrement the counter
     227        this->recursion -= 1;
     228
     229        // If we haven't left the last level of recursion
     230        // it means we don't need to do anything
     231        if( this->recursion != 0) {
     232                __cfaabi_dbg_print_safe( "Kernel :  recursion still %d\n", this->recursion);
     233                unlock( this->lock );
     234                return;
     235        }
     236
     237        // Get the next thread, will be null on low contention monitor
     238        $thread * new_owner = next_thread( this );
     239
     240        // Check the new owner is consistent with who we wake-up
     241        // new_owner might be null even if someone owns the monitor when the owner is still waiting for another monitor
     242        /* paranoid */ verifyf( !new_owner || new_owner == this->owner, "Expected owner to be %p, got %p (m: %p)", new_owner, this->owner, this );
     243
     244        // We can now let other threads in safely
     245        unlock( this->lock );
     246
     247        //We need to wake-up the thread
     248        /* paranoid */ verifyf( !new_owner || new_owner == this->owner, "Expected owner to be %p, got %p (m: %p)", new_owner, this->owner, this );
     249        unpark( new_owner );
     250}
     251
     252// Leave single monitor for the last time
     253void __dtor_leave( $monitor * this ) {
     254        __cfaabi_dbg_debug_do(
     255                if( TL_GET( this_thread ) != this->owner ) {
     256                        abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, TL_GET( this_thread ), this->owner);
    153257                }
    154                 else if( this->owner == thrd) {
    155                         // We already have the monitor... but where about to destroy it so the nesting will fail
    156                         // Abort!
    157                         abort( "Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.", this, thrd->self_cor.name, thrd );
     258                if( this->recursion != 1 ) {
     259                        abort( "Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
    158260                }
    159 
    160                 __lock_size_t count = 1;
    161                 monitor_desc ** monitors = &this;
    162                 __monitor_group_t group = { &this, 1, func };
    163                 if( is_accepted( this, group) ) {
    164                         __cfaabi_dbg_print_safe( "Kernel :  mon accepts dtor, block and signal it \n" );
    165 
    166                         // Wake the thread that is waiting for this
    167                         __condition_criterion_t * urgent = pop( this->signal_stack );
    168                         verify( urgent );
    169 
    170                         // Reset mask
    171                         reset_mask( this );
    172 
    173                         // Create the node specific to this wait operation
    174                         wait_ctx_primed( thrd, 0 )
    175 
    176                         // Some one else has the monitor, wait for him to finish and then run
    177                         BlockInternal( &this->lock, urgent->owner->waiting_thread );
    178 
    179                         // Some one was waiting for us, enter
    180                         set_owner( this, thrd );
    181                 }
    182                 else {
    183                         __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
    184 
    185                         wait_ctx( thrd, 0 )
    186                         this->dtor_node = &waiter;
    187 
    188                         // Some one else has the monitor, wait in line for it
    189                         append( this->entry_queue, thrd );
    190                         BlockInternal( &this->lock );
    191 
    192                         // BlockInternal will unlock spinlock, no need to unlock ourselves
    193                         return;
    194                 }
    195 
    196                 __cfaabi_dbg_print_safe( "Kernel : Destroying %p\n", this);
    197 
    198         }
    199 
    200         // Leave single monitor
    201         void __leave_monitor_desc( monitor_desc * this ) {
    202                 // Lock the monitor spinlock
    203                 lock( this->lock __cfaabi_dbg_ctx2 );
    204 
    205                 __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", kernelTLS.this_thread, this, this->owner);
    206 
    207                 verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
    208 
    209                 // Leaving a recursion level, decrement the counter
    210                 this->recursion -= 1;
    211 
    212                 // If we haven't left the last level of recursion
    213                 // it means we don't need to do anything
    214                 if( this->recursion != 0) {
    215                         __cfaabi_dbg_print_safe( "Kernel :  recursion still %d\n", this->recursion);
    216                         unlock( this->lock );
    217                         return;
    218                 }
    219 
    220                 // Get the next thread, will be null on low contention monitor
    221                 thread_desc * new_owner = next_thread( this );
    222 
    223                 // We can now let other threads in safely
    224                 unlock( this->lock );
    225 
    226                 //We need to wake-up the thread
    227                 WakeThread( new_owner );
    228         }
    229 
    230         // Leave single monitor for the last time
    231         void __leave_dtor_monitor_desc( monitor_desc * this ) {
    232                 __cfaabi_dbg_debug_do(
    233                         if( TL_GET( this_thread ) != this->owner ) {
    234                                 abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, TL_GET( this_thread ), this->owner);
    235                         }
    236                         if( this->recursion != 1 ) {
    237                                 abort( "Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
    238                         }
    239                 )
    240         }
    241 
     261        )
     262}
     263
     264extern "C" {
    242265        // Leave the thread monitor
    243266        // last routine called by a thread.
    244267        // Should never return
    245         void __leave_thread_monitor( thread_desc * thrd ) {
    246                 monitor_desc * this = &thrd->self_mon;
     268        void __cfactx_thrd_leave() {
     269                $thread * thrd = TL_GET( this_thread );
     270                $monitor * this = &thrd->self_mon;
    247271
    248272                // Lock the monitor now
     
    251275                disable_interrupts();
    252276
    253                 thrd->self_cor.state = Halted;
    254 
    255                 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", thrd, this->owner, this->recursion, this );
     277                thrd->state = Halted;
     278
     279                /* paranoid */ verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", thrd, this->owner, this->recursion, this );
    256280
    257281                // Leaving a recursion level, decrement the counter
     
    263287
    264288                // Fetch the next thread, can be null
    265                 thread_desc * new_owner = next_thread( this );
    266 
    267                 // Leave the thread, this will unlock the spinlock
    268                 // Use leave thread instead of BlockInternal which is
    269                 // specialized for this case and supports null new_owner
    270                 LeaveThread( &this->lock, new_owner );
     289                $thread * new_owner = next_thread( this );
     290
     291                // Release the monitor lock
     292                unlock( this->lock );
     293
     294                // Unpark the next owner if needed
     295                /* paranoid */ verifyf( !new_owner || new_owner == this->owner, "Expected owner to be %p, got %p (m: %p)", new_owner, this->owner, this );
     296                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     297                /* paranoid */ verify( ! kernelTLS.this_processor->destroyer );
     298                /* paranoid */ verify( thrd->state == Halted );
     299
     300                kernelTLS.this_processor->destroyer = new_owner;
     301
     302                // Leave the thread
     303                __leave_thread();
    271304
    272305                // Control flow should never reach here!
     
    278311static inline void enter( __monitor_group_t monitors ) {
    279312        for( __lock_size_t i = 0; i < monitors.size; i++) {
    280                 __enter_monitor_desc( monitors[i], monitors );
     313                __enter( monitors[i], monitors );
    281314        }
    282315}
     
    284317// Leave multiple monitor
    285318// relies on the monitor array being sorted
    286 static inline void leave(monitor_desc * monitors [], __lock_size_t count) {
     319static inline void leave($monitor * monitors [], __lock_size_t count) {
    287320        for( __lock_size_t i = count - 1; i >= 0; i--) {
    288                 __leave_monitor_desc( monitors[i] );
     321                __leave( monitors[i] );
    289322        }
    290323}
     
    292325// Ctor for monitor guard
    293326// Sorts monitors before entering
    294 void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
    295         thread_desc * thrd = TL_GET( this_thread );
     327void ?{}( monitor_guard_t & this, $monitor * m [], __lock_size_t count, fptr_t func ) {
     328        $thread * thrd = TL_GET( this_thread );
    296329
    297330        // Store current array
     
    333366// Ctor for monitor guard
    334367// Sorts monitors before entering
    335 void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {
     368void ?{}( monitor_dtor_guard_t & this, $monitor * m [], fptr_t func ) {
    336369        // optimization
    337         thread_desc * thrd = TL_GET( this_thread );
     370        $thread * thrd = TL_GET( this_thread );
    338371
    339372        // Store current array
     
    346379        (thrd->monitors){m, 1, func};
    347380
    348         __enter_monitor_dtor( this.m, func );
     381        __dtor_enter( this.m, func );
    349382}
    350383
     
    352385void ^?{}( monitor_dtor_guard_t & this ) {
    353386        // Leave the monitors in order
    354         __leave_dtor_monitor_desc( this.m );
     387        __dtor_leave( this.m );
    355388
    356389        // Restore thread context
     
    360393//-----------------------------------------------------------------------------
    361394// Internal scheduling types
    362 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
     395void ?{}(__condition_node_t & this, $thread * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
    363396        this.waiting_thread = waiting_thread;
    364397        this.count = count;
    365         this.next = NULL;
     398        this.next = 0p;
    366399        this.user_info = user_info;
    367400}
     
    369402void ?{}(__condition_criterion_t & this ) with( this ) {
    370403        ready  = false;
    371         target = NULL;
    372         owner  = NULL;
    373         next   = NULL;
    374 }
    375 
    376 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t & owner ) {
     404        target = 0p;
     405        owner  = 0p;
     406        next   = 0p;
     407}
     408
     409void ?{}(__condition_criterion_t & this, $monitor * target, __condition_node_t & owner ) {
    377410        this.ready  = false;
    378411        this.target = target;
    379412        this.owner  = &owner;
    380         this.next   = NULL;
     413        this.next   = 0p;
    381414}
    382415
     
    387420
    388421        // Check that everything is as expected
    389         assertf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors );
     422        assertf( this.monitors != 0p, "Waiting with no monitors (%p)", this.monitors );
    390423        verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count );
    391424        verifyf( this.monitor_count < 32u, "Excessive monitor count (%"PRIiFAST16")", this.monitor_count );
     
    399432        // Append the current wait operation to the ones already queued on the condition
    400433        // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion
     434        /* paranoid */ verify( waiter.next == 0p );
    401435        append( this.blocked, &waiter );
     436        /* paranoid */ verify( waiter.next == 1p );
    402437
    403438        // Lock all monitors (aggregates the locks as well)
     
    406441        // Find the next thread(s) to run
    407442        __lock_size_t thread_count = 0;
    408         thread_desc * threads[ count ];
     443        $thread * threads[ count ];
    409444        __builtin_memset( threads, 0, sizeof( threads ) );
    410445
     
    414449        // Remove any duplicate threads
    415450        for( __lock_size_t i = 0; i < count; i++) {
    416                 thread_desc * new_owner = next_thread( monitors[i] );
     451                $thread * new_owner = next_thread( monitors[i] );
    417452                insert_unique( threads, thread_count, new_owner );
    418453        }
    419454
     455        // Unlock the locks, we don't need them anymore
     456        for(int i = 0; i < count; i++) {
     457                unlock( *locks[i] );
     458        }
     459
     460        // Wake the threads
     461        for(int i = 0; i < thread_count; i++) {
     462                unpark( threads[i] );
     463        }
     464
    420465        // Everything is ready to go to sleep
    421         BlockInternal( locks, count, threads, thread_count );
     466        park();
    422467
    423468        // We are back, restore the owners and recursions
     
    434479        //Some more checking in debug
    435480        __cfaabi_dbg_debug_do(
    436                 thread_desc * this_thrd = TL_GET( this_thread );
     481                $thread * this_thrd = TL_GET( this_thread );
    437482                if ( this.monitor_count != this_thrd->monitors.size ) {
    438483                        abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi", &this, this.monitor_count, this_thrd->monitors.size );
     
    449494
    450495        // Lock all monitors
    451         lock_all( this.monitors, NULL, count );
     496        lock_all( this.monitors, 0p, count );
    452497
    453498        //Pop the head of the waiting queue
     
    471516
    472517        //Check that everything is as expected
    473         verifyf( this.monitors != NULL, "Waiting with no monitors (%p)", this.monitors );
     518        verifyf( this.monitors != 0p, "Waiting with no monitors (%p)", this.monitors );
    474519        verifyf( this.monitor_count != 0, "Waiting with 0 monitors (%"PRIiFAST16")", this.monitor_count );
    475520
     
    488533
    489534        //Find the thread to run
    490         thread_desc * signallee = pop_head( this.blocked )->waiting_thread;
    491         set_owner( monitors, count, signallee );
     535        $thread * signallee = pop_head( this.blocked )->waiting_thread;
     536        /* paranoid */ verify( signallee->next == 0p );
     537        __set_owner( monitors, count, signallee );
    492538
    493539        __cfaabi_dbg_print_buffer_decl( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
    494540
     541        // unlock all the monitors
     542        unlock_all( locks, count );
     543
     544        // unpark the thread we signalled
     545        unpark( signallee );
     546
    495547        //Everything is ready to go to sleep
    496         BlockInternal( locks, count, &signallee, 1 );
     548        park();
    497549
    498550
     
    535587        // Create one!
    536588        __lock_size_t max = count_max( mask );
    537         monitor_desc * mon_storage[max];
     589        $monitor * mon_storage[max];
    538590        __builtin_memset( mon_storage, 0, sizeof( mon_storage ) );
    539591        __lock_size_t actual_count = aggregate( mon_storage, mask );
     
    553605        {
    554606                // Check if the entry queue
    555                 thread_desc * next; int index;
     607                $thread * next; int index;
    556608                [next, index] = search_entry_queue( mask, monitors, count );
    557609
     
    563615                                verifyf( accepted.size == 1,  "ERROR: Accepted dtor has more than 1 mutex parameter." );
    564616
    565                                 monitor_desc * mon2dtor = accepted[0];
     617                                $monitor * mon2dtor = accepted[0];
    566618                                verifyf( mon2dtor->dtor_node, "ERROR: Accepted monitor has no dtor_node." );
    567619
     
    589641
    590642                                // Set the owners to be the next thread
    591                                 set_owner( monitors, count, next );
    592 
    593                                 // Everything is ready to go to sleep
    594                                 BlockInternal( locks, count, &next, 1 );
     643                                __set_owner( monitors, count, next );
     644
     645                                // unlock all the monitors
     646                                unlock_all( locks, count );
     647
     648                                // unpark the thread we signalled
     649                                unpark( next );
     650
     651                                //Everything is ready to go to sleep
     652                                park();
    595653
    596654                                // We are back, restore the owners and recursions
     
    630688        }
    631689
     690        // unlock all the monitors
     691        unlock_all( locks, count );
     692
    632693        //Everything is ready to go to sleep
    633         BlockInternal( locks, count );
     694        park();
    634695
    635696
     
    648709// Utilities
    649710
    650 static inline void set_owner( monitor_desc * this, thread_desc * owner ) {
    651         // __cfaabi_dbg_print_safe( "Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
     711static inline void __set_owner( $monitor * this, $thread * owner ) {
     712        /* paranoid */ verify( this->lock.lock );
    652713
    653714        //Pass the monitor appropriately
     
    658719}
    659720
    660 static inline void set_owner( monitor_desc * monitors [], __lock_size_t count, thread_desc * owner ) {
    661         monitors[0]->owner     = owner;
    662         monitors[0]->recursion = 1;
     721static inline void __set_owner( $monitor * monitors [], __lock_size_t count, $thread * owner ) {
     722        /* paranoid */ verify ( monitors[0]->lock.lock );
     723        /* paranoid */ verifyf( monitors[0]->owner == kernelTLS.this_thread, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, monitors[0]->owner, monitors[0]->recursion, monitors[0] );
     724        monitors[0]->owner        = owner;
     725        monitors[0]->recursion    = 1;
    663726        for( __lock_size_t i = 1; i < count; i++ ) {
    664                 monitors[i]->owner     = owner;
    665                 monitors[i]->recursion = 0;
    666         }
    667 }
    668 
    669 static inline void set_mask( monitor_desc * storage [], __lock_size_t count, const __waitfor_mask_t & mask ) {
     727                /* paranoid */ verify ( monitors[i]->lock.lock );
     728                /* paranoid */ verifyf( monitors[i]->owner == kernelTLS.this_thread, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, monitors[i]->owner, monitors[i]->recursion, monitors[i] );
     729                monitors[i]->owner        = owner;
     730                monitors[i]->recursion    = 0;
     731        }
     732}
     733
     734static inline void set_mask( $monitor * storage [], __lock_size_t count, const __waitfor_mask_t & mask ) {
    670735        for( __lock_size_t i = 0; i < count; i++) {
    671736                storage[i]->mask = mask;
     
    673738}
    674739
    675 static inline void reset_mask( monitor_desc * this ) {
    676         this->mask.accepted = NULL;
    677         this->mask.data = NULL;
     740static inline void reset_mask( $monitor * this ) {
     741        this->mask.accepted = 0p;
     742        this->mask.data = 0p;
    678743        this->mask.size = 0;
    679744}
    680745
    681 static inline thread_desc * next_thread( monitor_desc * this ) {
     746static inline $thread * next_thread( $monitor * this ) {
    682747        //Check the signaller stack
    683748        __cfaabi_dbg_print_safe( "Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
     
    687752                //regardless of if we are ready to baton pass,
    688753                //we need to set the monitor as in use
    689                 set_owner( this,  urgent->owner->waiting_thread );
     754                /* paranoid */ verifyf( !this->owner || kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     755                __set_owner( this,  urgent->owner->waiting_thread );
    690756
    691757                return check_condition( urgent );
     
    694760        // No signaller thread
    695761        // Get the next thread in the entry_queue
    696         thread_desc * new_owner = pop_head( this->entry_queue );
    697         set_owner( this, new_owner );
     762        $thread * new_owner = pop_head( this->entry_queue );
     763        /* paranoid */ verifyf( !this->owner || kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     764        /* paranoid */ verify( !new_owner || new_owner->next == 0p );
     765        __set_owner( this, new_owner );
    698766
    699767        return new_owner;
    700768}
    701769
    702 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
     770static inline bool is_accepted( $monitor * this, const __monitor_group_t & group ) {
    703771        __acceptable_t * it = this->mask.data; // Optim
    704772        __lock_size_t count = this->mask.size;
     
    722790}
    723791
    724 static inline void init( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
     792static inline void init( __lock_size_t count, $monitor * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
    725793        for( __lock_size_t i = 0; i < count; i++) {
    726794                (criteria[i]){ monitors[i], waiter };
     
    730798}
    731799
    732 static inline void init_push( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
     800static inline void init_push( __lock_size_t count, $monitor * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ) {
    733801        for( __lock_size_t i = 0; i < count; i++) {
    734802                (criteria[i]){ monitors[i], waiter };
     
    746814}
    747815
    748 static inline void lock_all( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count ) {
     816static inline void lock_all( $monitor * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count ) {
    749817        for( __lock_size_t i = 0; i < count; i++ ) {
    750818                __spinlock_t * l = &source[i]->lock;
     
    760828}
    761829
    762 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) {
     830static inline void unlock_all( $monitor * locks [], __lock_size_t count ) {
    763831        for( __lock_size_t i = 0; i < count; i++ ) {
    764832                unlock( locks[i]->lock );
     
    767835
    768836static inline void save(
    769         monitor_desc * ctx [],
     837        $monitor * ctx [],
    770838        __lock_size_t count,
    771839        __attribute((unused)) __spinlock_t * locks [],
     
    780848
    781849static inline void restore(
    782         monitor_desc * ctx [],
     850        $monitor * ctx [],
    783851        __lock_size_t count,
    784852        __spinlock_t * locks [],
     
    798866// 2 - Checks if all the monitors are ready to run
    799867//     if so return the thread to run
    800 static inline thread_desc * check_condition( __condition_criterion_t * target ) {
     868static inline $thread * check_condition( __condition_criterion_t * target ) {
    801869        __condition_node_t * node = target->owner;
    802870        unsigned short count = node->count;
     
    816884        }
    817885
    818         __cfaabi_dbg_print_safe( "Kernel :  Runing %i (%p)\n", ready2run, ready2run ? node->waiting_thread : NULL );
    819         return ready2run ? node->waiting_thread : NULL;
     886        __cfaabi_dbg_print_safe( "Kernel :  Runing %i (%p)\n", ready2run, ready2run ? node->waiting_thread : 0p );
     887        return ready2run ? node->waiting_thread : 0p;
    820888}
    821889
    822890static inline void brand_condition( condition & this ) {
    823         thread_desc * thrd = TL_GET( this_thread );
     891        $thread * thrd = TL_GET( this_thread );
    824892        if( !this.monitors ) {
    825893                // __cfaabi_dbg_print_safe( "Branding\n" );
    826                 assertf( thrd->monitors.data != NULL, "No current monitor to brand condition %p", thrd->monitors.data );
     894                assertf( thrd->monitors.data != 0p, "No current monitor to brand condition %p", thrd->monitors.data );
    827895                this.monitor_count = thrd->monitors.size;
    828896
    829                 this.monitors = (monitor_desc **)malloc( this.monitor_count * sizeof( *this.monitors ) );
     897                this.monitors = ($monitor **)malloc( this.monitor_count * sizeof( *this.monitors ) );
    830898                for( int i = 0; i < this.monitor_count; i++ ) {
    831899                        this.monitors[i] = thrd->monitors[i];
     
    834902}
    835903
    836 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc * monitors [], __lock_size_t count ) {
    837 
    838         __queue_t(thread_desc) & entry_queue = monitors[0]->entry_queue;
     904static inline [$thread *, int] search_entry_queue( const __waitfor_mask_t & mask, $monitor * monitors [], __lock_size_t count ) {
     905
     906        __queue_t($thread) & entry_queue = monitors[0]->entry_queue;
    839907
    840908        // For each thread in the entry-queue
    841         for(    thread_desc ** thrd_it = &entry_queue.head;
    842                 *thrd_it;
     909        for(    $thread ** thrd_it = &entry_queue.head;
     910                *thrd_it != 1p;
    843911                thrd_it = &(*thrd_it)->next
    844912        ) {
     
    883951}
    884952
    885 static inline __lock_size_t aggregate( monitor_desc * storage [], const __waitfor_mask_t & mask ) {
     953static inline __lock_size_t aggregate( $monitor * storage [], const __waitfor_mask_t & mask ) {
    886954        __lock_size_t size = 0;
    887955        for( __lock_size_t i = 0; i < mask.size; i++ ) {
  • libcfa/src/concurrency/monitor.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Oct  7 18:06:45 2017
    13 // Update Count     : 10
     12// Last Modified On : Wed Dec  4 07:55:32 2019
     13// Update Count     : 11
    1414//
    1515
     
    2323
    2424trait is_monitor(dtype T) {
    25         monitor_desc * get_monitor( T & );
     25        $monitor * get_monitor( T & );
    2626        void ^?{}( T & mutex );
    2727};
    2828
    29 static inline void ?{}(monitor_desc & this) with( this ) {
     29static inline void ?{}($monitor & this) with( this ) {
    3030        lock{};
    3131        entry_queue{};
    3232        signal_stack{};
    33         owner         = NULL;
     33        owner         = 0p;
    3434        recursion     = 0;
    35         mask.accepted = NULL;
    36         mask.data     = NULL;
     35        mask.accepted = 0p;
     36        mask.data     = 0p;
    3737        mask.size     = 0;
    38         dtor_node     = NULL;
     38        dtor_node     = 0p;
    3939}
    4040
     41static inline void ^?{}($monitor & ) {}
     42
    4143struct monitor_guard_t {
    42         monitor_desc **         m;
     44        $monitor **     m;
    4345        __lock_size_t           count;
    4446        __monitor_group_t prev;
    4547};
    4648
    47 void ?{}( monitor_guard_t & this, monitor_desc ** m, __lock_size_t count, void (*func)() );
     49void ?{}( monitor_guard_t & this, $monitor ** m, __lock_size_t count, void (*func)() );
    4850void ^?{}( monitor_guard_t & this );
    4951
    5052struct monitor_dtor_guard_t {
    51         monitor_desc *    m;
     53        $monitor *    m;
    5254        __monitor_group_t prev;
    5355};
    5456
    55 void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, void (*func)() );
     57void ?{}( monitor_dtor_guard_t & this, $monitor ** m, void (*func)() );
    5658void ^?{}( monitor_dtor_guard_t & this );
    5759
     
    7072
    7173        // The monitor this criterion concerns
    72         monitor_desc * target;
     74        $monitor * target;
    7375
    7476        // The parent node to which this criterion belongs
     
    8587struct __condition_node_t {
    8688        // Thread that needs to be woken when all criteria are met
    87         thread_desc * waiting_thread;
     89        $thread * waiting_thread;
    8890
    8991        // Array of criteria (Criterions are contiguous in memory)
     
    104106}
    105107
    106 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info );
     108void ?{}(__condition_node_t & this, $thread * waiting_thread, __lock_size_t count, uintptr_t user_info );
    107109void ?{}(__condition_criterion_t & this );
    108 void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner );
     110void ?{}(__condition_criterion_t & this, $monitor * target, __condition_node_t * owner );
    109111
    110112struct condition {
     
    113115
    114116        // Array of monitor pointers (Monitors are NOT contiguous in memory)
    115         monitor_desc ** monitors;
     117        $monitor ** monitors;
    116118
    117119        // Number of monitors in the array
     
    120122
    121123static inline void ?{}( condition & this ) {
    122         this.monitors = NULL;
     124        this.monitors = 0p;
    123125        this.monitor_count = 0;
    124126}
     
    131133              bool signal      ( condition & this );
    132134              bool signal_block( condition & this );
    133 static inline bool is_empty    ( condition & this ) { return !this.blocked.head; }
     135static inline bool is_empty    ( condition & this ) { return this.blocked.head == 1p; }
    134136         uintptr_t front       ( condition & this );
    135137
  • libcfa/src/concurrency/mutex.cfa

    r9fb8f01 r3d5701e  
    1111// Author           : Thierry Delisle
    1212// Created On       : Fri May 25 01:37:11 2018
    13 // Last Modified By : Thierry Delisle
    14 // Last Modified On : Fri May 25 01:37:51 2018
    15 // Update Count     : 0
     13// Last Modified By : Peter A. Buhr
     14// Last Modified On : Wed Dec  4 09:16:39 2019
     15// Update Count     : 1
    1616//
    1717
     
    4040        if( is_locked ) {
    4141                append( blocked_threads, kernelTLS.this_thread );
    42                 BlockInternal( &lock );
     42                unlock( lock );
     43                park();
    4344        }
    4445        else {
     
    6263        lock( this.lock __cfaabi_dbg_ctx2 );
    6364        this.is_locked = (this.blocked_threads != 0);
    64         WakeThread(
     65        unpark(
    6566                pop_head( this.blocked_threads )
    6667        );
     
    7374        this.lock{};
    7475        this.blocked_threads{};
    75         this.owner = NULL;
     76        this.owner = 0p;
    7677        this.recursion_count = 0;
    7778}
     
    8384void lock(recursive_mutex_lock & this) with(this) {
    8485        lock( lock __cfaabi_dbg_ctx2 );
    85         if( owner == NULL ) {
     86        if( owner == 0p ) {
    8687                owner = kernelTLS.this_thread;
    8788                recursion_count = 1;
     
    9495        else {
    9596                append( blocked_threads, kernelTLS.this_thread );
    96                 BlockInternal( &lock );
     97                unlock( lock );
     98                park();
    9799        }
    98100}
     
    101103        bool ret = false;
    102104        lock( lock __cfaabi_dbg_ctx2 );
    103         if( owner == NULL ) {
     105        if( owner == 0p ) {
    104106                owner = kernelTLS.this_thread;
    105107                recursion_count = 1;
     
    118120        recursion_count--;
    119121        if( recursion_count == 0 ) {
    120                 thread_desc * thrd = pop_head( blocked_threads );
     122                $thread * thrd = pop_head( blocked_threads );
    121123                owner = thrd;
    122124                recursion_count = (thrd ? 1 : 0);
    123                 WakeThread( thrd );
     125                unpark( thrd );
    124126        }
    125127        unlock( lock );
     
    138140void notify_one(condition_variable & this) with(this) {
    139141        lock( lock __cfaabi_dbg_ctx2 );
    140         WakeThread(
     142        unpark(
    141143                pop_head( this.blocked_threads )
    142144        );
     
    147149        lock( lock __cfaabi_dbg_ctx2 );
    148150        while(this.blocked_threads) {
    149                 WakeThread(
     151                unpark(
    150152                        pop_head( this.blocked_threads )
    151153                );
     
    157159        lock( this.lock __cfaabi_dbg_ctx2 );
    158160        append( this.blocked_threads, kernelTLS.this_thread );
    159         BlockInternal( &this.lock );
     161        unlock( this.lock );
     162        park();
    160163}
    161164
     
    164167        lock( this.lock __cfaabi_dbg_ctx2 );
    165168        append( this.blocked_threads, kernelTLS.this_thread );
    166         void __unlock(void) {
    167                 unlock(l);
    168                 unlock(this.lock);
    169         }
    170         BlockInternal( __unlock );
     169        unlock(l);
     170        unlock(this.lock);
     171        park();
    171172        lock(l);
    172173}
  • libcfa/src/concurrency/mutex.hfa

    r9fb8f01 r3d5701e  
    1111// Author           : Thierry Delisle
    1212// Created On       : Fri May 25 01:24:09 2018
    13 // Last Modified By : Thierry Delisle
    14 // Last Modified On : Fri May 25 01:24:12 2018
    15 // Update Count     : 0
     13// Last Modified By : Peter A. Buhr
     14// Last Modified On : Wed Dec  4 09:16:53 2019
     15// Update Count     : 1
    1616//
    1717
     
    3636
    3737        // List of blocked threads
    38         __queue_t(struct thread_desc) blocked_threads;
     38        __queue_t(struct $thread) blocked_threads;
    3939
    4040        // Locked flag
     
    5555
    5656        // List of blocked threads
    57         __queue_t(struct thread_desc) blocked_threads;
     57        __queue_t(struct $thread) blocked_threads;
    5858
    5959        // Current thread owning the lock
    60         struct thread_desc * owner;
     60        struct $thread * owner;
    6161
    6262        // Number of recursion level
     
    8383
    8484        // List of blocked threads
    85         __queue_t(struct thread_desc) blocked_threads;
     85        __queue_t(struct $thread) blocked_threads;
    8686};
    8787
     
    110110
    111111        static inline void ?{}(lock_scope(L) & this) {
    112                 this.locks = NULL;
     112                this.locks = 0p;
    113113                this.count = 0;
    114114        }
  • libcfa/src/concurrency/preemption.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun  5 17:35:49 2018
    13 // Update Count     : 37
     12// Last Modified On : Thu Dec  5 16:34:05 2019
     13// Update Count     : 43
    1414//
    1515
     
    2424#include <string.h>
    2525#include <unistd.h>
     26#include <limits.h>                                                                             // PTHREAD_STACK_MIN
    2627}
    2728
     
    3839// FwdDeclarations : timeout handlers
    3940static void preempt( processor   * this );
    40 static void timeout( thread_desc * this );
     41static void timeout( $thread * this );
    4142
    4243// FwdDeclarations : Signal handlers
     
    6465event_kernel_t * event_kernel;                        // kernel public handle to even kernel
    6566static pthread_t alarm_thread;                        // pthread handle to alarm thread
     67static void * alarm_stack;                                                        // pthread stack for alarm thread
    6668
    6769static void ?{}(event_kernel_t & this) with( this ) {
     
    8183// Get next expired node
    8284static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
    83         if( !alarms->head ) return NULL;                          // If no alarms return null
    84         if( alarms->head->alarm >= currtime ) return NULL;        // If alarms head not expired return null
    85         return pop(alarms);                                       // Otherwise just pop head
     85        if( !alarms->head ) return 0p;                                          // If no alarms return null
     86        if( alarms->head->alarm >= currtime ) return 0p;        // If alarms head not expired return null
     87        return pop(alarms);                                                                     // Otherwise just pop head
    8688}
    8789
    8890// Tick one frame of the Discrete Event Simulation for alarms
    8991static void tick_preemption() {
    90         alarm_node_t * node = NULL;                     // Used in the while loop but cannot be declared in the while condition
    91         alarm_list_t * alarms = &event_kernel->alarms;  // Local copy for ease of reading
    92         Time currtime = __kernel_get_time();                    // Check current time once so we everything "happens at once"
     92        alarm_node_t * node = 0p;                                                       // Used in the while loop but cannot be declared in the while condition
     93        alarm_list_t * alarms = &event_kernel->alarms;          // Local copy for ease of reading
     94        Time currtime = __kernel_get_time();                            // Check current time once so everything "happens at once"
    9395
    9496        //Loop throught every thing expired
     
    182184
    183185        // Enable interrupts by decrementing the counter
    184         // If counter reaches 0, execute any pending CtxSwitch
     186        // If counter reaches 0, execute any pending __cfactx_switch
    185187        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    186188                processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
    187                 thread_desc * thrd = kernelTLS.this_thread;       // Cache the thread now since interrupts can start happening after the atomic store
    188189
    189190                with( kernelTLS.preemption_state ){
     
    207208                                if( proc->pending_preemption ) {
    208209                                        proc->pending_preemption = false;
    209                                         BlockInternal( thrd );
     210                                        force_yield( __POLL_PREEMPTION );
    210211                                }
    211212                        }
     
    217218
    218219        // Disable interrupts by incrementint the counter
    219         // Don't execute any pending CtxSwitch even if counter reaches 0
     220        // Don't execute any pending __cfactx_switch even if counter reaches 0
    220221        void enable_interrupts_noPoll() {
    221222                unsigned short prev = kernelTLS.preemption_state.disable_count;
     
    243244        sigaddset( &mask, sig );
    244245
    245         if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) {
     246        if ( pthread_sigmask( SIG_UNBLOCK, &mask, 0p ) == -1 ) {
    246247            abort( "internal error, pthread_sigmask" );
    247248        }
     
    254255        sigaddset( &mask, sig );
    255256
    256         if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
     257        if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {
    257258            abort( "internal error, pthread_sigmask" );
    258259        }
     
    266267
    267268// reserved for future use
    268 static void timeout( thread_desc * this ) {
     269static void timeout( $thread * this ) {
    269270        //TODO : implement waking threads
    270271}
    271272
    272273// KERNEL ONLY
    273 // Check if a CtxSwitch signal handler shoud defer
     274// Check if a __cfactx_switch signal handler shoud defer
    274275// If true  : preemption is safe
    275276// If false : preemption is unsafe and marked as pending
     
    301302
    302303        // Setup proper signal handlers
    303         __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART );         // CtxSwitch handler
     304        __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // __cfactx_switch handler
    304305
    305306        signal_block( SIGALRM );
    306307
    307         pthread_create( &alarm_thread, NULL, alarm_loop, NULL );
     308        alarm_stack = __create_pthread( &alarm_thread, alarm_loop, 0p );
    308309}
    309310
     
    316317        sigset_t mask;
    317318        sigfillset( &mask );
    318         sigprocmask( SIG_BLOCK, &mask, NULL );
     319        sigprocmask( SIG_BLOCK, &mask, 0p );
    319320
    320321        // Notify the alarm thread of the shutdown
     
    323324
    324325        // Wait for the preemption thread to finish
    325         pthread_join( alarm_thread, NULL );
     326
     327        pthread_join( alarm_thread, 0p );
     328        free( alarm_stack );
    326329
    327330        // Preemption is now fully stopped
     
    380383        static_assert( sizeof( sigset_t ) == sizeof( cxt->uc_sigmask ), "Expected cxt->uc_sigmask to be of sigset_t" );
    381384        #endif
    382         if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), NULL ) == -1 ) {
     385        if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), 0p ) == -1 ) {
    383386                abort( "internal error, sigprocmask" );
    384387        }
     
    390393        // Preemption can occur here
    391394
    392         BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch
     395        force_yield( __ALARM_PREEMPTION ); // Do the actual __cfactx_switch
    393396}
    394397
     
    399402        sigset_t mask;
    400403        sigfillset(&mask);
    401         if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
     404        if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {
    402405            abort( "internal error, pthread_sigmask" );
    403406        }
     
    420423                                        {__cfaabi_dbg_print_buffer_decl( " KERNEL: Spurious wakeup %d.\n", err );}
    421424                                        continue;
    422                         case EINVAL :
     425                                case EINVAL :
    423426                                        abort( "Timeout was invalid." );
    424427                                default:
     
    453456EXIT:
    454457        __cfaabi_dbg_print_safe( "Kernel : Preemption thread stopping\n" );
    455         return NULL;
     458        return 0p;
    456459}
    457460
     
    466469        sigset_t oldset;
    467470        int ret;
    468         ret = pthread_sigmask(0, NULL, &oldset);
     471        ret = pthread_sigmask(0, 0p, &oldset);
    469472        if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    470473
  • libcfa/src/concurrency/thread.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 17:19:52 2018
    13 // Update Count     : 8
     12// Last Modified On : Wed Dec  4 09:17:49 2019
     13// Update Count     : 9
    1414//
    1515
     
    2323#include "invoke.h"
    2424
    25 extern "C" {
    26         #include <fenv.h>
    27         #include <stddef.h>
    28 }
    29 
    30 //extern volatile thread_local processor * this_processor;
    31 
    3225//-----------------------------------------------------------------------------
    3326// Thread ctors and dtors
    34 void ?{}(thread_desc & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
    35         context{ NULL, NULL };
     27void ?{}($thread & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
     28        context{ 0p, 0p };
    3629        self_cor{ name, storage, storageSize };
    3730        state = Start;
     31        preempted = __NO_PREEMPTION;
    3832        curr_cor = &self_cor;
    3933        self_mon.owner = &this;
     
    4135        self_mon_p = &self_mon;
    4236        curr_cluster = &cl;
    43         next = NULL;
     37        next = 0p;
    4438
    45         node.next = NULL;
    46         node.prev = NULL;
     39        node.next = 0p;
     40        node.prev = 0p;
    4741        doregister(curr_cluster, this);
    4842
     
    5044}
    5145
    52 void ^?{}(thread_desc& this) with( this ) {
     46void ^?{}($thread& this) with( this ) {
    5347        unregister(curr_cluster, this);
    5448        ^self_cor{};
    5549}
    5650
     51//-----------------------------------------------------------------------------
     52// Starting and stopping threads
     53forall( dtype T | is_thread(T) )
     54void __thrd_start( T & this, void (*main_p)(T &) ) {
     55        $thread * this_thrd = get_thread(this);
     56
     57        disable_interrupts();
     58        __cfactx_start(main_p, get_coroutine(this), this, __cfactx_invoke_thread);
     59
     60        this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
     61        verify( this_thrd->context.SP );
     62
     63        __schedule_thread(this_thrd);
     64        enable_interrupts( __cfaabi_dbg_ctx );
     65}
     66
     67//-----------------------------------------------------------------------------
     68// Support for threads that don't ues the thread keyword
    5769forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
    5870void ?{}( scoped(T)& this ) with( this ) {
    5971        handle{};
    60         __thrd_start(handle);
     72        __thrd_start(handle, main);
    6173}
    6274
     
    6476void ?{}( scoped(T)& this, P params ) with( this ) {
    6577        handle{ params };
    66         __thrd_start(handle);
     78        __thrd_start(handle, main);
    6779}
    6880
     
    7284}
    7385
    74 //-----------------------------------------------------------------------------
    75 // Starting and stopping threads
    76 forall( dtype T | is_thread(T) )
    77 void __thrd_start( T& this ) {
    78         thread_desc * this_thrd = get_thread(this);
    79         thread_desc * curr_thrd = TL_GET( this_thread );
    80 
    81         disable_interrupts();
    82         CtxStart(&this, CtxInvokeThread);
    83         this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
    84         verify( this_thrd->context.SP );
    85         CtxSwitch( &curr_thrd->context, &this_thrd->context );
    86 
    87         ScheduleThread(this_thrd);
    88         enable_interrupts( __cfaabi_dbg_ctx );
    89 }
    90 
    91 extern "C" {
    92         // KERNEL ONLY
    93         void __finish_creation(thread_desc * this) {
    94                 // set new coroutine that the processor is executing
    95                 // and context switch to it
    96                 verify( kernelTLS.this_thread != this );
    97                 verify( kernelTLS.this_thread->context.SP );
    98                 CtxSwitch( &this->context, &kernelTLS.this_thread->context );
    99         }
    100 }
    101 
    102 void yield( void ) {
    103         // Safety note : This could cause some false positives due to preemption
    104       verify( TL_GET( preemption_state.enabled ) );
    105         BlockInternal( TL_GET( this_thread ) );
    106         // Safety note : This could cause some false positives due to preemption
    107       verify( TL_GET( preemption_state.enabled ) );
    108 }
    109 
    110 void yield( unsigned times ) {
    111         for( unsigned i = 0; i < times; i++ ) {
    112                 yield();
    113         }
    114 }
    115 
    11686// Local Variables: //
    11787// mode: c //
  • libcfa/src/concurrency/thread.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 17:51:33 2019
    13 // Update Count     : 5
     12// Last Modified On : Wed Dec  4 09:18:14 2019
     13// Update Count     : 6
    1414//
    1515
     
    2828      void ^?{}(T& mutex this);
    2929      void main(T& this);
    30       thread_desc* get_thread(T& this);
     30      $thread* get_thread(T& this);
    3131};
    3232
    33 #define DECL_THREAD(X) thread_desc* get_thread(X& this) { return &this.__thrd; } void main(X& this)
     33// define that satisfies the trait without using the thread keyword
     34#define DECL_THREAD(X) $thread* get_thread(X& this) __attribute__((const)) { return &this.__thrd; } void main(X& this)
     35
     36// Inline getters for threads/coroutines/monitors
     37forall( dtype T | is_thread(T) )
     38static inline $coroutine* get_coroutine(T & this) __attribute__((const)) { return &get_thread(this)->self_cor; }
    3439
    3540forall( dtype T | is_thread(T) )
    36 static inline coroutine_desc* get_coroutine(T & this) {
    37         return &get_thread(this)->self_cor;
    38 }
     41static inline $monitor  * get_monitor  (T & this) __attribute__((const)) { return &get_thread(this)->self_mon; }
    3942
    40 forall( dtype T | is_thread(T) )
    41 static inline monitor_desc* get_monitor(T & this) {
    42         return &get_thread(this)->self_mon;
    43 }
     43static inline $coroutine* get_coroutine($thread * this) __attribute__((const)) { return &this->self_cor; }
     44static inline $monitor  * get_monitor  ($thread * this) __attribute__((const)) { return &this->self_mon; }
    4445
    45 static inline coroutine_desc* get_coroutine(thread_desc * this) {
    46         return &this->self_cor;
    47 }
    48 
    49 static inline monitor_desc* get_monitor(thread_desc * this) {
    50         return &this->self_mon;
    51 }
    52 
     46//-----------------------------------------------------------------------------
     47// forward declarations needed for threads
    5348extern struct cluster * mainCluster;
    5449
    5550forall( dtype T | is_thread(T) )
    56 void __thrd_start( T & this );
     51void __thrd_start( T & this, void (*)(T &) );
    5752
    5853//-----------------------------------------------------------------------------
    5954// Ctors and dtors
    60 void ?{}(thread_desc & this, const char * const name, struct cluster & cl, void * storage, size_t storageSize );
    61 void ^?{}(thread_desc & this);
     55void ?{}($thread & this, const char * const name, struct cluster & cl, void * storage, size_t storageSize );
     56void ^?{}($thread & this);
    6257
    63 static inline void ?{}(thread_desc & this)                                                                  { this{ "Anonymous Thread", *mainCluster, NULL, 65000 }; }
    64 static inline void ?{}(thread_desc & this, size_t stackSize )                                               { this{ "Anonymous Thread", *mainCluster, NULL, stackSize }; }
    65 static inline void ?{}(thread_desc & this, void * storage, size_t storageSize )                             { this{ "Anonymous Thread", *mainCluster, storage, storageSize }; }
    66 static inline void ?{}(thread_desc & this, struct cluster & cl )                                            { this{ "Anonymous Thread", cl, NULL, 65000 }; }
    67 static inline void ?{}(thread_desc & this, struct cluster & cl, size_t stackSize )                          { this{ "Anonymous Thread", cl, NULL, stackSize }; }
    68 static inline void ?{}(thread_desc & this, struct cluster & cl, void * storage, size_t storageSize )        { this{ "Anonymous Thread", cl, storage, storageSize }; }
    69 static inline void ?{}(thread_desc & this, const char * const name)                                         { this{ name, *mainCluster, NULL, 65000 }; }
    70 static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl )                   { this{ name, cl, NULL, 65000 }; }
    71 static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, NULL, stackSize }; }
     58static inline void ?{}($thread & this)                                                                  { this{ "Anonymous Thread", *mainCluster, 0p, 65000 }; }
     59static inline void ?{}($thread & this, size_t stackSize )                                               { this{ "Anonymous Thread", *mainCluster, 0p, stackSize }; }
     60static inline void ?{}($thread & this, void * storage, size_t storageSize )                             { this{ "Anonymous Thread", *mainCluster, storage, storageSize }; }
     61static inline void ?{}($thread & this, struct cluster & cl )                                            { this{ "Anonymous Thread", cl, 0p, 65000 }; }
     62static inline void ?{}($thread & this, struct cluster & cl, size_t stackSize )                          { this{ "Anonymous Thread", cl, 0p, stackSize }; }
     63static inline void ?{}($thread & this, struct cluster & cl, void * storage, size_t storageSize )        { this{ "Anonymous Thread", cl, storage, storageSize }; }
     64static inline void ?{}($thread & this, const char * const name)                                         { this{ name, *mainCluster, 0p, 65000 }; }
     65static inline void ?{}($thread & this, const char * const name, struct cluster & cl )                   { this{ name, cl, 0p, 65000 }; }
     66static inline void ?{}($thread & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, 0p, stackSize }; }
    7267
    7368//-----------------------------------------------------------------------------
     
    8883void ^?{}( scoped(T)& this );
    8984
    90 void yield();
    91 void yield( unsigned times );
     85//-----------------------------------------------------------------------------
     86// Thread getters
     87static inline struct $thread * active_thread () { return TL_GET( this_thread ); }
    9288
    93 static inline struct thread_desc * active_thread () { return TL_GET( this_thread ); }
     89//-----------------------------------------------------------------------------
     90// Scheduler API
     91
     92//----------
     93// Park thread: block until corresponding call to unpark, won't block if unpark is already called
     94void park( void );
     95
     96//----------
     97// Unpark a thread, if the thread is already blocked, schedule it
     98//                  if the thread is not yet block, signal that it should rerun immediately
     99void unpark( $thread * this );
     100
     101forall( dtype T | is_thread(T) )
     102static inline void unpark( T & this ) { if(!&this) return; unpark( get_thread( this ) );}
     103
     104//----------
     105// Yield: force thread to block and be rescheduled
     106bool force_yield( enum __Preemption_Reason );
     107
     108static inline void yield() {
     109        force_yield(__MANUAL_PREEMPTION);
     110}
     111
     112// Yield: yield N times
     113static inline void yield( unsigned times ) {
     114        for( times ) {
     115                yield();
     116        }
     117}
    94118
    95119// Local Variables: //
  • libcfa/src/exception.c

    r9fb8f01 r3d5701e  
    6969
    7070
    71 // This macro should be the only thing that needs to change across machines.  Used in the personality function, way down
    72 // in termination.
     71// This macro should be the only thing that needs to change across machines.
     72// Used in the personality function, way down in termination.
    7373// struct _Unwind_Context * -> _Unwind_Reason_Code(*)(exception_t *)
    7474#define MATCHER_FROM_CONTEXT(ptr_to_context) \
     
    102102}
    103103
    104 // Do we control where exceptions get thrown even with concurency?  If not these are not quite thread safe, the cleanup
    105 // hook has to be added after the node is built but before it is made the top node.
     104// Do we control where exceptions get thrown even with concurency?
     105// If not these are not quite thread safe, the cleanup hook has to
     106// be added after the node is built but before it is made the top node.
    106107
    107108void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node,
     
    212213        _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
    213214
    214         // If we reach here it means something happened.  For resumption to work we need to find a way to return back to
    215         // here.  Most of them will probably boil down to setting a global flag and making the phase 1 either stop or
    216         // fail.  Causing an error on purpose may help avoiding unnecessary work but it might have some weird side
    217         // effects.  If we just pretend no handler was found that would work but may be expensive for no reason since we
    218         // will always search the whole stack.
     215        // If we reach here it means something happened. For resumption to work we need to find a way
     216        // to return back to here. Most of them will probably boil down to setting a global flag and
     217        // making the phase 1 either stop or fail. Causing an error on purpose may help avoiding
     218        // unnecessary work but it might have some weird side effects. If we just pretend no handler
     219        // was found that would work but may be expensive for no reason since we will always search
     220        // the whole stack.
    219221
    220222        if( ret == _URC_END_OF_STACK ) {
    221                 // No proper handler was found.  This can be handled in several way.  C++ calls std::terminate Here we
    222                 // force unwind the stack, basically raising a cancellation.
     223                // No proper handler was found. This can be handled in many ways, C++ calls std::terminate.
     224                // Here we force unwind the stack, basically raising a cancellation.
    223225                printf("Uncaught exception %p\n", &this_exception_storage);
    224226
     
    228230        }
    229231
    230         // We did not simply reach the end of the stack without finding a handler.  Something wen't wrong
     232        // We did not simply reach the end of the stack without finding a handler. This is an error.
    231233        printf("UNWIND ERROR %d after raise exception\n", ret);
    232234        abort();
     
    246248}
    247249
    248 #if defined(PIC)
    249 #warning Exceptions not yet supported when using Position-Independent Code
    250 __attribute__((noinline))
    251 void __cfaabi_ehm__try_terminate(void (*try_block)(),
    252                 void (*catch_block)(int index, exception_t * except),
    253                 __attribute__((unused)) int (*match_block)(exception_t * except)) {
    254         abort();
    255 }
    256 #else
    257 // This is our personality routine.  For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0".
    258 // This function will be called twice when unwinding.  Once in the search phased and once in the cleanup phase.
     250#pragma GCC push_options
     251#pragma GCC optimize("O0")
     252
     253// This is our personality routine. For every stack frame annotated with
     254// ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding.
     255//  Once in the search phase and once in the cleanup phase.
    259256_Unwind_Reason_Code __gcfa_personality_v0 (
    260257                int version, _Unwind_Action actions, unsigned long long exceptionClass,
     
    264261
    265262        //__cfaabi_dbg_print_safe("CFA: 0x%lx\n", _Unwind_GetCFA(context));
    266         __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
     263        __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):",
     264                        version, actions, exceptionClass, unwind_exception, context);
    267265
    268266        // If we've reached the end of the stack then there is nothing much we can do...
     
    291289        // Get the instuction pointer and a reading pointer into the exception table
    292290        lsda_header_info lsd_info;
    293         const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
     291        const unsigned char * cur_ptr = parse_lsda_header(context, lsd, &lsd_info);
    294292        _Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
    295293
     
    302300
    303301                // Decode the common stuff we have in here
    304                 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
    305                 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
    306                 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
    307                 cur_ptr = read_uleb128 (cur_ptr, &callsite_action);
     302                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
     303                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
     304                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
     305                cur_ptr = read_uleb128(cur_ptr, &callsite_action);
    308306
    309307                // Have we reach the correct frame info yet?
     
    316314                        void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
    317315                        void * ip = (void*)instruction_ptr;
    318                         __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
     316                        __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n",
     317                                        bp, ep, ls, cs, cl, ip);
    319318#endif // __CFA_DEBUG_PRINT__
    320319                        continue;
    321320                }
    322321
    323                 // Have we gone too far
     322                // Have we gone too far?
    324323                if( lsd_info.Start + callsite_start > instruction_ptr ) {
    325324                        printf(" gone too far");
     
    331330                        // Which phase are we in
    332331                        if (actions & _UA_SEARCH_PHASE) {
    333                                 // Search phase, this means we probably found a potential handler and must check if it is a match
    334 
    335                                 // If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler
    336                                 // This doesn't seem to conflict the gcc default behavior
     332                                // In search phase, these means we found a potential handler we must check.
     333
     334                                // We have arbitrarily decided that 0 means nothing to do and 1 means there is
     335                                // a potential handler. This doesn't seem to conflict the gcc default behavior.
    337336                                if (callsite_action != 0) {
    338337                                        // Now we want to run some code to see if the handler matches
     
    351350                                        // The current apprach uses one exception table entry per try block
    352351                                        _uleb128_t imatcher;
    353                                         // Get the relative offset to the
    354                                         cur_ptr = read_uleb128 (cur_ptr, &imatcher);
    355 
    356                                         // Get a function pointer from the relative offset and call it
    357                                         // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;
     352                                        // Get the relative offset to the {...}?
     353                                        cur_ptr = read_uleb128(cur_ptr, &imatcher);
    358354
    359355                                        _Unwind_Reason_Code (*matcher)(exception_t *) =
     
    414410}
    415411
    416 // Try statements are hoisted out see comments for details.  With this could probably be unique and simply linked from
    417 // libcfa but there is one problem left, see the exception table for details
     412// Try statements are hoisted out see comments for details. While this could probably be unique
     413// and simply linked from libcfa but there is one problem left, see the exception table for details
    418414__attribute__((noinline))
    419415void __cfaabi_ehm__try_terminate(void (*try_block)(),
     
    428424        // assembly works.
    429425
    430         // Setup the personality routine
     426        // Setup the personality routine and exception table.
     427#ifdef __PIC__
     428        asm volatile (".cfi_personality 0x9b,CFA.ref.__gcfa_personality_v0");
     429        asm volatile (".cfi_lsda 0x1b, .LLSDACFA2");
     430#else
    431431        asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
    432         // Setup the exception table
    433432        asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
     433#endif
    434434
    435435        // Label which defines the start of the area for which the handler is setup.
     
    442442        asm volatile goto ("" : : : : CATCH );
    443443
    444         // Normal return
     444        // Normal return for when there is no throw.
    445445        return;
    446446
     
    459459}
    460460
    461 // Exception table data we need to generate.  While this is almost generic, the custom data refers to foo_try_match try
    462 // match, which is no way generic.  Some more works need to be done if we want to have a single call to the try routine.
    463 
     461// Exception table data we need to generate. While this is almost generic, the custom data refers
     462// to {*}try_terminate, which is no way generic. Some more works need to be done if we want to
     463// have a single call to the try routine.
     464
     465#ifdef __PIC__
    464466#if defined( __i386 ) || defined( __x86_64 )
    465467asm (
    466         //HEADER
     468        // HEADER
    467469        ".LFECFA1:\n"
    468470        "       .globl  __gcfa_personality_v0\n"
    469471        "       .section        .gcc_except_table,\"a\",@progbits\n"
    470         ".LLSDACFA2:\n"                                                 //TABLE header
     472        // TABLE HEADER (important field is the BODY length at the end)
     473        ".LLSDACFA2:\n"
    471474        "       .byte   0xff\n"
    472475        "       .byte   0xff\n"
    473476        "       .byte   0x1\n"
    474         "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"         // BODY length
    475         // Body uses language specific data and therefore could be modified arbitrarily
    476         ".LLSDACSBCFA2:\n"                                              // BODY start
    477         "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"               // Handled area start  (relative to start of function)
    478         "       .uleb128 .TRYEND-.TRYSTART\n"                           // Handled area length
    479         "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"                          // Hanlder landing pad adress  (relative to start of function)
    480         "       .uleb128 1\n"                                           // Action code, gcc seems to use always 0
    481         ".LLSDACSECFA2:\n"                                              // BODY end
    482         "       .text\n"                                                        // TABLE footer
     477        "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"
     478        // BODY (language specific data)
     479        // This uses language specific data and can be modified arbitrarily
     480        // We use handled area offset, handled area length,
     481        // handler landing pad offset and 1 (action code, gcc seems to use 0).
     482        ".LLSDACSBCFA2:\n"
     483        "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"
     484        "       .uleb128 .TRYEND-.TRYSTART\n"
     485        "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"
     486        "       .uleb128 1\n"
     487        ".LLSDACSECFA2:\n"
     488        // TABLE FOOTER
     489        "       .text\n"
     490        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
     491);
     492
     493// Somehow this piece of helps with the resolution of debug symbols.
     494__attribute__((unused)) static const int dummy = 0;
     495
     496asm (
     497        // Add a hidden symbol which points at the function.
     498        "       .hidden CFA.ref.__gcfa_personality_v0\n"
     499        "       .weak   CFA.ref.__gcfa_personality_v0\n"
     500        // No clue what this does specifically
     501        "       .section        .data.rel.local.CFA.ref.__gcfa_personality_v0,\"awG\",@progbits,CFA.ref.__gcfa_personality_v0,comdat\n"
     502        "       .align 8\n"
     503        "       .type CFA.ref.__gcfa_personality_v0, @object\n"
     504        "       .size CFA.ref.__gcfa_personality_v0, 8\n"
     505        "CFA.ref.__gcfa_personality_v0:\n"
     506#if defined( __x86_64 )
     507        "       .quad __gcfa_personality_v0\n"
     508#else // then __i386
     509        "   .long __gcfa_personality_v0\n"
     510#endif
     511);
     512#else
     513#error Exception Handling: unknown architecture for position independent code.
     514#endif // __i386 || __x86_64
     515#else // __PIC__
     516#if defined( __i386 ) || defined( __x86_64 )
     517asm (
     518        // HEADER
     519        ".LFECFA1:\n"
     520        "       .globl  __gcfa_personality_v0\n"
     521        "       .section        .gcc_except_table,\"a\",@progbits\n"
     522        // TABLE HEADER (important field is the BODY length at the end)
     523        ".LLSDACFA2:\n"
     524        "       .byte   0xff\n"
     525        "       .byte   0xff\n"
     526        "       .byte   0x1\n"
     527        "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"
     528        // BODY (language specific data)
     529        ".LLSDACSBCFA2:\n"
     530        //      Handled area start (relative to start of function)
     531        "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"
     532        //      Handled area length
     533        "       .uleb128 .TRYEND-.TRYSTART\n"
     534        //      Handler landing pad address (relative to start of function)
     535        "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"
     536        //      Action code, gcc seems to always use 0.
     537        "       .uleb128 1\n"
     538        // TABLE FOOTER
     539        ".LLSDACSECFA2:\n"
     540        "       .text\n"
    483541        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
    484542        "       .ident  \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
    485 //      "       .section        .note.GNU-stack,\"x\",@progbits\n"
     543        "       .section        .note.GNU-stack,\"x\",@progbits\n"
    486544);
     545#else
     546#error Exception Handling: unknown architecture for position dependent code.
    487547#endif // __i386 || __x86_64
    488 #endif //PIC
     548#endif // __PIC__
     549
     550#pragma GCC pop_options
  • libcfa/src/executor.cfa

    r9fb8f01 r3d5701e  
    88#include <stdio.h>
    99
    10 forall( otype T | is_node(T) | is_monitor(T) ) {
    11     monitor Buffer {                                    // unbounded buffer
    12         __queue_t( T ) queue;                           // unbounded list of work requests
    13         condition delay;
    14     }; // Buffer
    15 
     10forall( dtype T )
     11monitor Buffer {                                        // unbounded buffer
     12    __queue_t( T ) queue;                               // unbounded list of work requests
     13    condition delay;
     14}; // Buffer
     15forall( dtype T | is_node(T) ) {
    1616    void insert( Buffer( T ) & mutex buf, T * elem ) with(buf) {
    1717        append( queue, elem );                          // insert element into buffer
     
    2020
    2121    T * remove( Buffer( T ) & mutex buf ) with(buf) {
    22         if ( ! queue ) wait( delay );                   // no request to process ? => wait
    23         return pop_head( queue );
     22        if ( queue.head != 0 ) wait( delay );                   // no request to process ? => wait
     23//      return pop_head( queue );
    2424    } // remove
    2525} // distribution
  • libcfa/src/fstream.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 15 18:11:26 2019
    13 // Update Count     : 349
     12// Last Modified On : Fri Feb  7 19:01:01 2020
     13// Update Count     : 363
    1414//
    1515
     
    3232
    3333void ?{}( ofstream & os, void * file ) {
    34         os.file = file;
    35         os.sepDefault = true;
    36         os.sepOnOff = false;
    37         os.nlOnOff = true;
    38         os.prt = false;
    39         os.sawNL = false;
     34        os.$file = file;
     35        os.$sepDefault = true;
     36        os.$sepOnOff = false;
     37        os.$nlOnOff = true;
     38        os.$prt = false;
     39        os.$sawNL = false;
     40        $sepSetCur( os, sepGet( os ) );
    4041        sepSet( os, " " );
    41         sepSetCur( os, sepGet( os ) );
    4242        sepSetTuple( os, ", " );
    4343} // ?{}
    4444
    4545// private
    46 bool sepPrt( ofstream & os ) { setNL( os, false ); return os.sepOnOff; }
    47 void sepReset( ofstream & os ) { os.sepOnOff = os.sepDefault; }
    48 void sepReset( ofstream & os, bool reset ) { os.sepDefault = reset; os.sepOnOff = os.sepDefault; }
    49 const char * sepGetCur( ofstream & os ) { return os.sepCur; }
    50 void sepSetCur( ofstream & os, const char * sepCur ) { os.sepCur = sepCur; }
    51 bool getNL( ofstream & os ) { return os.sawNL; }
    52 void setNL( ofstream & os, bool state ) { os.sawNL = state; }
    53 bool getANL( ofstream & os ) { return os.nlOnOff; }
    54 bool getPrt( ofstream & os ) { return os.prt; }
    55 void setPrt( ofstream & os, bool state ) { os.prt = state; }
     46bool $sepPrt( ofstream & os ) { $setNL( os, false ); return os.$sepOnOff; }
     47void $sepReset( ofstream & os ) { os.$sepOnOff = os.$sepDefault; }
     48void $sepReset( ofstream & os, bool reset ) { os.$sepDefault = reset; os.$sepOnOff = os.$sepDefault; }
     49const char * $sepGetCur( ofstream & os ) { return os.$sepCur; }
     50void $sepSetCur( ofstream & os, const char sepCur[] ) { os.$sepCur = sepCur; }
     51bool $getNL( ofstream & os ) { return os.$sawNL; }
     52void $setNL( ofstream & os, bool state ) { os.$sawNL = state; }
     53bool $getANL( ofstream & os ) { return os.$nlOnOff; }
     54bool $getPrt( ofstream & os ) { return os.$prt; }
     55void $setPrt( ofstream & os, bool state ) { os.$prt = state; }
    5656
    5757// public
    58 void ?{}( ofstream & os ) { os.file = 0; }
    59 
    60 void ?{}( ofstream & os, const char * name, const char * mode ) {
     58void ?{}( ofstream & os ) { os.$file = 0p; }
     59
     60void ?{}( ofstream & os, const char name[], const char mode[] ) {
    6161        open( os, name, mode );
    6262} // ?{}
    6363
    64 void ?{}( ofstream & os, const char * name ) {
     64void ?{}( ofstream & os, const char name[] ) {
    6565        open( os, name, "w" );
    6666} // ?{}
    6767
    68 void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); }
    69 void sepOff( ofstream & os ) { os.sepOnOff = false; }
     68void ^?{}( ofstream & os ) {
     69        close( os );
     70} // ^?{}
     71
     72void sepOn( ofstream & os ) { os.$sepOnOff = ! $getNL( os ); }
     73void sepOff( ofstream & os ) { os.$sepOnOff = false; }
    7074
    7175bool sepDisable( ofstream & os ) {
    72         bool temp = os.sepDefault;
    73         os.sepDefault = false;
    74         sepReset( os );
     76        bool temp = os.$sepDefault;
     77        os.$sepDefault = false;
     78        $sepReset( os );
    7579        return temp;
    7680} // sepDisable
    7781
    7882bool sepEnable( ofstream & os ) {
    79         bool temp = os.sepDefault;
    80         os.sepDefault = true;
    81         if ( os.sepOnOff ) sepReset( os );                                      // start of line ?
     83        bool temp = os.$sepDefault;
     84        os.$sepDefault = true;
     85        if ( os.$sepOnOff ) $sepReset( os );                            // start of line ?
    8286        return temp;
    8387} // sepEnable
    8488
    85 void nlOn( ofstream & os ) { os.nlOnOff = true; }
    86 void nlOff( ofstream & os ) { os.nlOnOff = false; }
    87 
    88 const char * sepGet( ofstream & os ) { return os.separator; }
    89 void sepSet( ofstream & os, const char * s ) {
     89void nlOn( ofstream & os ) { os.$nlOnOff = true; }
     90void nlOff( ofstream & os ) { os.$nlOnOff = false; }
     91
     92const char * sepGet( ofstream & os ) { return os.$separator; }
     93void sepSet( ofstream & os, const char s[] ) {
    9094        assert( s );
    91         strncpy( os.separator, s, sepSize - 1 );
    92         os.separator[sepSize - 1] = '\0';
     95        strncpy( os.$separator, s, sepSize - 1 );
     96        os.$separator[sepSize - 1] = '\0';
    9397} // sepSet
    9498
    95 const char * sepGetTuple( ofstream & os ) { return os.tupleSeparator; }
    96 void sepSetTuple( ofstream & os, const char * s ) {
     99const char * sepGetTuple( ofstream & os ) { return os.$tupleSeparator; }
     100void sepSetTuple( ofstream & os, const char s[] ) {
    97101        assert( s );
    98         strncpy( os.tupleSeparator, s, sepSize - 1 );
    99         os.tupleSeparator[sepSize - 1] = '\0';
     102        strncpy( os.$tupleSeparator, s, sepSize - 1 );
     103        os.$tupleSeparator[sepSize - 1] = '\0';
    100104} // sepSet
    101105
    102106void ends( ofstream & os ) {
    103         if ( getANL( os ) ) nl( os );
    104         else setPrt( os, false );                                                       // turn off
     107        if ( $getANL( os ) ) nl( os );
     108        else $setPrt( os, false );                                                      // turn off
    105109        if ( &os == &exit ) exit( EXIT_FAILURE );
    106110        if ( &os == &abort ) abort();
     
    108112
    109113int fail( ofstream & os ) {
    110         return os.file == 0 || ferror( (FILE *)(os.file) );
     114        return os.$file == 0 || ferror( (FILE *)(os.$file) );
    111115} // fail
    112116
    113117int flush( ofstream & os ) {
    114         return fflush( (FILE *)(os.file) );
     118        return fflush( (FILE *)(os.$file) );
    115119} // flush
    116120
    117 void open( ofstream & os, const char * name, const char * mode ) {
     121void open( ofstream & os, const char name[], const char mode[] ) {
    118122        FILE * file = fopen( name, mode );
    119123        #ifdef __CFA_DEBUG__
    120         if ( file == 0 ) {
     124        if ( file == 0p ) {
    121125                abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
    122126        } // if
     
    125129} // open
    126130
    127 void open( ofstream & os, const char * name ) {
     131void open( ofstream & os, const char name[] ) {
    128132        open( os, name, "w" );
    129133} // open
    130134
    131135void close( ofstream & os ) {
    132         if ( (FILE *)(os.file) == stdout || (FILE *)(os.file) == stderr ) return;
    133 
    134         if ( fclose( (FILE *)(os.file) ) == EOF ) {
     136        if ( (FILE *)(os.$file) == stdout || (FILE *)(os.$file) == stderr ) return;
     137
     138        if ( fclose( (FILE *)(os.$file) ) == EOF ) {
    135139                abort | IO_MSG "close output" | nl | strerror( errno );
    136140        } // if
    137141} // close
    138142
    139 ofstream & write( ofstream & os, const char * data, size_t size ) {
     143ofstream & write( ofstream & os, const char data[], size_t size ) {
    140144        if ( fail( os ) ) {
    141145                abort | IO_MSG "attempt write I/O on failed stream";
    142146        } // if
    143147
    144         if ( fwrite( data, 1, size, (FILE *)(os.file) ) != size ) {
     148        if ( fwrite( data, 1, size, (FILE *)(os.$file) ) != size ) {
    145149                abort | IO_MSG "write" | nl | strerror( errno );
    146150        } // if
     
    151155        va_list args;
    152156        va_start( args, format );
    153         int len = vfprintf( (FILE *)(os.file), format, args );
     157        int len = vfprintf( (FILE *)(os.$file), format, args );
    154158        if ( len == EOF ) {
    155                 if ( ferror( (FILE *)(os.file) ) ) {
     159                if ( ferror( (FILE *)(os.$file) ) ) {
    156160                        abort | IO_MSG "invalid write";
    157161                } // if
     
    159163        va_end( args );
    160164
    161         setPrt( os, true );                                                                     // called in output cascade
    162         sepReset( os );                                                                         // reset separator
     165        $setPrt( os, true );                                                            // called in output cascade
     166        $sepReset( os );                                                                        // reset separator
    163167        return len;
    164168} // fmt
    165169
    166 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_) };
     170static ofstream soutFile = { (FILE *)stdout };
    167171ofstream & sout = soutFile, & stdout = soutFile;
    168 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_) };
     172static ofstream serrFile = { (FILE *)stderr };
    169173ofstream & serr = serrFile, & stderr = serrFile;
    170174
    171 static ofstream exitFile = { (FILE *)(&_IO_2_1_stdout_) };
     175static ofstream exitFile = { (FILE *)stdout };
    172176ofstream & exit = exitFile;
    173 static ofstream abortFile = { (FILE *)(&_IO_2_1_stderr_) };
     177static ofstream abortFile = { (FILE *)stderr };
    174178ofstream & abort = abortFile;
    175179
     
    180184// private
    181185void ?{}( ifstream & is, void * file ) {
    182         is.file = file;
    183         is.nlOnOff = false;
     186        is.$file = file;
     187        is.$nlOnOff = false;
    184188} // ?{}
    185189
    186190// public
    187 void ?{}( ifstream & is ) {     is.file = 0; }
    188 
    189 void ?{}( ifstream & is, const char * name, const char * mode ) {
     191void ?{}( ifstream & is ) { is.$file = 0p; }
     192
     193void ?{}( ifstream & is, const char name[], const char mode[] ) {
    190194        open( is, name, mode );
    191195} // ?{}
    192196
    193 void ?{}( ifstream & is, const char * name ) {
     197void ?{}( ifstream & is, const char name[] ) {
    194198        open( is, name, "r" );
    195199} // ?{}
    196200
    197 void nlOn( ifstream & os ) { os.nlOnOff = true; }
    198 void nlOff( ifstream & os ) { os.nlOnOff = false; }
    199 bool getANL( ifstream & os ) { return os.nlOnOff; }
     201void ^?{}( ifstream & is ) {
     202        close( is );
     203} // ^?{}
     204
     205void nlOn( ifstream & os ) { os.$nlOnOff = true; }
     206void nlOff( ifstream & os ) { os.$nlOnOff = false; }
     207bool getANL( ifstream & os ) { return os.$nlOnOff; }
    200208
    201209int fail( ifstream & is ) {
    202         return is.file == 0 || ferror( (FILE *)(is.file) );
     210        return is.$file == 0p || ferror( (FILE *)(is.$file) );
    203211} // fail
    204212
    205213int eof( ifstream & is ) {
    206         return feof( (FILE *)(is.file) );
     214        return feof( (FILE *)(is.$file) );
    207215} // eof
    208216
    209 void open( ifstream & is, const char * name, const char * mode ) {
     217void open( ifstream & is, const char name[], const char mode[] ) {
    210218        FILE * file = fopen( name, mode );
    211219        #ifdef __CFA_DEBUG__
    212         if ( file == 0 ) {
     220        if ( file == 0p ) {
    213221                abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
    214222        } // if
    215223        #endif // __CFA_DEBUG__
    216         is.file = file;
    217 } // open
    218 
    219 void open( ifstream & is, const char * name ) {
     224        is.$file = file;
     225} // open
     226
     227void open( ifstream & is, const char name[] ) {
    220228        open( is, name, "r" );
    221229} // open
    222230
    223231void close( ifstream & is ) {
    224         if ( (FILE *)(is.file) == stdin ) return;
    225 
    226         if ( fclose( (FILE *)(is.file) ) == EOF ) {
     232        if ( (FILE *)(is.$file) == stdin ) return;
     233
     234        if ( fclose( (FILE *)(is.$file) ) == EOF ) {
    227235                abort | IO_MSG "close input" | nl | strerror( errno );
    228236        } // if
     
    234242        } // if
    235243
    236         if ( fread( data, size, 1, (FILE *)(is.file) ) == 0 ) {
     244        if ( fread( data, size, 1, (FILE *)(is.$file) ) == 0 ) {
    237245                abort | IO_MSG "read" | nl | strerror( errno );
    238246        } // if
     
    245253        } // if
    246254
    247         if ( ungetc( c, (FILE *)(is.file) ) == EOF ) {
     255        if ( ungetc( c, (FILE *)(is.$file) ) == EOF ) {
    248256                abort | IO_MSG "ungetc" | nl | strerror( errno );
    249257        } // if
     
    255263
    256264        va_start( args, format );
    257         int len = vfscanf( (FILE *)(is.file), format, args );
     265        int len = vfscanf( (FILE *)(is.$file), format, args );
    258266        if ( len == EOF ) {
    259                 if ( ferror( (FILE *)(is.file) ) ) {
     267                if ( ferror( (FILE *)(is.$file) ) ) {
    260268                        abort | IO_MSG "invalid read";
    261269                } // if
     
    265273} // fmt
    266274
    267 
    268 static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) };
     275static ifstream sinFile = { (FILE *)stdin };
    269276ifstream & sin = sinFile, & stdin = sinFile;
    270277
  • libcfa/src/fstream.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 15 18:10:23 2019
    13 // Update Count     : 167
     12// Last Modified On : Mon Feb 17 08:29:23 2020
     13// Update Count     : 175
    1414//
    1515
     
    2424enum { sepSize = 16 };
    2525struct ofstream {
    26         void * file;
    27         bool sepDefault;
    28         bool sepOnOff;
    29         bool nlOnOff;
    30         bool prt;                                                                                       // print text
    31         bool sawNL;
    32         const char * sepCur;
    33         char separator[sepSize];
    34         char tupleSeparator[sepSize];
     26        void * $file;
     27        bool $sepDefault;
     28        bool $sepOnOff;
     29        bool $nlOnOff;
     30        bool $prt;                                                                                      // print text
     31        bool $sawNL;
     32        const char * $sepCur;
     33        char $separator[sepSize];
     34        char $tupleSeparator[sepSize];
    3535}; // ofstream
    3636
    3737// private
    38 bool sepPrt( ofstream & );
    39 void sepReset( ofstream & );
    40 void sepReset( ofstream &, bool );
    41 const char * sepGetCur( ofstream & );
    42 void sepSetCur( ofstream &, const char * );
    43 bool getNL( ofstream & );
    44 void setNL( ofstream &, bool );
    45 bool getANL( ofstream & );
    46 bool getPrt( ofstream & );
    47 void setPrt( ofstream &, bool );
     38bool $sepPrt( ofstream & );
     39void $sepReset( ofstream & );
     40void $sepReset( ofstream &, bool );
     41const char * $sepGetCur( ofstream & );
     42void $sepSetCur( ofstream &, const char [] );
     43bool $getNL( ofstream & );
     44void $setNL( ofstream &, bool );
     45bool $getANL( ofstream & );
     46bool $getPrt( ofstream & );
     47void $setPrt( ofstream &, bool );
    4848
    4949// public
     
    5656
    5757const char * sepGet( ofstream & );
    58 void sepSet( ofstream &, const char * );
     58void sepSet( ofstream &, const char [] );
    5959const char * sepGetTuple( ofstream & );
    60 void sepSetTuple( ofstream &, const char * );
     60void sepSetTuple( ofstream &, const char [] );
    6161
    6262void ends( ofstream & os );
    6363int fail( ofstream & );
    6464int flush( ofstream & );
    65 void open( ofstream &, const char * name, const char * mode );
    66 void open( ofstream &, const char * name );
     65void open( ofstream &, const char name[], const char mode[] );
     66void open( ofstream &, const char name[] );
    6767void close( ofstream & );
    68 ofstream & write( ofstream &, const char * data, size_t size );
    69 int fmt( ofstream &, const char format[], ... );
     68ofstream & write( ofstream &, const char data[], size_t size );
     69int fmt( ofstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    7070
    7171void ?{}( ofstream & os );
    72 void ?{}( ofstream & os, const char * name, const char * mode );
    73 void ?{}( ofstream & os, const char * name );
     72void ?{}( ofstream & os, const char name[], const char mode[] );
     73void ?{}( ofstream & os, const char name[] );
     74void ^?{}( ofstream & os );
    7475
    7576extern ofstream & sout, & stdout, & serr, & stderr;             // aliases
     
    8182
    8283struct ifstream {
    83         void * file;
    84         bool nlOnOff;
     84        void * $file;
     85        bool $nlOnOff;
    8586}; // ifstream
    8687
     
    9192int fail( ifstream & is );
    9293int eof( ifstream & is );
    93 void open( ifstream & is, const char * name, const char * mode );
    94 void open( ifstream & is, const char * name );
     94void open( ifstream & is, const char name[], const char mode[] );
     95void open( ifstream & is, const char name[] );
    9596void close( ifstream & is );
    9697ifstream & read( ifstream & is, char * data, size_t size );
    9798ifstream & ungetc( ifstream & is, char c );
    98 int fmt( ifstream &, const char format[], ... );
     99int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
    99100
    100101void ?{}( ifstream & is );
    101 void ?{}( ifstream & is, const char * name, const char * mode );
    102 void ?{}( ifstream & is, const char * name );
     102void ?{}( ifstream & is, const char name[], const char mode[] );
     103void ?{}( ifstream & is, const char name[] );
     104void ^?{}( ifstream & is );
    103105
    104106extern ifstream & sin, & stdin;                                                 // aliases
  • libcfa/src/gmp.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 15:25:05 2019
    13 // Update Count     : 27
     12// Last Modified On : Sun Feb  9 09:56:54 2020
     13// Update Count     : 31
    1414//
    1515
     
    2424
    2525static inline {
    26         // constructor
     26        // constructor, zero_t/one_t are unnecessary because of relationship with signed/unsigned int
    2727        void ?{}( Int & this ) { mpz_init( this.mpz ); }
    2828        void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
    29         void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
    30         void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
    3129        void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
    3230        void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
    33         void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
     31        void ?{}( Int & this, const char val[] ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
    3432        void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
    3533
     
    3735        Int ?`mp( signed long int init ) { return (Int){ init }; }
    3836        Int ?`mp( unsigned long int init ) { return (Int){ init }; }
    39         Int ?`mp( const char * init ) { return (Int){ init }; }
     37        Int ?`mp( const char init[] ) { return (Int){ init }; }
    4038
    4139        // assignment
     
    4341        Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
    4442        Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
    45         Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
     43        Int ?=?( Int & lhs, const char rhs[] ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
    4644
    4745        char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     
    265263        forall( dtype ostype | ostream( ostype ) ) {
    266264                ostype & ?|?( ostype & os, Int mp ) {
    267                         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     265                        if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    268266                        gmp_printf( "%Zd", mp.mpz );
    269267                        sepOn( os );
  • libcfa/src/heap.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 24 13:12:45 2019
    13 // Update Count     : 550
     12// Last Modified On : Tue Feb  4 10:04:51 2020
     13// Update Count     : 648
    1414//
    1515
     
    1818#include <stdio.h>                                                                              // snprintf, fileno
    1919#include <errno.h>                                                                              // errno
     20#include <string.h>                                                                             // memset, memcpy
    2021extern "C" {
    2122#include <sys/mman.h>                                                                   // mmap, munmap
     
    2728#include "bits/locks.hfa"                                                               // __spinlock_t
    2829#include "startup.hfa"                                                                  // STARTUP_PRIORITY_MEMORY
    29 #include "stdlib.hfa"                                                                   // bsearchl
     30//#include "stdlib.hfa"                                                                 // bsearchl
    3031#include "malloc.h"
    3132
     33#define MIN(x, y) (y > x ? x : y)
    3234
    3335static bool traceHeap = false;
    3436
    35 inline bool traceHeap() {
    36         return traceHeap;
    37 } // traceHeap
     37inline bool traceHeap() { return traceHeap; }
    3838
    3939bool traceHeapOn() {
     
    4949} // traceHeapOff
    5050
    51 
    52 static bool checkFree = false;
    53 
    54 inline bool checkFree() {
    55         return checkFree;
    56 } // checkFree
    57 
    58 bool checkFreeOn() {
    59         bool temp = checkFree;
    60         checkFree = true;
     51bool traceHeapTerm() { return false; }
     52
     53
     54static bool prtFree = false;
     55
     56inline bool prtFree() {
     57        return prtFree;
     58} // prtFree
     59
     60bool prtFreeOn() {
     61        bool temp = prtFree;
     62        prtFree = true;
    6163        return temp;
    62 } // checkFreeOn
    63 
    64 bool checkFreeOff() {
    65         bool temp = checkFree;
    66         checkFree = false;
     64} // prtFreeOn
     65
     66bool prtFreeOff() {
     67        bool temp = prtFree;
     68        prtFree = false;
    6769        return temp;
    68 } // checkFreeOff
    69 
    70 
    71 // static bool traceHeapTerm = false;
    72 
    73 // inline bool traceHeapTerm() {
    74 //      return traceHeapTerm;
    75 // } // traceHeapTerm
    76 
    77 // bool traceHeapTermOn() {
    78 //      bool temp = traceHeapTerm;
    79 //      traceHeapTerm = true;
    80 //      return temp;
    81 // } // traceHeapTermOn
    82 
    83 // bool traceHeapTermOff() {
    84 //      bool temp = traceHeapTerm;
    85 //      traceHeapTerm = false;
    86 //      return temp;
    87 // } // traceHeapTermOff
     70} // prtFreeOff
    8871
    8972
    9073enum {
     74        // Define the default extension heap amount in units of bytes. When the uC++ supplied heap reaches the brk address,
     75        // the brk address is extended by the extension amount.
     76        __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024),
     77
     78        // Define the mmap crossover point during allocation. Allocations less than this amount are allocated from buckets;
     79        // values greater than or equal to this value are mmap from the operating system.
    9180        __CFA_DEFAULT_MMAP_START__ = (512 * 1024 + 1),
    92         __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024),
    9381};
    9482
     
    10593static unsigned int allocFree;                                                  // running total of allocations minus frees
    10694
    107 static void checkUnfreed() {
     95static void prtUnfreed() {
    10896        if ( allocFree != 0 ) {
    10997                // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT.
    110                 // char helpText[512];
    111                 // int len = snprintf( helpText, sizeof(helpText), "CFA warning (UNIX pid:%ld) : program terminating with %u(0x%x) bytes of storage allocated but not freed.\n"
    112                 //                                      "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n",
    113                 //                                      (long int)getpid(), allocFree, allocFree ); // always print the UNIX pid
    114                 // __cfaabi_dbg_bits_write( helpText, len );
    115         } // if
    116 } // checkUnfreed
     98                char helpText[512];
     99                int len = snprintf( helpText, sizeof(helpText), "CFA warning (UNIX pid:%ld) : program terminating with %u(0x%x) bytes of storage allocated but not freed.\n"
     100                                                        "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n",
     101                                                        (long int)getpid(), allocFree, allocFree ); // always print the UNIX pid
     102                __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug
     103        } // if
     104} // prtUnfreed
    117105
    118106extern "C" {
     
    123111        void heapAppStop() {                                                            // called by __cfaabi_appready_startdown
    124112                fclose( stdin ); fclose( stdout );
    125                 checkUnfreed();
     113                prtUnfreed();
    126114        } // heapAppStop
    127115} // extern "C"
    128116#endif // __CFA_DEBUG__
     117
    129118
    130119// statically allocated variables => zero filled.
     
    134123static unsigned int maxBucketsUsed;                                             // maximum number of buckets in use
    135124
    136 
    137 // #comment TD : This defined is significantly different from the __ALIGN__ define from locks.hfa
    138 #define ALIGN 16
    139125
    140126#define SPINLOCK 0
     
    147133// Recursive definitions: HeapManager needs size of bucket array and bucket area needs sizeof HeapManager storage.
    148134// Break recusion by hardcoding number of buckets and statically checking number is correct after bucket array defined.
    149 enum { NoBucketSizes = 93 };                                                    // number of buckets sizes
     135enum { NoBucketSizes = 91 };                                                    // number of buckets sizes
    150136
    151137struct HeapManager {
     
    194180                        } kind; // Kind
    195181                } header; // Header
    196                 char pad[ALIGN - sizeof( Header )];
     182                char pad[libAlign() - sizeof( Header )];
    197183                char data[0];                                                                   // storage
    198184        }; // Storage
    199185
    200         static_assert( ALIGN >= sizeof( Storage ), "ALIGN < sizeof( Storage )" );
     186        static_assert( libAlign() >= sizeof( Storage ), "libAlign() < sizeof( Storage )" );
    201187
    202188        struct FreeHeader {
     
    228214#define __STATISTICS__
    229215
     216// Bucket size must be multiple of 16.
    230217// Powers of 2 are common allocation sizes, so make powers of 2 generate the minimum required size.
    231218static const unsigned int bucketSizes[] @= {                    // different bucket sizes
    232         16, 32, 48, 64,
    233         64 + sizeof(HeapManager.Storage), 96, 112, 128, 128 + sizeof(HeapManager.Storage), 160, 192, 224,
    234         256 + sizeof(HeapManager.Storage), 320, 384, 448, 512 + sizeof(HeapManager.Storage), 640, 768, 896,
    235         1_024 + sizeof(HeapManager.Storage), 1_536, 2_048 + sizeof(HeapManager.Storage), 2_560, 3_072, 3_584, 4_096 + sizeof(HeapManager.Storage), 6_144,
    236         8_192 + sizeof(HeapManager.Storage), 9_216, 10_240, 11_264, 12_288, 13_312, 14_336, 15_360,
    237         16_384 + sizeof(HeapManager.Storage), 18_432, 20_480, 22_528, 24_576, 26_624, 28_672, 30_720,
    238         32_768 + sizeof(HeapManager.Storage), 36_864, 40_960, 45_056, 49_152, 53_248, 57_344, 61_440,
    239         65_536 + sizeof(HeapManager.Storage), 73_728, 81_920, 90_112, 98_304, 106_496, 114_688, 122_880,
    240         131_072 + sizeof(HeapManager.Storage), 147_456, 163_840, 180_224, 196_608, 212_992, 229_376, 245_760,
    241         262_144 + sizeof(HeapManager.Storage), 294_912, 327_680, 360_448, 393_216, 425_984, 458_752, 491_520,
    242         524_288 + sizeof(HeapManager.Storage), 655_360, 786_432, 917_504, 1_048_576 + sizeof(HeapManager.Storage), 1_179_648, 1_310_720, 1_441_792,
    243         1_572_864, 1_703_936, 1_835_008, 1_966_080, 2_097_152 + sizeof(HeapManager.Storage), 2_621_440, 3_145_728, 3_670_016,
    244         4_194_304 + sizeof(HeapManager.Storage)
     219        16, 32, 48, 64 + sizeof(HeapManager.Storage), // 4
     220        96, 112, 128 + sizeof(HeapManager.Storage), // 3
     221        160, 192, 224, 256 + sizeof(HeapManager.Storage), // 4
     222        320, 384, 448, 512 + sizeof(HeapManager.Storage), // 4
     223        640, 768, 896, 1_024 + sizeof(HeapManager.Storage), // 4
     224        1_536, 2_048 + sizeof(HeapManager.Storage), // 2
     225        2_560, 3_072, 3_584, 4_096 + sizeof(HeapManager.Storage), // 4
     226        6_144, 8_192 + sizeof(HeapManager.Storage), // 2
     227        9_216, 10_240, 11_264, 12_288, 13_312, 14_336, 15_360, 16_384 + sizeof(HeapManager.Storage), // 8
     228        18_432, 20_480, 22_528, 24_576, 26_624, 28_672, 30_720, 32_768 + sizeof(HeapManager.Storage), // 8
     229        36_864, 40_960, 45_056, 49_152, 53_248, 57_344, 61_440, 65_536 + sizeof(HeapManager.Storage), // 8
     230        73_728, 81_920, 90_112, 98_304, 106_496, 114_688, 122_880, 131_072 + sizeof(HeapManager.Storage), // 8
     231        147_456, 163_840, 180_224, 196_608, 212_992, 229_376, 245_760, 262_144 + sizeof(HeapManager.Storage), // 8
     232        294_912, 327_680, 360_448, 393_216, 425_984, 458_752, 491_520, 524_288 + sizeof(HeapManager.Storage), // 8
     233        655_360, 786_432, 917_504, 1_048_576 + sizeof(HeapManager.Storage), // 4
     234        1_179_648, 1_310_720, 1_441_792, 1_572_864, 1_703_936, 1_835_008, 1_966_080, 2_097_152 + sizeof(HeapManager.Storage), // 8
     235        2_621_440, 3_145_728, 3_670_016, 4_194_304 + sizeof(HeapManager.Storage), // 4
    245236};
    246237
     
    251242static unsigned char lookup[LookupSizes];                               // O(1) lookup for small sizes
    252243#endif // FASTLOOKUP
     244
    253245static int mmapFd = -1;                                                                 // fake or actual fd for anonymous file
    254 
    255 
    256246#ifdef __CFA_DEBUG__
    257247static bool heapBoot = 0;                                                               // detect recursion during boot
     
    259249static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing
    260250
    261 // #comment TD : The return type of this function should be commented
    262 static inline bool setMmapStart( size_t value ) {
    263   if ( value < pageSize || bucketSizes[NoBucketSizes - 1] < value ) return true;
    264         mmapStart = value;                                                                      // set global
    265 
    266         // find the closest bucket size less than or equal to the mmapStart size
    267         maxBucketsUsed = bsearchl( (unsigned int)mmapStart, bucketSizes, NoBucketSizes ); // binary search
    268         assert( maxBucketsUsed < NoBucketSizes );                       // subscript failure ?
    269         assert( mmapStart <= bucketSizes[maxBucketsUsed] ); // search failure ?
    270         return false;
    271 } // setMmapStart
    272 
    273 
    274 static void ?{}( HeapManager & manager ) with ( manager ) {
    275         pageSize = sysconf( _SC_PAGESIZE );
    276 
    277         for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists
    278                 freeLists[i].blockSize = bucketSizes[i];
    279         } // for
    280 
    281         #ifdef FASTLOOKUP
    282         unsigned int idx = 0;
    283         for ( unsigned int i = 0; i < LookupSizes; i += 1 ) {
    284                 if ( i > bucketSizes[idx] ) idx += 1;
    285                 lookup[i] = idx;
    286         } // for
    287         #endif // FASTLOOKUP
    288 
    289         if ( setMmapStart( default_mmap_start() ) ) {
    290                 abort( "HeapManager : internal error, mmap start initialization failure." );
    291         } // if
    292         heapExpand = default_heap_expansion();
    293 
    294         char * End = (char *)sbrk( 0 );
    295         sbrk( (char *)libCeiling( (long unsigned int)End, libAlign() ) - End ); // move start of heap to multiple of alignment
    296         heapBegin = heapEnd = sbrk( 0 );                                        // get new start point
    297 } // HeapManager
    298 
    299 
    300 static void ^?{}( HeapManager & ) {
    301         #ifdef __STATISTICS__
    302         // if ( traceHeapTerm() ) {
    303         //      printStats();
    304         //      if ( checkfree() ) checkFree( heapManager, true );
    305         // } // if
    306         #endif // __STATISTICS__
    307 } // ~HeapManager
    308 
    309 
    310 static void memory_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_MEMORY ) ));
    311 void memory_startup( void ) {
    312         #ifdef __CFA_DEBUG__
    313         if ( unlikely( heapBoot ) ) {                                           // check for recursion during system boot
    314                 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT.
    315                 abort( "boot() : internal error, recursively invoked during system boot." );
    316         } // if
    317         heapBoot = true;
    318         #endif // __CFA_DEBUG__
    319 
    320         //assert( heapManager.heapBegin != 0 );
    321         //heapManager{};
    322         if ( heapManager.heapBegin == 0 ) heapManager{};
    323 } // memory_startup
    324 
    325 static void memory_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_MEMORY ) ));
    326 void memory_shutdown( void ) {
    327         ^heapManager{};
    328 } // memory_shutdown
    329 
    330251
    331252#ifdef __STATISTICS__
    332 static unsigned long long int mmap_storage;                             // heap statistics counters
     253// Heap statistics counters.
     254static unsigned long long int mmap_storage;
    333255static unsigned int mmap_calls;
    334256static unsigned long long int munmap_storage;
     
    348270static unsigned long long int realloc_storage;
    349271static unsigned int realloc_calls;
    350 
    351 static int statfd;                                                                              // statistics file descriptor (changed by malloc_stats_fd)
    352 
     272// Statistics file descriptor (changed by malloc_stats_fd).
     273static int statfd = STDERR_FILENO;                                              // default stderr
    353274
    354275// Use "write" because streams may be shutdown when calls are made.
    355276static void printStats() {
    356277        char helpText[512];
    357         __cfaabi_dbg_bits_print_buffer( helpText, sizeof(helpText),
     278        __cfaabi_bits_print_buffer( STDERR_FILENO, helpText, sizeof(helpText),
    358279                                                                        "\nHeap statistics:\n"
    359280                                                                        "  malloc: calls %u / storage %llu\n"
     
    405326                                                sbrk_calls, sbrk_storage
    406327                );
    407         return write( fileno( stream ), helpText, len );        // -1 => error
     328        __cfaabi_bits_write( fileno( stream ), helpText, len ); // ensures all bytes written or exit
     329        return len;
    408330} // printStatsXML
    409331#endif // __STATISTICS__
    410332
    411 // #comment TD : Is this the samething as Out-of-Memory?
    412 static inline void noMemory() {
    413         abort( "Heap memory exhausted at %zu bytes.\n"
    414                    "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
    415                    ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
    416 } // noMemory
     333
     334// static inline void noMemory() {
     335//      abort( "Heap memory exhausted at %zu bytes.\n"
     336//                 "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
     337//                 ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
     338// } // noMemory
    417339
    418340
    419341static inline void checkAlign( size_t alignment ) {
    420         if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) {
    421                 abort( "Alignment %zu for memory allocation is less than sizeof(void *) and/or not a power of 2.", alignment );
     342        if ( alignment < libAlign() || ! libPow2( alignment ) ) {
     343                abort( "Alignment %zu for memory allocation is less than %d and/or not a power of 2.", alignment, libAlign() );
    422344        } // if
    423345} // checkAlign
     
    431353
    432354
    433 static inline void checkHeader( bool check, const char * name, void * addr ) {
    434         if ( unlikely( check ) ) {                                                      // bad address ?
    435                 abort( "Attempt to %s storage %p with address outside the heap.\n"
    436                            "Possible cause is duplicate free on same block or overwriting of memory.",
    437                            name, addr );
    438         } // if
    439 } // checkHeader
    440 
    441 // #comment TD : function should be commented and/or have a more evocative name
    442 //               this isn't either a check or a constructor which is what I would expect this function to be
    443 static inline void fakeHeader( HeapManager.Storage.Header *& header, size_t & size, size_t & alignment ) {
    444         if ( unlikely( (header->kind.fake.alignment & 1) == 1 ) ) { // fake header ?
    445                 size_t offset = header->kind.fake.offset;
    446                 alignment = header->kind.fake.alignment & -2;   // remove flag from value
    447                 #ifdef __CFA_DEBUG__
    448                 checkAlign( alignment );                                                // check alignment
    449                 #endif // __CFA_DEBUG__
    450                 header = (HeapManager.Storage.Header *)((char *)header - offset);
    451         } // if
    452 } // fakeHeader
    453 
    454 // #comment TD : Why is this a define
    455 #define headerAddr( addr ) ((HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) ))
    456 
    457 static inline bool headers( const char * name, void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
    458         header = headerAddr( addr );
    459 
    460         if ( unlikely( heapEnd < addr ) ) {                                     // mmapped ?
    461                 fakeHeader( header, size, alignment );
    462                 size = header->kind.real.blockSize & -3;                // mmap size
    463                 return true;
    464         } // if
    465 
    466         #ifdef __CFA_DEBUG__
    467         checkHeader( addr < heapBegin || header < (HeapManager.Storage.Header *)heapBegin, name, addr ); // bad low address ?
    468         #endif // __CFA_DEBUG__
    469 
    470         // #comment TD : This code looks weird...
    471         //               It's called as the first statement of both branches of the last if, with the same parameters in all cases
    472 
    473         // header may be safe to dereference
    474         fakeHeader( header, size, alignment );
    475         #ifdef __CFA_DEBUG__
    476         checkHeader( header < (HeapManager.Storage.Header *)heapBegin || (HeapManager.Storage.Header *)heapEnd < header, name, addr ); // bad address ? (offset could be + or -)
    477         #endif // __CFA_DEBUG__
    478 
    479         freeElem = (HeapManager.FreeHeader *)((size_t)header->kind.real.home & -3);
    480         #ifdef __CFA_DEBUG__
    481         if ( freeElem < &freeLists[0] || &freeLists[NoBucketSizes] <= freeElem ) {
    482                 abort( "Attempt to %s storage %p with corrupted header.\n"
    483                            "Possible cause is duplicate free on same block or overwriting of header information.",
    484                            name, addr );
    485         } // if
    486         #endif // __CFA_DEBUG__
    487         size = freeElem->blockSize;
    488         return false;
    489 } // headers
    490 
    491 
    492 static inline void * extend( size_t size ) with ( heapManager ) {
    493         lock( extlock __cfaabi_dbg_ctx2 );
    494         ptrdiff_t rem = heapRemaining - size;
    495         if ( rem < 0 ) {
    496                 // If the size requested is bigger than the current remaining storage, increase the size of the heap.
    497 
    498                 size_t increase = libCeiling( size > heapExpand ? size : heapExpand, libAlign() );
    499                 if ( sbrk( increase ) == (void *)-1 ) {
    500                         unlock( extlock );
    501                         errno = ENOMEM;
    502                         return 0;
    503                 } // if
    504                 #ifdef __STATISTICS__
    505                 sbrk_calls += 1;
    506                 sbrk_storage += increase;
    507                 #endif // __STATISTICS__
    508                 #ifdef __CFA_DEBUG__
    509                 // Set new memory to garbage so subsequent uninitialized usages might fail.
    510                 memset( (char *)heapEnd + heapRemaining, '\377', increase );
    511                 #endif // __CFA_DEBUG__
    512                 rem = heapRemaining + increase - size;
    513         } // if
    514 
    515         HeapManager.Storage * block = (HeapManager.Storage *)heapEnd;
    516         heapRemaining = rem;
    517         heapEnd = (char *)heapEnd + size;
    518         unlock( extlock );
    519         return block;
    520 } // extend
    521 
    522 
     355// thunk problem
    523356size_t Bsearchl( unsigned int key, const unsigned int * vals, size_t dim ) {
    524357        size_t l = 0, m, h = dim;
     
    535368
    536369
     370static inline bool setMmapStart( size_t value ) {               // true => mmapped, false => sbrk
     371  if ( value < pageSize || bucketSizes[NoBucketSizes - 1] < value ) return true;
     372        mmapStart = value;                                                                      // set global
     373
     374        // find the closest bucket size less than or equal to the mmapStart size
     375        maxBucketsUsed = Bsearchl( (unsigned int)mmapStart, bucketSizes, NoBucketSizes ); // binary search
     376        assert( maxBucketsUsed < NoBucketSizes );                       // subscript failure ?
     377        assert( mmapStart <= bucketSizes[maxBucketsUsed] ); // search failure ?
     378        return false;
     379} // setMmapStart
     380
     381
     382static inline void checkHeader( bool check, const char name[], void * addr ) {
     383        if ( unlikely( check ) ) {                                                      // bad address ?
     384                abort( "Attempt to %s storage %p with address outside the heap.\n"
     385                           "Possible cause is duplicate free on same block or overwriting of memory.",
     386                           name, addr );
     387        } // if
     388} // checkHeader
     389
     390
     391static inline void fakeHeader( HeapManager.Storage.Header *& header, size_t & alignment ) {
     392        if ( unlikely( (header->kind.fake.alignment & 1) == 1 ) ) { // fake header ?
     393                size_t offset = header->kind.fake.offset;
     394                alignment = header->kind.fake.alignment & -2;   // remove flag from value
     395                #ifdef __CFA_DEBUG__
     396                checkAlign( alignment );                                                // check alignment
     397                #endif // __CFA_DEBUG__
     398                header = (HeapManager.Storage.Header *)((char *)header - offset);
     399        } // if
     400} // fakeHeader
     401
     402
     403// <-------+----------------------------------------------------> bsize (bucket size)
     404// |header |addr
     405//==================================================================================
     406//                                | alignment
     407// <-----------------<------------+-----------------------------> bsize (bucket size)
     408//                   |fake-header | addr
     409#define headerAddr( addr ) ((HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) ))
     410
     411// <-------<<--------------------- dsize ---------------------->> bsize (bucket size)
     412// |header |addr
     413//==================================================================================
     414//                                | alignment
     415// <------------------------------<<---------- dsize --------->>> bsize (bucket size)
     416//                   |fake-header |addr
     417#define dataStorage( bsize, addr, header ) (bsize - ( (char *)addr - (char *)header ))
     418
     419
     420static inline bool headers( const char name[] __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
     421        header = headerAddr( addr );
     422
     423        if ( unlikely( heapEnd < addr ) ) {                                     // mmapped ?
     424                fakeHeader( header, alignment );
     425                size = header->kind.real.blockSize & -3;                // mmap size
     426                return true;
     427        } // if
     428
     429        #ifdef __CFA_DEBUG__
     430        checkHeader( addr < heapBegin || header < (HeapManager.Storage.Header *)heapBegin, name, addr ); // bad low address ?
     431        #endif // __CFA_DEBUG__
     432
     433        // header may be safe to dereference
     434        fakeHeader( header, alignment );
     435        #ifdef __CFA_DEBUG__
     436        checkHeader( header < (HeapManager.Storage.Header *)heapBegin || (HeapManager.Storage.Header *)heapEnd < header, name, addr ); // bad address ? (offset could be + or -)
     437        #endif // __CFA_DEBUG__
     438
     439        freeElem = (HeapManager.FreeHeader *)((size_t)header->kind.real.home & -3);
     440        #ifdef __CFA_DEBUG__
     441        if ( freeElem < &freeLists[0] || &freeLists[NoBucketSizes] <= freeElem ) {
     442                abort( "Attempt to %s storage %p with corrupted header.\n"
     443                           "Possible cause is duplicate free on same block or overwriting of header information.",
     444                           name, addr );
     445        } // if
     446        #endif // __CFA_DEBUG__
     447        size = freeElem->blockSize;
     448        return false;
     449} // headers
     450
     451
     452static inline void * extend( size_t size ) with ( heapManager ) {
     453        lock( extlock __cfaabi_dbg_ctx2 );
     454        ptrdiff_t rem = heapRemaining - size;
     455        if ( rem < 0 ) {
     456                // If the size requested is bigger than the current remaining storage, increase the size of the heap.
     457
     458                size_t increase = libCeiling( size > heapExpand ? size : heapExpand, libAlign() );
     459                if ( sbrk( increase ) == (void *)-1 ) {
     460                        unlock( extlock );
     461                        errno = ENOMEM;
     462                        return 0p;
     463                } // if
     464                #ifdef __STATISTICS__
     465                sbrk_calls += 1;
     466                sbrk_storage += increase;
     467                #endif // __STATISTICS__
     468                #ifdef __CFA_DEBUG__
     469                // Set new memory to garbage so subsequent uninitialized usages might fail.
     470                memset( (char *)heapEnd + heapRemaining, '\377', increase );
     471                #endif // __CFA_DEBUG__
     472                rem = heapRemaining + increase - size;
     473        } // if
     474
     475        HeapManager.Storage * block = (HeapManager.Storage *)heapEnd;
     476        heapRemaining = rem;
     477        heapEnd = (char *)heapEnd + size;
     478        unlock( extlock );
     479        return block;
     480} // extend
     481
     482
    537483static inline void * doMalloc( size_t size ) with ( heapManager ) {
    538484        HeapManager.Storage * block;                                            // pointer to new block of storage
     
    541487        // along with the block and is a multiple of the alignment size.
    542488
     489  if ( unlikely( size > ~0ul - sizeof(HeapManager.Storage) ) ) return 0p;
    543490        size_t tsize = size + sizeof(HeapManager.Storage);
    544491        if ( likely( tsize < mmapStart ) ) {                            // small size => sbrk
     
    573520                block = freeElem->freeList.pop();
    574521                #endif // SPINLOCK
    575                 if ( unlikely( block == 0 ) ) {                                 // no free block ?
     522                if ( unlikely( block == 0p ) ) {                                // no free block ?
    576523                        #if defined( SPINLOCK )
    577524                        unlock( freeElem->lock );
     
    582529
    583530                        block = (HeapManager.Storage *)extend( tsize ); // mutual exclusion on call
    584   if ( unlikely( block == 0 ) ) return 0;
    585                         #if defined( SPINLOCK )
     531  if ( unlikely( block == 0p ) ) return 0p;
     532                #if defined( SPINLOCK )
    586533                } else {
    587534                        freeElem->freeList = block->header.kind.real.next;
    588535                        unlock( freeElem->lock );
    589                         #endif // SPINLOCK
     536                #endif // SPINLOCK
    590537                } // if
    591538
    592539                block->header.kind.real.home = freeElem;                // pointer back to free list of apropriate size
    593540        } else {                                                                                        // large size => mmap
     541  if ( unlikely( size > ~0ul - pageSize ) ) return 0p;
    594542                tsize = libCeiling( tsize, pageSize );                  // must be multiple of page size
    595543                #ifdef __STATISTICS__
     
    609557        } // if
    610558
    611         void * area = &(block->data);                                           // adjust off header to user bytes
     559        void * addr = &(block->data);                                           // adjust off header to user bytes
    612560
    613561        #ifdef __CFA_DEBUG__
    614         assert( ((uintptr_t)area & (libAlign() - 1)) == 0 ); // minimum alignment ?
     562        assert( ((uintptr_t)addr & (libAlign() - 1)) == 0 ); // minimum alignment ?
    615563        __atomic_add_fetch( &allocFree, tsize, __ATOMIC_SEQ_CST );
    616564        if ( traceHeap() ) {
    617565                enum { BufferSize = 64 };
    618566                char helpText[BufferSize];
    619                 int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", area, size, tsize );
    620                 // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", area, size );
    621                 __cfaabi_dbg_bits_write( helpText, len );
     567                int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", addr, size, tsize );
     568                // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", addr, size );
     569                __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug
    622570        } // if
    623571        #endif // __CFA_DEBUG__
    624572
    625         return area;
     573        return addr;
    626574} // doMalloc
    627575
     
    629577static inline void doFree( void * addr ) with ( heapManager ) {
    630578        #ifdef __CFA_DEBUG__
    631         if ( unlikely( heapManager.heapBegin == 0 ) ) {
     579        if ( unlikely( heapManager.heapBegin == 0p ) ) {
    632580                abort( "doFree( %p ) : internal error, called before heap is initialized.", addr );
    633581        } // if
     
    675623                char helpText[BufferSize];
    676624                int len = snprintf( helpText, sizeof(helpText), "Free( %p ) size:%zu\n", addr, size );
    677                 __cfaabi_dbg_bits_write( helpText, len );
     625                __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug
    678626        } // if
    679627        #endif // __CFA_DEBUG__
     
    681629
    682630
    683 size_t checkFree( HeapManager & manager ) with ( manager ) {
     631size_t prtFree( HeapManager & manager ) with ( manager ) {
    684632        size_t total = 0;
    685633        #ifdef __STATISTICS__
    686         __cfaabi_dbg_bits_acquire();
    687         __cfaabi_dbg_bits_print_nolock( "\nBin lists (bin size : free blocks on list)\n" );
     634        __cfaabi_bits_acquire();
     635        __cfaabi_bits_print_nolock( STDERR_FILENO, "\nBin lists (bin size : free blocks on list)\n" );
    688636        #endif // __STATISTICS__
    689637        for ( unsigned int i = 0; i < maxBucketsUsed; i += 1 ) {
     
    694642
    695643                #if defined( SPINLOCK )
    696                 for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0; p = p->header.kind.real.next ) {
     644                for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0p; p = p->header.kind.real.next ) {
    697645                #else
    698                 for ( HeapManager.Storage * p = freeLists[i].freeList.top(); p != 0; p = p->header.kind.real.next.top ) {
     646                for ( HeapManager.Storage * p = freeLists[i].freeList.top(); p != 0p; p = p->header.kind.real.next.top ) {
    699647                #endif // SPINLOCK
    700648                        total += size;
     
    705653
    706654                #ifdef __STATISTICS__
    707                 __cfaabi_dbg_bits_print_nolock( "%7zu, %-7u  ", size, N );
    708                 if ( (i + 1) % 8 == 0 ) __cfaabi_dbg_bits_print_nolock( "\n" );
     655                __cfaabi_bits_print_nolock( STDERR_FILENO, "%7zu, %-7u  ", size, N );
     656                if ( (i + 1) % 8 == 0 ) __cfaabi_bits_print_nolock( STDERR_FILENO, "\n" );
    709657                #endif // __STATISTICS__
    710658        } // for
    711659        #ifdef __STATISTICS__
    712         __cfaabi_dbg_bits_print_nolock( "\ntotal free blocks:%zu\n", total );
    713         __cfaabi_dbg_bits_release();
     660        __cfaabi_bits_print_nolock( STDERR_FILENO, "\ntotal free blocks:%zu\n", total );
     661        __cfaabi_bits_release();
    714662        #endif // __STATISTICS__
    715663        return (char *)heapEnd - (char *)heapBegin - total;
    716 } // checkFree
     664} // prtFree
     665
     666
     667static void ?{}( HeapManager & manager ) with ( manager ) {
     668        pageSize = sysconf( _SC_PAGESIZE );
     669
     670        for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists
     671                freeLists[i].blockSize = bucketSizes[i];
     672        } // for
     673
     674        #ifdef FASTLOOKUP
     675        unsigned int idx = 0;
     676        for ( unsigned int i = 0; i < LookupSizes; i += 1 ) {
     677                if ( i > bucketSizes[idx] ) idx += 1;
     678                lookup[i] = idx;
     679        } // for
     680        #endif // FASTLOOKUP
     681
     682        if ( setMmapStart( default_mmap_start() ) ) {
     683                abort( "HeapManager : internal error, mmap start initialization failure." );
     684        } // if
     685        heapExpand = default_heap_expansion();
     686
     687        char * end = (char *)sbrk( 0 );
     688        sbrk( (char *)libCeiling( (long unsigned int)end, libAlign() ) - end ); // move start of heap to multiple of alignment
     689        heapBegin = heapEnd = sbrk( 0 );                                        // get new start point
     690} // HeapManager
     691
     692
     693static void ^?{}( HeapManager & ) {
     694        #ifdef __STATISTICS__
     695        if ( traceHeapTerm() ) {
     696                printStats();
     697                // if ( prtfree() ) prtFree( heapManager, true );
     698        } // if
     699        #endif // __STATISTICS__
     700} // ~HeapManager
     701
     702
     703static void memory_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_MEMORY ) ));
     704void memory_startup( void ) {
     705        #ifdef __CFA_DEBUG__
     706        if ( unlikely( heapBoot ) ) {                                           // check for recursion during system boot
     707                // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT.
     708                abort( "boot() : internal error, recursively invoked during system boot." );
     709        } // if
     710        heapBoot = true;
     711        #endif // __CFA_DEBUG__
     712
     713        //assert( heapManager.heapBegin != 0 );
     714        //heapManager{};
     715        if ( heapManager.heapBegin == 0p ) heapManager{};
     716} // memory_startup
     717
     718static void memory_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_MEMORY ) ));
     719void memory_shutdown( void ) {
     720        ^heapManager{};
     721} // memory_shutdown
    717722
    718723
    719724static inline void * mallocNoStats( size_t size ) {             // necessary for malloc statistics
    720725        //assert( heapManager.heapBegin != 0 );
    721         if ( unlikely( heapManager.heapBegin == 0 ) ) heapManager{}; // called before memory_startup ?
    722         void * area = doMalloc( size );
    723         if ( unlikely( area == 0 ) ) errno = ENOMEM;            // POSIX
    724         return area;
     726        if ( unlikely( heapManager.heapBegin == 0p ) ) heapManager{}; // called before memory_startup ?
     727        void * addr = doMalloc( size );
     728        if ( unlikely( addr == 0p ) ) errno = ENOMEM;           // POSIX
     729        return addr;
    725730} // mallocNoStats
     731
     732
     733static inline void * callocNoStats( size_t noOfElems, size_t elemSize ) {
     734        size_t size = noOfElems * elemSize;
     735        char * addr = (char *)mallocNoStats( size );
     736  if ( unlikely( addr == 0p ) ) return 0p;
     737
     738        HeapManager.Storage.Header * header;
     739        HeapManager.FreeHeader * freeElem;
     740        size_t bsize, alignment;
     741        bool mapped __attribute__(( unused )) = headers( "calloc", addr, header, freeElem, bsize, alignment );
     742        #ifndef __CFA_DEBUG__
     743        // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
     744        if ( ! mapped )
     745        #endif // __CFA_DEBUG__
     746                // Zero entire data space even when > than size => realloc without a new allocation and zero fill works.
     747                // <-------00000000000000000000000000000000000000000000000000000> bsize (bucket size)
     748                // `-header`-addr                      `-size
     749                memset( addr, '\0', bsize - sizeof(HeapManager.Storage) ); // set to zeros
     750
     751        header->kind.real.blockSize |= 2;                                       // mark as zero filled
     752        return addr;
     753} // callocNoStats
    726754
    727755
     
    743771        // subtract libAlign() because it is already the minimum alignment
    744772        // add sizeof(Storage) for fake header
    745         // #comment TD : this is the only place that calls doMalloc without calling mallocNoStats, why ?
    746         char * area = (char *)doMalloc( size + alignment - libAlign() + sizeof(HeapManager.Storage) );
    747   if ( unlikely( area == 0 ) ) return area;
     773        char * addr = (char *)mallocNoStats( size + alignment - libAlign() + sizeof(HeapManager.Storage) );
     774  if ( unlikely( addr == 0p ) ) return addr;
    748775
    749776        // address in the block of the "next" alignment address
    750         char * user = (char *)libCeiling( (uintptr_t)(area + sizeof(HeapManager.Storage)), alignment );
     777        char * user = (char *)libCeiling( (uintptr_t)(addr + sizeof(HeapManager.Storage)), alignment );
    751778
    752779        // address of header from malloc
    753         HeapManager.Storage.Header * realHeader = headerAddr( area );
     780        HeapManager.Storage.Header * realHeader = headerAddr( addr );
    754781        // address of fake header * before* the alignment location
    755782        HeapManager.Storage.Header * fakeHeader = headerAddr( user );
     
    761788        return user;
    762789} // memalignNoStats
     790
     791
     792static inline void * cmemalignNoStats( size_t alignment, size_t noOfElems, size_t elemSize ) {
     793        size_t size = noOfElems * elemSize;
     794        char * addr = (char *)memalignNoStats( alignment, size );
     795  if ( unlikely( addr == 0p ) ) return 0p;
     796        HeapManager.Storage.Header * header;
     797        HeapManager.FreeHeader * freeElem;
     798        size_t bsize;
     799        bool mapped __attribute__(( unused )) = headers( "cmemalign", addr, header, freeElem, bsize, alignment );
     800        #ifndef __CFA_DEBUG__
     801        // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
     802        if ( ! mapped )
     803        #endif // __CFA_DEBUG__
     804                memset( addr, '\0', dataStorage( bsize, addr, header ) ); // set to zeros
     805        header->kind.real.blockSize |= 2;                               // mark as zero filled
     806
     807        return addr;
     808} // cmemalignNoStats
    763809
    764810
     
    774820extern "C" {
    775821        // The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not
    776         // initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be
     822        // initialized. If size is 0, then malloc() returns either 0p, or a unique pointer value that can later be
    777823        // successfully passed to free().
    778824        void * malloc( size_t size ) {
     
    786832
    787833        // The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to
    788         // the allocated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either NULL, or a
     834        // the allocated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either 0p, or a
    789835        // unique pointer value that can later be successfully passed to free().
    790836        void * calloc( size_t noOfElems, size_t elemSize ) {
    791                 size_t size = noOfElems * elemSize;
    792837                #ifdef __STATISTICS__
    793838                __atomic_add_fetch( &calloc_calls, 1, __ATOMIC_SEQ_CST );
    794                 __atomic_add_fetch( &calloc_storage, size, __ATOMIC_SEQ_CST );
    795                 #endif // __STATISTICS__
    796 
    797                 char * area = (char *)mallocNoStats( size );
    798           if ( unlikely( area == 0 ) ) return 0;
     839                __atomic_add_fetch( &calloc_storage, noOfElems * elemSize, __ATOMIC_SEQ_CST );
     840                #endif // __STATISTICS__
     841
     842                return callocNoStats( noOfElems, elemSize );
     843        } // calloc
     844
     845        // The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be
     846        // unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size
     847        // is larger than the old size, the added memory will not be initialized.  If ptr is 0p, then the call is
     848        // equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not 0p, then the call
     849        // is equivalent to free(ptr). Unless ptr is 0p, it must have been returned by an earlier call to malloc(),
     850        // calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
     851        void * realloc( void * oaddr, size_t size ) {
     852                #ifdef __STATISTICS__
     853                __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     854                #endif // __STATISTICS__
     855
     856                // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     857          if ( unlikely( size == 0 ) ) { free( oaddr ); return mallocNoStats( size ); } // special cases
     858          if ( unlikely( oaddr == 0p ) ) return mallocNoStats( size );
    799859
    800860                HeapManager.Storage.Header * header;
    801861                HeapManager.FreeHeader * freeElem;
    802                 size_t asize, alignment;
    803                 bool mapped __attribute__(( unused )) = headers( "calloc", area, header, freeElem, asize, alignment );
    804                 #ifndef __CFA_DEBUG__
    805                 // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    806                 if ( ! mapped )
    807                 #endif // __CFA_DEBUG__
    808                         memset( area, '\0', asize - sizeof(HeapManager.Storage) ); // set to zeros
    809 
    810                 header->kind.real.blockSize |= 2;                               // mark as zero filled
    811                 return area;
    812         } // calloc
    813 
    814         // #comment TD : Document this function
    815         void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ) {
    816                 size_t size = noOfElems * elemSize;
    817                 #ifdef __STATISTICS__
    818                 __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
    819                 __atomic_add_fetch( &cmemalign_storage, size, __ATOMIC_SEQ_CST );
    820                 #endif // __STATISTICS__
    821 
    822                 char * area = (char *)memalignNoStats( alignment, size );
    823           if ( unlikely( area == 0 ) ) return 0;
    824                 HeapManager.Storage.Header * header;
    825                 HeapManager.FreeHeader * freeElem;
    826                 size_t asize;
    827                 bool mapped __attribute__(( unused )) = headers( "cmemalign", area, header, freeElem, asize, alignment );
    828                 #ifndef __CFA_DEBUG__
    829                 // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    830                 if ( ! mapped )
    831                         #endif // __CFA_DEBUG__
    832                         memset( area, '\0', asize - ( (char *)area - (char *)header ) ); // set to zeros
    833                 header->kind.real.blockSize |= 2;                               // mark as zero filled
    834 
    835                 return area;
    836         } // cmemalign
    837 
    838         // The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be
    839         // unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size
    840         // is larger than the old size, the added memory will not be initialized.  If ptr is NULL, then the call is
    841         // equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call
    842         // is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an earlier call to malloc(),
    843         // calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
    844         void * realloc( void * addr, size_t size ) {
    845                 #ifdef __STATISTICS__
    846                 __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
    847                 #endif // __STATISTICS__
    848 
    849           if ( unlikely( addr == 0 ) ) return mallocNoStats( size ); // special cases
    850           if ( unlikely( size == 0 ) ) { free( addr ); return 0; }
    851 
    852                 HeapManager.Storage.Header * header;
    853                 HeapManager.FreeHeader * freeElem;
    854                 size_t asize, alignment = 0;
    855                 headers( "realloc", addr, header, freeElem, asize, alignment );
    856 
    857                 size_t usize = asize - ( (char *)addr - (char *)header ); // compute the amount of user storage in the block
    858                 if ( usize >= size ) {                                                  // already sufficient storage
     862                size_t bsize, oalign = 0;
     863                headers( "realloc", oaddr, header, freeElem, bsize, oalign );
     864
     865                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     866          if ( size <= odsize && odsize <= size * 2 ) { // allow up to 50% wasted storage in smaller size
     867                        // Do not know size of original allocation => cannot do 0 fill for any additional space because do not know
     868                        // where to start filling, i.e., do not overwrite existing values in space.
     869                        //
    859870                        // This case does not result in a new profiler entry because the previous one still exists and it must match with
    860871                        // the free for this memory.  Hence, this realloc does not appear in the profiler output.
    861                         return addr;
     872                        return oaddr;
    862873                } // if
    863874
     
    866877                #endif // __STATISTICS__
    867878
    868                 void * area;
    869                 if ( unlikely( alignment != 0 ) ) {                             // previous request memalign?
    870                         area = memalign( alignment, size );                     // create new aligned area
     879                // change size and copy old content to new storage
     880
     881                void * naddr;
     882                if ( unlikely( oalign != 0 ) ) {                                // previous request memalign?
     883                        if ( unlikely( header->kind.real.blockSize & 2 ) ) { // previous request zero fill
     884                                naddr = cmemalignNoStats( oalign, 1, size ); // create new aligned area
     885                        } else {
     886                                naddr = memalignNoStats( oalign, size ); // create new aligned area
     887                        } // if
    871888                } else {
    872                         area = mallocNoStats( size );                           // create new area
     889                        if ( unlikely( header->kind.real.blockSize & 2 ) ) { // previous request zero fill
     890                                naddr = callocNoStats( 1, size );               // create new area
     891                        } else {
     892                                naddr = mallocNoStats( size );                  // create new area
     893                        } // if
    873894                } // if
    874           if ( unlikely( area == 0 ) ) return 0;
    875                 if ( unlikely( header->kind.real.blockSize & 2 ) ) { // previous request zero fill (calloc/cmemalign) ?
    876                         assert( (header->kind.real.blockSize & 1) == 0 );
    877                         bool mapped __attribute__(( unused )) = headers( "realloc", area, header, freeElem, asize, alignment );
    878                         #ifndef __CFA_DEBUG__
    879                         // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    880                         if ( ! mapped )
    881                         #endif // __CFA_DEBUG__
    882                                 memset( (char *)area + usize, '\0', asize - ( (char *)area - (char *)header ) - usize ); // zero-fill back part
    883                         header->kind.real.blockSize |= 2;                       // mark new request as zero fill
    884                 } // if
    885                 memcpy( area, addr, usize );                                    // copy bytes
    886                 free( addr );
    887                 return area;
     895          if ( unlikely( naddr == 0p ) ) return 0p;
     896
     897                headers( "realloc", naddr, header, freeElem, bsize, oalign );
     898                size_t ndsize = dataStorage( bsize, naddr, header ); // data storage avilable in bucket
     899                // To preserve prior fill, the entire bucket must be copied versus the size.
     900                memcpy( naddr, oaddr, MIN( odsize, ndsize ) );  // copy bytes
     901                free( oaddr );
     902                return naddr;
    888903        } // realloc
    889 
    890904
    891905        // The obsolete function memalign() allocates size bytes and returns a pointer to the allocated memory. The memory
     
    897911                #endif // __STATISTICS__
    898912
    899                 void * area = memalignNoStats( alignment, size );
    900 
    901                 return area;
     913                return memalignNoStats( alignment, size );
    902914        } // memalign
     915
     916
     917        // The cmemalign() function is the same as calloc() with memory alignment.
     918        void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ) {
     919                #ifdef __STATISTICS__
     920                __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
     921                __atomic_add_fetch( &cmemalign_storage, noOfElems * elemSize, __ATOMIC_SEQ_CST );
     922                #endif // __STATISTICS__
     923
     924                return cmemalignNoStats( alignment, noOfElems, elemSize );
     925        } // cmemalign
    903926
    904927        // The function aligned_alloc() is the same as memalign(), except for the added restriction that size should be a
     
    911934        // The function posix_memalign() allocates size bytes and places the address of the allocated memory in *memptr. The
    912935        // address of the allocated memory will be a multiple of alignment, which must be a power of two and a multiple of
    913         // sizeof(void *). If size is 0, then posix_memalign() returns either NULL, or a unique pointer value that can later
     936        // sizeof(void *). If size is 0, then posix_memalign() returns either 0p, or a unique pointer value that can later
    914937        // be successfully passed to free(3).
    915938        int posix_memalign( void ** memptr, size_t alignment, size_t size ) {
    916939          if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) return EINVAL; // check alignment
    917940                * memptr = memalign( alignment, size );
    918           if ( unlikely( * memptr == 0 ) ) return ENOMEM;
     941          if ( unlikely( * memptr == 0p ) ) return ENOMEM;
    919942                return 0;
    920943        } // posix_memalign
     
    929952        // The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to
    930953        // malloc(), calloc() or realloc().  Otherwise, or if free(ptr) has already been called before, undefined behavior
    931         // occurs. If ptr is NULL, no operation is performed.
     954        // occurs. If ptr is 0p, no operation is performed.
    932955        void free( void * addr ) {
    933956                #ifdef __STATISTICS__
     
    935958                #endif // __STATISTICS__
    936959
    937                 // #comment TD : To decrease nesting I would but the special case in the
    938                 //               else instead, plus it reads more naturally to have the
    939                 //               short / normal case instead
    940                 if ( unlikely( addr == 0 ) ) {                                  // special case
    941                         #ifdef __CFA_DEBUG__
    942                         if ( traceHeap() ) {
    943                                 #define nullmsg "Free( 0x0 ) size:0\n"
    944                                 // Do not debug print free( 0 ), as it can cause recursive entry from sprintf.
    945                                 __cfaabi_dbg_bits_write( nullmsg, sizeof(nullmsg) - 1 );
    946                         } // if
    947                         #endif // __CFA_DEBUG__
     960          if ( unlikely( addr == 0p ) ) {                                       // special case
     961                        // #ifdef __CFA_DEBUG__
     962                        // if ( traceHeap() ) {
     963                        //      #define nullmsg "Free( 0x0 ) size:0\n"
     964                        //      // Do not debug print free( 0p ), as it can cause recursive entry from sprintf.
     965                        //      __cfaabi_dbg_write( nullmsg, sizeof(nullmsg) - 1 );
     966                        // } // if
     967                        // #endif // __CFA_DEBUG__
    948968                        return;
    949969                } // exit
     
    951971                doFree( addr );
    952972        } // free
     973
     974
     975        // The malloc_alignment() function returns the alignment of the allocation.
     976        size_t malloc_alignment( void * addr ) {
     977          if ( unlikely( addr == 0p ) ) return libAlign();      // minimum alignment
     978                HeapManager.Storage.Header * header = headerAddr( addr );
     979                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     980                        return header->kind.fake.alignment & -2;        // remove flag from value
     981                } else {
     982                        return libAlign ();                                                     // minimum alignment
     983                } // if
     984        } // malloc_alignment
     985
     986
     987        // The malloc_zero_fill() function returns true if the allocation is zero filled, i.e., initially allocated by calloc().
     988        bool malloc_zero_fill( void * addr ) {
     989          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     990                HeapManager.Storage.Header * header = headerAddr( addr );
     991                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     992                        header = (HeapManager.Storage.Header *)((char *)header - header->kind.fake.offset);
     993                } // if
     994                return (header->kind.real.blockSize & 2) != 0;  // zero filled (calloc/cmemalign) ?
     995        } // malloc_zero_fill
     996
     997
     998        // The malloc_usable_size() function returns the number of usable bytes in the block pointed to by ptr, a pointer to
     999        // a block of memory allocated by malloc(3) or a related function.
     1000        size_t malloc_usable_size( void * addr ) {
     1001          if ( unlikely( addr == 0p ) ) return 0;                       // null allocation has 0 size
     1002                HeapManager.Storage.Header * header;
     1003                HeapManager.FreeHeader * freeElem;
     1004                size_t bsize, alignment;
     1005
     1006                headers( "malloc_usable_size", addr, header, freeElem, bsize, alignment );
     1007                return dataStorage( bsize, addr, header );      // data storage in bucket
     1008        } // malloc_usable_size
     1009
     1010
     1011        // The malloc_stats() function prints (on default standard error) statistics about memory allocated by malloc(3) and
     1012        // related functions.
     1013        void malloc_stats( void ) {
     1014                #ifdef __STATISTICS__
     1015                printStats();
     1016                if ( prtFree() ) prtFree( heapManager );
     1017                #endif // __STATISTICS__
     1018        } // malloc_stats
     1019
     1020        // The malloc_stats_fd() function changes the file descripter where malloc_stats() writes the statistics.
     1021        int malloc_stats_fd( int fd __attribute__(( unused )) ) {
     1022                #ifdef __STATISTICS__
     1023                int temp = statfd;
     1024                statfd = fd;
     1025                return temp;
     1026                #else
     1027                return -1;
     1028                #endif // __STATISTICS__
     1029        } // malloc_stats_fd
     1030
    9531031
    9541032        // The mallopt() function adjusts parameters that control the behavior of the memory-allocation functions (see
     
    9581036                choose( option ) {
    9591037                  case M_TOP_PAD:
    960                         if ( setHeapExpand( value ) ) fallthru default;
     1038                        if ( setHeapExpand( value ) ) return 1;
    9611039                  case M_MMAP_THRESHOLD:
    962                         if ( setMmapStart( value ) ) fallthru default;
    963                   default:
    964                         // #comment TD : 1 for unsopported feels wrong
    965                         return 1;                                                                       // success, or unsupported
     1040                        if ( setMmapStart( value ) ) return 1;
    9661041                } // switch
    967                 return 0;                                                                               // error
     1042                return 0;                                                                               // error, unsupported
    9681043        } // mallopt
    9691044
     
    9741049        } // malloc_trim
    9751050
    976         // The malloc_usable_size() function returns the number of usable bytes in the block pointed to by ptr, a pointer to
    977         // a block of memory allocated by malloc(3) or a related function.
    978         size_t malloc_usable_size( void * addr ) {
    979           if ( unlikely( addr == 0 ) ) return 0;                        // null allocation has 0 size
    980 
    981                 HeapManager.Storage.Header * header;
    982                 HeapManager.FreeHeader * freeElem;
    983                 size_t size, alignment;
    984 
    985                 headers( "malloc_usable_size", addr, header, freeElem, size, alignment );
    986                 size_t usize = size - ( (char *)addr - (char *)header ); // compute the amount of user storage in the block
    987                 return usize;
    988         } // malloc_usable_size
    989 
    990 
    991     // The malloc_alignment() function returns the alignment of the allocation.
    992         size_t malloc_alignment( void * addr ) {
    993           if ( unlikely( addr == 0 ) ) return libAlign();       // minimum alignment
    994                 HeapManager.Storage.Header * header = (HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) );
    995                 if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
    996                         return header->kind.fake.alignment & -2;        // remove flag from value
    997                 } else {
    998                         return libAlign ();                                                     // minimum alignment
    999                 } // if
    1000         } // malloc_alignment
    1001 
    1002 
    1003     // The malloc_zero_fill() function returns true if the allocation is zero filled, i.e., initially allocated by calloc().
    1004         bool malloc_zero_fill( void * addr ) {
    1005           if ( unlikely( addr == 0 ) ) return false;            // null allocation is not zero fill
    1006 
    1007                 HeapManager.Storage.Header * header = (HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) );
    1008                 if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
    1009                         header = (HeapManager.Storage.Header *)((char *)header - header->kind.fake.offset);
    1010                 } // if
    1011                 return (header->kind.real.blockSize & 2) != 0;  // zero filled (calloc/cmemalign) ?
    1012         } // malloc_zero_fill
    1013 
    1014 
    1015     // The malloc_stats() function prints (on default standard error) statistics about memory allocated by malloc(3) and
    1016     // related functions.
    1017         void malloc_stats( void ) {
    1018                 #ifdef __STATISTICS__
    1019                 printStats();
    1020                 if ( checkFree() ) checkFree( heapManager );
    1021                 #endif // __STATISTICS__
    1022         } // malloc_stats
    1023 
    1024         // The malloc_stats_fd() function changes the file descripter where malloc_stats() writes the statistics.
    1025         int malloc_stats_fd( int fd ) {
    1026                 #ifdef __STATISTICS__
    1027                 int temp = statfd;
    1028                 statfd = fd;
    1029                 return temp;
    1030                 #else
    1031                 return -1;
    1032                 #endif // __STATISTICS__
    1033         } // malloc_stats_fd
    10341051
    10351052        // The malloc_info() function exports an XML string that describes the current state of the memory-allocation
     
    10371054        // information about all arenas (see malloc(3)).
    10381055        int malloc_info( int options, FILE * stream ) {
     1056                if ( options != 0 ) { errno = EINVAL; return -1; }
    10391057                return printStatsXML( stream );
    10401058        } // malloc_info
     
    10461064        // structure is returned as the function result.  (It is the caller's responsibility to free(3) this memory.)
    10471065        void * malloc_get_state( void ) {
    1048                 return 0;                                                                               // unsupported
     1066                return 0p;                                                                              // unsupported
    10491067        } // malloc_get_state
    10501068
     
    10581076
    10591077
     1078// Must have CFA linkage to overload with C linkage realloc.
     1079void * realloc( void * oaddr, size_t nalign, size_t size ) {
     1080        #ifdef __STATISTICS__
     1081        __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     1082        #endif // __STATISTICS__
     1083
     1084        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     1085  if ( unlikely( size == 0 ) ) { free( oaddr ); return mallocNoStats( size ); } // special cases
     1086  if ( unlikely( oaddr == 0p ) ) return mallocNoStats( size );
     1087
     1088        if ( unlikely( nalign == 0 ) ) nalign = libAlign();     // reset alignment to minimum
     1089        #ifdef __CFA_DEBUG__
     1090        else
     1091                checkAlign( nalign );                                                   // check alignment
     1092        #endif // __CFA_DEBUG__
     1093
     1094        HeapManager.Storage.Header * header;
     1095        HeapManager.FreeHeader * freeElem;
     1096        size_t bsize, oalign = 0;
     1097        headers( "realloc", oaddr, header, freeElem, bsize, oalign );
     1098        size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     1099
     1100  if ( oalign != 0 && (uintptr_t)oaddr % nalign == 0 ) { // has alignment and just happens to work out
     1101                headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
     1102                return realloc( oaddr, size );
     1103        } // if
     1104
     1105        #ifdef __STATISTICS__
     1106        __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
     1107        #endif // __STATISTICS__
     1108
     1109        // change size and copy old content to new storage
     1110
     1111        void * naddr;
     1112        if ( unlikely( header->kind.real.blockSize & 2 ) ) { // previous request zero fill
     1113                naddr = cmemalignNoStats( nalign, 1, size );    // create new aligned area
     1114        } else {
     1115                naddr = memalignNoStats( nalign, size );                // create new aligned area
     1116        } // if
     1117
     1118        headers( "realloc", naddr, header, freeElem, bsize, oalign );
     1119        size_t ndsize = dataStorage( bsize, naddr, header ); // data storage avilable in bucket
     1120        // To preserve prior fill, the entire bucket must be copied versus the size.
     1121        memcpy( naddr, oaddr, MIN( odsize, ndsize ) );          // copy bytes
     1122        free( oaddr );
     1123        return naddr;
     1124} // realloc
     1125
     1126
    10601127// Local Variables: //
    10611128// tab-width: 4 //
  • libcfa/src/interpose.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 14 22:57:16 2019
    13 // Update Count     : 116
     12// Last Modified On : Mon Feb 17 10:18:53 2020
     13// Update Count     : 166
    1414//
    1515
     
    2929#include "bits/signal.hfa"                                                              // sigHandler_?
    3030#include "startup.hfa"                                                                  // STARTUP_PRIORITY_CORE
     31#include <assert.h>
    3132
    3233//=============================================================================================
     
    4041
    4142typedef void (* generic_fptr_t)(void);
    42 generic_fptr_t interpose_symbol( const char * symbol, const char * version ) {
     43generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) {
    4344        const char * error;
    4445
     
    9596        void __cfaabi_interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
    9697        void __cfaabi_interpose_startup( void ) {
    97                 const char *version = NULL;
     98                const char *version = 0p;
    9899
    99100                preload_libgcc();
     
    105106#pragma GCC diagnostic pop
    106107
     108                // As a precaution (and necessity), errors that result in termination are delivered on a separate stack because
     109                // task stacks might be very small (4K) and the signal delivery corrupts memory to the point that a clean
     110                // shutdown is impossible. Also, when a stack overflow encounters the non-accessible sentinel page (debug only)
     111                // and generates a segment fault, the signal cannot be delivered on the sentinel page. Finally, calls to abort
     112                // print a stack trace that uses substantial stack space.
     113
     114                #define MINSTKSZ SIGSTKSZ * 8
     115                static char stack[MINSTKSZ] __attribute__(( aligned (16) ));
     116                static stack_t ss;
     117
     118                ss.ss_sp = stack;
     119                ss.ss_size = MINSTKSZ;
     120                ss.ss_flags = 0;
     121                if ( sigaltstack( &ss, 0p ) == -1 ) {
     122                        abort( "__cfaabi_interpose_startup : internal error, sigaltstack error(%d) %s.", errno, strerror( errno ) );
     123                } // if
     124
    107125                // Failure handler
    108                 __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );
    109                 __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );
    110                 __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO );
    111                 __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO );
    112                 __cfaabi_sigaction( SIGABRT, sigHandler_abrt, SA_SIGINFO | SA_RESETHAND);
    113                 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO );
    114                 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO );
     126                __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     127                __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     128                __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK );
     129                __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK );
     130                __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // one shot handler, return to default
     131                __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     132                __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     133                __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // terminal hangup
    115134        }
    116135}
     
    123142void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    124143void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     144void abort( bool signalAbort, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    125145
    126146extern "C" {
    127147        void abort( void ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
    128                 abort( NULL );
     148                abort( false, "%s", "" );
    129149        }
    130150
     
    132152                va_list argp;
    133153                va_start( argp, fmt );
    134                 abort( fmt, argp );
     154                abort( false, fmt, argp );
    135155                va_end( argp );
    136156        }
     
    141161}
    142162
    143 void * kernel_abort    ( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return NULL; }
    144 void   kernel_abort_msg( void * data, char * buffer, int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     163void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; }
     164void kernel_abort_msg( void * data, char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     165// See concurrency/kernel.cfa for strong definition used in multi-processor mode.
    145166int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
    146167
    147168enum { abort_text_size = 1024 };
    148169static char abort_text[ abort_text_size ];
    149 static int abort_lastframe;
    150 
    151 void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ )) {
    152     va_list args;
    153     va_start( args, fmt );
    154     vfprintf( stderr, fmt, args );
    155     va_end( args );
    156         __cabi_libc.exit( status );
    157 }
    158 
    159 void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
    160         void * kernel_data = kernel_abort();                    // must be done here to lock down kernel
    161         int len;
    162 
    163         abort_lastframe = kernel_abort_lastframe();
    164         len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
    165         __cfaabi_dbg_bits_write( abort_text, len );
    166 
    167         if ( fmt ) {
    168                 va_list args;
    169                 va_start( args, fmt );
    170 
    171                 len = vsnprintf( abort_text, abort_text_size, fmt, args );
    172                 va_end( args );
    173                 __cfaabi_dbg_bits_write( abort_text, len );
    174 
    175                 if ( fmt[strlen( fmt ) - 1] != '\n' ) {         // add optional newline if missing at the end of the format text
    176                         __cfaabi_dbg_bits_write( "\n", 1 );
    177                 }
    178         }
    179 
    180         kernel_abort_msg( kernel_data, abort_text, abort_text_size );
    181         __cabi_libc.abort();
    182 }
    183 
    184 static void __cfaabi_backtrace() {
    185         enum {
    186                 Frames = 50,                                                                    // maximum number of stack frames
    187                 Start = 8,                                                                              // skip first N stack frames
    188         };
     170
     171static void __cfaabi_backtrace( int start ) {
     172        enum { Frames = 50, };                                                          // maximum number of stack frames
     173        int last = kernel_abort_lastframe();                            // skip last N stack frames
    189174
    190175        void * array[Frames];
    191176        size_t size = backtrace( array, Frames );
    192         char ** messages = backtrace_symbols( array, size );
    193 
    194         // find executable name
    195         *index( messages[0], '(' ) = '\0';
    196         __cfaabi_dbg_bits_print_nolock( "Stack back trace for: %s\n", messages[0]);
    197 
    198         for ( int i = Start; i < size - abort_lastframe && messages != NULL; i += 1 ) {
    199                 char * name = NULL, * offset_begin = NULL, * offset_end = NULL;
    200 
    201                 for ( char * p = messages[i]; *p; ++p ) {
    202                         //__cfaabi_dbg_bits_print_nolock( "X %s\n", p);
    203                         // find parantheses and +offset
     177        char ** messages = backtrace_symbols( array, size ); // does not demangle names
     178
     179        *index( messages[0], '(' ) = '\0';                                      // find executable name
     180        __cfaabi_bits_print_nolock( STDERR_FILENO, "Stack back trace for: %s\n", messages[0]);
     181
     182        for ( unsigned int i = start; i < size - last && messages != 0p; i += 1 ) {
     183                char * name = 0p, * offset_begin = 0p, * offset_end = 0p;
     184
     185                for ( char * p = messages[i]; *p; p += 1 ) {    // find parantheses and +offset
     186                        //__cfaabi_bits_print_nolock( "X %s\n", p);
    204187                        if ( *p == '(' ) {
    205188                                name = p;
     
    212195                }
    213196
    214                 // if line contains symbol print it
    215                 int frameNo = i - Start;
     197                // if line contains symbol, print it
     198                int frameNo = i - start;
    216199                if ( name && offset_begin && offset_end && name < offset_begin ) {
    217                         // delimit strings
    218                         *name++ = '\0';
     200                        *name++ = '\0';                                                         // delimit strings
    219201                        *offset_begin++ = '\0';
    220202                        *offset_end++ = '\0';
    221203
    222                         __cfaabi_dbg_bits_print_nolock( "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
     204                        __cfaabi_bits_print_nolock( STDERR_FILENO, "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
    223205                } else {                                                                                // otherwise, print the whole line
    224                         __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] );
     206                        __cfaabi_bits_print_nolock( STDERR_FILENO, "(%i) %s\n", frameNo, messages[i] );
    225207                }
    226208        }
     
    228210}
    229211
     212void exit( int status, const char fmt[], ... ) {
     213        va_list args;
     214        va_start( args, fmt );
     215        vfprintf( stderr, fmt, args );
     216        va_end( args );
     217        __cabi_libc.exit( status );
     218}
     219
     220void abort( bool signalAbort, const char fmt[], ... ) {
     221        void * kernel_data = kernel_abort();                            // must be done here to lock down kernel
     222        int len;
     223
     224        signal( SIGABRT, SIG_DFL );                                                     // prevent final "real" abort from recursing to handler
     225
     226        len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
     227        __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     228
     229        assert( fmt );
     230        va_list args;
     231        va_start( args, fmt );
     232
     233        len = vsnprintf( abort_text, abort_text_size, fmt, args );
     234        va_end( args );
     235        __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     236
     237        if ( fmt[strlen( fmt ) - 1] != '\n' ) {                         // add optional newline if missing at the end of the format text
     238                __cfaabi_dbg_write( "\n", 1 );
     239        } // if
     240        kernel_abort_msg( kernel_data, abort_text, abort_text_size );
     241
     242        __cfaabi_backtrace( signalAbort ? 4 : 2 );
     243
     244        __cabi_libc.abort();                                                            // print stack trace in handler
     245}
     246
     247void abort( const char fmt[], ... ) {
     248        va_list args;
     249        va_start( args, fmt );
     250        abort( false, fmt, args );
     251        va_end( args );
     252}
     253
    230254void sigHandler_segv( __CFA_SIGPARMS__ ) {
    231         abort( "Addressing invalid memory at location %p\n"
    232                         "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript.\n",
    233                         sfp->si_addr );
     255                if ( sfp->si_addr == 0p ) {
     256                        abort( true, "Null pointer (0p) dereference.\n" );
     257                } else {
     258                        abort( true, "%s at memory location %p.\n"
     259                                   "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript.\n",
     260                                   (sig == SIGSEGV ? "Segment fault" : "Bus error"), sfp->si_addr );
     261                }
    234262}
    235263
    236264void sigHandler_ill( __CFA_SIGPARMS__ ) {
    237         abort( "Executing illegal instruction at location %p.\n"
     265        abort( true, "Executing illegal instruction at location %p.\n"
    238266                        "Possible cause is stack corruption.\n",
    239267                        sfp->si_addr );
     
    251279          default: msg = "unknown";
    252280        } // choose
    253         abort( "Computation error %s at location %p.\n", msg, sfp->si_addr );
    254 }
    255 
    256 void sigHandler_abrt( __CFA_SIGPARMS__ ) {
    257         __cfaabi_backtrace();
    258 
    259         // reset default signal handler
    260         __cfaabi_sigdefault( SIGABRT );
    261 
    262         raise( SIGABRT );
     281        abort( true, "Computation error %s at location %p.\n", msg, sfp->si_addr );
    263282}
    264283
    265284void sigHandler_term( __CFA_SIGPARMS__ ) {
    266         abort( "Application stopped by %s signal.", sig == SIGINT ? "an interrupt (SIGINT)" : "a terminate (SIGTERM)" );
     285        abort( true, "Application interrupted by signal: %s.\n", strsignal( sig ) );
    267286}
    268287
  • libcfa/src/iostream.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 08:07:59 2019
    13 // Update Count     : 821
     12// Last Modified On : Thu Feb 20 15:53:23 2020
     13// Update Count     : 829
    1414//
    1515
     
    1919#include <stdio.h>
    2020#include <stdbool.h>                                                                    // true/false
     21#include <stdint.h>                                                                             // UINT64_MAX
    2122//#include <string.h>                                                                   // strlen, strcmp
    2223extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
     
    3536forall( dtype ostype | ostream( ostype ) ) {
    3637        ostype & ?|?( ostype & os, zero_t ) {
    37                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     38                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    3839                fmt( os, "%d", 0n );
    3940                return os;
     
    4445
    4546        ostype & ?|?( ostype & os, one_t ) {
    46                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     47                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    4748                fmt( os, "%d", 1n );
    4849                return os;
     
    5354
    5455        ostype & ?|?( ostype & os, bool b ) {
    55                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     56                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    5657                fmt( os, "%s", b ? "true" : "false" );
    5758                return os;
     
    6364        ostype & ?|?( ostype & os, char c ) {
    6465                fmt( os, "%c", c );
    65                 if ( c == '\n' ) setNL( os, true );
     66                if ( c == '\n' ) $setNL( os, true );
    6667                return sepOff( os );
    6768        } // ?|?
     
    7172
    7273        ostype & ?|?( ostype & os, signed char sc ) {
    73                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     74                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    7475                fmt( os, "%hhd", sc );
    7576                return os;
     
    8081
    8182        ostype & ?|?( ostype & os, unsigned char usc ) {
    82                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     83                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    8384                fmt( os, "%hhu", usc );
    8485                return os;
     
    8990
    9091        ostype & ?|?( ostype & os, short int si ) {
    91                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     92                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    9293                fmt( os, "%hd", si );
    9394                return os;
     
    9899
    99100        ostype & ?|?( ostype & os, unsigned short int usi ) {
    100                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     101                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    101102                fmt( os, "%hu", usi );
    102103                return os;
     
    107108
    108109        ostype & ?|?( ostype & os, int i ) {
    109                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     110                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    110111                fmt( os, "%d", i );
    111112                return os;
     
    116117
    117118        ostype & ?|?( ostype & os, unsigned int ui ) {
    118                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     119                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    119120                fmt( os, "%u", ui );
    120121                return os;
     
    125126
    126127        ostype & ?|?( ostype & os, long int li ) {
    127                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     128                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    128129                fmt( os, "%ld", li );
    129130                return os;
     
    134135
    135136        ostype & ?|?( ostype & os, unsigned long int uli ) {
    136                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     137                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    137138                fmt( os, "%lu", uli );
    138139                return os;
     
    143144
    144145        ostype & ?|?( ostype & os, long long int lli ) {
    145                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     146                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    146147                fmt( os, "%lld", lli );
    147148                return os;
     
    152153
    153154        ostype & ?|?( ostype & os, unsigned long long int ulli ) {
    154                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     155                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    155156                fmt( os, "%llu", ulli );
    156157                return os;
     
    159160                (ostype &)(os | ulli); ends( os );
    160161        } // ?|?
     162
     163#if defined( __SIZEOF_INT128__ )
     164        //      UINT64_MAX 18_446_744_073_709_551_615_ULL
     165        #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
     166
     167        static void base10_128( ostype & os, unsigned int128 val ) {
     168                if ( val > UINT64_MAX ) {
     169                        base10_128( os, val / P10_UINT64 );                     // recursive
     170                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     171                } else {
     172                        fmt( os, "%lu", (uint64_t)val );
     173                } // if
     174        } // base10_128
     175
     176        static void base10_128( ostype & os, int128 val ) {
     177                if ( val < 0 ) {
     178                        fmt( os, "-" );                                                         // leading negative sign
     179                        val = -val;
     180                } // if
     181                base10_128( os, (unsigned int128)val );                 // print zero/positive value
     182        } // base10_128
     183
     184        ostype & ?|?( ostype & os, int128 llli ) {
     185                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     186                base10_128( os, llli );
     187                return os;
     188        } // ?|?
     189        void & ?|?( ostype & os, int128 llli ) {
     190                (ostype &)(os | llli); ends( os );
     191        } // ?|?
     192
     193        ostype & ?|?( ostype & os, unsigned int128 ullli ) {
     194                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     195                base10_128( os, ullli );
     196                return os;
     197        } // ?|?
     198        void & ?|?( ostype & os, unsigned int128 ullli ) {
     199                (ostype &)(os | ullli); ends( os );
     200        } // ?|?
     201#endif // __SIZEOF_INT128__
    161202
    162203        #define PrintWithDP( os, format, val, ... ) \
     
    175216
    176217        ostype & ?|?( ostype & os, float f ) {
    177                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     218                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    178219                PrintWithDP( os, "%g", f );
    179220                return os;
     
    184225
    185226        ostype & ?|?( ostype & os, double d ) {
    186                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     227                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    187228                PrintWithDP( os, "%.*lg", d, DBL_DIG );
    188229                return os;
     
    193234
    194235        ostype & ?|?( ostype & os, long double ld ) {
    195                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     236                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    196237                PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    197238                return os;
     
    202243
    203244        ostype & ?|?( ostype & os, float _Complex fc ) {
    204                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     245                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    205246//              os | crealf( fc ) | nonl;
    206247                PrintWithDP( os, "%g", crealf( fc ) );
     
    214255
    215256        ostype & ?|?( ostype & os, double _Complex dc ) {
    216                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     257                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    217258//              os | creal( dc ) | nonl;
    218259                PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
     
    226267
    227268        ostype & ?|?( ostype & os, long double _Complex ldc ) {
    228                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     269                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    229270//              os | creall( ldc ) || nonl;
    230271                PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
     
    237278        } // ?|?
    238279
    239         ostype & ?|?( ostype & os, const char * str ) {
     280        ostype & ?|?( ostype & os, const char str[] ) {
    240281                enum { Open = 1, Close, OpenClose };
    241282                static const unsigned char mask[256] @= {
     
    257298                // first character IS NOT spacing or closing punctuation => add left separator
    258299                unsigned char ch = str[0];                                              // must make unsigned
    259                 if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
    260                         fmt( os, "%s", sepGetCur( os ) );
     300                if ( $sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
     301                        fmt( os, "%s", $sepGetCur( os ) );
    261302                } // if
    262303
    263304                // if string starts line, must reset to determine open state because separator is off
    264                 sepReset( os );                                                                 // reset separator
     305                $sepReset( os );                                                                // reset separator
    265306
    266307                // last character IS spacing or opening punctuation => turn off separator for next item
    267308                size_t len = strlen( str );
    268309                ch = str[len - 1];                                                              // must make unsigned
    269                 if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     310                if ( $sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    270311                        sepOn( os );
    271312                } else {
    272313                        sepOff( os );
    273314                } // if
    274                 if ( ch == '\n' ) setNL( os, true );                    // check *AFTER* sepPrt call above as it resets NL flag
     315                if ( ch == '\n' ) $setNL( os, true );                   // check *AFTER* $sepPrt call above as it resets NL flag
    275316                return write( os, str, len );
    276317        } // ?|?
    277         void ?|?( ostype & os, const char * str ) {
     318
     319        void ?|?( ostype & os, const char str[] ) {
    278320                (ostype &)(os | str); ends( os );
    279321        } // ?|?
    280322
    281323//      ostype & ?|?( ostype & os, const char16_t * str ) {
    282 //              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     324//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    283325//              fmt( os, "%ls", str );
    284326//              return os;
     
    287329// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    288330//      ostype & ?|?( ostype & os, const char32_t * str ) {
    289 //              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     331//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    290332//              fmt( os, "%ls", str );
    291333//              return os;
     
    294336
    295337//      ostype & ?|?( ostype & os, const wchar_t * str ) {
    296 //              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     338//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    297339//              fmt( os, "%ls", str );
    298340//              return os;
     
    300342
    301343        ostype & ?|?( ostype & os, const void * p ) {
    302                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     344                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    303345                fmt( os, "%p", p );
    304346                return os;
     
    315357        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    316358                (ostype &)(manip( os ));
    317                 if ( getPrt( os ) ) ends( os );                                 // something printed ?
    318                 setPrt( os, false );                                                    // turn off
     359                if ( $getPrt( os ) ) ends( os );                                // something printed ?
     360                $setPrt( os, false );                                                   // turn off
    319361        } // ?|?
    320362
     
    329371        ostype & nl( ostype & os ) {
    330372                (ostype &)(os | '\n');
    331                 setPrt( os, false );                                                    // turn off
    332                 setNL( os, true );
     373                $setPrt( os, false );                                                   // turn off
     374                $setNL( os, true );
    333375                flush( os );
    334376                return sepOff( os );                                                    // prepare for next line
     
    336378
    337379        ostype & nonl( ostype & os ) {
    338                 setPrt( os, false );                                                    // turn off
     380                $setPrt( os, false );                                                   // turn off
    339381                return os;
    340382        } // nonl
     
    375417        ostype & ?|?( ostype & os, T arg, Params rest ) {
    376418                (ostype &)(os | arg);                                                   // print first argument
    377                 sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
     419                $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
    378420                (ostype &)(os | rest);                                                  // print remaining arguments
    379                 sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
     421                $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
    380422                return os;
    381423        } // ?|?
     
    383425                // (ostype &)(?|?( os, arg, rest )); ends( os );
    384426                (ostype &)(os | arg);                                                   // print first argument
    385                 sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
     427                $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
    386428                (ostype &)(os | rest);                                                  // print remaining arguments
    387                 sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
     429                $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
    388430                ends( os );
    389431        } // ?|?
     
    414456forall( dtype ostype | ostream( ostype ) ) { \
    415457        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    416                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     458                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    417459\
    418460                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
     
    463505\
    464506                if ( ! f.flags.pc ) {                                                   /* no precision */ \
    465                         /* printf( "%s\n", &fmtstr[star] ); */ \
    466507                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
     508                        /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
    467509                        fmt( os, &fmtstr[star], f.wd, f.val ); \
    468510                } else {                                                                                /* precision */ \
    469511                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    470                         /* printf( "%s\n", &fmtstr[star] ); */ \
     512                        /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
    471513                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
    472514                } /* if */ \
     
    486528IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
    487529IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
     530
     531
     532#if defined( __SIZEOF_INT128__ )
     533// Default prefix for non-decimal prints is 0b, 0, 0x.
     534#define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \
     535forall( dtype ostype | ostream( ostype ) ) \
     536static void base10_128( ostype & os, _Ostream_Manip(T) fmt ) { \
     537        if ( fmt.val > UINT64_MAX ) { \
     538                fmt.val /= P10_UINT64; \
     539                base10_128( os, fmt ); /* recursive */ \
     540                _Ostream_Manip(unsigned long long int) fmt2 @= { (uint64_t)(fmt.val % P10_UINT64), 0, 19, 'u', { .all : 0 } }; \
     541                fmt2.flags.nobsdp = true; \
     542                printf( "fmt2 %c %lld %d\n", fmt2.base, fmt2.val, fmt2.all );   \
     543                sepOff( os ); \
     544                (ostype &)(os | fmt2); \
     545        } else { \
     546                printf( "fmt %c %lld %d\n", fmt.base, fmt.val, fmt.all ); \
     547                (ostype &)(os | fmt); \
     548        } /* if */ \
     549} /* base10_128 */                                                 \
     550forall( dtype ostype | ostream( ostype ) ) { \
     551        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     552                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     553\
     554                if ( f.base == 'b' | f.base == 'o' | f.base == 'x' | f.base == 'X' ) { \
     555                        unsigned long long int msig = (unsigned long long int)(f.val >> 64); \
     556                        unsigned long long int lsig = (unsigned long long int)(f.val); \
     557                        _Ostream_Manip(SIGNED long long int) fmt @= { msig, f.wd, f.pc, f.base, { .all : f.all } }; \
     558                        _Ostream_Manip(unsigned long long int) fmt2 @= { lsig, 0, 0, f.base, { .all : 0 } }; \
     559                        if ( msig == 0 ) { \
     560                                fmt.val = lsig; \
     561                                (ostype &)(os | fmt); \
     562                        } else { \
     563                                fmt2.flags.pad0 = fmt2.flags.nobsdp = true;     \
     564                                if ( f.base == 'b' ) { \
     565                                        if ( f.wd > 64 ) fmt.wd = f.wd - 64; \
     566                                        fmt2.wd = 64; \
     567                                        (ostype &)(os | fmt | "" | fmt2); \
     568                                } else if ( f.base == 'o' ) { \
     569                                        fmt.val = (unsigned long long int)fmt.val >> 2; \
     570                                        if ( f.wd > 21 ) fmt.wd = f.wd - 21; \
     571                                        fmt2.wd = 1; \
     572                                        fmt2.val = ((msig & 0x3) << 1) + 1; \
     573                                        (ostype &)(os | fmt | "" | fmt2); \
     574                                        sepOff( os ); \
     575                                        fmt2.wd = 21; \
     576                                        fmt2.val = lsig & 0x7fffffffffffffff; \
     577                                        (ostype &)(os | fmt2); \
     578                                } else { \
     579                                        if ( f.flags.left ) { \
     580                                                if ( f.wd > 16 ) fmt2.wd = f.wd - 16;   \
     581                                                fmt.wd = 16;                                                    \
     582                                        } else { \
     583                                                if ( f.wd > 16 ) fmt.wd = f.wd - 16;    \
     584                                                fmt2.wd = 16;                                                   \
     585                                        } /* if */ \
     586                                        (ostype &)(os | fmt | "" | fmt2); \
     587                                } /* if */ \
     588                        } /* if */ \
     589                } else { \
     590                        base10_128( os, f ); \
     591                } /* if */ \
     592                return os; \
     593        } /* ?|? */ \
     594        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
     595} // distribution
     596
     597IntegralFMTImpl128( int128, signed, 'd', "%    *ll ", "%    *.*ll " )
     598IntegralFMTImpl128( unsigned int128, unsigned, 'u', "%    *ll ", "%    *.*ll " )
     599#endif // __SIZEOF_INT128__
    488600
    489601//*********************************** floating point ***********************************
     
    513625forall( dtype ostype | ostream( ostype ) ) { \
    514626        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    515                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     627                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    516628                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
    517629                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
     
    536648                return os; \
    537649        } /* ?|? */ \
     650\
    538651        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    539652} // distribution
     
    555668                } // if
    556669
    557                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     670                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    558671
    559672                #define CFMTNP "% * "
     
    571684                return os;
    572685        } // ?|?
     686
    573687        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); ends( os ); }
    574688} // distribution
     
    592706                } // if
    593707
    594                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     708                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    595709
    596710                #define SFMTNP "% * "
     
    616730                return os;
    617731        } // ?|?
     732
    618733        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); ends( os ); }
    619734} // distribution
     
    735850        } // ?|?
    736851
    737         // istype & ?|?( istype & is, const char * fmt ) {
     852        // istype & ?|?( istype & is, const char fmt[] ) {
    738853        //      fmt( is, fmt, "" );
    739854        //      return is;
  • libcfa/src/iostream.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 12:08:38 2019
    13 // Update Count     : 334
     12// Last Modified On : Thu Feb 20 15:30:56 2020
     13// Update Count     : 337
    1414//
    1515
     
    2424trait ostream( dtype ostype ) {
    2525        // private
    26         bool sepPrt( ostype & );                                                        // get separator state (on/off)
    27         void sepReset( ostype & );                                                      // set separator state to default state
    28         void sepReset( ostype &, bool );                                        // set separator and default state
    29         const char * sepGetCur( ostype & );                                     // get current separator string
    30         void sepSetCur( ostype &, const char * );                       // set current separator string
    31         bool getNL( ostype & );                                                         // check newline
    32         void setNL( ostype &, bool );                                           // saw newline
    33         bool getANL( ostype & );                                                        // get auto newline (on/off)
    34         bool getPrt( ostype & );                                                        // get fmt called in output cascade
    35         void setPrt( ostype &, bool );                                          // set fmt called in output cascade
     26        bool $sepPrt( ostype & );                                                       // get separator state (on/off)
     27        void $sepReset( ostype & );                                                     // set separator state to default state
     28        void $sepReset( ostype &, bool );                                       // set separator and default state
     29        const char * $sepGetCur( ostype & );                            // get current separator string
     30        void $sepSetCur( ostype &, const char [] );                     // set current separator string
     31        bool $getNL( ostype & );                                                        // check newline
     32        void $setNL( ostype &, bool );                                          // saw newline
     33        bool $getANL( ostype & );                                                       // get auto newline (on/off)
     34        bool $getPrt( ostype & );                                                       // get fmt called in output cascade
     35        void $setPrt( ostype &, bool );                                         // set fmt called in output cascade
    3636        // public
    3737        void sepOn( ostype & );                                                         // turn separator state on
     
    4343
    4444        const char * sepGet( ostype & );                                        // get separator string
    45         void sepSet( ostype &, const char * );                          // set separator to string (15 character maximum)
     45        void sepSet( ostype &, const char [] );                         // set separator to string (15 character maximum)
    4646        const char * sepGetTuple( ostype & );                           // get tuple separator string
    47         void sepSetTuple( ostype &, const char * );                     // set tuple separator to string (15 character maximum)
     47        void sepSetTuple( ostype &, const char [] );            // set tuple separator to string (15 character maximum)
    4848
    4949        void ends( ostype & os );                                                       // end of output statement
    5050        int fail( ostype & );
    5151        int flush( ostype & );
    52         void open( ostype & os, const char * name, const char * mode );
     52        void open( ostype & os, const char name[], const char mode[] );
    5353        void close( ostype & os );
    54         ostype & write( ostype &, const char *, size_t );
     54        ostype & write( ostype &, const char [], size_t );
    5555        int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    5656}; // ostream
     
    9898        ostype & ?|?( ostype &, unsigned long long int );
    9999        void ?|?( ostype &, unsigned long long int );
     100#if defined( __SIZEOF_INT128__ )
     101        ostype & ?|?( ostype &, int128 );
     102        void ?|?( ostype &, int128 );
     103        ostype & ?|?( ostype &, unsigned int128 );
     104        void ?|?( ostype &, unsigned int128 );
     105#endif // __SIZEOF_INT128__
    100106
    101107        ostype & ?|?( ostype &, float );
     
    113119        void ?|?( ostype &, long double _Complex );
    114120
    115         ostype & ?|?( ostype &, const char * );
    116         void ?|?( ostype &, const char * );
     121        ostype & ?|?( ostype &, const char [] );
     122        void ?|?( ostype &, const char [] );
    117123        // ostype & ?|?( ostype &, const char16_t * );
    118124#if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
     
    206212IntegralFMTDecl( signed long long int, 'd' )
    207213IntegralFMTDecl( unsigned long long int, 'u' )
     214#if defined( __SIZEOF_INT128__ )
     215IntegralFMTDecl( int128, 'd' )
     216IntegralFMTDecl( unsigned int128, 'u' )
     217#endif
    208218
    209219//*********************************** floating point ***********************************
     
    256266
    257267static inline {
    258         _Ostream_Manip(const char *) bin( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'b', { .all : 0 } }; }
    259         _Ostream_Manip(const char *) oct( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'o', { .all : 0 } }; }
    260         _Ostream_Manip(const char *) hex( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; }
    261         _Ostream_Manip(const char *) wd( unsigned int w, const char * s ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; }
    262         _Ostream_Manip(const char *) wd( unsigned int w, unsigned char pc, const char * s ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
     268        _Ostream_Manip(const char *) bin( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'b', { .all : 0 } }; }
     269        _Ostream_Manip(const char *) oct( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'o', { .all : 0 } }; }
     270        _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; }
     271        _Ostream_Manip(const char *) wd( unsigned int w, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; }
     272        _Ostream_Manip(const char *) wd( unsigned int w, unsigned char pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
    263273        _Ostream_Manip(const char *) & wd( unsigned int w, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; return fmt; }
    264274        _Ostream_Manip(const char *) & wd( unsigned int w, unsigned char pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; }
     
    281291        int fail( istype & );
    282292        int eof( istype & );
    283         void open( istype & is, const char * name );
     293        void open( istype & is, const char name[] );
    284294        void close( istype & is );
    285295        istype & read( istype &, char *, size_t );
     
    316326        istype & ?|?( istype &, long double _Complex & );
    317327
    318 //      istype & ?|?( istype &, const char * );
     328//      istype & ?|?( istype &, const char [] );
    319329        istype & ?|?( istype &, char * );
    320330
     
    343353static inline {
    344354        _Istream_Cstr skip( unsigned int n ) { return (_Istream_Cstr){ 0p, 0p, n, { .all : 0 } }; }
    345         _Istream_Cstr skip( const char * scanset ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
    346         _Istream_Cstr incl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
    347         _Istream_Cstr & incl( const char * scanset, _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
    348         _Istream_Cstr excl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : true } }; }
    349         _Istream_Cstr & excl( const char * scanset, _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
    350         _Istream_Cstr ignore( const char * s ) { return (_Istream_Cstr)@{ s, 0p, -1, { .flags.ignore : true } }; }
     355        _Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
     356        _Istream_Cstr incl( const char scanset[], char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
     357        _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
     358        _Istream_Cstr excl( const char scanset[], char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : true } }; }
     359        _Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
     360        _Istream_Cstr ignore( const char s[] ) { return (_Istream_Cstr)@{ s, 0p, -1, { .flags.ignore : true } }; }
    351361        _Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
    352         _Istream_Cstr wdi( unsigned int w, char * s ) { return (_Istream_Cstr)@{ s, 0p, w, { .all : 0 } }; }
     362        _Istream_Cstr wdi( unsigned int w, char s[] ) { return (_Istream_Cstr)@{ s, 0p, w, { .all : 0 } }; }
    353363        _Istream_Cstr & wdi( unsigned int w, _Istream_Cstr & fmt ) { fmt.wd = w; return fmt; }
    354364} // distribution
  • libcfa/src/math.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 13 11:02:15 2018
    13 // Update Count     : 116
     12// Last Modified On : Tue Feb  4 10:27:11 2020
     13// Update Count     : 117
    1414//
    1515
     
    5151static inline long double fdim( long double x, long double y ) { return fdiml( x, y ); }
    5252
    53 static inline float nan( const char * tag ) { return nanf( tag ); }
    54 // extern "C" { double nan( const char * ); }
    55 static inline long double nan( const char * tag ) { return nanl( tag ); }
     53static inline float nan( const char tag[] ) { return nanf( tag ); }
     54// extern "C" { double nan( const char [] ); }
     55static inline long double nan( const char tag[] ) { return nanl( tag ); }
    5656
    5757//---------------------- Exponential ----------------------
  • libcfa/src/rational.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 18:12:08 2019
    13 // Update Count     : 184
     12// Last Modified On : Sat Feb  8 17:56:36 2020
     13// Update Count     : 187
    1414//
    1515
     
    5656        } // rational
    5757
     58        void ?{}( Rational(RationalImpl) & r, zero_t ) {
     59                r{ (RationalImpl){0}, (RationalImpl){1} };
     60        } // rational
     61
     62        void ?{}( Rational(RationalImpl) & r, one_t ) {
     63                r{ (RationalImpl){1}, (RationalImpl){1} };
     64        } // rational
    5865
    5966        // getter for numerator/denominator
  • libcfa/src/startup.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jul 24 16:21:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 25 16:42:01 2018
    13 // Update Count     : 11
     12// Last Modified On : Tue Feb  4 13:03:18 2020
     13// Update Count     : 30
    1414//
    1515
     16#include <time.h>                                                                               // tzset
    1617#include "startup.hfa"
    17 #include <unistd.h>
    18 
    1918
    2019extern "C" {
    21     static void __cfaabi_appready_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_APPREADY ) ));
     20    void __cfaabi_appready_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_APPREADY ) ));
    2221    void __cfaabi_appready_startup( void ) {
     22                tzset();                                                                                // initialize time global variables
    2323                #ifdef __CFA_DEBUG__
    2424                extern void heapAppStart();
     
    2727    } // __cfaabi_appready_startup
    2828
    29     static void __cfaabi_appready_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_APPREADY ) ));
     29    void __cfaabi_appready_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_APPREADY ) ));
    3030    void __cfaabi_appready_shutdown( void ) {
    3131                #ifdef __CFA_DEBUG__
     
    4141struct __spinlock_t;
    4242extern "C" {
    43         void __cfaabi_dbg_record(struct __spinlock_t & this, const char * prev_name) __attribute__(( weak )) {}
     43        void __cfaabi_dbg_record(struct __spinlock_t & this, const char prev_name[]) __attribute__(( weak )) {}
    4444}
    4545
  • libcfa/src/stdhdr/assert.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Jul  4 23:25:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 31 23:09:32 2017
    13 // Update Count     : 13
     12// Last Modified On : Tue Feb  4 12:58:49 2020
     13// Update Count     : 15
    1414//
    1515
     
    2727        #define assertf( expr, fmt, ... ) ((expr) ? ((void)0) : __assert_fail_f(__VSTRINGIFY__(expr), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, ## __VA_ARGS__ ))
    2828
    29         void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) __attribute__((noreturn, format( printf, 5, 6) ));
     29        void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) __attribute__((noreturn, format( printf, 5, 6) ));
    3030#endif
    3131
  • libcfa/src/stdhdr/bfdlink.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jul 18 07:26:04 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 22 13:49:30 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:08 2020
     13// Update Count     : 6
    1414//
    1515
    1616// include file uses the CFA keyword "with".
    1717#if ! defined( with )                                                                   // nesting ?
    18 #define with `with`                                                                             // make keyword an identifier
     18#define with ``with                                                                             // make keyword an identifier
    1919#define __CFA_BFDLINK_H__
    2020#endif
  • libcfa/src/stdhdr/hwloc.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jul 18 07:45:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 22 13:49:58 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:18 2020
     13// Update Count     : 6
    1414//
    1515
    1616// include file uses the CFA keyword "thread".
    1717#if ! defined( thread )                                                                 // nesting ?
    18 #define thread `thread`                                                                 // make keyword an identifier
     18#define thread ``thread                                                                 // make keyword an identifier
    1919#define __CFA_HWLOC_H__
    2020#endif
  • libcfa/src/stdhdr/krb5.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Jul 18 07:55:44 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 22 13:50:24 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:35 2020
     13// Update Count     : 6
    1414//
    1515
    1616// include file uses the CFA keyword "enable".
    1717#if ! defined( enable )                                                                 // nesting ?
    18 #define enable `enable`                                                                 // make keyword an identifier
     18#define enable ``enable                                                                 // make keyword an identifier
    1919#define __CFA_KRB5_H__
    2020#endif
  • libcfa/src/stdhdr/math.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Jul  4 23:25:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 22 18:16:07 2018
    13 // Update Count     : 13
     12// Last Modified On : Fri Feb  7 19:05:27 2020
     13// Update Count     : 15
    1414//
    1515
    1616extern "C" {
    1717#if ! defined( exception )                                                              // nesting ?
    18 #define exception `exception`                                                   // make keyword an identifier
     18#define exception ``exception                                                   // make keyword an identifier
    1919#define __CFA_MATH_H__
    2020#endif
  • libcfa/src/stdhdr/sys/ucontext.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu Feb  8 23:48:16 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  8 23:50:44 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:41 2020
     13// Update Count     : 6
    1414//
    1515
    1616#if ! defined( ftype )                                                                  // nesting ?
    17 #define ftype `ftype`                                                                   // make keyword an identifier
     17#define ftype ``ftype                                                                   // make keyword an identifier
    1818#define __CFA_UCONTEXT_H__
    1919#endif
  • libcfa/src/stdlib.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun 24 17:34:44 2019
    13 // Update Count     : 462
     12// Last Modified On : Tue Feb  4 08:27:08 2020
     13// Update Count     : 486
    1414//
    1515
     
    2121#include <string.h>                                                                             // memcpy, memset
    2222#include <malloc.h>                                                                             // malloc_usable_size
    23 #include <math.h>                                                                               // fabsf, fabs, fabsl
     23//#include <math.h>                                                                             // fabsf, fabs, fabsl
    2424#include <complex.h>                                                                    // _Complex_I
    2525#include <assert.h>
     
    2727//---------------------------------------
    2828
    29 // resize, non-array types
    30 forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim, char fill ) {
    31         size_t olen = malloc_usable_size( ptr );                        // current allocation
    32     char * nptr = (void *)realloc( (void *)ptr, dim * (size_t)sizeof(T) ); // C realloc
    33         size_t nlen = malloc_usable_size( nptr );                       // new allocation
    34         if ( nlen > olen ) {                                                            // larger ?
    35                 memset( nptr + olen, (int)fill, nlen - olen );  // initialize added storage
    36         } //
    37     return (T *)nptr;
    38 } // alloc
     29forall( dtype T | sized(T) ) {
     30        T * alloc_set( T ptr[], size_t dim, char fill ) {       // realloc array with fill
     31                size_t olen = malloc_usable_size( ptr );                // current allocation
     32                void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     33                size_t nlen = malloc_usable_size( nptr );               // new allocation
     34                if ( nlen > olen ) {                                                    // larger ?
     35                        memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
     36                } // if
     37                return (T *)nptr;
     38        } // alloc_set
     39
     40        T * alloc_align_set( T ptr[], size_t align, char fill ) { // aligned realloc with fill
     41                size_t olen = malloc_usable_size( ptr );                // current allocation
     42                void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     43                // char * nptr = alloc_align( ptr, align );
     44                size_t nlen = malloc_usable_size( nptr );               // new allocation
     45                if ( nlen > olen ) {                                                    // larger ?
     46                        memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
     47                } // if
     48                return (T *)nptr;
     49        } // alloc_align_set
     50} // distribution
    3951
    4052// allocation/deallocation and constructor/destructor, non-array types
    4153forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
    4254T * new( Params p ) {
    43         return &(*malloc()){ p };                                                               // run constructor
     55        return &(*malloc()){ p };                                                       // run constructor
    4456} // new
    4557
     
    4759void delete( T * ptr ) {
    4860        if ( ptr ) {                                                                            // ignore null
    49                 ^(*ptr){};                                                                                      // run destructor
     61                ^(*ptr){};                                                                              // run destructor
    5062                free( ptr );
    5163        } // if
     
    5567void delete( T * ptr, Params rest ) {
    5668        if ( ptr ) {                                                                            // ignore null
    57                 ^(*ptr){};                                                                                      // run destructor
     69                ^(*ptr){};                                                                              // run destructor
    5870                free( ptr );
    5971        } // if
     
    95107//---------------------------------------
    96108
    97 float _Complex strto( const char * sptr, char ** eptr ) {
     109float _Complex strto( const char sptr[], char ** eptr ) {
    98110        float re, im;
    99111        char * eeptr;
     
    106118} // strto
    107119
    108 double _Complex strto( const char * sptr, char ** eptr ) {
     120double _Complex strto( const char sptr[], char ** eptr ) {
    109121        double re, im;
    110122        char * eeptr;
     
    117129} // strto
    118130
    119 long double _Complex strto( const char * sptr, char ** eptr ) {
     131long double _Complex strto( const char sptr[], char ** eptr ) {
    120132        long double re, im;
    121133        char * eeptr;
  • libcfa/src/stdlib.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 23 14:14:59 2019
    13 // Update Count     : 373
     12// Last Modified On : Tue Feb  4 08:27:01 2020
     13// Update Count     : 401
    1414//
    1515
     
    2525        void * memset( void * dest, int fill, size_t size ); // string.h
    2626        void * memcpy( void * dest, const void * src, size_t size ); // string.h
    27     void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA
     27    void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
    2828} // extern "C"
     29
     30void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap
    2931
    3032//---------------------------------------
     
    5052        } // calloc
    5153
    52         T * realloc( T * ptr, size_t size ) {
    53                 if ( unlikely( ptr == 0 ) ) return malloc();
    54                 return (T *)(void *)realloc( (void *)ptr, size );
     54        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
     55                return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
    5556        } // realloc
    5657
    5758        T * memalign( size_t align ) {
    58                 return (T *)memalign( align, sizeof(T) );
     59                return (T *)memalign( align, sizeof(T) );               // C memalign
    5960        } // memalign
    6061
     62        T * cmemalign( size_t align, size_t dim  ) {
     63                return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign
     64        } // cmemalign
     65
    6166        T * aligned_alloc( size_t align ) {
    62                 return (T *)aligned_alloc( align, sizeof(T) );
     67                return (T *)aligned_alloc( align, sizeof(T) );  // C aligned_alloc
    6368        } // aligned_alloc
    6469
     
    6772        } // posix_memalign
    6873
    69 
    7074        // Cforall dynamic allocation
    7175
     
    7478        } // alloc
    7579
    76         T * alloc( char fill ) {
    77                 T * ptr;
    78                 if ( _Alignof(T) <= libAlign() ) ptr = (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
    79                 else ptr = (T *)memalign( _Alignof(T), sizeof(T) );
    80                 return (T *)memset( ptr, (int)fill, sizeof(T) ); // initialize with fill value
    81         } // alloc
    82 
    8380        T * alloc( size_t dim ) {
    84                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
     81                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( dim * (size_t)sizeof(T) );
    8582                else return (T *)memalign( _Alignof(T), dim * sizeof(T) );
    8683        } // alloc
    8784
    88         T * alloc( size_t dim, char fill ) {
     85        T * alloc( T ptr[], size_t dim ) {                                      // realloc
     86                return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     87        } // alloc
     88
     89        T * alloc_set( char fill ) {
     90                return (T *)memset( (T *)alloc(), (int)fill, sizeof(T) ); // initialize with fill value
     91        } // alloc
     92
     93        T * alloc_set( T fill ) {
     94                return (T *)memcpy( (T *)alloc(), &fill, sizeof(T) ); // initialize with fill value
     95        } // alloc
     96
     97        T * alloc_set( size_t dim, char fill ) {
    8998                return (T *)memset( (T *)alloc( dim ), (int)fill, dim * sizeof(T) ); // initialize with fill value
    9099        } // alloc
    91100
    92         T * alloc( T ptr[], size_t dim ) {
    93                 return realloc( ptr, dim * sizeof(T) );
    94         } // alloc
    95 } // distribution
    96 
    97 
    98 static inline forall( dtype T | sized(T) ) {
    99         T * align_alloc( size_t align ) {
     101        T * alloc_set( size_t dim, T fill ) {
     102                T * r = (T *)alloc( dim );
     103                for ( i; dim ) { memcpy( &r[i], &fill, sizeof(T) ); } // initialize with fill value
     104                return r;
     105        } // alloc
     106
     107        T * alloc_set( size_t dim, const T fill[] ) {
     108                return (T *)memcpy( (T *)alloc( dim ), fill, dim * sizeof(T) ); // initialize with fill value
     109        } // alloc
     110} // distribution
     111
     112forall( dtype T | sized(T) ) {
     113        T * alloc_set( T ptr[], size_t dim, char fill );        // realloc array with fill
     114} // distribution
     115
     116static inline forall( dtype T | sized(T) ) {
     117        T * alloc_align( size_t align ) {
    100118                return (T *)memalign( align, sizeof(T) );
    101         } // align_alloc
    102 
    103         T * align_alloc( size_t align, char fill ) {
    104                 T * ptr = (T *)memalign( align, sizeof(T) );
    105                 return (T *)memset( ptr, (int)fill, sizeof(T) );
    106         } // align_alloc
    107 
    108         T * align_alloc( size_t align, size_t dim ) {
     119        } // alloc_align
     120
     121        T * alloc_align( size_t align, size_t dim ) {
    109122                return (T *)memalign( align, dim * sizeof(T) );
    110         } // align_alloc
    111 
    112         T * align_alloc( size_t align, size_t dim, char fill ) {
    113                 if ( fill == '\0' ) {
    114                         return (T *)cmemalign( align, dim, sizeof(T) );
    115                 } else {
    116                         return (T *)memset( (T *)memalign( align, dim * sizeof(T) ), (int)fill, dim * sizeof(T) );
    117                 } // if
    118         } // align_alloc
    119 } // distribution
    120 
    121 forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim, char fill );
    122 
     123        } // alloc_align
     124
     125        T * alloc_align( T ptr[], size_t align ) {                      // aligned realloc array
     126                return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     127        } // alloc_align
     128
     129        T * alloc_align( T ptr[], size_t align, size_t dim ) { // aligned realloc array
     130                return (T *)(void *)realloc( (void *)ptr, align, dim * sizeof(T) ); // CFA realloc
     131        } // alloc_align
     132
     133        T * alloc_align_set( size_t align, char fill ) {
     134                return (T *)memset( (T *)alloc_align( align ), (int)fill, sizeof(T) ); // initialize with fill value
     135        } // alloc_align
     136
     137        T * alloc_align_set( size_t align, T fill ) {
     138                return (T *)memcpy( (T *)alloc_align( align ), &fill, sizeof(T) ); // initialize with fill value
     139        } // alloc_align
     140
     141        T * alloc_align_set( size_t align, size_t dim, char fill ) {
     142                return (T *)memset( (T *)alloc_align( align, dim ), (int)fill, dim * sizeof(T) ); // initialize with fill value
     143        } // alloc_align
     144
     145        T * alloc_align_set( size_t align, size_t dim, T fill ) {
     146                T * r = (T *)alloc_align( align, dim );
     147                for ( i; dim ) { memcpy( &r[i], &fill, sizeof(T) ); } // initialize with fill value
     148                return r;
     149        } // alloc_align
     150
     151        T * alloc_align_set( size_t align, size_t dim, const T fill[] ) {
     152                return (T *)memcpy( (T *)alloc_align( align, dim ), fill, dim * sizeof(T) );
     153        } // alloc_align
     154} // distribution
     155
     156forall( dtype T | sized(T) ) {
     157        T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); // aligned realloc array with fill
     158} // distribution
    123159
    124160static inline forall( dtype T | sized(T) ) {
    125161        // data, non-array types
    126 
    127162        T * memset( T * dest, char fill ) {
    128163                return (T *)memset( dest, fill, sizeof(T) );
     
    136171static inline forall( dtype T | sized(T) ) {
    137172        // data, array types
    138 
    139173        T * amemset( T dest[], char fill, size_t dim ) {
    140174                return (T *)(void *)memset( dest, fill, dim * sizeof(T) ); // C memset
     
    159193
    160194static inline {
    161         int strto( const char * sptr, char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
    162         unsigned int strto( const char * sptr, char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
    163         long int strto( const char * sptr, char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
    164         unsigned long int strto( const char * sptr, char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
    165         long long int strto( const char * sptr, char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
    166         unsigned long long int strto( const char * sptr, char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
    167 
    168         float strto( const char * sptr, char ** eptr ) { return strtof( sptr, eptr ); }
    169         double strto( const char * sptr, char ** eptr ) { return strtod( sptr, eptr ); }
    170         long double strto( const char * sptr, char ** eptr ) { return strtold( sptr, eptr ); }
    171 } // distribution
    172 
    173 float _Complex strto( const char * sptr, char ** eptr );
    174 double _Complex strto( const char * sptr, char ** eptr );
    175 long double _Complex strto( const char * sptr, char ** eptr );
     195        int strto( const char sptr[], char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
     196        unsigned int strto( const char sptr[], char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
     197        long int strto( const char sptr[], char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
     198        unsigned long int strto( const char sptr[], char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
     199        long long int strto( const char sptr[], char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
     200        unsigned long long int strto( const char sptr[], char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
     201
     202        float strto( const char sptr[], char ** eptr ) { return strtof( sptr, eptr ); }
     203        double strto( const char sptr[], char ** eptr ) { return strtod( sptr, eptr ); }
     204        long double strto( const char sptr[], char ** eptr ) { return strtold( sptr, eptr ); }
     205} // distribution
     206
     207float _Complex strto( const char sptr[], char ** eptr );
     208double _Complex strto( const char sptr[], char ** eptr );
     209long double _Complex strto( const char sptr[], char ** eptr );
    176210
    177211static inline {
    178         int ato( const char * sptr ) { return (int)strtol( sptr, 0, 10 ); }
    179         unsigned int ato( const char * sptr ) { return (unsigned int)strtoul( sptr, 0, 10 ); }
    180         long int ato( const char * sptr ) { return strtol( sptr, 0, 10 ); }
    181         unsigned long int ato( const char * sptr ) { return strtoul( sptr, 0, 10 ); }
    182         long long int ato( const char * sptr ) { return strtoll( sptr, 0, 10 ); }
    183         unsigned long long int ato( const char * sptr ) { return strtoull( sptr, 0, 10 ); }
    184 
    185         float ato( const char * sptr ) { return strtof( sptr, 0 ); }
    186         double ato( const char * sptr ) { return strtod( sptr, 0 ); }
    187         long double ato( const char * sptr ) { return strtold( sptr, 0 ); }
    188 
    189         float _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
    190         double _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
    191         long double _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
     212        int ato( const char sptr[] ) { return (int)strtol( sptr, 0p, 10 ); }
     213        unsigned int ato( const char sptr[] ) { return (unsigned int)strtoul( sptr, 0p, 10 ); }
     214        long int ato( const char sptr[] ) { return strtol( sptr, 0p, 10 ); }
     215        unsigned long int ato( const char sptr[] ) { return strtoul( sptr, 0p, 10 ); }
     216        long long int ato( const char sptr[] ) { return strtoll( sptr, 0p, 10 ); }
     217        unsigned long long int ato( const char sptr[] ) { return strtoull( sptr, 0p, 10 ); }
     218
     219        float ato( const char sptr[] ) { return strtof( sptr, 0p ); }
     220        double ato( const char sptr[] ) { return strtod( sptr, 0p ); }
     221        long double ato( const char sptr[] ) { return strtold( sptr, 0p ); }
     222
     223        float _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
     224        double _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
     225        long double _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
    192226} // distribution
    193227
  • libcfa/src/time.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Mar 27 13:33:14 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 08:41:55 2019
    13 // Update Count     : 65
     12// Last Modified On : Tue Feb  4 08:24:18 2020
     13// Update Count     : 70
    1414//
    1515
     
    3333forall( dtype ostype | ostream( ostype ) ) {
    3434        ostype & ?|?( ostype & os, Duration dur ) with( dur ) {
    35                 (ostype &)(os | tv / TIMEGRAN);                                 // print seconds
    36                 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;   // compute nanoseconds
     35                (ostype &)(os | tn / TIMEGRAN);                                 // print seconds
     36                long int ns = (tn < 0 ? -tn : tn) % TIMEGRAN;   // compute nanoseconds
    3737                if ( ns != 0 ) {                                                                // some ?
    3838                        char buf[16];
     
    5252
    5353#ifdef __CFA_DEBUG__
    54 static void tabort( int year, int month, int day, int hour, int min, int sec, int nsec ) {
     54static void tabort( int year, int month, int day, int hour, int min, int sec, int64_t nsec ) {
    5555        abort | "Attempt to create Time( year=" | year | "(>=1970), month=" | month | "(1-12), day=" | day | "(1-31), hour=" | hour | "(0-23), min=" | min | "(0-59), sec=" | sec
    56                   | "(0-60), nsec=" | nsec | "(0-999_999_999), which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038.";
     56                  | "(0-60), nsec=" | nsec | "(0-999_999_999), which is not in the range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038, where month and day have 1 origin.";
    5757} // tabort
    5858#endif // __CFA_DEBUG__
    5959
    60 void ?{}( Time & time, int year, int month, int day, int hour, int min, int sec, int nsec ) with( time ) {
     60void ?{}( Time & time, int year, int month, int day, int hour, int min, int sec, int64_t nsec ) with( time ) {
    6161        tm tm;
    6262
    63         tm.tm_isdst = -1;                                                                       // let mktime determine if alternate timezone is in effect
     63        // Values can be in any range (+/-) but result must be in the epoch.
    6464        tm.tm_year = year - 1900;                                                       // mktime uses 1900 as its starting point
    65 #ifdef __CFA_DEBUG__
    66         if ( month < 1 || 12 < month ) {
    67                 tabort( year, month, day, hour, min, sec, nsec );
    68         } // if
    69 #endif // __CFA_DEBUG__
     65        // Make month in range 1-12 to match with day.
    7066        tm.tm_mon = month - 1;                                                          // mktime uses range 0-11
    71 #ifdef __CFA_DEBUG__
    72         if ( day < 1 || 31 < day ) {
    73                 tabort( year, month, day, hour, min, sec, nsec );
    74         } // if
    75 #endif // __CFA_DEBUG__
    7667        tm.tm_mday = day;                                                                       // mktime uses range 1-31
    7768        tm.tm_hour = hour;
    7869        tm.tm_min = min;
    7970        tm.tm_sec = sec;
     71        tm.tm_isdst = -1;                                                                       // let mktime determine if alternate timezone is in effect
    8072        time_t epochsec = mktime( &tm );
    8173#ifdef __CFA_DEBUG__
    82         if ( epochsec == (time_t)-1 ) {
     74        if ( epochsec <= (time_t)-1 ) {                                         // MUST BE LESS THAN OR EQUAL!
    8375                tabort( year, month, day, hour, min, sec, nsec );
    8476        } // if
    8577#endif // __CFA_DEBUG__
    86         tv = (int64_t)(epochsec) * TIMEGRAN + nsec;                     // convert to nanoseconds
     78        tn = (int64_t)(epochsec) * TIMEGRAN + nsec;                     // convert to nanoseconds
    8779#ifdef __CFA_DEBUG__
    88         if ( tv > 2147483647LL * TIMEGRAN ) {                           // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
     80        if ( tn > 2147483647LL * TIMEGRAN ) {                           // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
    8981                tabort( year, month, day, hour, min, sec, nsec );
    9082        } // if
     
    9385
    9486char * yy_mm_dd( Time time, char * buf ) with( time ) {
    95         time_t s = tv / TIMEGRAN;
     87        time_t s = tn / TIMEGRAN;
    9688        tm tm;
    9789        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     
    108100
    109101char * mm_dd_yy( Time time, char * buf ) with( time ) {
    110         time_t s = tv / TIMEGRAN;
     102        time_t s = tn / TIMEGRAN;
    111103        tm tm;
    112104        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     
    123115
    124116char * dd_mm_yy( Time time, char * buf ) with( time ) {
    125         time_t s = tv / TIMEGRAN;
     117        time_t s = tn / TIMEGRAN;
    126118        tm tm;
    127119        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     
    137129} // dd_mm_yy
    138130
    139 size_t strftime( char * buf, size_t size, const char * fmt, Time time ) with( time ) {
    140         time_t s = tv / TIMEGRAN;
     131size_t strftime( char buf[], size_t size, const char fmt[], Time time ) with( time ) {
     132        time_t s = tn / TIMEGRAN;
    141133        tm tm;
    142134        gmtime_r( &s, &tm );
     
    147139        ostype & ?|?( ostype & os, Time time ) with( time ) {
    148140                char buf[32];                                                                   // at least 26
    149                 time_t s = tv / TIMEGRAN;
     141                time_t s = tn / TIMEGRAN;
    150142                ctime_r( &s, (char *)&buf );                                    // 26 characters: "Wed Jun 30 21:49:08 1993\n"
    151143                buf[24] = '\0';                                                                 // remove trailing '\n'
    152                 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;   // compute nanoseconds
     144                long int ns = (tn < 0 ? -tn : tn) % TIMEGRAN;   // compute nanoseconds
    153145                if ( ns == 0 ) {                                                                // none ?
    154146                        (ostype &)(os | buf);                                           // print date/time/year
  • libcfa/src/time.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Mar 14 23:18:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep 22 12:25:34 2018
    13 // Update Count     : 643
     12// Last Modified On : Tue Feb  4 08:24:32 2020
     13// Update Count     : 654
    1414//
    1515
     
    3232        Duration ?=?( Duration & dur, __attribute__((unused)) zero_t ) { return dur{ 0 }; }
    3333
    34         Duration +?( Duration rhs ) with( rhs ) {       return (Duration)@{ +tv }; }
    35         Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; }
     34        Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tn }; }
     35        Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tn + rhs.tn }; }
    3636        Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
    3737
    38         Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; }
    39         Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
     38        Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tn }; }
     39        Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tn - rhs.tn }; }
    4040        Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
    4141
    42         Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; }
    43         Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; }
     42        Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tn * rhs }; }
     43        Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tn }; }
    4444        Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; }
    4545
    46         int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; }
    47         Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; }
     46        int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tn / rhs.tn; }
     47        Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tn / rhs }; }
    4848        Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; }
    49         double div( Duration lhs, Duration rhs ) { return (double)lhs.tv / (double)rhs.tv; }
    50 
    51         Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tv % rhs.tv }; }
     49        double div( Duration lhs, Duration rhs ) { return (double)lhs.tn / (double)rhs.tn; }
     50
     51        Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tn % rhs.tn }; }
    5252        Duration ?%=?( Duration & lhs, Duration rhs ) { lhs = lhs % rhs; return lhs; }
    5353
    54         bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; }
    55         bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; }
    56         bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tv <  rhs.tv; }
    57         bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; }
    58         bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tv >  rhs.tv; }
    59         bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; }
    60 
    61         bool ?==?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv == 0; }
    62         bool ?!=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv != 0; }
    63         bool ?<? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv <  0; }
    64         bool ?<=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv <= 0; }
    65         bool ?>? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv >  0; }
    66         bool ?>=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv >= 0; }
    67 
    68         Duration abs( Duration rhs ) { return rhs.tv >= 0 ? rhs : -rhs; }
     54        bool ?==?( Duration lhs, Duration rhs ) { return lhs.tn == rhs.tn; }
     55        bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tn != rhs.tn; }
     56        bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tn <  rhs.tn; }
     57        bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tn <= rhs.tn; }
     58        bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tn >  rhs.tn; }
     59        bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tn >= rhs.tn; }
     60
     61        bool ?==?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn == 0; }
     62        bool ?!=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn != 0; }
     63        bool ?<? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn <  0; }
     64        bool ?<=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn <= 0; }
     65        bool ?>? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn >  0; }
     66        bool ?>=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn >= 0; }
     67
     68        Duration abs( Duration rhs ) { return rhs.tn >= 0 ? rhs : -rhs; }
    6969
    7070        Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; }
     
    8282        Duration ?`w( double weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; }
    8383
    84         int64_t ?`ns( Duration dur ) { return dur.tv; }
    85         int64_t ?`us( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000_000LL); }
    86         int64_t ?`ms( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000LL); }
    87         int64_t ?`s( Duration dur ) { return dur.tv / TIMEGRAN; }
    88         int64_t ?`m( Duration dur ) { return dur.tv / (60LL * TIMEGRAN); }
    89         int64_t ?`h( Duration dur ) { return dur.tv / (60LL * 60LL * TIMEGRAN); }
    90         int64_t ?`d( Duration dur ) { return dur.tv / (24LL * 60LL * 60LL * TIMEGRAN); }
    91         int64_t ?`w( Duration dur ) { return dur.tv / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); }
    92 
    93         Duration max( Duration lhs, Duration rhs ) { return  (lhs.tv < rhs.tv) ? rhs : lhs;}
    94         Duration min( Duration lhs, Duration rhs ) { return !(rhs.tv < lhs.tv) ? lhs : rhs;}
     84        int64_t ?`ns( Duration dur ) { return dur.tn; }
     85        int64_t ?`us( Duration dur ) { return dur.tn / (TIMEGRAN / 1_000_000LL); }
     86        int64_t ?`ms( Duration dur ) { return dur.tn / (TIMEGRAN / 1_000LL); }
     87        int64_t ?`s( Duration dur ) { return dur.tn / TIMEGRAN; }
     88        int64_t ?`m( Duration dur ) { return dur.tn / (60LL * TIMEGRAN); }
     89        int64_t ?`h( Duration dur ) { return dur.tn / (60LL * 60LL * TIMEGRAN); }
     90        int64_t ?`d( Duration dur ) { return dur.tn / (24LL * 60LL * 60LL * TIMEGRAN); }
     91        int64_t ?`w( Duration dur ) { return dur.tn / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); }
     92
     93        Duration max( Duration lhs, Duration rhs ) { return  (lhs.tn < rhs.tn) ? rhs : lhs;}
     94        Duration min( Duration lhs, Duration rhs ) { return !(rhs.tn < lhs.tn) ? lhs : rhs;}
    9595} // distribution
    9696
     
    143143//######################### Time #########################
    144144
    145 void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 );
     145void ?{}( Time & time, int year, int month = 1, int day = 1, int hour = 0, int min = 0, int sec = 0, int64_t nsec = 0 );
    146146static inline {
    147147        Time ?=?( Time & time, __attribute__((unused)) zero_t ) { return time{ 0 }; }
    148148
    149         void ?{}( Time & time, timeval t ) with( time ) { tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000; }
     149        void ?{}( Time & time, timeval t ) with( time ) { tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000; }
    150150        Time ?=?( Time & time, timeval t ) with( time ) {
    151                 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL);
     151                tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL);
    152152                return time;
    153153        } // ?=?
    154154
    155         void ?{}( Time & time, timespec t ) with( time ) { tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec; }
     155        void ?{}( Time & time, timespec t ) with( time ) { tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec; }
    156156        Time ?=?( Time & time, timespec t ) with( time ) {
    157                 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
     157                tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
    158158                return time;
    159159        } // ?=?
    160160
    161         Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; }
     161        Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tn + rhs.tn }; }
    162162        Time ?+?( Duration lhs, Time rhs ) { return rhs + lhs; }
    163163        Time ?+=?( Time & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
    164164
    165         Duration ?-?( Time lhs, Time rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
    166         Time ?-?( Time lhs, Duration rhs ) { return (Time)@{ lhs.tv - rhs.tv }; }
     165        Duration ?-?( Time lhs, Time rhs ) { return (Duration)@{ lhs.tn - rhs.tn }; }
     166        Time ?-?( Time lhs, Duration rhs ) { return (Time)@{ lhs.tn - rhs.tn }; }
    167167        Time ?-=?( Time & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
    168         bool ?==?( Time lhs, Time rhs ) { return lhs.tv == rhs.tv; }
    169         bool ?!=?( Time lhs, Time rhs ) { return lhs.tv != rhs.tv; }
    170         bool ?<?( Time lhs, Time rhs ) { return lhs.tv < rhs.tv; }
    171         bool ?<=?( Time lhs, Time rhs ) { return lhs.tv <= rhs.tv; }
    172         bool ?>?( Time lhs, Time rhs ) { return lhs.tv > rhs.tv; }
    173         bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; }
     168        bool ?==?( Time lhs, Time rhs ) { return lhs.tn == rhs.tn; }
     169        bool ?!=?( Time lhs, Time rhs ) { return lhs.tn != rhs.tn; }
     170        bool ?<?( Time lhs, Time rhs ) { return lhs.tn < rhs.tn; }
     171        bool ?<=?( Time lhs, Time rhs ) { return lhs.tn <= rhs.tn; }
     172        bool ?>?( Time lhs, Time rhs ) { return lhs.tn > rhs.tn; }
     173        bool ?>=?( Time lhs, Time rhs ) { return lhs.tn >= rhs.tn; }
     174
     175        int64_t ?`ns( Time t ) { return t.tn; }
    174176} // distribution
    175177
     
    189191} // dmy
    190192
    191 size_t strftime( char * buf, size_t size, const char * fmt, Time time );
     193size_t strftime( char buf[], size_t size, const char fmt[], Time time );
    192194
    193195//------------------------- timeval (cont) -------------------------
    194196
    195197static inline void ?{}( timeval & t, Time time ) with( t, time ) {
    196         tv_sec = tv / TIMEGRAN;                                                         // seconds
    197         tv_usec = tv % TIMEGRAN / (TIMEGRAN / 1_000_000LL);     // microseconds
     198        tv_sec = tn / TIMEGRAN;                                                         // seconds
     199        tv_usec = tn % TIMEGRAN / (TIMEGRAN / 1_000_000LL);     // microseconds
    198200} // ?{}
    199201
     
    201203
    202204static inline void ?{}( timespec & t, Time time ) with( t, time ) {
    203         tv_sec = tv / TIMEGRAN;                                                         // seconds
    204         tv_nsec = tv % TIMEGRAN;                                                        // nanoseconds
     205        tv_sec = tn / TIMEGRAN;                                                         // seconds
     206        tv_nsec = tn % TIMEGRAN;                                                        // nanoseconds
    205207} // ?{}
    206208
  • libcfa/src/time_t.hfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Apr 10 14:42:03 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr 13 07:51:47 2018
    13 // Update Count     : 6
     12// Last Modified On : Sun Jan  5 08:22:46 2020
     13// Update Count     : 7
    1414//
    1515
     
    2020
    2121struct Duration {                                                                               // private
    22         int64_t tv;                                                                                     // nanoseconds
     22        int64_t tn;                                                                                     // nanoseconds
    2323}; // Duration
    2424
    25 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }
    26 static inline void ?{}( Duration & dur, __attribute__((unused)) zero_t ) with( dur ) { tv = 0; }
     25static inline void ?{}( Duration & dur ) with( dur ) { tn = 0; }
     26static inline void ?{}( Duration & dur, __attribute__((unused)) zero_t ) with( dur ) { tn = 0; }
    2727
    2828
     
    3030
    3131struct Time {                                                                                   // private
    32         uint64_t tv;                                                                            // nanoseconds since UNIX epoch
     32        uint64_t tn;                                                                            // nanoseconds since UNIX epoch
    3333}; // Time
    3434
    35 static inline void ?{}( Time & time ) with( time ) { tv = 0; }
    36 static inline void ?{}( Time & time, __attribute__((unused)) zero_t ) with( time ) { tv = 0; }
     35static inline void ?{}( Time & time ) with( time ) { tn = 0; }
     36static inline void ?{}( Time & time, __attribute__((unused)) zero_t ) with( time ) { tn = 0; }
    3737
    3838// Local Variables: //
  • longrun_tests/Makefile.am

    r9fb8f01 r3d5701e  
    4242        -I$(abs_top_srcdir)/tests \
    4343        -I$(srcdir) \
    44         -DTEST_$(shell cat .type | tr a-z A-Z) \
    45         -in-tree
     44        -DTEST_$(shell cat .type | tr a-z A-Z)
    4645
    4746TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
  • longrun_tests/Makefile.in

    r9fb8f01 r3d5701e  
    348348CCDEPMODE = @CCDEPMODE@
    349349CFACC = @CFACC@
     350CFACC_INSTALL = @CFACC_INSTALL@
    350351CFACPP = @CFACPP@
    351352CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    378379FGREP = @FGREP@
    379380GREP = @GREP@
     381HAS_DISTCC = @HAS_DISTCC@
    380382HOST_FLAGS = @HOST_FLAGS@
    381383INSTALL = @INSTALL@
     
    484486LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
    485487        $(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \
    486         $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \
    487         $(AM_CFLAGS) $(CFLAGS)
     488        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(AM_CFLAGS) $(CFAFLAGS) $(CFLAGS)
    488489
    489490AM_V_CFA = $(am__v_CFA_@AM_V@)
     
    491492am__v_CFA_0 = @echo "  CFA     " $@;
    492493am__v_CFA_1 =
    493 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
    494 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
    495 am__v_JAVAC_0 = @echo "  JAVAC   " $@;
    496 am__v_JAVAC_1 =
    497 AM_V_GOC = $(am__v_GOC_@AM_V@)
    498 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
    499 am__v_GOC_0 = @echo "  GOC     " $@;
    500 am__v_GOC_1 =
    501494UPPCC = u++
    502495UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
     
    505498am__v_UPP_0 = @echo "  UPP     " $@;
    506499am__v_UPP_1 =
     500AM_V_GOC = $(am__v_GOC_@AM_V@)
     501am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
     502am__v_GOC_0 = @echo "  GOC     " $@;
     503am__v_GOC_1 =
     504AM_V_PY = $(am__v_PY_@AM_V@)
     505am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
     506am__v_PY_0 = @echo "  PYTHON  " $@;
     507am__v_PY_1 =
     508AM_V_RUST = $(am__v_RUST_@AM_V@)
     509am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
     510am__v_RUST_0 = @echo "  RUST    " $@;
     511am__v_RUST_1 =
     512AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
     513am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
     514am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     515am__v_NODEJS_1 =
     516AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     517am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
     518am__v_JAVAC_0 = @echo "  JAVAC   " $@;
     519am__v_JAVAC_1 =
    507520repeats = 10
    508521max_time = 600
     
    524537        -I$(abs_top_srcdir)/tests \
    525538        -I$(srcdir) \
    526         -DTEST_$(shell cat .type | tr a-z A-Z) \
    527         -in-tree
     539        -DTEST_$(shell cat .type | tr a-z A-Z)
    528540
    529541TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
  • src/AST/Convert.cpp

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu May 09 15::37::05 2019
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 25 22:21:46 2019
    13 // Update Count     : 13
     12// Last Modified On : Wed Dec 11 21:39:32 2019
     13// Update Count     : 33
    1414//
    1515
     
    245245                auto decl = new StructDecl(
    246246                        node->name,
    247                         node->kind,
     247                        (AggregateDecl::Aggregate)node->kind,
    248248                        get<Attribute>().acceptL( node->attributes ),
    249249                        LinkageSpec::Spec( node->linkage.val )
     
    675675
    676676        const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
    677                 KeywordCastExpr::Target castTarget = KeywordCastExpr::NUMBER_OF_TARGETS;
    678                 switch (node->target) {
    679                         case ast::KeywordCastExpr::Coroutine:
    680                                 castTarget = KeywordCastExpr::Coroutine;
    681                                 break;
    682                         case ast::KeywordCastExpr::Thread:
    683                                 castTarget = KeywordCastExpr::Thread;
    684                                 break;
    685                         case ast::KeywordCastExpr::Monitor:
    686                                 castTarget = KeywordCastExpr::Monitor;
    687                                 break;
    688                         default:
    689                                 break;
    690                 }
    691                 assert ( castTarget < KeywordCastExpr::NUMBER_OF_TARGETS );
     677                AggregateDecl::Aggregate castTarget = (AggregateDecl::Aggregate)node->target;
     678                assert( AggregateDecl::Generator <= castTarget && castTarget <= AggregateDecl::Thread );
    692679                auto expr = visitBaseExpr( node,
    693680                        new KeywordCastExpr(
     
    887874                auto expr = visitBaseExpr( node,
    888875                        new AsmExpr(
    889                                 get<Expression>().accept1(node->inout),
     876                                new std::string(node->inout),
    890877                                get<Expression>().accept1(node->constraint),
    891878                                get<Expression>().accept1(node->operand)
     
    12361223                                cv( node ),
    12371224                                node->name,
    1238                                 node->kind == ast::TypeVar::Ftype,
     1225                                node->kind == ast::TypeDecl::Ftype,
    12391226                                get<Attribute>().acceptL( node->attributes )
    12401227                        };
     
    15041491                        old->location,
    15051492                        old->name,
    1506                         old->kind,
     1493                        (ast::AggregateDecl::Aggregate)old->kind,
    15071494                        GET_ACCEPT_V(attributes, Attribute),
    15081495                        { old->linkage.val }
     
    15911578                        { old->storageClasses.val },
    15921579                        GET_ACCEPT_1(base, Type),
    1593                         (ast::TypeVar::Kind)(unsigned)old->kind,
     1580                        (ast::TypeDecl::Kind)(unsigned)old->kind,
    15941581                        old->sized,
    15951582                        GET_ACCEPT_1(init, Type)
     
    20452032        }
    20462033
    2047         virtual void visit( const KeywordCastExpr * old) override final {
    2048                 ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
    2049                 switch (old->target) {
    2050                         case KeywordCastExpr::Coroutine:
    2051                                 castTarget = ast::KeywordCastExpr::Coroutine;
    2052                                 break;
    2053                         case KeywordCastExpr::Thread:
    2054                                 castTarget = ast::KeywordCastExpr::Thread;
    2055                                 break;
    2056                         case KeywordCastExpr::Monitor:
    2057                                 castTarget = ast::KeywordCastExpr::Monitor;
    2058                                 break;
    2059                         default:
    2060                                 break;
    2061                 }
    2062                 assert ( castTarget < ast::KeywordCastExpr::NUMBER_OF_TARGETS );
     2034        virtual void visit( const KeywordCastExpr * old ) override final {
     2035                ast::AggregateDecl::Aggregate castTarget = (ast::AggregateDecl::Aggregate)old->target;
     2036                assert( ast::AggregateDecl::Generator <= castTarget && castTarget <= ast::AggregateDecl::Thread );
    20632037                this->node = visitBaseExpr( old,
    20642038                        new ast::KeywordCastExpr(
     
    22582232                        new ast::AsmExpr(
    22592233                                old->location,
    2260                                 GET_ACCEPT_1(inout, Expr),
     2234                                old->inout,
    22612235                                GET_ACCEPT_1(constraint, Expr),
    22622236                                GET_ACCEPT_1(operand, Expr)
     
    25872561                        ty = new ast::TypeInstType{
    25882562                                old->name,
    2589                                 old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype,
     2563                                old->isFtype ? ast::TypeDecl::Ftype : ast::TypeDecl::Dtype,
    25902564                                cv( old ),
    25912565                                GET_ACCEPT_V( attributes, Attribute )
  • src/AST/Decl.cpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Thu May 9 10:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Thu May 9 10:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 16:23:15 2019
     13// Update Count     : 20
    1414//
    1515
     
    1818#include <cassert>             // for assert, strict_dynamic_cast
    1919#include <iostream>
    20 #include <string>
    2120#include <unordered_map>
    2221
     
    2726#include "Node.hpp"            // for readonly
    2827#include "Type.hpp"            // for readonly
    29 #include "Parser/ParseNode.h"  // for DeclarationNode
    3028
    3129namespace ast {
     
    5654// --- TypeDecl
    5755
    58 std::string TypeDecl::typeString() const {
    59         static const std::string kindNames[] = { "object type", "function type", "tuple type" };
    60         assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1,
    61                 "typeString: kindNames is out of sync." );
    62         assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
    63         return (sized ? "sized " : "") + kindNames[ kind ];
     56const char * TypeDecl::typeString() const {
     57        static const char * kindNames[] = { "sized data type", "sized object type", "sized function type", "sized tuple type" };
     58        static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." );
     59        assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
     60        return sized ? kindNames[ kind ] : &kindNames[ kind ][ sizeof("sized") ]; // sizeof includes '\0'
    6461}
    6562
    66 std::string TypeDecl::genTypeString() const {
    67         static const std::string kindNames[] = { "dtype", "ftype", "ttype" };
    68         assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1, "genTypeString: kindNames is out of sync." );
    69         assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
     63const char * TypeDecl::genTypeString() const {
     64        static const char * kindNames[] = { "dtype", "otype", "ftype", "ttype" };
     65        static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "genTypeString: kindNames is out of sync." );
     66        assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
    7067        return kindNames[ kind ];
    7168}
     
    7370std::ostream & operator<< ( std::ostream & out, const TypeDecl::Data & data ) {
    7471        return out << data.kind << ", " << data.isComplete;
     72}
     73
     74// --- AggregateDecl
     75
     76// These must harmonize with the corresponding AggregateDecl::Aggregate enumerations.
     77static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };
     78
     79const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) {
     80        return aggregateNames[aggr];
    7581}
    7682
  • src/AST/Decl.hpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Thu May 9 10:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Thu May 9 10:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 17:38:33 2019
     13// Update Count     : 29
    1414//
    1515
     
    2020#include <unordered_map>
    2121#include <vector>
     22#include <algorithm>
    2223
    2324#include "FunctionSpec.hpp"
     
    2728#include "ParseNode.hpp"
    2829#include "StorageClasses.hpp"
    29 #include "TypeVar.hpp"
    3030#include "Visitor.hpp"
    31 #include "Parser/ParseNode.h"  // for DeclarationNode::Aggregate
     31#include "Common/utility.h"
     32#include "Common/SemanticError.h"                                               // error_str
    3233
    3334// Must be included in *all* AST classes; should be #undef'd at the end of the file
     
    125126        std::vector< ptr<Expr> > withExprs;
    126127
    127         FunctionDecl( const CodeLocation & loc, const std::string &name, FunctionType * type,
     128        FunctionDecl( const CodeLocation & loc, const std::string & name, FunctionType * type,
    128129                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
    129130                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {})
     
    136137        bool has_body() const { return stmts; }
    137138
    138         const DeclWithType * accept( Visitor &v ) const override { return v.visit( this ); }
     139        const DeclWithType * accept( Visitor & v ) const override { return v.visit( this ); }
    139140private:
    140141        FunctionDecl * clone() const override { return new FunctionDecl( *this ); }
     
    154155
    155156        /// Produces a name for the kind of alias
    156         virtual std::string typeString() const = 0;
     157        virtual const char * typeString() const = 0;
    157158
    158159private:
     
    163164/// Cforall type variable: `dtype T`
    164165class TypeDecl final : public NamedTypeDecl {
    165 public:
    166         TypeVar::Kind kind;
     166  public:
     167        enum Kind { Dtype, Otype, Ftype, Ttype, NUMBER_OF_KINDS };
     168
     169        Kind kind;
    167170        bool sized;
    168171        ptr<Type> init;
     
    170173        /// Data extracted from a type decl
    171174        struct Data {
    172                 TypeVar::Kind kind;
     175                Kind kind;
    173176                bool isComplete;
    174177
    175                 Data() : kind( (TypeVar::Kind)-1 ), isComplete( false ) {}
     178                Data() : kind( NUMBER_OF_KINDS ), isComplete( false ) {}
    176179                Data( const TypeDecl * d ) : kind( d->kind ), isComplete( d->sized ) {}
    177                 Data( TypeVar::Kind k, bool c ) : kind( k ), isComplete( c ) {}
     180                Data( Kind k, bool c ) : kind( k ), isComplete( c ) {}
    178181                Data( const Data & d1, const Data & d2 )
    179                 : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {}
    180 
    181                 bool operator== ( const Data & o ) const {
    182                         return kind == o.kind && isComplete == o.isComplete;
    183                 }
    184                 bool operator!= ( const Data & o ) const { return !(*this == o); }
     182                        : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {}
     183
     184                bool operator==( const Data & o ) const { return kind == o.kind && isComplete == o.isComplete; }
     185                bool operator!=( const Data & o ) const { return !(*this == o); }
    185186        };
    186187
    187         TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b,
    188                 TypeVar::Kind k, bool s, Type* i = nullptr )
    189         : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == TypeVar::Ttype || s ),
    190           init( i ) {}
    191 
    192         std::string typeString() const override;
     188        TypeDecl( const CodeLocation & loc, const std::string & name, Storage::Classes storage, Type * b,
     189                          Kind k, bool s, Type * i = nullptr )
     190                : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == Ttype || s ),
     191                init( i ) {}
     192
     193        const char * typeString() const override;
    193194        /// Produces a name for generated code
    194         std::string genTypeString() const;
     195        const char * genTypeString() const;
    195196
    196197        /// convenience accessor to match Type::isComplete()
     
    198199
    199200        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
    200 private:
     201  private:
    201202        TypeDecl * clone() const override { return new TypeDecl{ *this }; }
    202203        MUTATE_FRIEND
     
    212213        : NamedTypeDecl( loc, name, storage, b, spec ) {}
    213214
    214         std::string typeString() const override { return "typedef"; }
     215        const char * typeString() const override { return "typedef"; }
    215216
    216217        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     
    223224class AggregateDecl : public Decl {
    224225public:
     226        enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };
     227        static const char * aggrString( Aggregate aggr );
     228
    225229        std::vector<ptr<Decl>> members;
    226230        std::vector<ptr<TypeDecl>> params;
     
    237241
    238242        /// Produces a name for the kind of aggregate
    239         virtual std::string typeString() const = 0;
     243        virtual const char * typeString() const = 0;
    240244
    241245private:
     
    247251class StructDecl final : public AggregateDecl {
    248252public:
    249         DeclarationNode::Aggregate kind;
     253        Aggregate kind;
    250254
    251255        StructDecl( const CodeLocation& loc, const std::string& name,
    252                 DeclarationNode::Aggregate kind = DeclarationNode::Struct,
     256                Aggregate kind = Struct,
    253257                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    254258        : AggregateDecl( loc, name, std::move(attrs), linkage ), kind( kind ) {}
    255259
    256         bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
    257         bool is_monitor() { return kind == DeclarationNode::Monitor; }
    258         bool is_thread() { return kind == DeclarationNode::Thread; }
    259 
    260         const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
    261 
    262         std::string typeString() const override { return "struct"; }
     260        bool is_coroutine() { return kind == Coroutine; }
     261        bool is_monitor() { return kind == Monitor; }
     262        bool is_thread() { return kind == Thread; }
     263
     264        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     265
     266        const char * typeString() const override { return aggrString( kind ); }
    263267
    264268private:
     
    276280        const Decl * accept( Visitor& v ) const override { return v.visit( this ); }
    277281
    278         std::string typeString() const override { return "union"; }
     282        const char * typeString() const override { return aggrString( Union ); }
    279283
    280284private:
     
    295299        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
    296300
    297         std::string typeString() const override { return "enum"; }
     301        const char * typeString() const override { return aggrString( Enum ); }
    298302
    299303private:
     
    314318        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
    315319
    316         std::string typeString() const override { return "trait"; }
     320        const char * typeString() const override { return "trait"; }
    317321
    318322private:
     
    340344        ptr<AsmStmt> stmt;
    341345
    342         AsmDecl( const CodeLocation & loc, AsmStmt *stmt )
     346        AsmDecl( const CodeLocation & loc, AsmStmt * stmt )
    343347        : Decl( loc, "", {}, {} ), stmt(stmt) {}
    344348
    345         const AsmDecl * accept( Visitor &v ) const override { return v.visit( this ); }
    346 private:
    347         AsmDecl *clone() const override { return new AsmDecl( *this ); }
     349        const AsmDecl * accept( Visitor & v ) const override { return v.visit( this ); }
     350private:
     351        AsmDecl * clone() const override { return new AsmDecl( *this ); }
    348352        MUTATE_FRIEND
    349353};
     
    357361        : Decl( loc, "", {}, {} ), cond( condition ), msg( msg ) {}
    358362
    359         const StaticAssertDecl * accept( Visitor &v ) const override { return v.visit( this ); }
     363        const StaticAssertDecl * accept( Visitor & v ) const override { return v.visit( this ); }
    360364private:
    361365        StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
  • src/AST/Expr.cpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 15 17:00:00 2019
    11 // Last Modified By : Andrew Beach
     11// Last Modified By : Peter A. Buhr
    1212// Created On       : Thr Jun 13 13:38:00 2019
    13 // Update Count     : 2
     13// Update Count     : 6
    1414//
    1515
     
    141141// --- KeywordCastExpr
    142142
    143 const std::string & KeywordCastExpr::targetString() const {
    144         static const std::string targetStrs[] = {
    145                 "coroutine", "thread", "monitor"
    146         };
    147         static_assert(
    148                 (sizeof(targetStrs) / sizeof(targetStrs[0])) == ((unsigned long)NUMBER_OF_TARGETS),
    149                 "Each KeywordCastExpr::Target should have a corresponding string representation"
    150         );
    151         return targetStrs[(unsigned long)target];
     143const char * KeywordCastExpr::targetString() const {
     144        return AggregateDecl::aggrString( target );
    152145}
    153146
  • src/AST/Expr.hpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Fri May 10 10:30:00 2019
    11 // Last Modified By : Aaron B. Moss
     11// Last Modified By : Peter A. Buhr
    1212// Created On       : Fri May 10 10:30:00 2019
    13 // Update Count     : 1
     13// Update Count     : 7
    1414//
    1515
     
    2626#include "Fwd.hpp"        // for UniqueId
    2727#include "Label.hpp"
     28#include "Decl.hpp"
    2829#include "ParseNode.hpp"
    2930#include "Visitor.hpp"
     
    300301public:
    301302        ptr<Expr> arg;
    302         enum Target { Coroutine, Thread, Monitor, NUMBER_OF_TARGETS } target;
    303 
    304         KeywordCastExpr( const CodeLocation & loc, const Expr * a, Target t )
     303        ast::AggregateDecl::Aggregate target;
     304
     305        KeywordCastExpr( const CodeLocation & loc, const Expr * a, ast::AggregateDecl::Aggregate t )
    305306        : Expr( loc ), arg( a ), target( t ) {}
    306307
    307308        /// Get a name for the target type
    308         const std::string& targetString() const;
     309        const char * targetString() const;
    309310
    310311        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
     
    556557class AsmExpr final : public Expr {
    557558public:
    558         ptr<Expr> inout;
     559        std::string inout;
    559560        ptr<Expr> constraint;
    560561        ptr<Expr> operand;
    561562
    562         AsmExpr( const CodeLocation & loc, const Expr * io, const Expr * con, const Expr * op )
     563        AsmExpr( const CodeLocation & loc, const std::string & io, const Expr * con, const Expr * op )
    563564        : Expr( loc ), inout( io ), constraint( con ), operand( op ) {}
    564565
  • src/AST/Pass.impl.hpp

    r9fb8f01 r3d5701e  
    13001300                        maybe_accept( node, &AsmExpr::result );
    13011301                }
    1302                 maybe_accept( node, &AsmExpr::inout      );
    13031302                maybe_accept( node, &AsmExpr::constraint );
    13041303                maybe_accept( node, &AsmExpr::operand    );
  • src/AST/Print.cpp

    r9fb8f01 r3d5701e  
    10111011                os << "Asm Expression:" << endl;
    10121012                ++indent;
    1013                 if ( node->inout ) node->inout->accept( *this );
     1013                if ( !node->inout.empty() ) os << "[" << node->inout << "] ";
    10141014                if ( node->constraint ) node->constraint->accept( *this );
    10151015                if ( node->operand ) node->operand->accept( *this );
     
    13591359                preprint( node );
    13601360                os << "instance of type " << node->name
    1361                    << " (" << (node->kind == ast::TypeVar::Ftype ? "" : "not ") << "function type)";
     1361                   << " (" << (node->kind == ast::TypeDecl::Ftype ? "" : "not ") << "function type)";
    13621362                print( node->params );
    13631363
  • src/AST/Type.cpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Mon May 13 15:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Mon May 13 15:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Dec 15 16:56:28 2019
     13// Update Count     : 4
    1414//
    1515
     
    4848// --- BasicType
    4949
    50 const char *BasicType::typeNames[] = {
     50// GENERATED START, DO NOT EDIT
     51// GENERATED BY BasicTypes-gen.cc
     52const char * BasicType::typeNames[] = {
    5153        "_Bool",
    5254        "char",
     
    8688        "_Float128x _Complex",
    8789};
    88 static_assert(
    89         sizeof(BasicType::typeNames)/sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
    90         "Each basic type name should have a corresponding kind enum value"
    91 );
     90// GENERATED END
    9291
    9392// --- FunctionType
  • src/AST/Type.hpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Thu May 9 10:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Thu May 9 10:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Dec 11 21:56:46 2019
     13// Update Count     : 5
    1414//
    1515
     
    2626#include "Fwd.hpp"
    2727#include "Node.hpp"          // for Node, ptr, ptr_base
    28 #include "TypeVar.hpp"
    2928#include "Visitor.hpp"
    3029
     
    423422public:
    424423        readonly<TypeDecl> base;
    425         TypeVar::Kind kind;
     424        TypeDecl::Kind kind;
    426425
    427426        TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
    428427                std::vector<ptr<Attribute>> && as = {} )
    429428        : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
    430         TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
     429        TypeInstType( const std::string& n, TypeDecl::Kind k, CV::Qualifiers q = {},
    431430                std::vector<ptr<Attribute>> && as = {} )
    432431        : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
  • src/AST/TypeEnvironment.cpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 29 11:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Wed May 29 11:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Dec 11 21:49:13 2019
     13// Update Count     : 4
    1414//
    1515
     
    240240                return true;
    241241        } else if ( auto typeInst = dynamic_cast< const TypeInstType * >( type ) ) {
    242                 return typeInst->kind == TypeVar::Ftype;
     242                return typeInst->kind == TypeDecl::Ftype;
    243243        } else return false;
    244244}
     
    248248        bool tyVarCompatible( const TypeDecl::Data & data, const Type * type ) {
    249249                switch ( data.kind ) {
    250                   case TypeVar::Dtype:
     250                  case TypeDecl::Dtype:
    251251                        // to bind to an object type variable, the type must not be a function type.
    252252                        // if the type variable is specified to be a complete type then the incoming
     
    254254                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    255255                        return ! isFtype( type ) && ( ! data.isComplete || type->isComplete() );
    256                   case TypeVar::Ftype:
     256                  case TypeDecl::Ftype:
    257257                        return isFtype( type );
    258                   case TypeVar::Ttype:
     258                  case TypeDecl::Ttype:
    259259                        // ttype unifies with any tuple type
    260260                        return dynamic_cast< const TupleType * >( type ) || Tuples::isTtype( type );
  • src/AST/TypeEnvironment.hpp

    r9fb8f01 r3d5701e  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 29 11:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Wed May 29 11:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Dec 11 21:55:54 2019
     13// Update Count     : 3
    1414//
    1515
     
    2828#include "Type.hpp"
    2929#include "TypeSubstitution.hpp"
    30 #include "TypeVar.hpp"
    3130#include "Common/Indenter.h"
    3231#include "ResolvExpr/WidenMode.h"
     
    107106        /// Singleton class constructor from substitution
    108107        EqvClass( const std::string & v, const Type * b )
    109         : vars{ v }, bound( b ), allowWidening( false ), data( TypeVar::Dtype, false ) {}
     108        : vars{ v }, bound( b ), allowWidening( false ), data( TypeDecl::Dtype, false ) {}
    110109
    111110        /// Single-var constructor (strips qualifiers from bound type)
  • src/AST/module.mk

    r9fb8f01 r3d5701e  
    1010## Author           : Thierry Delisle
    1111## Created On       : Thu May 09 16:05:36 2019
    12 ## Last Modified By :
    13 ## Last Modified On :
    14 ## Update Count     :
     12## Last Modified By : Peter A. Buhr
     13## Last Modified On : Sat Dec 14 07:29:10 2019
     14## Update Count     : 3
    1515###############################################################################
    1616
     
    3434        AST/TypeSubstitution.cpp
    3535
    36 
    37 
    3836SRC += $(SRC_AST)
    3937SRCDEMANGLE += $(SRC_AST)
  • src/BasicTypes-gen.cc

    r9fb8f01 r3d5701e  
    273273
    274274
    275         #define Type TOP_SRCDIR "src/SynTree/Type.h"
    276         resetInput( file, Type, buffer, code, str );
    277 
    278         if ( (start = str.find( STARTMK )) == string::npos ) Abort( "start", Type );
     275        #define TypeH TOP_SRCDIR "src/SynTree/Type.h"
     276        resetInput( file, TypeH, buffer, code, str );
     277
     278        if ( (start = str.find( STARTMK )) == string::npos ) Abort( "start", TypeH );
    279279        start += sizeof( STARTMK );                                                     // includes newline
    280280        code << str.substr( 0, start );
     
    289289        code << "\t";                                                                           // indentation for end marker
    290290
    291         if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", Type );
    292         code << str.substr( start );
    293 
    294         output( file, Type, code );
     291        if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", TypeH );
     292        code << str.substr( start );
     293
     294        output( file, TypeH, code );
     295        // cout << code.str();
     296
     297
     298        #define TypeC TOP_SRCDIR "src/SynTree/Type.cc"
     299        resetInput( file, TypeC, buffer, code, str );
     300
     301        if ( (start = str.find( STARTMK )) == string::npos ) Abort( "start", TypeC );
     302        start += sizeof( STARTMK );                                                     // includes newline
     303        code << str.substr( 0, start );
     304
     305        code << BYMK << endl;
     306        code << "const char * BasicType::typeNames[] = {" << endl;
     307        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) {
     308                code << "\t\"" << graph[r].type << "\"," << endl;
     309        } // for       
     310        code << "};" << endl;
     311
     312        if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", TypeC );
     313        code << str.substr( start );
     314
     315        output( file, TypeC, code );
    295316        // cout << code.str();
    296317
    297318
    298319        // TEMPORARY DURING CHANGE OVER
    299         #define TypeAST TOP_SRCDIR "src/AST/Type.hpp"
    300         resetInput( file, TypeAST, buffer, code, str );
    301 
    302         if ( (start = str.find( STARTMK )) == string::npos ) Abort( "start", TypeAST );
     320        #define TypeH_AST TOP_SRCDIR "src/AST/Type.hpp"
     321        resetInput( file, TypeH_AST, buffer, code, str );
     322
     323        if ( (start = str.find( STARTMK )) == string::npos ) Abort( "start", TypeH_AST );
    303324        start += sizeof( STARTMK );                                                     // includes newline
    304325        code << str.substr( 0, start );
     
    313334        code << "\t";                                                                           // indentation for end marker
    314335
    315         if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", TypeAST );
    316         code << str.substr( start );
    317 
    318         output( file, TypeAST, code );
     336        if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", TypeH_AST );
     337        code << str.substr( start );
     338
     339        output( file, TypeH_AST, code );
     340        // cout << code.str();
     341
     342
     343        #define TypeC_AST TOP_SRCDIR "src/AST/Type.cpp"
     344        resetInput( file, TypeC_AST, buffer, code, str );
     345
     346        if ( (start = str.find( STARTMK )) == string::npos ) Abort( "start", TypeC_AST );
     347        start += sizeof( STARTMK );                                                     // includes newline
     348        code << str.substr( 0, start );
     349
     350        code << BYMK << endl;
     351        code << "const char * BasicType::typeNames[] = {" << endl;
     352        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) {
     353                code << "\t\"" << graph[r].type << "\"," << endl;
     354        } // for       
     355        code << "};" << endl;
     356
     357        if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", TypeC_AST );
     358        code << str.substr( start );
     359
     360        output( file, TypeC_AST, code );
    319361        // cout << code.str();
    320362
  • src/CodeGen/CodeGenerator.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May  2 10:47:00 2019
    13 // Update Count     : 497
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Feb 16 08:32:48 2020
     13// Update Count     : 532
    1414//
    1515#include "CodeGenerator.h"
     
    2323#include "InitTweak/InitTweak.h"     // for getPointerBase
    2424#include "OperatorTable.h"           // for OperatorInfo, operatorLookup
    25 #include "Parser/LinkageSpec.h"      // for Spec, Intrinsic
     25#include "SynTree/LinkageSpec.h"     // for Spec, Intrinsic
    2626#include "SynTree/Attribute.h"       // for Attribute
    2727#include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
     
    3939        int CodeGenerator::tabsize = 4;
    4040
    41         // the kinds of statements that would ideally be followed by whitespace
     41        // The kinds of statements that would ideally be followed by whitespace.
    4242        bool wantSpacing( Statement * stmt) {
    4343                return dynamic_cast< IfStmt * >( stmt ) || dynamic_cast< CompoundStmt * >( stmt ) ||
     
    7878        }
    7979
    80         /* Using updateLocation at the beginning of a node and endl
    81          * within a node should become the method of formating.
    82          */
     80        // Using updateLocation at the beginning of a node and endl within a node should become the method of formating.
    8381        void CodeGenerator::updateLocation( CodeLocation const & to ) {
    8482                // skip if linemarks shouldn't appear or if codelocation is unset
     
    9593                } else {
    9694                        output << "\n# " << to.first_line << " \"" << to.filename
    97                                << "\"\n" << indent;
     95                                   << "\"\n" << indent;
    9896                        currentLocation = to;
    9997                }
     
    131129
    132130        void CodeGenerator::genAttributes( list< Attribute * > & attributes ) {
    133           if ( attributes.empty() ) return;
     131                if ( attributes.empty() ) return;
    134132                output << "__attribute__ ((";
    135133                for ( list< Attribute * >::iterator attr( attributes.begin() );; ) {
     
    140138                                output << ")";
    141139                        } // if
    142                   if ( ++attr == attributes.end() ) break;
     140                        if ( ++attr == attributes.end() ) break;
    143141                        output << ",";                                                          // separator
    144142                } // for
     
    165163                previsit( (BaseSyntaxNode *)node );
    166164                GuardAction( [this, node](){
    167                         if ( options.printExprTypes && node->result ) {
    168                                 output << " /* " << genType( node->result, "", options ) << " */ ";
    169                         }
    170                 } );
     165                                if ( options.printExprTypes && node->result ) {
     166                                        output << " /* " << genType( node->result, "", options ) << " */ ";
     167                                }
     168                        } );
    171169        }
    172170
     
    198196                // deleted decls should never be used, so don't print them
    199197                if ( objectDecl->isDeleted && options.genC ) return;
    200                 if (objectDecl->get_name().empty() && options.genC ) {
     198
     199                // gcc allows an empty declarator (no name) for bit-fields and C states: 6.7.2.1 Structure and union specifiers,
     200                // point 4, page 113: If the (bit field) value is zero, the declaration shall have no declarator.  For anything
     201                // else, the anonymous name refers to the anonymous object for plan9 inheritance.
     202                if ( objectDecl->get_name().empty() && options.genC && ! objectDecl->get_bitfieldWidth() ) {
    201203                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    202204                        static UniqueName name = { "__anonymous_object" };
    203205                        objectDecl->set_name( name.newName() );
    204             // Stops unused parameter warnings.
    205             if ( options.anonymousUnused ) {
    206                 objectDecl->attributes.push_back( new Attribute( "unused" ) );
    207             }
     206                        // Stops unused parameter warnings.
     207                        if ( options.anonymousUnused ) {
     208                                objectDecl->attributes.push_back( new Attribute( "unused" ) );
     209                        }
    208210                }
    209211
     
    395397                extension( applicationExpr );
    396398                if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
    397                         OperatorInfo opInfo;
    398                         if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
     399                        const OperatorInfo * opInfo;
     400                        if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && ( opInfo = operatorLookup( varExpr->get_var()->get_name() ) ) ) {
    399401                                std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
    400                                 switch ( opInfo.type ) {
     402                                switch ( opInfo->type ) {
    401403                                  case OT_INDEX:
    402404                                        assert( applicationExpr->get_args().size() == 2 );
     
    419421                                                output << "(";
    420422                                                (*arg++)->accept( *visitor );
    421                                                 output << ") /* " << opInfo.inputName << " */";
     423                                                output << ") /* " << opInfo->inputName << " */";
    422424                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    423425                                                // intrinsic two parameter constructors are essentially bitwise assignment
    424426                                                output << "(";
    425427                                                (*arg++)->accept( *visitor );
    426                                                 output << opInfo.symbol;
     428                                                output << opInfo->symbol;
    427429                                                (*arg)->accept( *visitor );
    428                                                 output << ") /* " << opInfo.inputName << " */";
     430                                                output << ") /* " << opInfo->inputName << " */";
    429431                                        } else {
    430432                                                // no constructors with 0 or more than 2 parameters
     
    437439                                        assert( applicationExpr->get_args().size() == 1 );
    438440                                        output << "(";
    439                                         output << opInfo.symbol;
     441                                        output << opInfo->symbol;
    440442                                        (*arg)->accept( *visitor );
    441443                                        output << ")";
     
    446448                                        assert( applicationExpr->get_args().size() == 1 );
    447449                                        (*arg)->accept( *visitor );
    448                                         output << opInfo.symbol;
     450                                        output << opInfo->symbol;
    449451                                        break;
    450452
     
    455457                                        output << "(";
    456458                                        (*arg++)->accept( *visitor );
    457                                         output << opInfo.symbol;
     459                                        output << opInfo->symbol;
    458460                                        (*arg)->accept( *visitor );
    459461                                        output << ")";
     
    482484                extension( untypedExpr );
    483485                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) {
    484                         OperatorInfo opInfo;
    485                         if ( operatorLookup( nameExpr->name, opInfo ) ) {
     486                        const OperatorInfo * opInfo = operatorLookup( nameExpr->name );
     487                        if ( opInfo ) {
    486488                                std::list< Expression* >::iterator arg = untypedExpr->args.begin();
    487                                 switch ( opInfo.type ) {
     489                                switch ( opInfo->type ) {
    488490                                  case OT_INDEX:
    489491                                        assert( untypedExpr->args.size() == 2 );
     
    504506                                                output << "(";
    505507                                                (*arg++)->accept( *visitor );
    506                                                 output << ") /* " << opInfo.inputName << " */";
     508                                                output << ") /* " << opInfo->inputName << " */";
    507509                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    508510                                                // intrinsic two parameter constructors are essentially bitwise assignment
    509511                                                output << "(";
    510512                                                (*arg++)->accept( *visitor );
    511                                                 output << opInfo.symbol;
     513                                                output << opInfo->symbol;
    512514                                                (*arg)->accept( *visitor );
    513                                                 output << ") /* " << opInfo.inputName << " */";
     515                                                output << ") /* " << opInfo->inputName << " */";
    514516                                        } else {
    515517                                                // no constructors with 0 or more than 2 parameters
     
    517519                                                output << "(";
    518520                                                (*arg++)->accept( *visitor );
    519                                                 output << opInfo.symbol << "{ ";
     521                                                output << opInfo->symbol << "{ ";
    520522                                                genCommaList( arg, untypedExpr->args.end() );
    521                                                 output << "}) /* " << opInfo.inputName << " */";
     523                                                output << "}) /* " << opInfo->inputName << " */";
    522524                                        } // if
    523525                                        break;
     
    528530                                        assert( untypedExpr->args.size() == 1 );
    529531                                        output << "(";
    530                                         output << opInfo.symbol;
     532                                        output << opInfo->symbol;
    531533                                        (*arg)->accept( *visitor );
    532534                                        output << ")";
     
    537539                                        assert( untypedExpr->args.size() == 1 );
    538540                                        (*arg)->accept( *visitor );
    539                                         output << opInfo.symbol;
     541                                        output << opInfo->symbol;
    540542                                        break;
    541543
     
    545547                                        output << "(";
    546548                                        (*arg++)->accept( *visitor );
    547                                         output << opInfo.symbol;
     549                                        output << opInfo->symbol;
    548550                                        (*arg)->accept( *visitor );
    549551                                        output << ")";
     
    577579        void CodeGenerator::postvisit( NameExpr * nameExpr ) {
    578580                extension( nameExpr );
    579                 OperatorInfo opInfo;
    580                 if ( operatorLookup( nameExpr->name, opInfo ) ) {
    581                         if ( opInfo.type == OT_CONSTANT ) {
    582                                 output << opInfo.symbol;
     581                const OperatorInfo * opInfo = operatorLookup( nameExpr->name );
     582                if ( opInfo ) {
     583                        if ( opInfo->type == OT_CONSTANT ) {
     584                                output << opInfo->symbol;
    583585                        } else {
    584                                 output << opInfo.outputName;
     586                                output << opInfo->outputName;
    585587                        }
    586588                } else {
     
    650652        void CodeGenerator::postvisit( VariableExpr * variableExpr ) {
    651653                extension( variableExpr );
    652                 OperatorInfo opInfo;
    653                 if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
    654                         output << opInfo.symbol;
     654                const OperatorInfo * opInfo;
     655                if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && (opInfo = operatorLookup( variableExpr->get_var()->get_name() )) && opInfo->type == OT_CONSTANT ) {
     656                        output << opInfo->symbol;
    655657                } else {
    656658                        output << mangleName( variableExpr->get_var() );
     
    782784
    783785        void CodeGenerator::postvisit( AsmExpr * asmExpr ) {
    784                 if ( asmExpr->get_inout() ) {
     786                if ( !asmExpr->inout.empty() ) {
    785787                        output << "[ ";
    786                         asmExpr->get_inout()->accept( *visitor );
     788                        output << asmExpr->inout;
    787789                        output << " ] ";
    788790                } // if
    789                 asmExpr->get_constraint()->accept( *visitor );
     791                asmExpr->constraint->accept( *visitor );
    790792                output << " ( ";
    791                 asmExpr->get_operand()->accept( *visitor );
     793                asmExpr->operand->accept( *visitor );
    792794                output << " )";
    793795        }
     
    10071009                  case BranchStmt::FallThroughDefault:
    10081010                        assertf( ! options.genC, "fallthru should not reach code generation." );
    1009                   output << "fallthru";
     1011                        output << "fallthru";
    10101012                        break;
    10111013                } // switch
     
    10311033
    10321034                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
    1033                            "throw" : "throwResume");
     1035                                   "throw" : "throwResume");
    10341036                if (throwStmt->get_expr()) {
    10351037                        output << " ";
     
    10461048
    10471049                output << ((stmt->get_kind() == CatchStmt::Terminate) ?
    1048                 "catch" : "catchResume");
     1050                                   "catch" : "catchResume");
    10491051                output << "( ";
    10501052                stmt->decl->accept( *visitor );
     
    11831185
    11841186        std::string genName( DeclarationWithType * decl ) {
    1185                 CodeGen::OperatorInfo opInfo;
    1186                 if ( operatorLookup( decl->get_name(), opInfo ) ) {
    1187                         return opInfo.outputName;
     1187                const OperatorInfo * opInfo = operatorLookup( decl->get_name() );
     1188                if ( opInfo ) {
     1189                        return opInfo->outputName;
    11881190                } else {
    11891191                        return decl->get_name();
  • src/CodeGen/CodeGenerator.h

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Apr 30 12:01:00 2019
    13 // Update Count     : 57
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Feb 16 03:58:31 2020
     13// Update Count     : 62
    1414//
    1515
     
    2929namespace CodeGen {
    3030        struct CodeGenerator : public WithShortCircuiting, public WithGuards, public WithVisitorRef<CodeGenerator> {
    31           static int tabsize;
     31                static int tabsize;
    3232
    3333                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false, bool printExprTypes = false );
     
    104104                void postvisit( AsmStmt * );
    105105                void postvisit( DirectiveStmt * );
    106                 void postvisit( AsmDecl * );                            // special: statement in declaration context
     106                void postvisit( AsmDecl * );                                    // special: statement in declaration context
    107107                void postvisit( IfStmt * );
    108108                void postvisit( SwitchStmt * );
     
    147147                LabelPrinter printLabels;
    148148                Options options;
    149         public:
     149          public:
    150150                LineEnder endl;
    151         private:
     151          private:
    152152
    153153                CodeLocation currentLocation;
     
    162162        template< class Iterator >
    163163        void CodeGenerator::genCommaList( Iterator begin, Iterator end ) {
    164           if ( begin == end ) return;
     164                if ( begin == end ) return;
    165165                for ( ;; ) {
    166166                        (*begin++)->accept( *visitor );
    167                   if ( begin == end ) break;
     167                        if ( begin == end ) break;
    168168                        output << ", ";                                                         // separator
    169169                } // for
  • src/CodeGen/FixMain.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Thr Jan 12 14:11:09 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 22:16:59 2017
    13 // Update Count     : 1
     12// Last Modified On : Sun Feb 16 03:24:32 2020
     13// Update Count     : 5
    1414//
    1515
     
    1919#include <memory>
    2020
    21 #include "Parser/LinkageSpec.h"
     21#include "SynTree/LinkageSpec.h"
    2222
    2323class FunctionDecl;
     
    4242                static std::unique_ptr<FunctionDecl> main_signature;
    4343        };
    44 };
     44} // namespace CodeGen
  • src/CodeGen/FixNames.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jun 28 15:26:00 2017
    13 // Update Count     : 20
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:39:14 2019
     13// Update Count     : 21
    1414//
    1515
     
    2222#include "Common/SemanticError.h"  // for SemanticError
    2323#include "FixMain.h"               // for FixMain
    24 #include "Parser/LinkageSpec.h"    // for Cforall, isMangled
    2524#include "SymTab/Mangler.h"        // for Mangler
     25#include "SynTree/LinkageSpec.h"   // for Cforall, isMangled
    2626#include "SynTree/Constant.h"      // for Constant
    2727#include "SynTree/Declaration.h"   // for FunctionDecl, ObjectDecl, Declarat...
  • src/CodeGen/GenType.cc

    r9fb8f01 r3d5701e  
    335335                        typeString = "_Atomic " + typeString;
    336336                } // if
    337                 if ( type->get_lvalue() && ! options.genC ) {
    338                         // when not generating C code, print lvalue for debugging.
    339                         typeString = "lvalue " + typeString;
    340                 }
    341337        }
    342338} // namespace CodeGen
  • src/CodeGen/GenType.h

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Apr 30 11:47:00 2019
    13 // Update Count     : 3
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Feb 16 04:11:40 2020
     13// Update Count     : 5
    1414//
    1515
     
    2525        std::string genType( Type *type, const std::string &baseString, const Options &options );
    2626        std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false, bool lineMarks = false );
    27   std::string genPrettyType( Type * type, const std::string & baseString );
     27        std::string genPrettyType( Type * type, const std::string & baseString );
    2828} // namespace CodeGen
    2929
  • src/CodeGen/Generate.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 18 15:39:00 2017
    13 // Update Count     : 7
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Feb 16 03:01:51 2020
     13// Update Count     : 9
    1414//
    1515#include "Generate.h"
     
    2222#include "GenType.h"                 // for genPrettyType
    2323#include "Common/PassVisitor.h"      // for PassVisitor
    24 #include "Parser/LinkageSpec.h"      // for isBuiltin, isGeneratable
     24#include "SynTree/LinkageSpec.h"     // for isBuiltin, isGeneratable
    2525#include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
    2626#include "SynTree/Declaration.h"     // for Declaration
     
    6464        void generate( BaseSyntaxNode * node, std::ostream & os ) {
    6565                if ( Type * type = dynamic_cast< Type * >( node ) ) {
    66                         os << CodeGen::genPrettyType( type, "" );
     66                        os << genPrettyType( type, "" );
    6767                } else {
    6868                        PassVisitor<CodeGenerator> cgv( os, true, false, false, false );
  • src/CodeGen/OperatorTable.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 15 17:12:22 2017
    13 // Update Count     : 15
     12// Last Modified On : Tue Feb 18 15:55:01 2020
     13// Update Count     : 55
    1414//
    1515
     
    1717#include <map>        // for map, _Rb_tree_const_iterator, map<>::const_iterator
    1818#include <utility>    // for pair
     19using namespace std;
    1920
    2021#include "OperatorTable.h"
     
    2223
    2324namespace CodeGen {
    24         namespace {
    25                 const OperatorInfo tableValues[] = {
    26                         {       "?[?]",         "",             "_operator_index",                              OT_INDEX                        },
    27                         {       "?{}",          "=",    "_constructor",                                 OT_CTOR                         },
    28                         {       "^?{}",         "",             "_destructor",                                  OT_DTOR                         },
    29                         {       "?()",          "",             "_operator_call",                               OT_CALL                         },
    30                         {       "?++",          "++",   "_operator_postincr",                   OT_POSTFIXASSIGN        },
    31                         {       "?--",          "--",   "_operator_postdecr",                   OT_POSTFIXASSIGN        },
    32                         {       "*?",           "*",    "_operator_deref",                              OT_PREFIX                       },
    33                         {       "+?",           "+",    "_operator_unaryplus",                  OT_PREFIX                       },
    34                         {       "-?",           "-",    "_operator_unaryminus",                 OT_PREFIX                       },
    35                         {       "~?",           "~",    "_operator_bitnot",                             OT_PREFIX                       },
    36                         {       "!?",           "!",    "_operator_lognot",                             OT_PREFIX                       },
    37                         {       "++?",          "++",   "_operator_preincr",                    OT_PREFIXASSIGN         },
    38                         {       "--?",          "--",   "_operator_predecr",                    OT_PREFIXASSIGN         },
    39                         {       "?\\?",         "\\",   "_operator_exponential",                OT_INFIX                        },
    40                         {       "?*?",          "*",    "_operator_multiply",                   OT_INFIX                        },
    41                         {       "?/?",          "/",    "_operator_divide",                             OT_INFIX                        },
    42                         {       "?%?",          "%",    "_operator_modulus",                    OT_INFIX                        },
    43                         {       "?+?",          "+",    "_operator_add",                                OT_INFIX                        },
    44                         {       "?-?",          "-",    "_operator_subtract",                   OT_INFIX                        },
    45                         {       "?<<?",         "<<",   "_operator_shiftleft",                  OT_INFIX                        },
    46                         {       "?>>?",         ">>",   "_operator_shiftright",                 OT_INFIX                        },
    47                         {       "?<?",          "<",    "_operator_less",                               OT_INFIX                        },
    48                         {       "?>?",          ">",    "_operator_greater",                    OT_INFIX                        },
    49                         {       "?<=?",         "<=",   "_operator_lessequal",                  OT_INFIX                        },
    50                         {       "?>=?",         ">=",   "_operator_greaterequal",               OT_INFIX                        },
    51                         {       "?==?",         "==",   "_operator_equal",                              OT_INFIX                        },
    52                         {       "?!=?",         "!=",   "_operator_notequal",                   OT_INFIX                        },
    53                         {       "?&?",          "&",    "_operator_bitand",                             OT_INFIX                        },
    54                         {       "?^?",          "^",    "_operator_bitxor",                             OT_INFIX                        },
    55                         {       "?|?",          "|",    "_operator_bitor",                              OT_INFIX                        },
    56                         {       "?=?",          "=",    "_operator_assign",                             OT_INFIXASSIGN          },
    57                         {       "?\\=?",        "\\=",  "_operator_expassign",                  OT_INFIXASSIGN          },
    58                         {       "?*=?",         "*=",   "_operator_multassign",                 OT_INFIXASSIGN          },
    59                         {       "?/=?",         "/=",   "_operator_divassign",                  OT_INFIXASSIGN          },
    60                         {       "?%=?",         "%=",   "_operator_modassign",                  OT_INFIXASSIGN          },
    61                         {       "?+=?",         "+=",   "_operator_addassign",                  OT_INFIXASSIGN          },
    62                         {       "?-=?",         "-=",   "_operator_subassign",                  OT_INFIXASSIGN          },
    63                         {       "?<<=?",        "<<=",  "_operator_shiftleftassign",    OT_INFIXASSIGN          },
    64                         {       "?>>=?",        ">>=",  "_operator_shiftrightassign",   OT_INFIXASSIGN          },
    65                         {       "?&=?",         "&=",   "_operator_bitandassign",               OT_INFIXASSIGN          },
    66                         {       "?^=?",         "^=",   "_operator_bitxorassign",               OT_INFIXASSIGN          },
    67                         {       "?|=?",         "|=",   "_operator_bitorassign",                OT_INFIXASSIGN          },
    68                 };
     25        const OperatorInfo CodeGen::tableValues[] = {
     26                // inputName symbol   outputName                     friendlyName                  type
     27                {       "?[?]",   "",     "_operator_index",             "Index",                      OT_INDEX          },
     28                {       "?{}",    "=",    "_constructor",                "Constructor",                OT_CTOR           },
     29                {       "^?{}",   "",     "_destructor",                 "Destructor",                 OT_DTOR           },
     30                {       "?()",    "",     "_operator_call",              "Call Operator",              OT_CALL           },
     31                {       "?++",    "++",   "_operator_postincr",          "Postfix Increment",          OT_POSTFIXASSIGN  },
     32                {       "?--",    "--",   "_operator_postdecr",          "Postfix Decrement",          OT_POSTFIXASSIGN  },
     33                {       "*?",     "*",    "_operator_deref",             "Dereference",                OT_PREFIX         },
     34                {       "+?",     "+",    "_operator_unaryplus",         "Plus",                       OT_PREFIX         },
     35                {       "-?",     "-",    "_operator_unaryminus",        "Minus",                      OT_PREFIX         },
     36                {       "~?",     "~",    "_operator_bitnot",            "Bitwise Not",                OT_PREFIX         },
     37                {       "!?",     "!",    "_operator_lognot",            "Logical Not",                OT_PREFIX         },
     38                {       "++?",    "++",   "_operator_preincr",           "Prefix Increment",           OT_PREFIXASSIGN   },
     39                {       "--?",    "--",   "_operator_predecr",           "Prefix Decrement",           OT_PREFIXASSIGN   },
     40                {       "?\\?",   "\\",   "_operator_exponential",       "Exponentiation",             OT_INFIX          },
     41                {       "?*?",    "*",    "_operator_multiply",          "Multiplication",             OT_INFIX          },
     42                {       "?/?",    "/",    "_operator_divide",            "Division",                   OT_INFIX          },
     43                {       "?%?",    "%",    "_operator_modulus",           "Modulo",                     OT_INFIX          },
     44                {       "?+?",    "+",    "_operator_add",               "Addition",                   OT_INFIX          },
     45                {       "?-?",    "-",    "_operator_subtract",          "Substraction",               OT_INFIX          },
     46                {       "?<<?",   "<<",   "_operator_shiftleft",         "Shift Left",                 OT_INFIX          },
     47                {       "?>>?",   ">>",   "_operator_shiftright",        "Shift Right",                OT_INFIX          },
     48                {       "?<?",    "<",    "_operator_less",              "Less-than",                  OT_INFIX          },
     49                {       "?>?",    ">",    "_operator_greater",           "Greater-than",               OT_INFIX          },
     50                {       "?<=?",   "<=",   "_operator_lessequal",         "Less-than-or-Equal",         OT_INFIX          },
     51                {       "?>=?",   ">=",   "_operator_greaterequal",      "Greater-than-or-Equal",      OT_INFIX          },
     52                {       "?==?",   "==",   "_operator_equal",             "Equality",                   OT_INFIX          },
     53                {       "?!=?",   "!=",   "_operator_notequal",          "Not-Equal",                  OT_INFIX          },
     54                {       "?&?",    "&",    "_operator_bitand",            "Bitwise And",                OT_INFIX          },
     55                {       "?^?",    "^",    "_operator_bitxor",            "Bitwise Xor",                OT_INFIX          },
     56                {       "?|?",    "|",    "_operator_bitor",             "Bitwise Or",                 OT_INFIX          },
     57                {       "?=?",    "=",    "_operator_assign",            "Assignment",                 OT_INFIXASSIGN    },
     58                {       "?\\=?",  "\\=",  "_operator_expassign",         "Exponentiation Assignment",  OT_INFIXASSIGN    },
     59                {       "?*=?",   "*=",   "_operator_multassign",        "Multiplication Assignment",  OT_INFIXASSIGN    },
     60                {       "?/=?",   "/=",   "_operator_divassign",         "Division Assignment",        OT_INFIXASSIGN    },
     61                {       "?%=?",   "%=",   "_operator_modassign",         "Modulo Assignment",          OT_INFIXASSIGN    },
     62                {       "?+=?",   "+=",   "_operator_addassign",         "Addition Assignment",        OT_INFIXASSIGN    },
     63                {       "?-=?",   "-=",   "_operator_subassign",         "Substrction Assignment",     OT_INFIXASSIGN    },
     64                {       "?<<=?",  "<<=",  "_operator_shiftleftassign",   "Shift Left Assignment",      OT_INFIXASSIGN    },
     65                {       "?>>=?",  ">>=",  "_operator_shiftrightassign",  "Shift Right Assignment",     OT_INFIXASSIGN    },
     66                {       "?&=?",   "&=",   "_operator_bitandassign",      "Bitwise And Assignment",     OT_INFIXASSIGN    },
     67                {       "?^=?",   "^=",   "_operator_bitxorassign",      "Bitwise Xor Assignment",     OT_INFIXASSIGN    },
     68                {       "?|=?",   "|=",   "_operator_bitorassign",       "Bitwise Or Assignment",      OT_INFIXASSIGN    },
     69        }; // tableValues
    6970
    70                 const int numOps = sizeof( tableValues ) / sizeof( OperatorInfo );
     71        std::map< std::string, OperatorInfo > CodeGen::table;
    7172
    72                 std::map< std::string, OperatorInfo > table;
    73 
    74                 void initialize() {
    75                         for ( int i = 0; i < numOps; ++i ) {
    76                                 table[ tableValues[i].inputName ] = tableValues[i];
    77                         } // for
    78                 }
    79         } // namespace
    80 
    81         bool operatorLookup( const std::string & funcName, OperatorInfo & info ) {
    82                 static bool init = false;
    83                 if ( ! init ) {
    84                         initialize();
    85                 } // if
    86 
    87                 std::map< std::string, OperatorInfo >::const_iterator i = table.find( funcName );
    88                 if ( i == table.end() ) {
    89                         if ( isPrefix( funcName, "?`" ) ) {
    90                                 // handle literal suffixes, which are user-defined postfix operators
    91                                 info.inputName = funcName;
    92                                 info.symbol = funcName.substr(2);
    93                                 info.outputName = toString( "__operator_literal_", info.symbol );
    94                                 info.type = OT_POSTFIX;
    95                                 return true;
    96                         }
    97                         return false;
    98                 } else {
    99                         info = i->second;
    100                         return true;
    101                 } // if
     73        CodeGen::CodeGen() {
     74                enum { numOps = sizeof( tableValues ) / sizeof( OperatorInfo ) };
     75                for ( int i = 0; i < numOps; i += 1 ) {
     76                        table[ tableValues[i].inputName ] = tableValues[i];
     77                } // for
    10278        }
    10379
    104         bool isOperator( const std::string & funcName ) {
    105                 OperatorInfo info;
    106                 return operatorLookup( funcName, info );
     80        const OperatorInfo * operatorLookup( const string & funcName ) {
     81                if ( funcName.find_first_of( "?^*+-!", 0, 1 ) == string::npos ) return nullptr; // prefilter
     82                const OperatorInfo * ret = &CodeGen::table.find( funcName )->second; // must be in the table
     83                assert( ret );
     84                return ret;
    10785        }
    10886
    109         /// determines if a given function name is one of the operator types between [begin, end)
    110         template<typename Iterator>
    111         bool isOperatorType( const std::string & funcName, Iterator begin, Iterator end ) {
    112                 OperatorInfo info;
    113                 if ( operatorLookup( funcName, info ) ) {
    114                         return std::find( begin, end, info.type ) != end;
    115                 }
     87        bool isOperator( const string & funcName ) {
     88                return operatorLookup( funcName ) != nullptr;
     89        }
     90
     91        string operatorFriendlyName( const string & funcName ) {
     92                const OperatorInfo * info = operatorLookup( funcName );
     93                if ( info ) return info->friendlyName;
     94                return "";
     95        }
     96
     97        bool isConstructor( const string & funcName ) {
     98                const OperatorInfo * info = operatorLookup( funcName );
     99                if ( info ) return info->type == OT_CTOR;
    116100                return false;
    117101        }
    118102
    119         bool isConstructor( const std::string & funcName ) {
    120                 static OperatorType types[] = { OT_CTOR };
    121                 return isOperatorType( funcName, std::begin(types), std::end(types) );
     103        bool isDestructor( const string & funcName ) {
     104                const OperatorInfo * info = operatorLookup( funcName );
     105                if ( info ) return info->type == OT_DTOR;
     106                return false;
    122107        }
    123108
    124         bool isDestructor( const std::string & funcName ) {
    125                 static OperatorType types[] = { OT_DTOR };
    126                 return isOperatorType( funcName, std::begin(types), std::end(types) );
     109        bool isCtorDtor( const string & funcName ) {
     110                const OperatorInfo * info = operatorLookup( funcName );
     111                if ( info ) return info->type <= OT_CONSTRUCTOR;
     112                return false;
    127113        }
    128114
    129         bool isAssignment( const std::string & funcName ) {
    130                 static OperatorType types[] = { OT_PREFIXASSIGN, OT_POSTFIXASSIGN, OT_INFIXASSIGN };
    131                 return isOperatorType( funcName, std::begin(types), std::end(types) );
     115        bool isAssignment( const string & funcName ) {
     116                const OperatorInfo * info = operatorLookup( funcName );
     117                if ( info ) return info->type > OT_CONSTRUCTOR && info->type <= OT_ASSIGNMENT;
     118                return false;
    132119        }
    133120
    134         bool isCtorDtor( const std::string & funcName ) {
    135                 static OperatorType types[] = { OT_CTOR, OT_DTOR };
    136                 return isOperatorType( funcName, std::begin(types), std::end(types) );
     121        bool isCtorDtorAssign( const string & funcName ) {
     122                const OperatorInfo * info = operatorLookup( funcName );
     123                if ( info ) return info->type <= OT_ASSIGNMENT;
     124                return false;
    137125        }
    138126
    139         bool isCtorDtorAssign( const std::string & funcName ) {
    140                 static OperatorType types[] = { OT_CTOR, OT_DTOR, OT_PREFIXASSIGN, OT_POSTFIXASSIGN, OT_INFIXASSIGN };
    141                 return isOperatorType( funcName, std::begin(types), std::end(types) );
    142         }
     127        CodeGen codegen;                                                                        // initialize singleton package
    143128} // namespace CodeGen
    144129
    145130// Local Variables: //
    146131// tab-width: 4 //
    147 // mode: c++ //
    148 // compile-command: "make install" //
    149132// End: //
  • src/CodeGen/OperatorTable.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 22:17:11 2017
    13 // Update Count     : 6
     12// Last Modified On : Sun Feb 16 08:13:34 2020
     13// Update Count     : 26
    1414//
    1515
     
    1717
    1818#include <string>
     19#include <map>
    1920
    2021namespace CodeGen {
    2122        enum OperatorType {
    22                 OT_INDEX,
    2323                OT_CTOR,
    2424                OT_DTOR,
    25                 OT_CALL,
    26                 OT_PREFIX,
    27                 OT_POSTFIX,
    28                 OT_INFIX,
     25                OT_CONSTRUCTOR = OT_DTOR,
    2926                OT_PREFIXASSIGN,
    3027                OT_POSTFIXASSIGN,
    3128                OT_INFIXASSIGN,
     29                OT_ASSIGNMENT = OT_INFIXASSIGN,
     30                OT_CALL,
     31                OT_PREFIX,
     32                OT_INFIX,
     33                OT_POSTFIX,
     34                OT_INDEX,
    3235                OT_LABELADDRESS,
    3336                OT_CONSTANT
     
    3841                std::string symbol;
    3942                std::string outputName;
     43                std::string friendlyName;
    4044                OperatorType type;
    4145        };
    4246
     47        class CodeGen {
     48                friend const OperatorInfo * operatorLookup( const std::string & funcName );
     49
     50                static const OperatorInfo tableValues[];
     51                static std::map< std::string, OperatorInfo > table;
     52          public:
     53                CodeGen();
     54        }; // CodeGen
     55
    4356        bool isOperator( const std::string & funcName );
    44         bool operatorLookup( const std::string & funcName, OperatorInfo & info );
     57        const OperatorInfo * operatorLookup( const std::string & funcName );
     58        std::string operatorFriendlyName( const std::string & funcName );
    4559
    4660        bool isConstructor( const std::string & );
  • src/CodeGen/Options.h

    r9fb8f01 r3d5701e  
    99// Author           : Andrew Beach
    1010// Created On       : Tue Apr 30 11:36:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May  2 10:45:00 2019
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat Feb 15 18:37:06 2020
     13// Update Count     : 3
    1414//
    1515
    1616#pragma once
    1717
    18 namespace CodeGen {
    19         struct Options {
    20                 // External Options: Same thoughout a pass.
    21                 bool pretty;
    22                 bool genC;
    23                 bool lineMarks;
    24                 bool printExprTypes;
     18struct Options {
     19        // External Options: Same thoughout a pass.
     20        bool pretty;
     21        bool genC;
     22        bool lineMarks;
     23        bool printExprTypes;
    2524
    26                 // Internal Options: Changed on some recurisive calls.
    27                 bool anonymousUnused = false;
     25        // Internal Options: Changed on some recurisive calls.
     26        bool anonymousUnused = false;
    2827
    29                 Options(bool pretty, bool genC, bool lineMarks, bool printExprTypes) :
    30                         pretty(pretty), genC(genC), lineMarks(lineMarks), printExprTypes(printExprTypes)
     28        Options(bool pretty, bool genC, bool lineMarks, bool printExprTypes) :
     29                pretty(pretty), genC(genC), lineMarks(lineMarks), printExprTypes(printExprTypes)
    3130                {}
    32         };
    33 } // namespace CodeGen
     31};
    3432
    3533// Local Variables: //
  • src/CodeGen/module.mk

    r9fb8f01 r3d5701e  
    1111## Created On       : Mon Jun  1 17:49:17 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Tue Jun  2 11:17:02 2015
    14 ## Update Count     : 3
     13## Last Modified On : Sat Dec 14 07:29:42 2019
     14## Update Count     : 4
    1515###############################################################################
    1616
     
    2424        CodeGen/OperatorTable.cc
    2525
    26 
    2726SRC += $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/FixNames.cc
    2827SRCDEMANGLE += $(SRC_CODEGEN)
  • src/CodeTools/DeclStats.cc

    r9fb8f01 r3d5701e  
    99// Author           : Aaron Moss
    1010// Created On       : Wed Jan 31 16:40:00 2016
    11 // Last Modified By : Aaron Moss
    12 // Last Modified On : Wed Jan 31 16:40:00 2016
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:39:33 2019
     13// Update Count     : 2
    1414//
    1515
     
    2626#include "Common/VectorMap.h"      // for VectorMap
    2727#include "GenPoly/GenPoly.h"       // for hasPolyBase
    28 #include "Parser/LinkageSpec.h"    // for ::NoOfSpecs, Spec
     28#include "SynTree/LinkageSpec.h"   // for ::NoOfSpecs, Spec
    2929#include "SynTree/Declaration.h"   // for FunctionDecl, TypeDecl, Declaration
    3030#include "SynTree/Expression.h"    // for UntypedExpr, Expression
  • src/CodeTools/ResolvProtoDump.cc

    r9fb8f01 r3d5701e  
    99// Author           : Aaron Moss
    1010// Created On       : Tue Sep 11 09:04:00 2018
    11 // Last Modified By : Aaron Moss
    12 // Last Modified On : Tue Sep 11 09:04:00 2018
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat Feb 15 13:50:11 2020
     13// Update Count     : 3
    1414//
    1515
     
    182182
    183183                        // replace operator names
    184                         CodeGen::OperatorInfo info;
    185                         if ( CodeGen::operatorLookup( name, info ) ) {
     184                        const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( name );
     185                        if ( opInfo ) {
    186186                                ss << new_prefix(pre, "");
    187                                 op_name( info.outputName, ss );
     187                                op_name( opInfo->outputName, ss );
    188188                                return;
    189189                        }
  • src/Common/Debug.h

    r9fb8f01 r3d5701e  
    99// Author           : Rob Schluntz
    1010// Created On       : Fri Sep 1 11:09:14 2017
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Sep 1 11:09:36 2017
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:39:42 2019
     13// Update Count     : 3
    1414//
    1515
     
    2121
    2222#include "CodeGen/Generate.h"
    23 #include "Parser/LinkageSpec.h"
     23#include "SynTree/LinkageSpec.h"
    2424#include "SynTree/Declaration.h"
    2525
  • src/Common/PassVisitor.impl.h

    r9fb8f01 r3d5701e  
    24522452
    24532453        indexerScopedAccept( node->result    , *this );
    2454         maybeAccept_impl   ( node->inout     , *this );
    24552454        maybeAccept_impl   ( node->constraint, *this );
    24562455        maybeAccept_impl   ( node->operand   , *this );
     
    24642463
    24652464        indexerScopedAccept( node->result    , *this );
    2466         maybeAccept_impl   ( node->inout     , *this );
    24672465        maybeAccept_impl   ( node->constraint, *this );
    24682466        maybeAccept_impl   ( node->operand   , *this );
     
    24772475        indexerScopedMutate( node->env       , *this );
    24782476        indexerScopedMutate( node->result    , *this );
    2479         maybeMutate_impl   ( node->inout     , *this );
    24802477        maybeMutate_impl   ( node->constraint, *this );
    24812478        maybeMutate_impl   ( node->operand   , *this );
     
    33053302        VISIT_START( node );
    33063303
    3307         indexerAddStruct( node->name );
     3304        indexerAddUnion( node->name );
    33083305
    33093306        {
     
    33203317        VISIT_START( node );
    33213318
    3322         indexerAddStruct( node->name );
     3319        indexerAddUnion( node->name );
    33233320
    33243321        {
     
    33353332        MUTATE_START( node );
    33363333
    3337         indexerAddStruct( node->name );
     3334        indexerAddUnion( node->name );
    33383335
    33393336        {
  • src/Common/SemanticError.cc

    r9fb8f01 r3d5701e  
    149149// Helpers
    150150namespace ErrorHelpers {
     151        Colors colors = Colors::Auto;
     152
     153        static inline bool with_colors() {
     154                return colors == Colors::Auto ? isatty( STDERR_FILENO ) : bool(colors);
     155        }
     156
    151157        const std::string & error_str() {
    152                 static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
     158                static std::string str = with_colors() ? "\e[31merror:\e[39m " : "error: ";
    153159                return str;
    154160        }
    155161
    156162        const std::string & warning_str() {
    157                 static std::string str = isatty( STDERR_FILENO ) ? "\e[95mwarning:\e[39m " : "warning: ";
     163                static std::string str = with_colors() ? "\e[95mwarning:\e[39m " : "warning: ";
    158164                return str;
    159165        }
    160166
    161167        const std::string & bold_ttycode() {
    162                 static std::string str = isatty( STDERR_FILENO ) ? "\e[1m" : "";
     168                static std::string str = with_colors() ? "\e[1m" : "";
    163169                return str;
    164170        }
    165171
    166172        const std::string & reset_font_ttycode() {
    167                 static std::string str = isatty( STDERR_FILENO ) ? "\e[0m" : "";
     173                static std::string str = with_colors() ? "\e[0m" : "";
    168174                return str;
    169175        }
  • src/Common/SemanticError.h

    r9fb8f01 r3d5701e  
    4949struct WarningData {
    5050        const char * const name;
     51        const Severity default_severity;
    5152        const char * const message;
    52         const Severity default_severity;
    5353};
    5454
    5555constexpr WarningData WarningFormats[] = {
    56         {"self-assign"            , "self assignment of expression: %s"            , Severity::Warn},
    57         {"reference-conversion"   , "rvalue to reference conversion of rvalue: %s" , Severity::Warn},
    58         {"qualifiers-zero_t-one_t", "questionable use of type qualifier %s with %s", Severity::Warn},
    59         {"aggregate-forward-decl" , "forward declaration of nested aggregate: %s"  , Severity::Warn},
    60         {"superfluous-decl"       , "declaration does not allocate storage: %s"    , Severity::Warn},
    61         {"gcc-attributes"         , "invalid attribute: %s"                        , Severity::Warn},
     56        {"self-assign"            , Severity::Warn    , "self assignment of expression: %s"                          },
     57        {"reference-conversion"   , Severity::Warn    , "rvalue to reference conversion of rvalue: %s"               },
     58        {"qualifiers-zero_t-one_t", Severity::Warn    , "questionable use of type qualifier %s with %s"              },
     59        {"aggregate-forward-decl" , Severity::Warn    , "forward declaration of nested aggregate: %s"                },
     60        {"superfluous-decl"       , Severity::Warn    , "declaration does not allocate storage: %s"                  },
     61        {"gcc-attributes"         , Severity::Warn    , "invalid attribute: %s"                                      },
     62        {"c++-like-copy"          , Severity::Warn    , "Constructor from reference is not a valid copy constructor" },
    6263};
    6364
     
    6970        SuperfluousDecl,
    7071        GccAttributes,
     72        CppCopy,
    7173        NUMBER_OF_WARNINGS, // This MUST be the last warning
    7274};
     
    9799// Helpers
    98100namespace ErrorHelpers {
     101        enum class Colors {
     102                Never = false,
     103                Always = true,
     104                Auto,
     105        };
     106
     107        extern Colors colors;
     108
    99109        const std::string & error_str();
    100110        const std::string & warning_str();
  • src/Common/Stats/Time.h

    r9fb8f01 r3d5701e  
    99// Author           : Thierry Delisle
    1010// Created On       : Fri Mar 01 15:14:11 2019
    11 // Last Modified By :
     11// Last Modified By : Andrew Beach
    1212// Last Modified On :
    1313// Update Count     :
     
    4141                                f();
    4242                        }
     43
     44                        template<typename ret_t = void, typename func_t, typename... arg_t>
     45                        inline ret_t TimeCall(
     46                                        const char *, func_t func, arg_t&&... arg) {
     47                                return func(std::forward<arg_t>(arg)...);
     48                        }
    4349#               else
    4450                        void StartGlobal();
     
    5965                                func();
    6066                        }
     67
     68                        template<typename ret_t = void, typename func_t, typename... arg_t>
     69                        inline ret_t TimeCall(
     70                                        const char * name, func_t func, arg_t&&... arg) {
     71                                BlockGuard guard(name);
     72                                return func(std::forward<arg_t>(arg)...);
     73                        }
    6174#               endif
    6275        }
  • src/Common/utility.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 24 14:28:19 2019
    13 // Update Count     : 41
     12// Last Modified On : Tue Feb 11 13:00:36 2020
     13// Update Count     : 50
    1414//
    1515
     
    2929#include <utility>
    3030#include <vector>
     31#include <cstring>                                                                              // memcmp
    3132
    3233#include "Common/Indenter.h"
     
    264265}
    265266
    266 /// determines if `pref` is a prefix of `str`
    267 static inline bool isPrefix( const std::string & str, const std::string & pref ) {
     267// determines if pref is a prefix of str
     268static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) {
    268269        if ( pref.size() > str.size() ) return false;
    269         auto its = std::mismatch( pref.begin(), pref.end(), str.begin() );
    270         return its.first == pref.end();
     270    return 0 == memcmp( str.c_str() + start, pref.c_str(), pref.size() );
     271        // return prefix == full.substr(0, prefix.size()); // for future, requires c++17
    271272}
    272273
  • src/Concurrency/Keywords.cc

    r9fb8f01 r3d5701e  
    1111// Last Modified By :
    1212// Last Modified On :
    13 // Update Count     : 5
     13// Update Count     : 10
    1414//
    1515
     
    2424#include "CodeGen/OperatorTable.h" // for isConstructor
    2525#include "InitTweak/InitTweak.h"   // for getPointerBase
    26 #include "Parser/LinkageSpec.h"    // for Cforall
     26#include "SynTree/LinkageSpec.h"   // for Cforall
    2727#include "SynTree/Constant.h"      // for Constant
    2828#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    5353          public:
    5454
    55                 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, KeywordCastExpr::Target cast_target ) :
     55                ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, AggregateDecl::Aggregate cast_target ) :
    5656                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ), cast_target( cast_target ) {}
    5757
     
    5959
    6060                Declaration * postmutate( StructDecl * decl );
     61                DeclarationWithType * postmutate( FunctionDecl * decl );
    6162
    6263                void handle( StructDecl * );
     
    7576                const std::string context_error;
    7677                bool needs_main;
    77                 KeywordCastExpr::Target cast_target;
    78 
    79                 StructDecl* type_decl = nullptr;
     78                AggregateDecl::Aggregate cast_target;
     79
     80                StructDecl   * type_decl = nullptr;
     81                FunctionDecl * dtor_decl = nullptr;
    8082        };
    8183
     
    8688        //      int data;                                  int data;
    8789        //      a_struct_t more_data;                      a_struct_t more_data;
    88         //                                =>             thread_desc __thrd_d;
     90        //                                =>             $thread __thrd_d;
    8991        // };                                        };
    90         //                                           static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; }
     92        //                                           static inline $thread * get_thread( MyThread * this ) { return &this->__thrd_d; }
    9193        //
    9294        class ThreadKeyword final : public ConcurrentSueKeyword {
     
    9496
    9597                ThreadKeyword() : ConcurrentSueKeyword(
    96                         "thread_desc",
     98                        "$thread",
    9799                        "__thrd",
    98100                        "get_thread",
    99                         "thread keyword requires threads to be in scope, add #include <thread.hfa>",
     101                        "thread keyword requires threads to be in scope, add #include <thread.hfa>\n",
    100102                        true,
    101                         KeywordCastExpr::Thread
     103                        AggregateDecl::Thread
    102104                )
    103105                {}
     
    118120        //      int data;                                  int data;
    119121        //      a_struct_t more_data;                      a_struct_t more_data;
    120         //                                =>             coroutine_desc __cor_d;
     122        //                                =>             $coroutine __cor_d;
    121123        // };                                        };
    122         //                                           static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
     124        //                                           static inline $coroutine * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
    123125        //
    124126        class CoroutineKeyword final : public ConcurrentSueKeyword {
     
    126128
    127129                CoroutineKeyword() : ConcurrentSueKeyword(
    128                         "coroutine_desc",
     130                        "$coroutine",
    129131                        "__cor",
    130132                        "get_coroutine",
    131                         "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>",
     133                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n",
    132134                        true,
    133                         KeywordCastExpr::Coroutine
     135                        AggregateDecl::Coroutine
    134136                )
    135137                {}
     
    150152        //      int data;                                  int data;
    151153        //      a_struct_t more_data;                      a_struct_t more_data;
    152         //                                =>             monitor_desc __mon_d;
     154        //                                =>             $monitor __mon_d;
    153155        // };                                        };
    154         //                                           static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
     156        //                                           static inline $monitor * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
    155157        //
    156158        class MonitorKeyword final : public ConcurrentSueKeyword {
     
    158160
    159161                MonitorKeyword() : ConcurrentSueKeyword(
    160                         "monitor_desc",
     162                        "$monitor",
    161163                        "__mon",
    162164                        "get_monitor",
    163                         "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>",
     165                        "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n",
    164166                        false,
    165                         KeywordCastExpr::Monitor
     167                        AggregateDecl::Monitor
    166168                )
    167169                {}
     
    180182        //Handles mutex routines definitions :
    181183        // void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
    182         //                                                                       monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     184        //                                                                       $monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
    183185        //                                                                       monitor_guard_t __guard = { __monitors, 2 };
    184186        //    /*Some code*/                                       =>           /*Some code*/
     
    219221        //Handles mutex routines definitions :
    220222        // void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
    221         //                                                                       monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     223        //                                                                       $monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
    222224        //                                                                       monitor_guard_t __guard = { __monitors, 2 };
    223225        //    /*Some code*/                                       =>           /*Some code*/
     
    284286        }
    285287
     288        DeclarationWithType * ConcurrentSueKeyword::postmutate( FunctionDecl * decl ) {
     289                if( !type_decl ) return decl;
     290                if( !CodeGen::isDestructor( decl->name ) ) return decl;
     291
     292                auto params = decl->type->parameters;
     293                if( params.size() != 1 ) return decl;
     294
     295                auto type = dynamic_cast<ReferenceType*>( params.front()->get_type() );
     296                if( !type ) return decl;
     297
     298                auto stype = dynamic_cast<StructInstType*>( type->base );
     299                if( !stype ) return decl;
     300                if( stype->baseStruct != type_decl ) return decl;
     301
     302                if( !dtor_decl ) dtor_decl = decl;
     303                return decl;
     304        }
     305
    286306        Expression * ConcurrentSueKeyword::postmutate( KeywordCastExpr * cast ) {
    287307                if ( cast_target == cast->target ) {
    288                         // convert (thread &)t to (thread_desc &)*get_thread(t), etc.
     308                        // convert (thread &)t to ($thread &)*get_thread(t), etc.
    289309                        if( !type_decl ) SemanticError( cast, context_error );
    290                         Expression * arg = cast->arg;
    291                         cast->arg = nullptr;
    292                         delete cast;
    293                         return new CastExpr(
    294                                 UntypedExpr::createDeref(
    295                                         new UntypedExpr( new NameExpr( getter_name ), { arg } )
    296                                 ),
    297                                 new ReferenceType(
    298                                         noQualifiers,
    299                                         new StructInstType( noQualifiers, type_decl ) )
    300                                 );
     310                        if( !dtor_decl ) SemanticError( cast, context_error );
     311                        assert( cast->result == nullptr );
     312                        cast->set_result( new ReferenceType( noQualifiers, new StructInstType( noQualifiers, type_decl ) ) );
     313                        cast->concrete_target.field  = field_name;
     314                        cast->concrete_target.getter = getter_name;
    301315                }
    302316                return cast;
     
    308322
    309323                if( !type_decl ) SemanticError( decl, context_error );
     324                if( !dtor_decl ) SemanticError( decl, context_error );
    310325
    311326                FunctionDecl * func = forwardDeclare( decl );
     
    362377                        get_type,
    363378                        nullptr,
    364                         noAttributes,
     379                        { new Attribute("const") },
    365380                        Type::Inline
    366381                );
     
    501516        void MutexKeyword::postvisit(StructDecl* decl) {
    502517
    503                 if( decl->name == "monitor_desc" && decl->body ) {
     518                if( decl->name == "$monitor" && decl->body ) {
    504519                        assert( !monitor_decl );
    505520                        monitor_decl = decl;
     
    597612                );
    598613
    599                 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     614                //$monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
    600615                body->push_front( new DeclStmt( monitors) );
    601616        }
     
    658673                );
    659674
    660                 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     675                //$monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
    661676                body->push_front( new DeclStmt( monitors) );
    662677        }
     
    666681        //=============================================================================================
    667682        void ThreadStarter::previsit( StructDecl * decl ) {
    668                 if( decl->name == "thread_desc" && decl->body ) {
     683                if( decl->name == "$thread" && decl->body ) {
    669684                        assert( !thread_decl );
    670685                        thread_decl = decl;
     
    701716                                new UntypedExpr(
    702717                                        new NameExpr( "__thrd_start" ),
    703                                         { new VariableExpr( param ) }
     718                                        { new VariableExpr( param ), new NameExpr("main") }
    704719                                )
    705720                        )
  • src/Concurrency/Waitfor.cc

    r9fb8f01 r3d5701e  
    1111// Last Modified By :
    1212// Last Modified On :
    13 // Update Count     : 7
     13// Update Count     : 12
    1414//
    1515
     
    2323#include "Common/PassVisitor.h"    // for PassVisitor
    2424#include "Common/SemanticError.h"  // for SemanticError
     25#include "Common/UniqueName.h"     // for UniqueName
    2526#include "Common/utility.h"        // for deleteAll, map_range
    2627#include "CodeGen/OperatorTable.h" // for isConstructor
    2728#include "InitTweak/InitTweak.h"   // for getPointerBase
    28 #include "Parser/LinkageSpec.h"    // for Cforall
    2929#include "ResolvExpr/Resolver.h"   // for findVoidExpression
     30#include "SynTree/LinkageSpec.h"   // for Cforall
    3031#include "SynTree/Constant.h"      // for Constant
    3132#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    4142void foo() {
    4243        while( true ) {
    43                 when( a < 1 ) waitfor( f, a ) { bar(); }
     44                when( a < 1 ) waitfor( f : a ) { bar(); }
    4445                or timeout( swagl() );
    45                 or waitfor( g, a ) { baz(); }
    46                 or waitfor( ^?{}, a ) { break; }
     46                or waitfor( g : a ) { baz(); }
     47                or waitfor( ^?{} : a ) { break; }
    4748                or waitfor( ^?{} ) { break; }
    4849        }
     
    243244                        decl_mask = decl;
    244245                }
    245                 else if( decl->name == "monitor_desc" ) {
     246                else if( decl->name == "$monitor" ) {
    246247                        assert( !decl_monitor );
    247248                        decl_monitor = decl;
  • src/ControlStruct/ExceptTranslate.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 13 18:15:29 2019
    13 // Update Count     : 11
     12// Last Modified On : Fri Dec 13 23:40:15 2019
     13// Update Count     : 12
    1414//
    1515
     
    2424#include "Common/SemanticError.h"     // for SemanticError
    2525#include "Common/utility.h"           // for CodeLocation
    26 #include "Parser/LinkageSpec.h"       // for Cforall
     26#include "SynTree/LinkageSpec.h"      // for Cforall
    2727#include "SynTree/Attribute.h"        // for Attribute
    2828#include "SynTree/Constant.h"         // for Constant
  • src/ControlStruct/LabelFixer.cc

    r9fb8f01 r3d5701e  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar 11 22:26:02 2019
    13 // Update Count     : 159
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jan 21 10:32:00 2020
     13// Update Count     : 160
    1414//
    1515
     
    2121#include "ControlStruct/LabelGenerator.h"  // for LabelGenerator
    2222#include "LabelFixer.h"
    23 #include "MLEMutator.h"                    // for MLEMutator
     23#include "MLEMutator.h"                    // for MultiLevelExitMutator
    2424#include "SynTree/Declaration.h"           // for FunctionDecl
    2525#include "SynTree/Expression.h"            // for NameExpr, Expression, Unty...
     
    4444
    4545        void LabelFixer::postvisit( FunctionDecl * functionDecl ) {
    46                 PassVisitor<MLEMutator> mlemut( resolveJumps(), generator );
    47                 functionDecl->acceptMutator( mlemut );
     46                PassVisitor<MultiLevelExitMutator> mlem( resolveJumps(), generator );
     47                // We start in the body so we can stop when we hit another FunctionDecl.
     48                maybeMutate( functionDecl->statements, mlem );
    4849        }
    4950
     
    7576
    7677
    77         // sets the definition of the labelTable entry to be the provided statement for every label in the list
    78         // parameter. Happens for every kind of statement
     78        // Sets the definition of the labelTable entry to be the provided statement for every label in
     79        // the list parameter. Happens for every kind of statement.
    7980        Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) {
    8081                assert( definition != 0 );
    8182                assert( llabel.size() > 0 );
    82 
    83                 Entry * e = new Entry( definition );
    8483
    8584                for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
     
    8786                        l.set_statement( definition ); // attach statement to the label to be used later
    8887                        if ( labelTable.find( l ) == labelTable.end() ) {
    89                                 // all labels on this statement need to use the same entry, so this should only be created once
     88                                // All labels on this statement need to use the same entry,
     89                                // so this should only be created once.
    9090                                // undefined and unused until now, add an entry
    91                                 labelTable[ l ] =  e;
     91                                labelTable[ l ] = new Entry( definition );
    9292                        } else if ( labelTable[ l ]->defined() ) {
    9393                                // defined twice, error
    94                                 SemanticError( l.get_statement()->location, "Duplicate definition of label: " + l.get_name() );
    95                         }       else {
     94                                SemanticError( l.get_statement()->location,
     95                                        "Duplicate definition of label: " + l.get_name() );
     96                        } else {
    9697                                // used previously, but undefined until now -> link with this entry
     98                                // Question: Is changing objects important?
    9799                                delete labelTable[ l ];
    98                                 labelTable[ l ] = e;
     100                                labelTable[ l ] = new Entry( definition );
    99101                        } // if
    100102                } // for
    101103
    102                 // produce one of the labels attached to this statement to be temporarily used as the canonical label
     104                // Produce one of the labels attached to this statement to be temporarily used as the
     105                // canonical label.
    103106                return labelTable[ llabel.front() ]->get_label();
    104107        }
  • src/ControlStruct/MLEMutator.cc

    r9fb8f01 r3d5701e  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  8 17:08:25 2018
    13 // Update Count     : 219
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jan 22 11:50:00 2020
     13// Update Count     : 223
    1414//
    1515
     
    3333
    3434namespace ControlStruct {
    35         MLEMutator::~MLEMutator() {
     35        MultiLevelExitMutator::~MultiLevelExitMutator() {
    3636                delete targetTable;
    3737                targetTable = 0;
    3838        }
    3939        namespace {
    40                 bool isLoop( const MLEMutator::Entry & e ) { return dynamic_cast< WhileStmt * >( e.get_controlStructure() ) || dynamic_cast< ForStmt * >( e.get_controlStructure() ); }
    41                 bool isSwitch( const MLEMutator::Entry & e ) { return dynamic_cast< SwitchStmt *>( e.get_controlStructure() ); }
    42 
    43                 bool isBreakTarget( const MLEMutator::Entry & e ) { return isLoop( e ) || isSwitch( e ) || dynamic_cast< CompoundStmt *>( e.get_controlStructure() ); }
    44                 bool isContinueTarget( const MLEMutator::Entry & e ) { return isLoop( e ); }
    45                 bool isFallthroughTarget( const MLEMutator::Entry & e ) { return dynamic_cast< CaseStmt *>( e.get_controlStructure() );; }
    46                 bool isFallthroughDefaultTarget( const MLEMutator::Entry & e ) { return isSwitch( e ); }
     40                bool isLoop( const MultiLevelExitMutator::Entry & e ) {
     41                        return dynamic_cast< WhileStmt * >( e.get_controlStructure() )
     42                                || dynamic_cast< ForStmt * >( e.get_controlStructure() );
     43                }
     44                bool isSwitch( const MultiLevelExitMutator::Entry & e ) {
     45                        return dynamic_cast< SwitchStmt *>( e.get_controlStructure() );
     46                }
     47
     48                bool isBreakTarget( const MultiLevelExitMutator::Entry & e ) {
     49                        return isLoop( e ) || isSwitch( e )
     50                                || dynamic_cast< CompoundStmt *>( e.get_controlStructure() );
     51                }
     52                bool isContinueTarget( const MultiLevelExitMutator::Entry & e ) {
     53                        return isLoop( e );
     54                }
     55                bool isFallthroughTarget( const MultiLevelExitMutator::Entry & e ) {
     56                        return dynamic_cast< CaseStmt *>( e.get_controlStructure() );
     57                }
     58                bool isFallthroughDefaultTarget( const MultiLevelExitMutator::Entry & e ) {
     59                        return isSwitch( e );
     60                }
    4761        } // namespace
     62
     63        void MultiLevelExitMutator::premutate( FunctionDecl * ) {
     64                visit_children = false;
     65        }
    4866
    4967        // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us
    5068        // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the
    5169        // body of statements
    52         void MLEMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {
     70        void MultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {
    5371                SemanticErrorException errors;
    5472
     
    8199        }
    82100
    83         void MLEMutator::premutate( CompoundStmt *cmpndStmt ) {
     101        void MultiLevelExitMutator::premutate( CompoundStmt *cmpndStmt ) {
    84102                visit_children = false;
    85103                bool labeledBlock = !(cmpndStmt->labels.empty());
     
    118136                        }
    119137                }
    120                 assertf( false, "Could not find label '%s' on statement %s", originalTarget.get_name().c_str(), toString( stmt ).c_str() );
    121         }
    122 
    123 
    124         Statement *MLEMutator::postmutate( BranchStmt *branchStmt ) throw ( SemanticErrorException ) {
     138                assertf( false, "Could not find label '%s' on statement %s",
     139                        originalTarget.get_name().c_str(), toString( stmt ).c_str() );
     140        }
     141
     142
     143        Statement *MultiLevelExitMutator::postmutate( BranchStmt *branchStmt )
     144                        throw ( SemanticErrorException ) {
    125145                std::string originalTarget = branchStmt->originalTarget;
    126146
     
    230250        }
    231251
    232         Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
     252        Statement *MultiLevelExitMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
     253                // only generate these when needed
     254                if( !e.isContUsed() && !e.isBreakUsed() ) return bodyLoop;
     255
    233256                // ensure loop body is a block
    234                 CompoundStmt *newBody;
    235                 if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
    236                         newBody = new CompoundStmt();
    237                         newBody->get_kids().push_back( bodyLoop );
    238                 } // if
    239 
    240                 // only generate these when needed
     257                CompoundStmt * newBody = new CompoundStmt();
     258                newBody->get_kids().push_back( bodyLoop );
    241259
    242260                if ( e.isContUsed() ) {
     
    255273
    256274        template< typename LoopClass >
    257         void MLEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
     275        void MultiLevelExitMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
    258276                // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
    259277                // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
     
    266284
    267285        template< typename LoopClass >
    268         Statement * MLEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
     286        Statement * MultiLevelExitMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
    269287                assert( ! enclosingControlStructures.empty() );
    270288                Entry &e = enclosingControlStructures.back();
     
    277295        }
    278296
    279         void MLEMutator::premutate( WhileStmt * whileStmt ) {
     297        void MultiLevelExitMutator::premutate( WhileStmt * whileStmt ) {
    280298                return prehandleLoopStmt( whileStmt );
    281299        }
    282300
    283         void MLEMutator::premutate( ForStmt * forStmt ) {
     301        void MultiLevelExitMutator::premutate( ForStmt * forStmt ) {
    284302                return prehandleLoopStmt( forStmt );
    285303        }
    286304
    287         Statement * MLEMutator::postmutate( WhileStmt * whileStmt ) {
     305        Statement * MultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) {
    288306                return posthandleLoopStmt( whileStmt );
    289307        }
    290308
    291         Statement * MLEMutator::postmutate( ForStmt * forStmt ) {
     309        Statement * MultiLevelExitMutator::postmutate( ForStmt * forStmt ) {
    292310                return posthandleLoopStmt( forStmt );
    293311        }
    294312
    295         void MLEMutator::premutate( IfStmt * ifStmt ) {
     313        void MultiLevelExitMutator::premutate( IfStmt * ifStmt ) {
    296314                // generate a label for breaking out of a labeled if
    297315                bool labeledBlock = !(ifStmt->get_labels().empty());
     
    303321        }
    304322
    305         Statement * MLEMutator::postmutate( IfStmt * ifStmt ) {
     323        Statement * MultiLevelExitMutator::postmutate( IfStmt * ifStmt ) {
    306324                bool labeledBlock = !(ifStmt->get_labels().empty());
    307325                if ( labeledBlock ) {
     
    313331        }
    314332
    315         void MLEMutator::premutate( CaseStmt *caseStmt ) {
     333        void MultiLevelExitMutator::premutate( TryStmt * tryStmt ) {
     334                // generate a label for breaking out of a labeled if
     335                bool labeledBlock = !(tryStmt->get_labels().empty());
     336                if ( labeledBlock ) {
     337                        Label brkLabel = generator->newLabel("blockBreak", tryStmt);
     338                        enclosingControlStructures.push_back( Entry( tryStmt, brkLabel ) );
     339                        GuardAction( [this]() { enclosingControlStructures.pop_back(); } );
     340                } // if
     341        }
     342
     343        Statement * MultiLevelExitMutator::postmutate( TryStmt * tryStmt ) {
     344                bool labeledBlock = !(tryStmt->get_labels().empty());
     345                if ( labeledBlock ) {
     346                        if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
     347                                set_breakLabel( enclosingControlStructures.back().useBreakExit() );
     348                        } // if
     349                } // if
     350                return tryStmt;
     351        }
     352
     353        void MultiLevelExitMutator::premutate( FinallyStmt * ) {
     354                GuardAction([this, old = std::move(enclosingControlStructures)]() {
     355                        enclosingControlStructures = std::move(old);
     356                });
     357                enclosingControlStructures = std::list<Entry>();
     358                GuardValue( inFinally );
     359                inFinally = true;
     360        }
     361
     362        void MultiLevelExitMutator::premutate( ReturnStmt *returnStmt ) {
     363                if ( inFinally ) {
     364                        SemanticError( returnStmt->location, "'return' may not appear in a finally clause" );
     365                }
     366        }
     367
     368        void MultiLevelExitMutator::premutate( CaseStmt *caseStmt ) {
    316369                visit_children = false;
    317370
     
    352405        }
    353406
    354         void MLEMutator::premutate( SwitchStmt *switchStmt ) {
     407        void MultiLevelExitMutator::premutate( SwitchStmt *switchStmt ) {
    355408                // generate a label for breaking out of a labeled switch
    356409                Label brkLabel = generator->newLabel("switchBreak", switchStmt);
     
    378431        }
    379432
    380         Statement * MLEMutator::postmutate( SwitchStmt * switchStmt ) {
     433        Statement * MultiLevelExitMutator::postmutate( SwitchStmt * switchStmt ) {
    381434                Entry &e = enclosingControlStructures.back();
    382435                assert ( e == switchStmt );
  • src/ControlStruct/MLEMutator.h

    r9fb8f01 r3d5701e  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  8 16:42:32 2018
    13 // Update Count     : 41
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jan 22 11:50:00 2020
     13// Update Count     : 48
    1414//
    1515
     
    3030        class LabelGenerator;
    3131
    32         class MLEMutator : public WithVisitorRef<MLEMutator>, public WithShortCircuiting, public WithGuards {
     32        class MultiLevelExitMutator : public WithVisitorRef<MultiLevelExitMutator>,
     33                        public WithShortCircuiting, public WithGuards {
    3334          public:
    3435                class Entry;
    35                 MLEMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
    36                 ~MLEMutator();
     36                MultiLevelExitMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) :
     37                        targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
     38                ~MultiLevelExitMutator();
     39
     40                void premutate( FunctionDecl * );
    3741
    3842                void premutate( CompoundStmt *cmpndStmt );
     
    4751                void premutate( SwitchStmt *switchStmt );
    4852                Statement * postmutate( SwitchStmt *switchStmt );
     53                void premutate( ReturnStmt *returnStmt );
     54                void premutate( TryStmt *tryStmt );
     55                Statement * postmutate( TryStmt *tryStmt );
     56                void premutate( FinallyStmt *finallyStmt );
    4957
    5058                Statement *mutateLoop( Statement *bodyLoop, Entry &e );
     
    7381                        explicit Entry( SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) :
    7482                                stmt( stmt ), breakExit( breakExit ), fallDefaultExit( fallDefaultExit ) {}
     83
     84                        explicit Entry( TryStmt *stmt, Label breakExit ) :
     85                                stmt( stmt ), breakExit( breakExit ) {}
    7586
    7687                        bool operator==( const Statement *other ) { return stmt == other; }
     
    105116                Label breakLabel;
    106117                LabelGenerator *generator;
     118                bool inFinally = false;
    107119
    108120                template< typename LoopClass >
  • src/ControlStruct/Mutate.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug  4 11:39:08 2016
    13 // Update Count     : 9
     12// Last Modified On : Sun Feb 16 03:22:07 2020
     13// Update Count     : 10
    1414//
    1515
     
    3737                mutateAll( translationUnit, formut );
    3838        }
    39 } // namespace CodeGen
     39} // namespace ControlStruct
    4040
    4141// Local Variables: //
  • src/GenPoly/Box.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 21 15:49:59 2017
    13 // Update Count     : 346
     12// Last Modified On : Fri Dec 13 23:40:34 2019
     13// Update Count     : 347
    1414//
    1515
     
    3737#include "InitTweak/InitTweak.h"         // for getFunctionName, isAssignment
    3838#include "Lvalue.h"                      // for generalizedLvalue
    39 #include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
    4039#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4140#include "ResolvExpr/typeops.h"          // for typesCompatible
     
    4443#include "SymTab/Indexer.h"              // for Indexer
    4544#include "SymTab/Mangler.h"              // for Mangler
     45#include "SynTree/LinkageSpec.h"         // for C, Spec, Cforall, Intrinsic
    4646#include "SynTree/Attribute.h"           // for Attribute
    4747#include "SynTree/Constant.h"            // for Constant
     
    837837                                        deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    838838                                        deref->result = arg->get_type()->clone();
    839                                         deref->result->set_lvalue( true );
    840839                                        return deref;
    841840                                } // if
  • src/GenPoly/Lvalue.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:11:18 2017
    13 // Update Count     : 5
     12// Last Modified On : Fri Dec 13 23:14:38 2019
     13// Update Count     : 7
    1414//
    1515
     
    1717#include <string>                        // for string
    1818
     19#include "Common/UniqueName.h"
    1920#include "Common/PassVisitor.h"
    2021#include "GenPoly.h"                     // for isPolyType
     
    2223
    2324#include "InitTweak/InitTweak.h"
    24 #include "Parser/LinkageSpec.h"          // for Spec, isBuiltin, Intrinsic
    2525#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
    2626#include "ResolvExpr/Unify.h"            // for unify
    2727#include "ResolvExpr/typeops.h"
    2828#include "SymTab/Indexer.h"              // for Indexer
     29#include "SynTree/LinkageSpec.h"         // for Spec, isBuiltin, Intrinsic
    2930#include "SynTree/Declaration.h"         // for Declaration, FunctionDecl
    3031#include "SynTree/Expression.h"          // for Expression, ConditionalExpr
     
    5455                                delete ret->result;
    5556                                ret->result = base->clone();
    56                                 ret->result->set_lvalue( true );
    5757                                return ret;
    5858                        } else {
     
    6161                }
    6262
    63                 struct ReferenceConversions final : public WithStmtsToAdd {
     63                struct ReferenceConversions final : public WithStmtsToAdd, public WithGuards {
    6464                        Expression * postmutate( CastExpr * castExpr );
    6565                        Expression * postmutate( AddressExpr * addrExpr );
     
    7272
    7373                struct FixIntrinsicResult final : public WithGuards {
     74                        enum {
     75                                NoSkip,
     76                                Skip,
     77                                SkipInProgress
     78                        } skip = NoSkip;
     79
     80                        void premutate( AsmExpr * ) { GuardValue( skip ); skip = Skip; }
     81                        void premutate( ApplicationExpr * ) { GuardValue( skip ); skip = (skip == Skip) ? SkipInProgress : NoSkip; }
     82
     83
    7484                        Expression * postmutate( ApplicationExpr * appExpr );
    7585                        void premutate( FunctionDecl * funcDecl );
     
    163173
    164174                Expression * FixIntrinsicResult::postmutate( ApplicationExpr * appExpr ) {
    165                         if ( isIntrinsicReference( appExpr ) ) {
     175                        if ( skip != SkipInProgress && isIntrinsicReference( appExpr ) ) {
    166176                                // eliminate reference types from intrinsic applications - now they return lvalues
    167177                                ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result );
    168178                                appExpr->result = result->base->clone();
    169                                 appExpr->result->set_lvalue( true );
    170179                                if ( ! inIntrinsic ) {
    171180                                        // when not in an intrinsic function, add a cast to
     
    436445                                delete ret->result;
    437446                                ret->result = castExpr->result;
    438                                 ret->result->set_lvalue( true ); // ensure result is lvalue
     447                                assert( ret->get_lvalue() ); // ensure result is lvalue
    439448                                castExpr->env = nullptr;
    440449                                castExpr->arg = nullptr;
  • src/GenPoly/Specialize.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 07:53:59 2017
    13 // Update Count     : 31
     12// Last Modified On : Fri Dec 13 23:40:49 2019
     13// Update Count     : 32
    1414//
    1515
     
    2727#include "GenPoly.h"                     // for getFunctionType
    2828#include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    29 #include "Parser/LinkageSpec.h"          // for C
    3029#include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
    3130#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
    3231#include "Specialize.h"
     32#include "SynTree/LinkageSpec.h"         // for C
    3333#include "SynTree/Attribute.h"           // for Attribute
    3434#include "SynTree/Declaration.h"         // for FunctionDecl, DeclarationWit...
  • src/InitTweak/FixGlobalInit.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 04 15:14:56 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 07:53:11 2017
    13 // Update Count     : 18
     12// Last Modified On : Fri Dec 13 23:41:10 2019
     13// Update Count     : 19
    1414//
    1515
     
    2323#include "Common/UniqueName.h"     // for UniqueName
    2424#include "InitTweak.h"             // for isIntrinsicSingleArgCallStmt
    25 #include "Parser/LinkageSpec.h"    // for C
     25#include "SynTree/LinkageSpec.h"   // for C
    2626#include "SynTree/Attribute.h"     // for Attribute
    2727#include "SynTree/Constant.h"      // for Constant
  • src/InitTweak/FixInit.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 13 18:15:56 2019
    13 // Update Count     : 76
     12// Last Modified On : Sun Feb 16 04:17:07 2020
     13// Update Count     : 82
    1414//
    1515#include "FixInit.h"
     
    3838#include "GenPoly/GenPoly.h"           // for getFunctionType
    3939#include "InitTweak.h"                 // for getFunctionName, getCallArg
    40 #include "Parser/LinkageSpec.h"        // for C, Spec, Cforall, isBuiltin
    4140#include "ResolvExpr/Resolver.h"       // for findVoidExpression
    4241#include "ResolvExpr/typeops.h"        // for typesCompatible
     
    4443#include "SymTab/Indexer.h"            // for Indexer
    4544#include "SymTab/Mangler.h"            // for Mangler
     45#include "SynTree/LinkageSpec.h"       // for C, Spec, Cforall, isBuiltin
    4646#include "SynTree/Attribute.h"         // for Attribute
    4747#include "SynTree/Constant.h"          // for Constant
     
    745745                }
    746746
    747                 // to prevent warnings (‘_unq0’ may be used uninitialized in this function),
     747                // to prevent warnings ('_unq0' may be used uninitialized in this function),
    748748                // insert an appropriate zero initializer for UniqueExpr temporaries.
    749749                Initializer * makeInit( Type * t ) {
  • src/InitTweak/FixInit.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:31:06 2017
    13 // Update Count     : 6
     12// Last Modified On : Sun Feb 16 07:54:50 2020
     13// Update Count     : 8
    1414//
    1515
     
    2222
    2323namespace InitTweak {
    24   /// replace constructor initializers with expression statements
    25   /// and unwrap basic C-style initializers
     24        /// replace constructor initializers with expression statements and unwrap basic C-style initializers
    2625        void fix( std::list< Declaration * > & translationUnit, bool inLibrary );
    2726} // namespace
  • src/InitTweak/GenInit.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:12:36 2017
    13 // Update Count     : 183
     12// Last Modified On : Fri Dec 13 23:15:10 2019
     13// Update Count     : 184
    1414//
    1515#include "GenInit.h"
     
    3434#include "GenPoly/ScopedSet.h"         // for ScopedSet, ScopedSet<>::const_iter...
    3535#include "InitTweak.h"                 // for isConstExpr, InitExpander, checkIn...
    36 #include "Parser/LinkageSpec.h"        // for isOverridable, C
    3736#include "ResolvExpr/Resolver.h"
    3837#include "SymTab/Autogen.h"            // for genImplicitCall
    3938#include "SymTab/Mangler.h"            // for Mangler
     39#include "SynTree/LinkageSpec.h"       // for isOverridable, C
    4040#include "SynTree/Declaration.h"       // for ObjectDecl, DeclarationWithType
    4141#include "SynTree/Expression.h"        // for VariableExpr, UntypedExpr, Address...
  • src/InitTweak/InitTweak.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Fri May 13 11:26:36 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 25 22:21:48 2019
    13 // Update Count     : 7
     12// Last Modified On : Fri Dec 13 23:15:52 2019
     13// Update Count     : 8
    1414//
    1515
     
    3333#include "GenPoly/GenPoly.h"       // for getFunctionType
    3434#include "InitTweak.h"
    35 #include "Parser/LinkageSpec.h"    // for Spec, isBuiltin, Intrinsic
    3635#include "ResolvExpr/typeops.h"    // for typesCompatibleIgnoreQualifiers
    3736#include "SymTab/Autogen.h"
    3837#include "SymTab/Indexer.h"        // for Indexer
     38#include "SynTree/LinkageSpec.h"   // for Spec, isBuiltin, Intrinsic
    3939#include "SynTree/Attribute.h"     // for Attribute
    4040#include "SynTree/Constant.h"      // for Constant
  • src/MakeLibCfa.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 10:33:33 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 17 21:08:09 2019
    13 // Update Count     : 41
     12// Last Modified On : Sun Feb 16 03:49:49 2020
     13// Update Count     : 45
    1414//
    1515
     
    2323#include "Common/SemanticError.h"   // for SemanticError
    2424#include "Common/UniqueName.h"      // for UniqueName
    25 #include "Parser/LinkageSpec.h"     // for Spec, Intrinsic, C
     25#include "SynTree/LinkageSpec.h"    // for Spec, Intrinsic, C
    2626#include "SynTree/Declaration.h"    // for FunctionDecl, ObjectDecl, Declara...
    2727#include "SynTree/Expression.h"     // for NameExpr, UntypedExpr, VariableExpr
     
    9696
    9797                        FunctionDecl *funcDecl = origFuncDecl->clone();
    98                         CodeGen::OperatorInfo opInfo;
    99                         bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
    100                         assert( lookResult );
     98                        const CodeGen::OperatorInfo * opInfo;
     99                        opInfo = CodeGen::operatorLookup( funcDecl->get_name() );
     100                        assert( opInfo );
    101101                        assert( ! funcDecl->get_statements() );
    102102                        // build a recursive call - this is okay, as the call will actually be codegen'd using operator syntax
     
    120120
    121121                        Statement * stmt = nullptr;
    122                         switch ( opInfo.type ) {
     122                        switch ( opInfo->type ) {
    123123                          case CodeGen::OT_INDEX:
    124124                          case CodeGen::OT_CALL:
  • src/Makefile.in

    r9fb8f01 r3d5701e  
    212212        SymTab/Indexer.$(OBJEXT) SymTab/Mangler.$(OBJEXT) \
    213213        SymTab/ManglerCommon.$(OBJEXT) SymTab/Validate.$(OBJEXT)
    214 am__objects_7 = SynTree/Type.$(OBJEXT) SynTree/VoidType.$(OBJEXT) \
    215         SynTree/BasicType.$(OBJEXT) SynTree/PointerType.$(OBJEXT) \
    216         SynTree/ArrayType.$(OBJEXT) SynTree/ReferenceType.$(OBJEXT) \
    217         SynTree/FunctionType.$(OBJEXT) \
    218         SynTree/ReferenceToType.$(OBJEXT) SynTree/TupleType.$(OBJEXT) \
    219         SynTree/TypeofType.$(OBJEXT) SynTree/AttrType.$(OBJEXT) \
    220         SynTree/VarArgsType.$(OBJEXT) SynTree/ZeroOneType.$(OBJEXT) \
    221         SynTree/Constant.$(OBJEXT) SynTree/Expression.$(OBJEXT) \
    222         SynTree/TupleExpr.$(OBJEXT) SynTree/CommaExpr.$(OBJEXT) \
    223         SynTree/TypeExpr.$(OBJEXT) SynTree/ApplicationExpr.$(OBJEXT) \
    224         SynTree/AddressExpr.$(OBJEXT) SynTree/Statement.$(OBJEXT) \
    225         SynTree/CompoundStmt.$(OBJEXT) SynTree/DeclStmt.$(OBJEXT) \
     214am__objects_7 = SynTree/AddressExpr.$(OBJEXT) \
     215        SynTree/AggregateDecl.$(OBJEXT) \
     216        SynTree/ApplicationExpr.$(OBJEXT) SynTree/ArrayType.$(OBJEXT) \
     217        SynTree/AttrType.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \
     218        SynTree/BasicType.$(OBJEXT) SynTree/CommaExpr.$(OBJEXT) \
     219        SynTree/CompoundStmt.$(OBJEXT) SynTree/Constant.$(OBJEXT) \
     220        SynTree/DeclReplacer.$(OBJEXT) SynTree/DeclStmt.$(OBJEXT) \
    226221        SynTree/Declaration.$(OBJEXT) \
    227222        SynTree/DeclarationWithType.$(OBJEXT) \
    228         SynTree/ObjectDecl.$(OBJEXT) SynTree/FunctionDecl.$(OBJEXT) \
    229         SynTree/AggregateDecl.$(OBJEXT) \
    230         SynTree/NamedTypeDecl.$(OBJEXT) SynTree/TypeDecl.$(OBJEXT) \
    231         SynTree/Initializer.$(OBJEXT) \
    232         SynTree/TypeSubstitution.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \
    233         SynTree/DeclReplacer.$(OBJEXT) SynTree/TopLvalue.$(OBJEXT)
     223        SynTree/Expression.$(OBJEXT) SynTree/FunctionDecl.$(OBJEXT) \
     224        SynTree/FunctionType.$(OBJEXT) SynTree/Initializer.$(OBJEXT) \
     225        SynTree/LinkageSpec.$(OBJEXT) SynTree/NamedTypeDecl.$(OBJEXT) \
     226        SynTree/ObjectDecl.$(OBJEXT) SynTree/PointerType.$(OBJEXT) \
     227        SynTree/ReferenceToType.$(OBJEXT) \
     228        SynTree/ReferenceType.$(OBJEXT) SynTree/Statement.$(OBJEXT) \
     229        SynTree/TupleExpr.$(OBJEXT) SynTree/TupleType.$(OBJEXT) \
     230        SynTree/Type.$(OBJEXT) SynTree/TypeDecl.$(OBJEXT) \
     231        SynTree/TypeExpr.$(OBJEXT) SynTree/TypeSubstitution.$(OBJEXT) \
     232        SynTree/TypeofType.$(OBJEXT) SynTree/VarArgsType.$(OBJEXT) \
     233        SynTree/VoidType.$(OBJEXT) SynTree/ZeroOneType.$(OBJEXT)
    234234am__objects_8 = CompilationState.$(OBJEXT) $(am__objects_1) \
    235235        $(am__objects_2) Concurrency/Keywords.$(OBJEXT) \
    236236        $(am__objects_3) $(am__objects_4) GenPoly/GenPoly.$(OBJEXT) \
    237237        GenPoly/Lvalue.$(OBJEXT) InitTweak/GenInit.$(OBJEXT) \
    238         InitTweak/InitTweak.$(OBJEXT) Parser/LinkageSpec.$(OBJEXT) \
    239         $(am__objects_5) $(am__objects_6) SymTab/Demangle.$(OBJEXT) \
    240         $(am__objects_7) Tuples/TupleAssignment.$(OBJEXT) \
     238        InitTweak/InitTweak.$(OBJEXT) $(am__objects_5) \
     239        $(am__objects_6) SymTab/Demangle.$(OBJEXT) $(am__objects_7) \
     240        Tuples/TupleAssignment.$(OBJEXT) \
    241241        Tuples/TupleExpansion.$(OBJEXT) Tuples/Explode.$(OBJEXT) \
    242242        Tuples/Tuples.$(OBJEXT) Validate/HandleAttributes.$(OBJEXT) \
     
    261261        InitTweak/GenInit.$(OBJEXT) InitTweak/FixInit.$(OBJEXT) \
    262262        InitTweak/FixGlobalInit.$(OBJEXT) \
    263         InitTweak/InitTweak.$(OBJEXT) Parser/parser.$(OBJEXT) \
    264         Parser/lex.$(OBJEXT) Parser/TypedefTable.$(OBJEXT) \
    265         Parser/ParseNode.$(OBJEXT) Parser/DeclarationNode.$(OBJEXT) \
    266         Parser/ExpressionNode.$(OBJEXT) Parser/StatementNode.$(OBJEXT) \
    267         Parser/InitializerNode.$(OBJEXT) Parser/TypeData.$(OBJEXT) \
    268         Parser/LinkageSpec.$(OBJEXT) Parser/parserutility.$(OBJEXT) \
     263        InitTweak/InitTweak.$(OBJEXT) Parser/DeclarationNode.$(OBJEXT) \
     264        Parser/ExpressionNode.$(OBJEXT) \
     265        Parser/InitializerNode.$(OBJEXT) Parser/ParseNode.$(OBJEXT) \
     266        Parser/StatementNode.$(OBJEXT) Parser/TypeData.$(OBJEXT) \
     267        Parser/TypedefTable.$(OBJEXT) Parser/lex.$(OBJEXT) \
     268        Parser/parser.$(OBJEXT) Parser/parserutility.$(OBJEXT) \
    269269        $(am__objects_5) ResolvExpr/AlternativePrinter.$(OBJEXT) \
    270270        $(am__objects_6) $(am__objects_7) \
     
    411411CCDEPMODE = @CCDEPMODE@
    412412CFACC = @CFACC@
     413CFACC_INSTALL = @CFACC_INSTALL@
    413414CFACPP = @CFACPP@
    414415CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    441442FGREP = @FGREP@
    442443GREP = @GREP@
     444HAS_DISTCC = @HAS_DISTCC@
    443445HOST_FLAGS = @HOST_FLAGS@
    444446INSTALL = @INSTALL@
     
    557559        InitTweak/GenInit.cc InitTweak/FixInit.cc \
    558560        InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \
    559         Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
    560         Parser/ParseNode.cc Parser/DeclarationNode.cc \
    561         Parser/ExpressionNode.cc Parser/StatementNode.cc \
    562         Parser/InitializerNode.cc Parser/TypeData.cc \
    563         Parser/LinkageSpec.cc Parser/parserutility.cc \
    564         $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc \
    565         $(SRC_SYMTAB) $(SRC_SYNTREE) Tuples/TupleAssignment.cc \
    566         Tuples/TupleExpansion.cc Tuples/Explode.cc Tuples/Tuples.cc \
     561        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     562        Parser/InitializerNode.cc Parser/ParseNode.cc \
     563        Parser/StatementNode.cc Parser/TypeData.cc \
     564        Parser/TypedefTable.cc Parser/lex.ll Parser/parser.yy \
     565        Parser/parserutility.cc $(SRC_RESOLVEXPR) \
     566        ResolvExpr/AlternativePrinter.cc $(SRC_SYMTAB) $(SRC_SYNTREE) \
     567        Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
     568        Tuples/Explode.cc Tuples/Tuples.cc \
    567569        Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc \
    568570        Virtual/ExpandCasts.cc
     
    570572        Concurrency/Keywords.cc $(SRC_COMMON) $(SRC_CONTROLSTRUCT) \
    571573        GenPoly/GenPoly.cc GenPoly/Lvalue.cc InitTweak/GenInit.cc \
    572         InitTweak/InitTweak.cc Parser/LinkageSpec.cc $(SRC_RESOLVEXPR) \
    573         $(SRC_SYMTAB) SymTab/Demangle.cc $(SRC_SYNTREE) \
    574         Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
    575         Tuples/Explode.cc Tuples/Tuples.cc \
     574        InitTweak/InitTweak.cc $(SRC_RESOLVEXPR) $(SRC_SYMTAB) \
     575        SymTab/Demangle.cc $(SRC_SYNTREE) Tuples/TupleAssignment.cc \
     576        Tuples/TupleExpansion.cc Tuples/Explode.cc Tuples/Tuples.cc \
    576577        Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc
    577578MAINTAINERCLEANFILES = ${libdir}/${notdir ${cfa_cpplib_PROGRAMS}}
     
    661662
    662663SRC_SYNTREE = \
    663       SynTree/Type.cc \
    664       SynTree/VoidType.cc \
     664      SynTree/AddressExpr.cc \
     665      SynTree/AggregateDecl.cc \
     666      SynTree/ApplicationExpr.cc \
     667      SynTree/ArrayType.cc \
     668      SynTree/AttrType.cc \
     669      SynTree/Attribute.cc \
    665670      SynTree/BasicType.cc \
    666       SynTree/PointerType.cc \
    667       SynTree/ArrayType.cc \
    668       SynTree/ReferenceType.cc \
    669       SynTree/FunctionType.cc \
    670       SynTree/ReferenceToType.cc \
    671       SynTree/TupleType.cc \
    672       SynTree/TypeofType.cc \
    673       SynTree/AttrType.cc \
    674       SynTree/VarArgsType.cc \
    675       SynTree/ZeroOneType.cc \
     671      SynTree/CommaExpr.cc \
     672      SynTree/CompoundStmt.cc \
    676673      SynTree/Constant.cc \
    677       SynTree/Expression.cc \
    678       SynTree/TupleExpr.cc \
    679       SynTree/CommaExpr.cc \
    680       SynTree/TypeExpr.cc \
    681       SynTree/ApplicationExpr.cc \
    682       SynTree/AddressExpr.cc \
    683       SynTree/Statement.cc \
    684       SynTree/CompoundStmt.cc \
     674      SynTree/DeclReplacer.cc \
    685675      SynTree/DeclStmt.cc \
    686676      SynTree/Declaration.cc \
    687677      SynTree/DeclarationWithType.cc \
     678      SynTree/Expression.cc \
     679      SynTree/FunctionDecl.cc \
     680      SynTree/FunctionType.cc \
     681      SynTree/Initializer.cc \
     682      SynTree/LinkageSpec.cc \
     683      SynTree/NamedTypeDecl.cc \
    688684      SynTree/ObjectDecl.cc \
    689       SynTree/FunctionDecl.cc \
    690       SynTree/AggregateDecl.cc \
    691       SynTree/NamedTypeDecl.cc \
     685      SynTree/PointerType.cc \
     686      SynTree/ReferenceToType.cc \
     687      SynTree/ReferenceType.cc \
     688      SynTree/Statement.cc \
     689      SynTree/TupleExpr.cc \
     690      SynTree/TupleType.cc \
     691      SynTree/Type.cc \
    692692      SynTree/TypeDecl.cc \
    693       SynTree/Initializer.cc \
     693      SynTree/TypeExpr.cc \
    694694      SynTree/TypeSubstitution.cc \
    695       SynTree/Attribute.cc \
    696       SynTree/DeclReplacer.cc \
    697       SynTree/TopLvalue.cc
     695      SynTree/TypeofType.cc \
     696      SynTree/VarArgsType.cc \
     697      SynTree/VoidType.cc \
     698      SynTree/ZeroOneType.cc
    698699
    699700
     
    868869InitTweak/InitTweak.$(OBJEXT): InitTweak/$(am__dirstamp) \
    869870        InitTweak/$(DEPDIR)/$(am__dirstamp)
    870 Parser/$(am__dirstamp):
    871         @$(MKDIR_P) Parser
    872         @: > Parser/$(am__dirstamp)
    873 Parser/$(DEPDIR)/$(am__dirstamp):
    874         @$(MKDIR_P) Parser/$(DEPDIR)
    875         @: > Parser/$(DEPDIR)/$(am__dirstamp)
    876 Parser/LinkageSpec.$(OBJEXT): Parser/$(am__dirstamp) \
    877         Parser/$(DEPDIR)/$(am__dirstamp)
    878871ResolvExpr/$(am__dirstamp):
    879872        @$(MKDIR_P) ResolvExpr
     
    956949        @$(MKDIR_P) SynTree/$(DEPDIR)
    957950        @: > SynTree/$(DEPDIR)/$(am__dirstamp)
     951SynTree/AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     952        SynTree/$(DEPDIR)/$(am__dirstamp)
     953SynTree/AggregateDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     954        SynTree/$(DEPDIR)/$(am__dirstamp)
     955SynTree/ApplicationExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     956        SynTree/$(DEPDIR)/$(am__dirstamp)
     957SynTree/ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
     958        SynTree/$(DEPDIR)/$(am__dirstamp)
     959SynTree/AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \
     960        SynTree/$(DEPDIR)/$(am__dirstamp)
     961SynTree/Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
     962        SynTree/$(DEPDIR)/$(am__dirstamp)
     963SynTree/BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \
     964        SynTree/$(DEPDIR)/$(am__dirstamp)
     965SynTree/CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     966        SynTree/$(DEPDIR)/$(am__dirstamp)
     967SynTree/CompoundStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
     968        SynTree/$(DEPDIR)/$(am__dirstamp)
     969SynTree/Constant.$(OBJEXT): SynTree/$(am__dirstamp) \
     970        SynTree/$(DEPDIR)/$(am__dirstamp)
     971SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \
     972        SynTree/$(DEPDIR)/$(am__dirstamp)
     973SynTree/DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
     974        SynTree/$(DEPDIR)/$(am__dirstamp)
     975SynTree/Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \
     976        SynTree/$(DEPDIR)/$(am__dirstamp)
     977SynTree/DeclarationWithType.$(OBJEXT): SynTree/$(am__dirstamp) \
     978        SynTree/$(DEPDIR)/$(am__dirstamp)
     979SynTree/Expression.$(OBJEXT): SynTree/$(am__dirstamp) \
     980        SynTree/$(DEPDIR)/$(am__dirstamp)
     981SynTree/FunctionDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     982        SynTree/$(DEPDIR)/$(am__dirstamp)
     983SynTree/FunctionType.$(OBJEXT): SynTree/$(am__dirstamp) \
     984        SynTree/$(DEPDIR)/$(am__dirstamp)
     985SynTree/Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
     986        SynTree/$(DEPDIR)/$(am__dirstamp)
     987SynTree/LinkageSpec.$(OBJEXT): SynTree/$(am__dirstamp) \
     988        SynTree/$(DEPDIR)/$(am__dirstamp)
     989SynTree/NamedTypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     990        SynTree/$(DEPDIR)/$(am__dirstamp)
     991SynTree/ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     992        SynTree/$(DEPDIR)/$(am__dirstamp)
     993SynTree/PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \
     994        SynTree/$(DEPDIR)/$(am__dirstamp)
     995SynTree/ReferenceToType.$(OBJEXT): SynTree/$(am__dirstamp) \
     996        SynTree/$(DEPDIR)/$(am__dirstamp)
     997SynTree/ReferenceType.$(OBJEXT): SynTree/$(am__dirstamp) \
     998        SynTree/$(DEPDIR)/$(am__dirstamp)
     999SynTree/Statement.$(OBJEXT): SynTree/$(am__dirstamp) \
     1000        SynTree/$(DEPDIR)/$(am__dirstamp)
     1001SynTree/TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     1002        SynTree/$(DEPDIR)/$(am__dirstamp)
     1003SynTree/TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \
     1004        SynTree/$(DEPDIR)/$(am__dirstamp)
    9581005SynTree/Type.$(OBJEXT): SynTree/$(am__dirstamp) \
    9591006        SynTree/$(DEPDIR)/$(am__dirstamp)
     1007SynTree/TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     1008        SynTree/$(DEPDIR)/$(am__dirstamp)
     1009SynTree/TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     1010        SynTree/$(DEPDIR)/$(am__dirstamp)
     1011SynTree/TypeSubstitution.$(OBJEXT): SynTree/$(am__dirstamp) \
     1012        SynTree/$(DEPDIR)/$(am__dirstamp)
     1013SynTree/TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \
     1014        SynTree/$(DEPDIR)/$(am__dirstamp)
     1015SynTree/VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \
     1016        SynTree/$(DEPDIR)/$(am__dirstamp)
    9601017SynTree/VoidType.$(OBJEXT): SynTree/$(am__dirstamp) \
    9611018        SynTree/$(DEPDIR)/$(am__dirstamp)
    962 SynTree/BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \
    963         SynTree/$(DEPDIR)/$(am__dirstamp)
    964 SynTree/PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \
    965         SynTree/$(DEPDIR)/$(am__dirstamp)
    966 SynTree/ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
    967         SynTree/$(DEPDIR)/$(am__dirstamp)
    968 SynTree/ReferenceType.$(OBJEXT): SynTree/$(am__dirstamp) \
    969         SynTree/$(DEPDIR)/$(am__dirstamp)
    970 SynTree/FunctionType.$(OBJEXT): SynTree/$(am__dirstamp) \
    971         SynTree/$(DEPDIR)/$(am__dirstamp)
    972 SynTree/ReferenceToType.$(OBJEXT): SynTree/$(am__dirstamp) \
    973         SynTree/$(DEPDIR)/$(am__dirstamp)
    974 SynTree/TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \
    975         SynTree/$(DEPDIR)/$(am__dirstamp)
    976 SynTree/TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \
    977         SynTree/$(DEPDIR)/$(am__dirstamp)
    978 SynTree/AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \
    979         SynTree/$(DEPDIR)/$(am__dirstamp)
    980 SynTree/VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \
    981         SynTree/$(DEPDIR)/$(am__dirstamp)
    9821019SynTree/ZeroOneType.$(OBJEXT): SynTree/$(am__dirstamp) \
    983         SynTree/$(DEPDIR)/$(am__dirstamp)
    984 SynTree/Constant.$(OBJEXT): SynTree/$(am__dirstamp) \
    985         SynTree/$(DEPDIR)/$(am__dirstamp)
    986 SynTree/Expression.$(OBJEXT): SynTree/$(am__dirstamp) \
    987         SynTree/$(DEPDIR)/$(am__dirstamp)
    988 SynTree/TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    989         SynTree/$(DEPDIR)/$(am__dirstamp)
    990 SynTree/CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    991         SynTree/$(DEPDIR)/$(am__dirstamp)
    992 SynTree/TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    993         SynTree/$(DEPDIR)/$(am__dirstamp)
    994 SynTree/ApplicationExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    995         SynTree/$(DEPDIR)/$(am__dirstamp)
    996 SynTree/AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    997         SynTree/$(DEPDIR)/$(am__dirstamp)
    998 SynTree/Statement.$(OBJEXT): SynTree/$(am__dirstamp) \
    999         SynTree/$(DEPDIR)/$(am__dirstamp)
    1000 SynTree/CompoundStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
    1001         SynTree/$(DEPDIR)/$(am__dirstamp)
    1002 SynTree/DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
    1003         SynTree/$(DEPDIR)/$(am__dirstamp)
    1004 SynTree/Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \
    1005         SynTree/$(DEPDIR)/$(am__dirstamp)
    1006 SynTree/DeclarationWithType.$(OBJEXT): SynTree/$(am__dirstamp) \
    1007         SynTree/$(DEPDIR)/$(am__dirstamp)
    1008 SynTree/ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    1009         SynTree/$(DEPDIR)/$(am__dirstamp)
    1010 SynTree/FunctionDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    1011         SynTree/$(DEPDIR)/$(am__dirstamp)
    1012 SynTree/AggregateDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    1013         SynTree/$(DEPDIR)/$(am__dirstamp)
    1014 SynTree/NamedTypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    1015         SynTree/$(DEPDIR)/$(am__dirstamp)
    1016 SynTree/TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    1017         SynTree/$(DEPDIR)/$(am__dirstamp)
    1018 SynTree/Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
    1019         SynTree/$(DEPDIR)/$(am__dirstamp)
    1020 SynTree/TypeSubstitution.$(OBJEXT): SynTree/$(am__dirstamp) \
    1021         SynTree/$(DEPDIR)/$(am__dirstamp)
    1022 SynTree/Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
    1023         SynTree/$(DEPDIR)/$(am__dirstamp)
    1024 SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \
    1025         SynTree/$(DEPDIR)/$(am__dirstamp)
    1026 SynTree/TopLvalue.$(OBJEXT): SynTree/$(am__dirstamp) \
    10271020        SynTree/$(DEPDIR)/$(am__dirstamp)
    10281021Tuples/$(am__dirstamp):
     
    11411134InitTweak/FixGlobalInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
    11421135        InitTweak/$(DEPDIR)/$(am__dirstamp)
     1136Parser/$(am__dirstamp):
     1137        @$(MKDIR_P) Parser
     1138        @: > Parser/$(am__dirstamp)
     1139Parser/$(DEPDIR)/$(am__dirstamp):
     1140        @$(MKDIR_P) Parser/$(DEPDIR)
     1141        @: > Parser/$(DEPDIR)/$(am__dirstamp)
     1142Parser/DeclarationNode.$(OBJEXT): Parser/$(am__dirstamp) \
     1143        Parser/$(DEPDIR)/$(am__dirstamp)
     1144Parser/ExpressionNode.$(OBJEXT): Parser/$(am__dirstamp) \
     1145        Parser/$(DEPDIR)/$(am__dirstamp)
     1146Parser/InitializerNode.$(OBJEXT): Parser/$(am__dirstamp) \
     1147        Parser/$(DEPDIR)/$(am__dirstamp)
     1148Parser/ParseNode.$(OBJEXT): Parser/$(am__dirstamp) \
     1149        Parser/$(DEPDIR)/$(am__dirstamp)
     1150Parser/StatementNode.$(OBJEXT): Parser/$(am__dirstamp) \
     1151        Parser/$(DEPDIR)/$(am__dirstamp)
     1152Parser/TypeData.$(OBJEXT): Parser/$(am__dirstamp) \
     1153        Parser/$(DEPDIR)/$(am__dirstamp)
     1154Parser/TypedefTable.$(OBJEXT): Parser/$(am__dirstamp) \
     1155        Parser/$(DEPDIR)/$(am__dirstamp)
     1156Parser/lex.$(OBJEXT): Parser/$(am__dirstamp) \
     1157        Parser/$(DEPDIR)/$(am__dirstamp)
    11431158Parser/parser.hh: Parser/parser.cc
    11441159        @if test ! -f $@; then rm -f Parser/parser.cc; else :; fi
    11451160        @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) Parser/parser.cc; else :; fi
    11461161Parser/parser.$(OBJEXT): Parser/$(am__dirstamp) \
    1147         Parser/$(DEPDIR)/$(am__dirstamp)
    1148 Parser/lex.$(OBJEXT): Parser/$(am__dirstamp) \
    1149         Parser/$(DEPDIR)/$(am__dirstamp)
    1150 Parser/TypedefTable.$(OBJEXT): Parser/$(am__dirstamp) \
    1151         Parser/$(DEPDIR)/$(am__dirstamp)
    1152 Parser/ParseNode.$(OBJEXT): Parser/$(am__dirstamp) \
    1153         Parser/$(DEPDIR)/$(am__dirstamp)
    1154 Parser/DeclarationNode.$(OBJEXT): Parser/$(am__dirstamp) \
    1155         Parser/$(DEPDIR)/$(am__dirstamp)
    1156 Parser/ExpressionNode.$(OBJEXT): Parser/$(am__dirstamp) \
    1157         Parser/$(DEPDIR)/$(am__dirstamp)
    1158 Parser/StatementNode.$(OBJEXT): Parser/$(am__dirstamp) \
    1159         Parser/$(DEPDIR)/$(am__dirstamp)
    1160 Parser/InitializerNode.$(OBJEXT): Parser/$(am__dirstamp) \
    1161         Parser/$(DEPDIR)/$(am__dirstamp)
    1162 Parser/TypeData.$(OBJEXT): Parser/$(am__dirstamp) \
    11631162        Parser/$(DEPDIR)/$(am__dirstamp)
    11641163Parser/parserutility.$(OBJEXT): Parser/$(am__dirstamp) \
     
    12711270@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/ExpressionNode.Po@am__quote@
    12721271@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/InitializerNode.Po@am__quote@
    1273 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/LinkageSpec.Po@am__quote@
    12741272@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/ParseNode.Po@am__quote@
    12751273@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/StatementNode.Po@am__quote@
     
    13301328@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/FunctionType.Po@am__quote@
    13311329@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Initializer.Po@am__quote@
     1330@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/LinkageSpec.Po@am__quote@
    13321331@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/NamedTypeDecl.Po@am__quote@
    13331332@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ObjectDecl.Po@am__quote@
     
    13361335@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ReferenceType.Po@am__quote@
    13371336@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Statement.Po@am__quote@
    1338 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TopLvalue.Po@am__quote@
    13391337@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleExpr.Po@am__quote@
    13401338@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleType.Po@am__quote@
  • src/Parser/DeclarationNode.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 25 22:17:10 2019
    13 // Update Count     : 1116
     12// Last Modified On : Mon Dec 16 15:32:22 2019
     13// Update Count     : 1133
    1414//
    1515
     
    2424#include "Common/UniqueName.h"     // for UniqueName
    2525#include "Common/utility.h"        // for maybeClone, maybeBuild, CodeLocation
    26 #include "Parser/LinkageSpec.h"    // for Spec, linkageName, Cforall
    2726#include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
     27#include "SynTree/LinkageSpec.h"   // for Spec, linkageName, Cforall
    2828#include "SynTree/Attribute.h"     // for Attribute
    2929#include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, Declaration
     
    4747const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
    4848const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
    49 const char * DeclarationNode::aggregateNames[] = { "struct", "union", "trait", "coroutine", "monitor", "thread", "NoAggregateNames" };
    50 const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" };
    5149const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" };
    5250
     
    5957
    6058//      variable.name = nullptr;
    61         variable.tyClass = NoTypeClass;
     59        variable.tyClass = TypeDecl::NUMBER_OF_KINDS;
    6260        variable.assertions = nullptr;
    6361        variable.initializer = nullptr;
     
    135133
    136134        if ( linkage != LinkageSpec::Cforall ) {
    137                 os << LinkageSpec::linkageName( linkage ) << " ";
     135                os << LinkageSpec::name( linkage ) << " ";
    138136        } // if
    139137
     
    267265}
    268266
    269 DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
     267DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    270268        DeclarationNode * newnode = new DeclarationNode;
    271269        newnode->type = new TypeData( TypeData::Aggregate );
     
    313311} // DeclarationNode::newFromTypeGen
    314312
    315 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, const string * name ) {
     313DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {
    316314        DeclarationNode * newnode = new DeclarationNode;
    317315        newnode->type = nullptr;
     
    328326        newnode->type = new TypeData( TypeData::Aggregate );
    329327        newnode->type->aggregate.name = name;
    330         newnode->type->aggregate.kind = Trait;
     328        newnode->type->aggregate.kind = AggregateDecl::Trait;
    331329        newnode->type->aggregate.params = params;
    332330        newnode->type->aggregate.fields = asserts;
     
    338336        newnode->type = new TypeData( TypeData::AggregateInst );
    339337        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
    340         newnode->type->aggInst.aggregate->aggregate.kind = Trait;
     338        newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;
    341339        newnode->type->aggInst.aggregate->aggregate.name = name;
    342340        newnode->type->aggInst.params = params;
     
    671669
    672670DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
    673         if ( variable.tyClass != NoTypeClass ) {
     671        if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
    674672                if ( variable.assertions ) {
    675673                        variable.assertions->appendList( assertions );
     
    876874
    877875DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
    878         assertf( variable.tyClass != NoTypeClass, "Called addTypeInitializer on something that isn't a type variable." );
     876        assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
    879877        variable.initializer = init;
    880878        return this;
     
    10751073        } // if
    10761074
    1077         if ( variable.tyClass != NoTypeClass ) {
     1075        if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
    10781076                // otype is internally converted to dtype + otype parameters
    10791077                static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype };
    1080                 assertf( sizeof(kindMap)/sizeof(kindMap[0]) == NoTypeClass, "DeclarationNode::build: kindMap is out of sync." );
     1078                static_assert( sizeof(kindMap)/sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
    10811079                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    1082                 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == Otype, variable.initializer ? variable.initializer->buildType() : nullptr );
     1080                TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype, variable.initializer ? variable.initializer->buildType() : nullptr );
    10831081                buildList( variable.assertions, ret->get_assertions() );
    10841082                return ret;
  • src/Parser/ExpressionNode.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug  4 20:57:55 2019
    13 // Update Count     : 978
     12// Last Modified On : Wed Dec 18 21:14:58 2019
     13// Update Count     : 981
    1414//
    1515
     
    265265        static const BasicType::Kind kind[2][12] = {
    266266                { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x },
    267                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex },
     267                { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex },
    268268        };
    269269
     
    374374
    375375Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
    376         if ( str[str.size()-1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str );
     376        if ( str[str.size() - 1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str );
    377377        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
    378378        delete &str;
     
    434434} // build_cast
    435435
    436 Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node ) {
     436Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) {
    437437        return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target );
    438438}
  • src/Parser/ParseNode.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 25 22:17:10 2019
    13 // Update Count     : 876
     12// Last Modified On : Fri Feb  7 17:56:02 2020
     13// Update Count     : 891
    1414//
    1515
     
    2828#include "Common/UniqueName.h"     // for UniqueName
    2929#include "Common/utility.h"        // for maybeClone, maybeBuild
    30 #include "Parser/LinkageSpec.h"    // for Spec
     30#include "SynTree/LinkageSpec.h"   // for Spec
     31#include "SynTree/Declaration.h"   // for Aggregate
    3132#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
    3233#include "SynTree/Label.h"         // for Label
     
    184185
    185186Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    186 Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
     187Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
    187188Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    188189Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
     
    217218        enum Length { Short, Long, LongLong, NoLength };
    218219        static const char * lengthNames[];
    219         enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
    220         static const char * aggregateNames[];
    221         enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
    222         static const char * typeClassNames[];
    223220        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
    224221        static const char * builtinTypeNames[];
     
    237234        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
    238235        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    239         static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
     236        static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    240237        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
    241238        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
    242239        static DeclarationNode * newName( const std::string * );
    243240        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
    244         static DeclarationNode * newTypeParam( TypeClass, const std::string * );
     241        static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
    245242        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
    246243        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
     
    312309        struct Variable_t {
    313310//              const std::string * name;
    314                 DeclarationNode::TypeClass tyClass;
     311                TypeDecl::Kind tyClass;
    315312                DeclarationNode * assertions;
    316313                DeclarationNode * initializer;
     
    452449                                * out++ = result;
    453450                        } else {
    454                                 assertf(false, "buildList unknown type");
     451                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
    455452                        } // if
    456453                } catch( SemanticErrorException & e ) {
  • src/Parser/ParserTypes.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat Sep 22 08:58:10 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:33:28 2017
    13 // Update Count     : 350
     12// Last Modified On : Sat Feb 15 11:04:40 2020
     13// Update Count     : 351
    1414//
    1515
     
    2727// current location in the input
    2828extern int yylineno;
    29 extern char *yyfilename;
     29extern char * yyfilename;
    3030
    3131struct Location {
    32     char *file;
     32    char * file;
    3333    int line;
    3434}; // Location
    3535
    3636struct Token {
    37     std::string *str;                                                                   // must be pointer as used in union
     37    std::string * str;                                                                  // must be pointer as used in union
    3838    Location loc;
    3939
  • src/Parser/TypeData.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 13 18:16:23 2019
    13 // Update Count     : 649
     12// Last Modified On : Mon Dec 16 07:56:46 2019
     13// Update Count     : 662
    1414//
    1515
     
    6767          case Aggregate:
    6868                // aggregate = new Aggregate_t;
    69                 aggregate.kind = DeclarationNode::NoAggregate;
     69                aggregate.kind = AggregateDecl::NoAggregate;
    7070                aggregate.name = nullptr;
    7171                aggregate.params = nullptr;
     
    345345                break;
    346346          case Aggregate:
    347                 os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl;
     347                os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
    348348                if ( aggregate.params ) {
    349349                        os << string( indent + 2, ' ' ) << "with type parameters" << endl;
     
    489489        for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) {
    490490                TypeDecl * td = static_cast<TypeDecl *>(*i);
    491                 if ( n->variable.tyClass == DeclarationNode::Otype ) {
     491                if ( n->variable.tyClass == TypeDecl::Otype ) {
    492492                        // add assertion parameters to `type' tyvars in reverse order
    493493                        // add dtor:  void ^?{}(T *)
     
    522522        switch ( td->kind ) {
    523523          case TypeData::Unknown:
    524                         // fill in implicit int
    525                         return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
     524                // fill in implicit int
     525                return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
    526526          case TypeData::Basic:
    527                         return buildBasicType( td );
     527                return buildBasicType( td );
    528528          case TypeData::Pointer:
    529                         return buildPointer( td );
     529                return buildPointer( td );
    530530          case TypeData::Array:
    531                         return buildArray( td );
     531                return buildArray( td );
    532532          case TypeData::Reference:
    533                         return buildReference( td );
     533                return buildReference( td );
    534534          case TypeData::Function:
    535                         return buildFunction( td );
     535                return buildFunction( td );
    536536          case TypeData::AggregateInst:
    537                         return buildAggInst( td );
     537                return buildAggInst( td );
    538538          case TypeData::EnumConstant:
    539                         // the name gets filled in later -- by SymTab::Validate
    540                         return new EnumInstType( buildQualifiers( td ), "" );
     539                // the name gets filled in later -- by SymTab::Validate
     540                return new EnumInstType( buildQualifiers( td ), "" );
    541541          case TypeData::SymbolicInst:
    542                         return buildSymbolicInst( td );
     542                return buildSymbolicInst( td );
    543543          case TypeData::Tuple:
    544                         return buildTuple( td );
     544                return buildTuple( td );
    545545          case TypeData::Typeof:
    546546          case TypeData::Basetypeof:
    547                         return buildTypeof( td );
     547                return buildTypeof( td );
    548548          case TypeData::Builtin:
    549                         if (td->builtintype == DeclarationNode::Zero) {
    550                                 return new ZeroType( noQualifiers );
    551                         }
    552                         else if (td->builtintype == DeclarationNode::One) {
    553                                 return new OneType( noQualifiers );
    554                         }
    555                         else {
    556                                 return new VarArgsType( buildQualifiers( td ) );
    557                         }
     549                switch ( td->builtintype ) {
     550                  case DeclarationNode::Zero:
     551                        return new ZeroType( noQualifiers );
     552                  case DeclarationNode::One:
     553                        return new OneType( noQualifiers );
     554                  default:
     555                        return new VarArgsType( buildQualifiers( td ) );
     556                } // switch
    558557          case TypeData::GlobalScope:
    559                         return new GlobalScopeType();
    560                 case TypeData::Qualified:
    561                         return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
     558                return new GlobalScopeType();
     559          case TypeData::Qualified:
     560                return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
    562561          case TypeData::Symbolic:
    563562          case TypeData::Enum:
    564563          case TypeData::Aggregate:
    565                         assert( false );
     564                assert( false );
    566565        } // switch
    567566
     
    768767        AggregateDecl * at;
    769768        switch ( td->aggregate.kind ) {
    770           case DeclarationNode::Struct:
    771           case DeclarationNode::Coroutine:
    772           case DeclarationNode::Monitor:
    773           case DeclarationNode::Thread:
     769          case AggregateDecl::Struct:
     770          case AggregateDecl::Coroutine:
     771          case AggregateDecl::Monitor:
     772          case AggregateDecl::Thread:
    774773                at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage );
    775774                buildForall( td->aggregate.params, at->get_parameters() );
    776775                break;
    777           case DeclarationNode::Union:
     776          case AggregateDecl::Union:
    778777                at = new UnionDecl( *td->aggregate.name, attributes, linkage );
    779778                buildForall( td->aggregate.params, at->get_parameters() );
    780779                break;
    781           case DeclarationNode::Trait:
     780          case AggregateDecl::Trait:
    782781                at = new TraitDecl( *td->aggregate.name, attributes, linkage );
    783782                buildList( td->aggregate.params, at->get_parameters() );
     
    809808                          AggregateDecl * typedecl = buildAggregate( type, attributes, linkage );
    810809                          switch ( type->aggregate.kind ) {
    811                                 case DeclarationNode::Struct:
    812                                 case DeclarationNode::Coroutine:
    813                                 case DeclarationNode::Monitor:
    814                                 case DeclarationNode::Thread:
     810                                case AggregateDecl::Struct:
     811                                case AggregateDecl::Coroutine:
     812                                case AggregateDecl::Monitor:
     813                                case AggregateDecl::Thread:
    815814                                  ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
    816815                                  break;
    817                                 case DeclarationNode::Union:
     816                                case AggregateDecl::Union:
    818817                                  ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
    819818                                  break;
    820                                 case DeclarationNode::Trait:
     819                                case AggregateDecl::Trait:
    821820                                  assert( false );
    822821                                  //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
     
    827826                  } else {
    828827                          switch ( type->aggregate.kind ) {
    829                                 case DeclarationNode::Struct:
    830                                 case DeclarationNode::Coroutine:
    831                                 case DeclarationNode::Monitor:
    832                                 case DeclarationNode::Thread:
     828                                case AggregateDecl::Struct:
     829                                case AggregateDecl::Coroutine:
     830                                case AggregateDecl::Monitor:
     831                                case AggregateDecl::Thread:
    833832                                  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
    834833                                  break;
    835                                 case DeclarationNode::Union:
     834                                case AggregateDecl::Union:
    836835                                  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
    837836                                  break;
    838                                 case DeclarationNode::Trait:
     837                                case AggregateDecl::Trait:
    839838                                  ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
    840839                                  break;
     
    863862          case TypeData::Aggregate: {
    864863                  switch ( type->aggregate.kind ) {
    865                         case DeclarationNode::Struct:
    866                         case DeclarationNode::Coroutine:
    867                         case DeclarationNode::Monitor:
    868                         case DeclarationNode::Thread:
     864                        case AggregateDecl::Struct:
     865                        case AggregateDecl::Coroutine:
     866                        case AggregateDecl::Monitor:
     867                        case AggregateDecl::Thread:
    869868                          ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
    870869                          break;
    871                         case DeclarationNode::Union:
     870                        case AggregateDecl::Union:
    872871                          ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
    873872                          break;
    874                         case DeclarationNode::Trait:
     873                        case AggregateDecl::Trait:
    875874                          ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
    876875                          break;
  • src/Parser/TypeData.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 15:18:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  1 20:56:46 2018
    13 // Update Count     : 196
     12// Last Modified On : Fri Dec 13 23:42:35 2019
     13// Update Count     : 199
    1414//
    1515
     
    2121
    2222#include "ParseNode.h"           // for DeclarationNode, DeclarationNode::Ag...
    23 #include "Parser/LinkageSpec.h" // for Spec
     23#include "SynTree/LinkageSpec.h" // for Spec
    2424#include "SynTree/Type.h"        // for Type, ReferenceToType (ptr only)
    2525#include "SynTree/SynTree.h"     // for Visitor Nodes
     
    3030
    3131        struct Aggregate_t {
    32                 DeclarationNode::Aggregate kind;
     32                AggregateDecl::Aggregate kind;
    3333                const std::string * name = nullptr;
    3434                DeclarationNode * params = nullptr;
  • src/Parser/TypedefTable.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 25 15:32:35 2018
    13 // Update Count     : 258
     12// Last Modified On : Sat Feb 15 08:06:36 2020
     13// Update Count     : 259
    1414//
    1515
     
    4747} // TypedefTable::~TypedefTable
    4848
    49 bool TypedefTable::exists( const string & identifier ) {
     49bool TypedefTable::exists( const string & identifier ) const {
    5050        return kindTable.find( identifier ) != kindTable.end();
    5151} // TypedefTable::exists
    5252
    53 bool TypedefTable::existsCurr( const string & identifier ) {
     53bool TypedefTable::existsCurr( const string & identifier ) const {
    5454        return kindTable.findAt( kindTable.currentScope() - 1, identifier ) != kindTable.end();
    5555} // TypedefTable::exists
  • src/Parser/TypedefTable.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 25 15:33:55 2018
    13 // Update Count     : 114
     12// Last Modified On : Sat Feb 15 08:06:37 2020
     13// Update Count     : 117
    1414//
    1515
     
    3030        ~TypedefTable();
    3131
    32         bool exists( const std::string & identifier );
    33         bool existsCurr( const std::string & identifier );
     32        bool exists( const std::string & identifier ) const;
     33        bool existsCurr( const std::string & identifier ) const;
    3434        int isKind( const std::string & identifier ) const;
    3535        void makeTypedef( const std::string & name, int kind = TYPEDEFname );
  • src/Parser/lex.ll

    r9fb8f01 r3d5701e  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Sun Aug  4 20:53:47 2019
    13  * Update Count     : 719
     12 * Last Modified On : Sat Feb 15 11:05:50 2020
     13 * Update Count     : 737
    1414 */
    1515
     
    4242#include "ParseNode.h"
    4343#include "TypedefTable.h"
     44
     45string * build_postfix_name( string * name );
    4446
    4547char *yyfilename;
     
    330332                                /* identifier */
    331333{identifier}    { IDENTIFIER_RETURN(); }
    332 "`"{identifier}"`" {                                                                    // CFA
    333         yytext[yyleng - 1] = '\0'; yytext += 1;                         // SKULLDUGGERY: remove backquotes (ok to shorten?)
     334"``"{identifier} {                                                                              // CFA
     335        yytext[yyleng] = '\0'; yytext += 2;                                     // SKULLDUGGERY: remove backquotes (ok to shorten?)
    334336        IDENTIFIER_RETURN();
    335337}
     
    432434"?"({op_unary_pre_post}|"()"|"[?]"|"{}") { IDENTIFIER_RETURN(); }
    433435"^?{}"                  { IDENTIFIER_RETURN(); }
    434 "?`"{identifier} { IDENTIFIER_RETURN(); }                               // postfix operator
     436"?`"{identifier} {                                                                              // postfix operator
     437        yylval.tok.str = new string( &yytext[2] );                      // remove ?`
     438        yylval.tok.str = build_postfix_name( yylval.tok.str ); // add prefix
     439        RETURN_LOCN( typedefTable.isKind( *yylval.tok.str ) );
     440}
    435441"?"{op_binary_over}"?"  { IDENTIFIER_RETURN(); }                // binary
    436442        /*
  • src/Parser/module.mk

    r9fb8f01 r3d5701e  
    1111## Created On       : Sat May 16 15:29:09 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Wed Jun 28 21:58:29 2017
    14 ## Update Count     : 104
     13## Last Modified On : Sat Dec 14 07:34:47 2019
     14## Update Count     : 107
    1515###############################################################################
    1616
     
    1919AM_YFLAGS = -d -t -v
    2020
    21 SRC += Parser/parser.yy \
    22        Parser/lex.ll \
    23        Parser/TypedefTable.cc \
    24        Parser/ParseNode.cc \
     21SRC += \
    2522       Parser/DeclarationNode.cc \
    2623       Parser/ExpressionNode.cc \
     24       Parser/InitializerNode.cc \
     25       Parser/ParseNode.cc \
    2726       Parser/StatementNode.cc \
    28        Parser/InitializerNode.cc \
    2927       Parser/TypeData.cc \
    30        Parser/LinkageSpec.cc \
     28       Parser/TypedefTable.cc \
     29       Parser/lex.ll \
     30       Parser/parser.yy \
    3131       Parser/parserutility.cc
    3232
    33 SRCDEMANGLE += \
    34         Parser/LinkageSpec.cc
    35 
    36 
    3733MOSTLYCLEANFILES += Parser/lex.cc Parser/parser.cc Parser/parser.hh Parser/parser.output
  • src/Parser/parser.yy

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug  4 21:48:23 2019
    13 // Update Count     : 4364
     12// Last Modified On : Fri Feb 21 14:47:29 2020
     13// Update Count     : 4468
    1414//
    1515
     
    5151using namespace std;
    5252
     53#include "SynTree/Declaration.h"
    5354#include "ParseNode.h"
    5455#include "TypedefTable.h"
    5556#include "TypeData.h"
    56 #include "LinkageSpec.h"
     57#include "SynTree/LinkageSpec.h"
    5758#include "Common/SemanticError.h"                                               // error_str
    5859#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
     
    165166} // rebindForall
    166167
    167 NameExpr * build_postfix_name( const string * name ) {
    168         NameExpr * new_name = build_varref( new string( "?`" + *name ) );
    169         delete name;
    170         return new_name;
     168string * build_postfix_name( string * name ) {
     169        *name = string("__postfix_func_") + *name;
     170        return name;
    171171} // build_postfix_name
    172172
     
    210210        } // if
    211211} // forCtrl
    212 
    213212
    214213bool forall = false, yyy = false;                                               // aggregate have one or more forall qualifiers ?
     
    237236        ExpressionNode * en;
    238237        DeclarationNode * decl;
    239         DeclarationNode::Aggregate aggKey;
    240         DeclarationNode::TypeClass tclass;
     238        AggregateDecl::Aggregate aggKey;
     239        TypeDecl::Kind tclass;
    241240        StatementNode * sn;
    242241        WaitForStmt * wfs;
     
    323322%type<op> ptrref_operator                               unary_operator                          assignment_operator
    324323%type<en> primary_expression                    postfix_expression                      unary_expression
    325 %type<en> cast_expression                               exponential_expression          multiplicative_expression       additive_expression
     324%type<en> cast_expression_list                  cast_expression                         exponential_expression          multiplicative_expression       additive_expression
    326325%type<en> shift_expression                              relational_expression           equality_expression
    327326%type<en> AND_expression                                exclusive_OR_expression         inclusive_OR_expression
     
    365364%type<decl> abstract_parameter_declaration
    366365
    367 %type<aggKey> aggregate_key
     366%type<aggKey> aggregate_key aggregate_data aggregate_control
    368367%type<decl> aggregate_type aggregate_type_nobody
    369368
     
    579578        | '(' compound_statement ')'                                            // GCC, lambda expression
    580579                { $$ = new ExpressionNode( new StmtExpr( dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >($2) ) ) ); }
    581         | constant '`' IDENTIFIER                                                       // CFA, postfix call
    582                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $3 ) ), $1 ) ); }
    583         | string_literal '`' IDENTIFIER                                         // CFA, postfix call
    584                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $3 ) ), new ExpressionNode( $1 ) ) ); }
    585         | IDENTIFIER '`' IDENTIFIER                                                     // CFA, postfix call
    586                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $3 ) ), new ExpressionNode( build_varref( $1 ) ) ) ); }
    587         | tuple '`' IDENTIFIER                                                          // CFA, postfix call
    588                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $3 ) ), $1 ) ); }
    589         | '(' comma_expression ')' '`' IDENTIFIER                       // CFA, postfix call
    590                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
    591580        | type_name '.' identifier                                                      // CFA, nested type
    592581                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    642631        | postfix_expression '(' argument_expression_list ')'
    643632                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     633        | postfix_expression '`' identifier                                     // CFA, postfix call
     634                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     635        | constant '`' identifier                                                       // CFA, postfix call
     636                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     637        | string_literal '`' identifier                                         // CFA, postfix call
     638                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
    644639        | postfix_expression '.' identifier
    645640                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     
    650645        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    651646                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     647        | postfix_expression '.' aggregate_control
     648                { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
    652649        | postfix_expression ARROW identifier
    653650                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
     
    664661        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    665662                { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    666         | '^' primary_expression '{' argument_expression_list '}' // CFA
     663        | '^' primary_expression '{' argument_expression_list '}' // CFA, destructor call
    667664                {
    668665                        Token fn;
     
    677674        | argument_expression
    678675        | argument_expression_list ',' argument_expression
    679                 { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     676                { $$ = (ExpressionNode *)($1->set_last( $3 )); }
    680677        ;
    681678
     
    689686field_name_list:                                                                                // CFA, tuple field selector
    690687        field
    691         | field_name_list ',' field                                     { $$ = (ExpressionNode *)$1->set_last( $3 ); }
     688        | field_name_list ',' field                                     { $$ = (ExpressionNode *)($1->set_last( $3 )); }
    692689        ;
    693690
     
    793790        | '(' type_no_function ')' cast_expression
    794791                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    795                 // keyword cast cannot be grouped because of reduction in aggregate_key
    796         | '(' GENERATOR '&' ')' cast_expression                         // CFA
    797                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
    798         | '(' COROUTINE '&' ')' cast_expression                         // CFA
    799                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
    800         | '(' THREAD '&' ')' cast_expression                            // CFA
    801                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Thread, $5 ) ); }
    802         | '(' MONITOR '&' ')' cast_expression                           // CFA
    803                 { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Monitor, $5 ) ); }
     792        | '(' aggregate_control '&' ')' cast_expression         // CFA
     793                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    804794                // VIRTUAL cannot be opt because of look ahead issues
    805795        | '(' VIRTUAL ')' cast_expression                                       // CFA
     
    965955                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    966956        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    967                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $6 ) ) ); }
     957                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
    968958        ;
    969959
     
    971961        assignment_expression_opt
    972962        | tuple_expression_list ',' assignment_expression_opt
    973                 { $$ = (ExpressionNode *)$1->set_last( $3 ); }
     963                { $$ = (ExpressionNode *)($1->set_last( $3 )); }
    974964        ;
    975965
     
    11951185                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    11961186                                                OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1187        | '=' comma_expression                                                                  // CFA
     1188                { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1189                                                OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    11971190        | comma_expression inclexcl comma_expression            // CFA
    11981191                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     
    12021195                { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    12031196                                                OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1197        | comma_expression ';' '=' comma_expression                             // CFA
     1198                { $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1199                                                OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    12041200        | comma_expression ';' comma_expression inclexcl comma_expression // CFA
    12051201                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     
    13061302        WAITFOR '(' cast_expression ')'
    13071303                { $$ = $3; }
    1308         | WAITFOR '(' cast_expression ',' argument_expression_list ')'
    1309                 { $$ = (ExpressionNode *)$3->set_last( $5 ); }
     1304//      | WAITFOR '(' cast_expression ',' argument_expression_list ')'
     1305//              { $$ = (ExpressionNode *)$3->set_last( $5 ); }
     1306        | WAITFOR '(' cast_expression_list ':' argument_expression_list ')'
     1307                { $$ = (ExpressionNode *)($3->set_last( $5 )); }
     1308        ;
     1309
     1310cast_expression_list:
     1311        cast_expression
     1312        | cast_expression_list ',' cast_expression
     1313                { $$ = (ExpressionNode *)($1->set_last( $3 )); }
    13101314        ;
    13111315
     
    14181422        asm_operand
    14191423        | asm_operands_list ',' asm_operand
    1420                 { $$ = (ExpressionNode *)$1->set_last( $3 ); }
     1424                { $$ = (ExpressionNode *)($1->set_last( $3 )); }
    14211425        ;
    14221426
    14231427asm_operand:                                                                                    // GCC
    14241428        string_literal '(' constant_expression ')'
    1425                 { $$ = new ExpressionNode( new AsmExpr( maybeMoveBuild< Expression >( (ExpressionNode *)nullptr ), $1, maybeMoveBuild< Expression >( $3 ) ) ); }
    1426         | '[' constant_expression ']' string_literal '(' constant_expression ')'
    1427                 { $$ = new ExpressionNode( new AsmExpr( maybeMoveBuild< Expression >( $2 ), $4, maybeMoveBuild< Expression >( $6 ) ) ); }
     1429                { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild< Expression >( $3 ) ) ); }
     1430        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
     1431                { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild< Expression >( $6 ) ) ); }
    14281432        ;
    14291433
     
    14341438                { $$ = new ExpressionNode( $1 ); }
    14351439        | asm_clobbers_list_opt ',' string_literal
    1436                 // set_last returns ParseNode *
    1437                 { $$ = (ExpressionNode *)$1->set_last( new ExpressionNode( $3 ) ); }
     1440                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); }
    14381441        ;
    14391442
     
    15861589                // type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
    15871590                // flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
    1588         cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
     1591        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    15891592                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1590                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
    1591         | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
    1592                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
     1593                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
     1594        | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
     1595                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    15931596        ;
    15941597
     
    20592062
    20602063aggregate_key:
     2064        aggregate_data
     2065        | aggregate_control
     2066        ;
     2067
     2068aggregate_data:
    20612069        STRUCT
    2062                 { yyy = true; $$ = DeclarationNode::Struct; }
     2070                { yyy = true; $$ = AggregateDecl::Struct; }
    20632071        | UNION
    2064                 { yyy = true; $$ = DeclarationNode::Union; }
    2065         | EXCEPTION
    2066                 { yyy = true; $$ = DeclarationNode::Exception; }
    2067         | GENERATOR
    2068                 { yyy = true; $$ = DeclarationNode::Coroutine; }
     2072                { yyy = true; $$ = AggregateDecl::Union; }
     2073        | EXCEPTION                                                                                     // CFA
     2074                { yyy = true; $$ = AggregateDecl::Exception; }
     2075        ;
     2076
     2077aggregate_control:                                                                              // CFA
     2078        GENERATOR
     2079                { yyy = true; $$ = AggregateDecl::Coroutine; }
    20692080        | COROUTINE
    2070                 { yyy = true; $$ = DeclarationNode::Coroutine; }
     2081                { yyy = true; $$ = AggregateDecl::Coroutine; }
    20712082        | MONITOR
    2072                 { yyy = true; $$ = DeclarationNode::Monitor; }
     2083                { yyy = true; $$ = AggregateDecl::Monitor; }
    20732084        | THREAD
    2074                 { yyy = true; $$ = DeclarationNode::Thread; }
     2085                { yyy = true; $$ = AggregateDecl::Thread; }
    20752086        ;
    20762087
     
    20962107                        distInl( $3 );
    20972108                }
     2109        | INLINE aggregate_control ';'                                          // CFA
     2110                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    20982111        | typedef_declaration ';'                                                       // CFA
    20992112        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    23482361        | initializer_list_opt ',' initializer          { $$ = (InitializerNode *)( $1->set_last( $3 ) ); }
    23492362        | initializer_list_opt ',' designation initializer
    2350                 { $$ = (InitializerNode *)( $1->set_last( $4->set_designators( $3 ) ) ); }
     2363                { $$ = (InitializerNode *)($1->set_last( $4->set_designators( $3 ) )); }
    23512364        ;
    23522365
     
    23702383        designator
    23712384        | designator_list designator
    2372                 { $$ = (ExpressionNode *)( $1->set_last( $2 ) ); }
     2385                { $$ = (ExpressionNode *)($1->set_last( $2 )); }
    23732386        //| designator_list designator                                          { $$ = new ExpressionNode( $1, $2 ); }
    23742387        ;
     
    24262439        | type_specifier identifier_parameter_declarator
    24272440        | assertion_list
    2428                 { $$ = DeclarationNode::newTypeParam( DeclarationNode::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2441                { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    24292442        ;
    24302443
    24312444type_class:                                                                                             // CFA
    24322445        OTYPE
    2433                 { $$ = DeclarationNode::Otype; }
     2446                { $$ = TypeDecl::Otype; }
    24342447        | DTYPE
    2435                 { $$ = DeclarationNode::Dtype; }
     2448                { $$ = TypeDecl::Dtype; }
    24362449        | FTYPE
    2437                 { $$ = DeclarationNode::Ftype; }
     2450                { $$ = TypeDecl::Ftype; }
    24382451        | TTYPE
    2439                 { $$ = DeclarationNode::Ttype; }
     2452                { $$ = TypeDecl::Ttype; }
    24402453        ;
    24412454
     
    24672480                { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $1->build()) ); $$ = nullptr; }
    24682481        | type_list ',' type
    2469                 { $$ = (ExpressionNode *)( $1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) ) ); }
     2482                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    24702483        | type_list ',' assignment_expression
    24712484                { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $3->build()) ); $$ = nullptr; }
     
    25782591                {
    25792592                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    2580                         linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 );
     2593                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    25812594                }
    25822595          '{' up external_definition_list_opt down '}'
  • src/ResolvExpr/AdjustExprType.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 23:41:42 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:34:53 2016
    13 // Update Count     : 4
     12// Last Modified On : Wed Dec 11 21:43:56 2019
     13// Update Count     : 6
    1414//
    1515
     
    133133                        // replace known function-type-variables with pointer-to-function
    134134                        if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) {
    135                                 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
     135                                if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) {
    136136                                        return new ast::PointerType{ inst };
    137137                                }
    138138                        } else if ( const ast::NamedTypeDecl * ntDecl = symtab.lookupType( inst->name ) ) {
    139139                                if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( ntDecl ) ) {
    140                                         if ( tyDecl->kind == ast::TypeVar::Ftype ) {
     140                                        if ( tyDecl->kind == ast::TypeDecl::Ftype ) {
    141141                                                return new ast::PointerType{ inst };
    142142                                        }
  • src/ResolvExpr/AlternativeFinder.cc

    r9fb8f01 r3d5701e  
    6969                void postvisit( CastExpr * castExpr );
    7070                void postvisit( VirtualCastExpr * castExpr );
     71                void postvisit( KeywordCastExpr * castExpr );
    7172                void postvisit( UntypedMemberExpr * memberExpr );
    7273                void postvisit( MemberExpr * memberExpr );
     
    12551256        }
    12561257
     1258        void AlternativeFinder::Finder::postvisit( KeywordCastExpr * castExpr ) {
     1259                assertf( castExpr->get_result(), "Cast target should have been set in Validate." );
     1260                auto ref = dynamic_cast<ReferenceType*>(castExpr->get_result());
     1261                assert(ref);
     1262                auto inst = dynamic_cast<StructInstType*>(ref->base);
     1263                assert(inst);
     1264                auto target = inst->baseStruct;
     1265
     1266                AlternativeFinder finder( indexer, env );
     1267
     1268                auto pick_alternatives = [target, this](AltList & found, bool expect_ref) {
     1269                        for(auto & alt : found) {
     1270                                Type * expr = alt.expr->get_result();
     1271                                if(expect_ref) {
     1272                                        auto res = dynamic_cast<ReferenceType*>(expr);
     1273                                        if(!res) { continue; }
     1274                                        expr = res->base;
     1275                                }
     1276
     1277                                if(auto insttype = dynamic_cast<TypeInstType*>(expr)) {
     1278                                        auto td = alt.env.lookup(insttype->name);
     1279                                        if(!td) { continue; }
     1280                                        expr = td->type;
     1281                                }
     1282
     1283                                if(auto base = dynamic_cast<StructInstType*>(expr)) {
     1284                                        if(base->baseStruct == target) {
     1285                                                alternatives.push_back(
     1286                                                        std::move(alt)
     1287                                                );
     1288                                        }
     1289                                }
     1290                        }
     1291                };
     1292
     1293                try {
     1294                        // Attempt 1 : turn (thread&)X into ($thread&)X.__thrd
     1295                        // Clone is purely for memory management
     1296                        std::unique_ptr<Expression> tech1 { new UntypedMemberExpr(new NameExpr(castExpr->concrete_target.field), castExpr->arg->clone()) };
     1297
     1298                        // don't prune here, since it's guaranteed all alternatives will have the same type
     1299                        finder.findWithoutPrune( tech1.get() );
     1300                        pick_alternatives(finder.alternatives, false);
     1301
     1302                        return;
     1303                } catch(SemanticErrorException & ) {}
     1304
     1305                // Fallback : turn (thread&)X into ($thread&)get_thread(X)
     1306                std::unique_ptr<Expression> fallback { UntypedExpr::createDeref( new UntypedExpr(new NameExpr(castExpr->concrete_target.getter), { castExpr->arg->clone() })) };
     1307                // don't prune here, since it's guaranteed all alternatives will have the same type
     1308                finder.findWithoutPrune( fallback.get() );
     1309
     1310                pick_alternatives(finder.alternatives, true);
     1311
     1312                // Whatever happens here, we have no more fallbacks
     1313        }
     1314
    12571315        namespace {
    12581316                /// Gets name from untyped member expression (member must be NameExpr)
  • src/ResolvExpr/ConversionCost.cc

    r9fb8f01 r3d5701e  
    157157                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    158158                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    159                                 assert( src->get_lvalue() == srcIsLvalue );
    160159                                if ( srcIsLvalue ) {
    161160                                        PRINT(
  • src/ResolvExpr/PtrsCastable.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sun May 17 11:48:00 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:36:18 2016
    13 // Update Count     : 8
     12// Last Modified On : Wed Dec 11 21:48:33 2019
     13// Update Count     : 9
    1414//
    1515
     
    176176                        if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
    177177                                if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) {
    178                                         if ( tyDecl->kind == ast::TypeVar::Ftype ) {
     178                                        if ( tyDecl->kind == ast::TypeDecl::Ftype ) {
    179179                                                return -1;
    180180                                        }
    181181                                }
    182182                        } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
    183                                 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
     183                                if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) {
    184184                                        return -1;
    185185                                }
  • src/ResolvExpr/ResolveAssertions.cc

    r9fb8f01 r3d5701e  
    156156                        for ( const auto& assn : x.assns ) {
    157157                                // compute conversion cost from satisfying decl to assertion
    158                                 assert( !assn.match.adjType->get_lvalue() );
    159158                                k += computeConversionCost(
    160159                                        assn.match.adjType, assn.decl->get_type(), false, indexer, x.env );
  • src/ResolvExpr/Resolver.cc

    r9fb8f01 r3d5701e  
    8484                void previsit( ThrowStmt * throwStmt );
    8585                void previsit( CatchStmt * catchStmt );
     86                void postvisit( CatchStmt * catchStmt );
    8687                void previsit( WaitForStmt * stmt );
    8788
     
    485486                visit_children = false;
    486487                findVoidExpression( asmExpr->operand, indexer );
    487                 if ( asmExpr->get_inout() ) {
    488                         findVoidExpression( asmExpr->inout, indexer );
    489                 } // if
    490488        }
    491489
     
    570568
    571569        void Resolver_old::previsit( CatchStmt * catchStmt ) {
     570                // Until we are very sure this invarent (ifs that move between passes have thenPart)
     571                // holds, check it. This allows a check for when to decode the mangling.
     572                if ( IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body ) ) {
     573                        assert( ifStmt->thenPart );
     574                }
     575                // Encode the catchStmt so the condition can see the declaration.
    572576                if ( catchStmt->cond ) {
    573                         findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
     577                        IfStmt * ifStmt = new IfStmt( catchStmt->cond, nullptr, catchStmt->body );
     578                        catchStmt->cond = nullptr;
     579                        catchStmt->body = ifStmt;
     580                }
     581        }
     582
     583        void Resolver_old::postvisit( CatchStmt * catchStmt ) {
     584                // Decode the catchStmt so everything is stored properly.
     585                IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body );
     586                if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) {
     587                        assert( ifStmt->condition );
     588                        assert( ifStmt->elsePart );
     589                        catchStmt->cond = ifStmt->condition;
     590                        catchStmt->body = ifStmt->elsePart;
     591                        ifStmt->condition = nullptr;
     592                        ifStmt->elsePart = nullptr;
     593                        delete ifStmt;
    574594                }
    575595        }
     
    13661386                        asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
    13671387
    1368                 if ( asmExpr->inout ) {
    1369                         asmExpr = ast::mutate_field(
    1370                                 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
    1371                 }
    1372 
    13731388                return asmExpr;
    13741389        }
     
    14741489
    14751490        const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
     1491                // TODO: This will need a fix for the decl/cond scoping problem.
    14761492                if ( catchStmt->cond ) {
    14771493                        ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
  • src/ResolvExpr/Unify.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Mon Jun 18 11:58:00 2018
    13 // Update Count     : 43
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:43:05 2019
     13// Update Count     : 46
    1414//
    1515
     
    3232#include "Common/PassVisitor.h"     // for PassVisitor
    3333#include "FindOpenVars.h"           // for findOpenVars
    34 #include "Parser/LinkageSpec.h"     // for C
     34#include "SynTree/LinkageSpec.h"    // for C
    3535#include "SynTree/Constant.h"       // for Constant
    3636#include "SynTree/Declaration.h"    // for TypeDecl, TypeDecl::Data, Declarati...
     
    278278#endif
    279279                        if ( ( common = commonType( type1, type2, widen.first, widen.second, indexer, env, openVars ) ) ) {
    280                                 common->get_qualifiers() = tq1 | tq2;
     280                                common->tq = tq1.unify( tq2 );
    281281#ifdef DEBUG
    282282                                std::cerr << "unifyInexact: common type is ";
     
    295295                                if ( ( tq1 > tq2 || widen.first ) && ( tq2 > tq1 || widen.second ) ) {
    296296                                        common = type1->clone();
    297                                         common->get_qualifiers() = tq1 | tq2;
     297                                        common->tq = tq1.unify( tq2 );
    298298                                        result = true;
    299299                                } else {
     
    302302                        } else {
    303303                                common = type1->clone();
    304                                 common->get_qualifiers() = tq1 | tq2;
     304                                common->tq = tq1.unify( tq2 );
    305305                                result = true;
    306306                        } // if
     
    781781                                if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name ) ) {
    782782                                        // expand ttype parameter into its actual type
    783                                         if ( clz->data.kind == ast::TypeVar::Ttype && clz->bound ) {
     783                                        if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) {
    784784                                                return clz->bound;
    785785                                        }
  • src/SymTab/Autogen.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Sun May 17 21:53:34 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:50:25 2017
    13 // Update Count     : 15
     12// Last Modified On : Fri Dec 13 16:38:06 2019
     13// Update Count     : 16
    1414//
    1515
     
    3434#include "SynTree/Expression.h"   // for NameExpr, ConstantExpr, UntypedExpr...
    3535#include "SynTree/Type.h"         // for Type, ArrayType, Type::Qualifiers
     36#include "SynTree/Statement.h"    // for CompoundStmt, DeclStmt, ExprStmt
    3637
    3738class CompoundStmt;
     
    9798                        //   type->get_qualifiers() = Type::Qualifiers();
    9899                        Type * castType = addCast->clone();
    99                         castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     100                        castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    100101                        // castType->set_lvalue( true ); // xxx - might not need this
    101102                        dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) );
  • src/SymTab/Demangle.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Thu Jul 19 12:52:41 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 30 13:46:33 2019
    13 // Update Count     : 3
     12// Last Modified On : Tue Feb 11 15:09:18 2020
     13// Update Count     : 10
    1414//
    1515
     
    1919#include "CodeGen/GenType.h"
    2020#include "Common/PassVisitor.h"
     21#include "Common/utility.h"                                                             // isPrefix
    2122#include "Mangler.h"
    2223#include "SynTree/Type.h"
     
    366367                                // type variable types
    367368                                for (size_t k = 0; k < TypeDecl::NUMBER_OF_KINDS; ++k) {
    368                                         static const std::string typeVariableNames[] = { "DT", "FT", "TT", };
     369                                        static const std::string typeVariableNames[] = { "DT", "OT", "FT", "TT", };
    369370                                        static_assert(
    370371                                                sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == TypeDecl::NUMBER_OF_KINDS,
     
    416417
    417418                        bool StringView::isPrefix(const std::string & pref) {
    418                                 if ( pref.size() > str.size()-idx ) return false;
    419                                 auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) );
    420                                 if (its.first == pref.end()) {
     419                                // if ( pref.size() > str.size()-idx ) return false;
     420                                // auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) );
     421                                // if (its.first == pref.end()) {
     422                                //      idx += pref.size();
     423                                //      return true;
     424                                // }
     425
     426                                // This update is untested because there are no tests for this code.
     427                                if ( ::isPrefix( str, pref, idx ) ) {
    421428                                        idx += pref.size();
    422429                                        return true;
     
    429436                                PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; )
    430437                                if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix
    431                                 if (! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back())) return false;
     438                                if ( ! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back() ) ) return false;
    432439
    433440                                // get name
  • src/SymTab/Indexer.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:37:33 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Fri Mar  8 13:55:00 2019
    13 // Update Count     : 21
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:43:19 2019
     13// Update Count     : 22
    1414//
    1515
     
    3131#include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
    3232#include "Mangler.h"               // for Mangler
    33 #include "Parser/LinkageSpec.h"    // for isMangled, isOverridable, Spec
    3433#include "ResolvExpr/typeops.h"    // for typesCompatible
     34#include "SynTree/LinkageSpec.h"   // for isMangled, isOverridable, Spec
    3535#include "SynTree/Constant.h"      // for Constant
    3636#include "SynTree/Declaration.h"   // for DeclarationWithType, FunctionDecl
  • src/SymTab/Mangler.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sun May 17 21:40:29 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 30 13:46:10 2019
    13 // Update Count     : 26
     12// Last Modified On : Sat Feb 15 13:55:12 2020
     13// Update Count     : 33
    1414//
    1515#include "Mangler.h"
     
    2626#include "Common/SemanticError.h"        // for SemanticError
    2727#include "Common/utility.h"              // for toString
    28 #include "Parser/LinkageSpec.h"          // for Spec, isOverridable, AutoGen, Int...
    2928#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
     29#include "SynTree/LinkageSpec.h"         // for Spec, isOverridable, AutoGen, Int...
    3030#include "SynTree/Declaration.h"         // for TypeDecl, DeclarationWithType
    3131#include "SynTree/Expression.h"          // for TypeExpr, Expression, operator<<
     
    128128                                } // if
    129129                                mangleName << Encoding::manglePrefix;
    130                                 CodeGen::OperatorInfo opInfo;
    131                                 if ( operatorLookup( declaration->get_name(), opInfo ) ) {
    132                                         mangleName << opInfo.outputName.size() << opInfo.outputName;
     130                                const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );
     131                                if ( opInfo ) {
     132                                        mangleName << opInfo->outputName.size() << opInfo->outputName;
    133133                                } else {
    134134                                        mangleName << declaration->name.size() << declaration->name;
     
    471471                        } // if
    472472                        mangleName << Encoding::manglePrefix;
    473                         CodeGen::OperatorInfo opInfo;
    474                         if ( operatorLookup( decl->name, opInfo ) ) {
    475                                 mangleName << opInfo.outputName.size() << opInfo.outputName;
     473                        const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( decl->name );
     474                        if ( opInfo ) {
     475                                mangleName << opInfo->outputName.size() << opInfo->outputName;
    476476                        } else {
    477477                                mangleName << decl->name.size() << decl->name;
     
    654654                        // aside from the assert false.
    655655                        assertf(false, "Mangler_new should not visit typedecl: %s", toCString(decl));
    656                         assertf( decl->kind < ast::TypeVar::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
     656                        assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
    657657                        mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
    658658                }
     
    674674                                        for ( const ast::TypeDecl * decl : ptype->forall ) {
    675675                                                switch ( decl->kind ) {
    676                                                 case ast::TypeVar::Kind::Dtype:
     676                                                case ast::TypeDecl::Kind::Dtype:
    677677                                                        dcount++;
    678678                                                        break;
    679                                                 case ast::TypeVar::Kind::Ftype:
     679                                                case ast::TypeDecl::Kind::Ftype:
    680680                                                        fcount++;
    681681                                                        break;
    682                                                 case ast::TypeVar::Kind::Ttype:
     682                                                case ast::TypeDecl::Kind::Ttype:
    683683                                                        vcount++;
    684684                                                        break;
  • src/SymTab/ManglerCommon.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Sun May 17 21:44:03 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 14 17:06:37 2019
    13 // Update Count     : 26
     12// Last Modified On : Fri Dec 13 14:54:38 2019
     13// Update Count     : 28
    1414//
    1515
     
    8888                                { Type::Atomic, "DA" }, // A is array, so need something unique for atmoic. For now, go with multiletter DA
    8989                                { Type::Mutex, "X" },
    90                                 { Type::Lvalue, "L" },
    9190                        };
    9291
     
    105104                        const std::string typeVariables[] = {
    106105                                "BD", // dtype
     106                                "BO", // otype
    107107                                "BF", // ftype
    108108                                "BT", // ttype
  • src/SymTab/Validate.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  7 6:42:00 2019
    13 // Update Count     : 360
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:43:34 2019
     13// Update Count     : 363
    1414//
    1515
     
    6969#include "InitTweak/GenInit.h"         // for fixReturnStatements
    7070#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    71 #include "Parser/LinkageSpec.h"        // for C
    7271#include "ResolvExpr/typeops.h"        // for typesCompatible
    7372#include "ResolvExpr/Resolver.h"       // for findSingleExpression
    7473#include "ResolvExpr/ResolveTypeof.h"  // for resolveTypeof
    7574#include "SymTab/Autogen.h"            // for SizeType
     75#include "SynTree/LinkageSpec.h"       // for C
    7676#include "SynTree/Attribute.h"         // for noAttributes, Attribute
    7777#include "SynTree/Constant.h"          // for Constant
     
    8181#include "SynTree/Label.h"             // for operator==, Label
    8282#include "SynTree/Mutator.h"           // for Mutator
    83 #include "SynTree/TopLvalue.h"         // for assertTopLvalue, clearInnerLvalue
    8483#include "SynTree/Type.h"              // for Type, TypeInstType, EnumInstType
    8584#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
     
    309308                PassVisitor<FixQualifiedTypes> fixQual;
    310309
    311                 assertTopLvalue( translationUnit );
    312310                {
    313311                        Stats::Heap::newPass("validate-A");
    314312                        Stats::Time::BlockGuard guard("validate-A");
     313                        VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    315314                        acceptAll( translationUnit, hoistDecls );
    316315                        ReplaceTypedef::replaceTypedef( translationUnit );
     
    318317                        acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling
    319318                }
    320                 assertTopLvalue( translationUnit );
    321319                {
    322320                        Stats::Heap::newPass("validate-B");
    323321                        Stats::Time::BlockGuard guard("validate-B");
    324                         assertTopLvalue( translationUnit );
    325322                        Stats::Time::TimeBlock("Link Reference To Types", [&]() {
    326323                                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
    327324                        });
    328                         clearInnerLvalue( translationUnit );
    329                         assertTopLvalue( translationUnit );
    330325                        Stats::Time::TimeBlock("Fix Qualified Types", [&]() {
    331326                                mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed
    332327                        });
    333                         assertTopLvalue( translationUnit );
    334328                        Stats::Time::TimeBlock("Hoist Structs", [&]() {
    335329                                HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
    336330                        });
    337                         assertTopLvalue( translationUnit );
    338331                        Stats::Time::TimeBlock("Eliminate Typedefs", [&]() {
    339332                                EliminateTypedef::eliminateTypedef( translationUnit ); //
    340333                        });
    341334                }
    342                 assertTopLvalue( translationUnit );
    343335                {
    344336                        Stats::Heap::newPass("validate-C");
    345337                        Stats::Time::BlockGuard guard("validate-C");
    346338                        acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes_old
    347                         VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    348339                        ReturnChecker::checkFunctionReturns( translationUnit );
    349340                        InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
    350341                }
    351                 assertTopLvalue( translationUnit );
    352342                {
    353343                        Stats::Heap::newPass("validate-D");
    354344                        Stats::Time::BlockGuard guard("validate-D");
    355                         assertTopLvalue( translationUnit );
    356345                        Stats::Time::TimeBlock("Apply Concurrent Keywords", [&]() {
    357346                                Concurrency::applyKeywords( translationUnit );
    358347                        });
    359                         clearInnerLvalue( translationUnit );
    360                         assertTopLvalue( translationUnit );
    361348                        Stats::Time::TimeBlock("Forall Pointer Decay", [&]() {
    362349                                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
    363350                        });
    364                         assertTopLvalue( translationUnit );
    365351                        Stats::Time::TimeBlock("Hoist Control Declarations", [&]() {
    366352                                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    367353                        });
    368                         assertTopLvalue( translationUnit );
    369354                        Stats::Time::TimeBlock("Generate Autogen routines", [&]() {
    370355                                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old
    371356                        });
    372                         clearInnerLvalue( translationUnit );
    373                 }
    374                 assertTopLvalue( translationUnit );
     357                }
    375358                {
    376359                        Stats::Heap::newPass("validate-E");
    377360                        Stats::Time::BlockGuard guard("validate-E");
    378                         assertTopLvalue( translationUnit );
    379361                        Stats::Time::TimeBlock("Implement Mutex Func", [&]() {
    380362                                Concurrency::implementMutexFuncs( translationUnit );
    381363                        });
    382                         clearInnerLvalue( translationUnit );
    383                         assertTopLvalue( translationUnit );
    384364                        Stats::Time::TimeBlock("Implement Thread Start", [&]() {
    385365                                Concurrency::implementThreadStarter( translationUnit );
    386366                        });
    387                         assertTopLvalue( translationUnit );
    388367                        Stats::Time::TimeBlock("Compound Literal", [&]() {
    389368                                mutateAll( translationUnit, compoundliteral );
    390369                        });
    391                         assertTopLvalue( translationUnit );
    392370                        Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
    393371                                ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
    394372                        });
    395                         clearInnerLvalue( translationUnit );
    396                 }
    397                 assertTopLvalue( translationUnit );
     373                }
    398374                {
    399375                        Stats::Heap::newPass("validate-F");
    400376                        Stats::Time::BlockGuard guard("validate-F");
    401                         assertTopLvalue( translationUnit );
    402                         Stats::Time::TimeBlock("Fix Object Type", [&]() {
    403                                 FixObjectType::fix( translationUnit );
    404                         });
    405                         assertTopLvalue( translationUnit );
    406                         Stats::Time::TimeBlock("Array Length", [&]() {
    407                                 ArrayLength::computeLength( translationUnit );
    408                         });
    409                         clearInnerLvalue( translationUnit );
    410                         assertTopLvalue( translationUnit );
    411                         Stats::Time::TimeBlock("Find Special Declarations", [&]() {
    412                                 Validate::findSpecialDecls( translationUnit );
    413                         });
    414                         assertTopLvalue( translationUnit );
    415                         Stats::Time::TimeBlock("Fix Label Address", [&]() {
    416                                 mutateAll( translationUnit, labelAddrFixer );
    417                         });
    418                         assertTopLvalue( translationUnit );
    419                         Stats::Time::TimeBlock("Handle Attributes", [&]() {
    420                                 Validate::handleAttributes( translationUnit );
    421                         });
    422                 }
    423                 assertTopLvalue( translationUnit );
     377                        Stats::Time::TimeCall("Fix Object Type",
     378                                FixObjectType::fix, translationUnit);
     379                        Stats::Time::TimeCall("Array Length",
     380                                ArrayLength::computeLength, translationUnit);
     381                        Stats::Time::TimeCall("Find Special Declarations",
     382                                Validate::findSpecialDecls, translationUnit);
     383                        Stats::Time::TimeCall("Fix Label Address",
     384                                mutateAll<LabelAddressFixer>, translationUnit, labelAddrFixer);
     385                        Stats::Time::TimeCall("Handle Attributes",
     386                                Validate::handleAttributes, translationUnit);
     387                }
    424388        }
    425389
     
    10801044                Type * designatorType = tyDecl->base->stripDeclarator();
    10811045                if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
    1082                         declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
     1046                        declsToAddBefore.push_back( new StructDecl( aggDecl->name, AggregateDecl::Struct, noAttributes, tyDecl->linkage ) );
    10831047                } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
    10841048                        declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
     
    12181182                if ( CodeGen::isCtorDtorAssign( funcDecl->get_name() ) ) { // TODO: also check /=, etc.
    12191183                        if ( params.size() == 0 ) {
    1220                                 SemanticError( funcDecl, "Constructors, destructors, and assignment functions require at least one parameter " );
     1184                                SemanticError( funcDecl->location, "Constructors, destructors, and assignment functions require at least one parameter." );
    12211185                        }
    12221186                        ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
    12231187                        if ( ! refType ) {
    1224                                 SemanticError( funcDecl, "First parameter of a constructor, destructor, or assignment function must be a reference " );
     1188                                SemanticError( funcDecl->location, "First parameter of a constructor, destructor, or assignment function must be a reference." );
    12251189                        }
    12261190                        if ( CodeGen::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
    1227                                 SemanticError( funcDecl, "Constructors and destructors cannot have explicit return values " );
     1191                                if(!returnVals.front()->get_type()->isVoid()) {
     1192                                        SemanticError( funcDecl->location, "Constructors and destructors cannot have explicit return values." );
     1193                                }
    12281194                        }
    12291195                }
     
    13341300        void FixObjectType::previsit( ObjectDecl * objDecl ) {
    13351301                Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
    1336                 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
    13371302                objDecl->set_type( new_type );
    13381303        }
     
    13401305        void FixObjectType::previsit( FunctionDecl * funcDecl ) {
    13411306                Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
    1342                 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
    13431307                funcDecl->set_type( new_type );
    13441308        }
     
    13471311                if ( typeDecl->get_base() ) {
    13481312                        Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
    1349                         new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
    13501313                        typeDecl->set_base( new_type );
    13511314                } // if
  • src/SynTree/AddressExpr.cc

    r9fb8f01 r3d5701e  
    5353                        } // if
    5454                }
    55                 // result of & is never an lvalue
    56                 get_result()->set_lvalue( false );
    5755        }
    5856}
  • src/SynTree/AggregateDecl.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 23:56:39 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug  4 14:22:00 2017
    13 // Update Count     : 22
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Dec 16 15:07:20 2019
     13// Update Count     : 31
    1414//
    1515
     
    2121#include "Common/utility.h"      // for printAll, cloneAll, deleteAll
    2222#include "Declaration.h"         // for AggregateDecl, TypeDecl, Declaration
    23 #include "Parser/LinkageSpec.h"  // for Spec, linkageName, Cforall
     23#include "Initializer.h"
     24#include "LinkageSpec.h"         // for Spec, linkageName, Cforall
    2425#include "Type.h"                // for Type, Type::StorageClasses
    2526
     27
     28// These must harmonize with the corresponding AggregateDecl::Aggregate enumerations.
     29static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };
     30
     31const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) {
     32        return aggregateNames[aggr];
     33}
    2634
    2735AggregateDecl::AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes, LinkageSpec::Spec linkage ) : Parent( name, Type::StorageClasses(), linkage ), body( false ), attributes( attributes ) {
     
    4755        os << typeString() << " " << name << ":";
    4856        if ( get_linkage() != LinkageSpec::Cforall ) {
    49                 os << " " << LinkageSpec::linkageName( linkage );
     57                os << " " << LinkageSpec::name( linkage );
    5058        } // if
    5159        os << " with body " << has_body();
     
    7886}
    7987
    80 std::string StructDecl::typeString() const { return "struct"; }
     88const char * StructDecl::typeString() const { return aggrString( kind ); }
    8189
    82 std::string UnionDecl::typeString() const { return "union"; }
     90const char * UnionDecl::typeString() const { return aggrString( Union ); }
    8391
    84 std::string EnumDecl::typeString() const { return "enum"; }
     92const char * EnumDecl::typeString() const { return aggrString( Enum ); }
    8593
    86 std::string TraitDecl::typeString() const { return "trait"; }
     94const char * TraitDecl::typeString() const { return aggrString( Trait ); }
    8795
    8896bool EnumDecl::valueOf( Declaration * enumerator, long long int & value ) {
  • src/SynTree/ApplicationExpr.cc

    r9fb8f01 r3d5701e  
    2525#include "Declaration.h"         // for Declaration
    2626#include "Expression.h"          // for ParamEntry, ApplicationExpr, Expression
     27#include "InitTweak/InitTweak.h" // for getFunction
    2728#include "ResolvExpr/typeops.h"  // for extractResultType
    2829#include "Type.h"                // for Type, PointerType, FunctionType
     
    7778
    7879bool ApplicationExpr::get_lvalue() const {
    79         return result->get_lvalue();
     80        // from src/GenPoly/Lvalue.cc: isIntrinsicReference
     81        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
     82        if ( const DeclarationWithType * func = InitTweak::getFunction( this ) ) {
     83                return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name);
     84        }
     85        return false;
    8086}
    8187
  • src/SynTree/ArrayType.cc

    r9fb8f01 r3d5701e  
    2626ArrayType::ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes )
    2727        : Type( tq, attributes ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic ) {
    28         base->set_lvalue( false );
    2928}
    3029
  • src/SynTree/Attribute.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:54:14 2017
    13 // Update Count     : 39
     12// Last Modified On : Thu Feb 13 21:34:08 2020
     13// Update Count     : 40
    1414//
    1515
     
    3838        virtual ~Attribute();
    3939
    40         std::string get_name() const { return name; }
     40        const std::string & get_name() const { return name; }
    4141        void set_name( const std::string & newValue ) { name = newValue; }
    4242        std::list< Expression * > & get_parameters() { return parameters; }
  • src/SynTree/CommaExpr.cc

    r9fb8f01 r3d5701e  
    2323CommaExpr::CommaExpr( Expression *arg1, Expression *arg2 )
    2424                : Expression(), arg1( arg1 ), arg2( arg2 ) {
    25         // xxx - result of a comma expression is never an lvalue, so should set lvalue
    26         // to false on all result types. Actually doing this causes some strange things
    27         // to happen in later passes (particularly, Specialize, Lvalue, and Box). This needs to be looked into.
    2825        set_result( maybeClone( arg2->get_result() ) );
    29         // get_type->set_isLvalue( false );
    3026}
    3127
     
    4036
    4137bool CommaExpr::get_lvalue() const {
    42         // xxx - as above, shouldn't be an lvalue but that information is used anyways.
    43         return result->get_lvalue();
     38        // This is wrong by C, but the current implementation uses it.
     39        // (ex: Specialize, Lvalue and Box)
     40        return arg2->get_lvalue();
    4441}
    4542
  • src/SynTree/Declaration.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  9 14:38:00 2017
    13 // Update Count     : 25
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Dec 11 16:39:56 2019
     13// Update Count     : 36
    1414//
    1515
     
    2424#include "SynTree/Statement.h"       // for AsmStmt
    2525#include "SynTree/SynTree.h"         // for UniqueId
     26#include "SynTree/Expression.h"
    2627#include "Type.h"                    // for Type, Type::StorageClasses
    2728
     29// To canonicalize declarations
    2830static UniqueId lastUniqueId = 0;
    2931
  • src/SynTree/Declaration.h

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May  2 10:47:00 2019
    13 // Update Count     : 135
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:11:22 2019
     13// Update Count     : 157
    1414//
    1515
     
    2424#include "BaseSyntaxNode.h"      // for BaseSyntaxNode
    2525#include "Mutator.h"             // for Mutator
    26 #include "Parser/LinkageSpec.h"  // for Spec, Cforall
    27 #include "Parser/ParseNode.h"    // for DeclarationNode, DeclarationNode::Ag...
     26#include "LinkageSpec.h"         // for Spec, Cforall
    2827#include "SynTree.h"             // for UniqueId
    2928#include "SynTree/Type.h"        // for Type, Type::StorageClasses, Type::Fu...
     
    4443        bool extension = false;
    4544
    46         Declaration( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage );
    47         Declaration( const Declaration &other );
     45        Declaration( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage );
     46        Declaration( const Declaration & other );
    4847        virtual ~Declaration();
    4948
    50         const std::string &get_name() const { return name; }
     49        const std::string & get_name() const { return name; }
    5150        void set_name( std::string newValue ) { name = newValue; }
    5251
     
    5958
    6059        bool get_extension() const { return extension; }
    61         Declaration *set_extension( bool exten ) { extension = exten; return this; }
     60        Declaration * set_extension( bool exten ) { extension = exten; return this; }
    6261
    6362        void fixUniqueId( void );
    64         virtual Declaration *clone() const override = 0;
     63        virtual Declaration * clone() const override = 0;
    6564        virtual void accept( Visitor & v ) override = 0;
    6665        virtual void accept( Visitor & v ) const override = 0;
    67         virtual Declaration *acceptMutator( Mutator &m ) override = 0;
    68         virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
    69         virtual void printShort( std::ostream &os, Indenter indent = {} ) const = 0;
     66        virtual Declaration * acceptMutator( Mutator & m ) override = 0;
     67        virtual void print( std::ostream & os, Indenter indent = {} ) const override = 0;
     68        virtual void printShort( std::ostream & os, Indenter indent = {} ) const = 0;
    7069
    7170        UniqueId uniqueId;
     
    8180        int scopeLevel = 0;
    8281
    83         Expression *asmName;
     82        Expression * asmName;
    8483        std::list< Attribute * > attributes;
    8584        bool isDeleted = false;
    8685
    87         DeclarationWithType( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, const std::list< Attribute * > & attributes, Type::FuncSpecifiers fs );
    88         DeclarationWithType( const DeclarationWithType &other );
     86        DeclarationWithType( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage, const std::list< Attribute * > & attributes, Type::FuncSpecifiers fs );
     87        DeclarationWithType( const DeclarationWithType & other );
    8988        virtual ~DeclarationWithType();
    9089
     
    9796        DeclarationWithType * set_scopeLevel( int newValue ) { scopeLevel = newValue; return this; }
    9897
    99         Expression *get_asmName() const { return asmName; }
    100         DeclarationWithType * set_asmName( Expression *newValue ) { asmName = newValue; return this; }
     98        Expression * get_asmName() const { return asmName; }
     99        DeclarationWithType * set_asmName( Expression * newValue ) { asmName = newValue; return this; }
    101100
    102101        std::list< Attribute * >& get_attributes() { return attributes; }
     
    106105        //void set_functionSpecifiers( Type::FuncSpecifiers newValue ) { fs = newValue; }
    107106
    108         virtual DeclarationWithType *clone() const override = 0;
    109         virtual DeclarationWithType *acceptMutator( Mutator &m )  override = 0;
     107        virtual DeclarationWithType * clone() const override = 0;
     108        virtual DeclarationWithType * acceptMutator( Mutator & m )  override = 0;
    110109
    111110        virtual Type * get_type() const = 0;
     
    119118        typedef DeclarationWithType Parent;
    120119  public:
    121         Type *type;
    122         Initializer *init;
    123         Expression *bitfieldWidth;
    124 
    125         ObjectDecl( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, Expression *bitfieldWidth, Type *type, Initializer *init,
     120        Type * type;
     121        Initializer * init;
     122        Expression * bitfieldWidth;
     123
     124        ObjectDecl( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage, Expression * bitfieldWidth, Type * type, Initializer * init,
    126125                                const std::list< Attribute * > attributes = std::list< Attribute * >(), Type::FuncSpecifiers fs = Type::FuncSpecifiers() );
    127         ObjectDecl( const ObjectDecl &other );
     126        ObjectDecl( const ObjectDecl & other );
    128127        virtual ~ObjectDecl();
    129128
    130129        virtual Type * get_type() const override { return type; }
    131         virtual void set_type(Type *newType) override { type = newType; }
    132 
    133         Initializer *get_init() const { return init; }
    134         void set_init( Initializer *newValue ) { init = newValue; }
    135 
    136         Expression *get_bitfieldWidth() const { return bitfieldWidth; }
    137         void set_bitfieldWidth( Expression *newValue ) { bitfieldWidth = newValue; }
     130        virtual void set_type(Type * newType) override { type = newType; }
     131
     132        Initializer * get_init() const { return init; }
     133        void set_init( Initializer * newValue ) { init = newValue; }
     134
     135        Expression * get_bitfieldWidth() const { return bitfieldWidth; }
     136        void set_bitfieldWidth( Expression * newValue ) { bitfieldWidth = newValue; }
    138137
    139138        static ObjectDecl * newObject( const std::string & name, Type * type, Initializer * init );
    140139
    141         virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); }
    142         virtual void accept( Visitor & v ) override { v.visit( this ); }
    143         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    144         virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    145         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    146         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     140        virtual ObjectDecl * clone() const override { return new ObjectDecl( *this ); }
     141        virtual void accept( Visitor & v ) override { v.visit( this ); }
     142        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     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;
    147146};
    148147
     
    150149        typedef DeclarationWithType Parent;
    151150  public:
    152         FunctionType *type;
    153         CompoundStmt *statements;
     151        FunctionType * type;
     152        CompoundStmt * statements;
    154153        std::list< Expression * > withExprs;
    155154
    156         FunctionDecl( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, FunctionType *type, CompoundStmt *statements,
     155        FunctionDecl( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage, FunctionType * type, CompoundStmt * statements,
    157156                                  const std::list< Attribute * > attributes = std::list< Attribute * >(), Type::FuncSpecifiers fs = Type::FuncSpecifiers() );
    158         FunctionDecl( const FunctionDecl &other );
     157        FunctionDecl( const FunctionDecl & other );
    159158        virtual ~FunctionDecl();
    160159
     
    163162
    164163        FunctionType * get_functionType() const { return type; }
    165         void set_functionType( FunctionType *newValue ) { type = newValue; }
    166         CompoundStmt *get_statements() const { return statements; }
    167         void set_statements( CompoundStmt *newValue ) { statements = newValue; }
     164        void set_functionType( FunctionType * newValue ) { type = newValue; }
     165        CompoundStmt * get_statements() const { return statements; }
     166        void set_statements( CompoundStmt * newValue ) { statements = newValue; }
    168167        bool has_body() const { return NULL != statements; }
    169168
    170169        static FunctionDecl * newFunction( const std::string & name, FunctionType * type, CompoundStmt * statements );
    171170
    172         virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); }
    173         virtual void accept( Visitor & v ) override { v.visit( this ); }
    174         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    175         virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    176         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    177         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     171        virtual FunctionDecl * clone() const override { return new FunctionDecl( *this ); }
     172        virtual void accept( Visitor & v ) override { v.visit( this ); }
     173        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     174        virtual DeclarationWithType * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     175        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     176        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
    178177};
    179178
     
    181180        typedef Declaration Parent;
    182181  public:
    183         Type *base;
    184         std::list< TypeDecl* > parameters;
    185         std::list< DeclarationWithType* > assertions;
    186 
    187         NamedTypeDecl( const std::string &name, Type::StorageClasses scs, Type *type );
    188         NamedTypeDecl( const NamedTypeDecl &other );
     182        Type * base;
     183        std::list< TypeDecl * > parameters;
     184        std::list< DeclarationWithType * > assertions;
     185
     186        NamedTypeDecl( const std::string & name, Type::StorageClasses scs, Type * type );
     187        NamedTypeDecl( const NamedTypeDecl & other );
    189188        virtual ~NamedTypeDecl();
    190189
    191         Type *get_base() const { return base; }
    192         void set_base( Type *newValue ) { base = newValue; }
    193         std::list< TypeDecl* >& get_parameters() { return parameters; }
    194         std::list< DeclarationWithType* >& get_assertions() { return assertions; }
    195 
    196         virtual std::string typeString() const = 0;
    197 
    198         virtual NamedTypeDecl *clone() const override = 0;
    199         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    200         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     190        Type * get_base() const { return base; }
     191        void set_base( Type * newValue ) { base = newValue; }
     192        std::list< TypeDecl* > & get_parameters() { return parameters; }
     193        std::list< DeclarationWithType * >& get_assertions() { return assertions; }
     194
     195        virtual const char * typeString() const = 0;
     196
     197        virtual NamedTypeDecl * clone() const override = 0;
     198        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     199        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
    201200};
    202201
     
    204203        typedef NamedTypeDecl Parent;
    205204  public:
    206         enum Kind { Dtype, Ftype, Ttype, NUMBER_OF_KINDS };
    207 
     205        enum Kind { Dtype, Otype, Ftype, Ttype, NUMBER_OF_KINDS };
     206
     207        Kind kind;
     208        bool sized;
    208209        Type * init;
    209         bool sized;
    210210
    211211        /// Data extracted from a type decl
    212212        struct Data {
    213                 TypeDecl::Kind kind;
     213                Kind kind;
    214214                bool isComplete;
    215215
    216                 Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {}
    217                 Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {}
     216                Data() : kind( NUMBER_OF_KINDS ), isComplete( false ) {}
     217                Data( const TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {}
    218218                Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {}
    219                 Data( const Data& d1, const Data& d2 )
    220                 : kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {}
    221 
    222                 bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; }
    223                 bool operator!=(const Data & other) const { return !(*this == other);}
     219                Data( const Data & d1, const Data & d2 )
     220                        : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {}
     221
     222                bool operator==( const Data & other ) const { return kind == other.kind && isComplete == other.isComplete; }
     223                bool operator!=( const Data & other ) const { return !(*this == other);}
    224224        };
    225225
    226         TypeDecl( const std::string &name, Type::StorageClasses scs, Type *type, Kind kind, bool sized, Type * init = nullptr );
    227         TypeDecl( const TypeDecl &other );
     226        TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init = nullptr );
     227        TypeDecl( const TypeDecl & other );
    228228        virtual ~TypeDecl();
    229229
     
    237237        TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
    238238
    239         virtual std::string typeString() const override;
    240         virtual std::string genTypeString() const;
    241 
    242         virtual TypeDecl *clone() const override { return new TypeDecl( *this ); }
    243         virtual void accept( Visitor & v ) override { v.visit( this ); }
    244         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    245         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    246         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    247 
    248         Kind kind;
     239        virtual const char * typeString() const override;
     240        virtual const char * genTypeString() const;
     241
     242        virtual TypeDecl * clone() const override { return new TypeDecl( *this ); }
     243        virtual void accept( Visitor & v ) override { v.visit( this ); }
     244        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     245        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     246        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    249247};
    250248
     
    252250        typedef NamedTypeDecl Parent;
    253251  public:
    254         TypedefDecl( const std::string &name, CodeLocation location, Type::StorageClasses scs, Type *type, LinkageSpec::Spec spec = LinkageSpec::Cforall )
     252        TypedefDecl( const std::string & name, CodeLocation location, Type::StorageClasses scs, Type * type, LinkageSpec::Spec spec = LinkageSpec::Cforall )
    255253                : Parent( name, scs, type ) { set_linkage( spec ); this->location = location; }
    256254
    257         TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
    258 
    259         virtual std::string typeString() const override;
    260 
    261         virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); }
    262         virtual void accept( Visitor & v ) override { v.visit( this ); }
    263         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    264         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     255        TypedefDecl( const TypedefDecl & other ) : Parent( other ) {}
     256
     257        virtual const char * typeString() const override;
     258
     259        virtual TypedefDecl * clone() const override { return new TypedefDecl( *this ); }
     260        virtual void accept( Visitor & v ) override { v.visit( this ); }
     261        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     262        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    265263  private:
    266264};
     
    269267        typedef Declaration Parent;
    270268  public:
     269        enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };
     270        static const char * aggrString( Aggregate aggr );
     271
    271272        std::list<Declaration*> members;
    272273        std::list<TypeDecl*> parameters;
     
    275276        AggregateDecl * parent = nullptr;
    276277
    277         AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall );
    278         AggregateDecl( const AggregateDecl &other );
     278        AggregateDecl( const std::string & name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall );
     279        AggregateDecl( const AggregateDecl & other );
    279280        virtual ~AggregateDecl();
    280281
     
    288289        AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; }
    289290
    290         virtual void print( std::ostream &os, Indenter indent = {} ) const override final;
    291         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     291        virtual void print( std::ostream & os, Indenter indent = {} ) const override final;
     292        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
    292293  protected:
    293         virtual std::string typeString() const = 0;
     294        virtual const char * typeString() const = 0;
    294295};
    295296
     
    297298        typedef AggregateDecl Parent;
    298299  public:
    299         StructDecl( const std::string &name, DeclarationNode::Aggregate kind = DeclarationNode::Struct, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ), kind( kind ) {}
    300         StructDecl( const StructDecl &other ) : Parent( other ), kind( other.kind ) {}
    301 
    302         bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
    303         bool is_monitor() { return kind == DeclarationNode::Monitor; }
    304         bool is_thread() { return kind == DeclarationNode::Thread; }
    305 
    306         virtual StructDecl *clone() const override { return new StructDecl( *this ); }
    307         virtual void accept( Visitor & v ) override { v.visit( this ); }
    308         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    309         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    310         DeclarationNode::Aggregate kind;
    311   private:
    312         virtual std::string typeString() const override;
     300        StructDecl( const std::string & name, Aggregate kind = Struct, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ), kind( kind ) {}
     301        StructDecl( const StructDecl & other ) : Parent( other ), kind( other.kind ) {}
     302
     303        bool is_coroutine() { return kind == Coroutine; }
     304        bool is_monitor() { return kind == Monitor; }
     305        bool is_thread() { return kind == Thread; }
     306
     307        virtual StructDecl * clone() const override { return new StructDecl( *this ); }
     308        virtual void accept( Visitor & v ) override { v.visit( this ); }
     309        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     310        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     311        Aggregate kind;
     312  private:
     313        virtual const char * typeString() const override;
    313314};
    314315
     
    316317        typedef AggregateDecl Parent;
    317318  public:
    318         UnionDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ) {}
    319         UnionDecl( const UnionDecl &other ) : Parent( other ) {}
    320 
    321         virtual UnionDecl *clone() const override { return new UnionDecl( *this ); }
    322         virtual void accept( Visitor & v ) override { v.visit( this ); }
    323         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    324         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    325   private:
    326         virtual std::string typeString() const override;
     319        UnionDecl( const std::string & name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ) {}
     320        UnionDecl( const UnionDecl & other ) : Parent( other ) {}
     321
     322        virtual UnionDecl * clone() const override { return new UnionDecl( *this ); }
     323        virtual void accept( Visitor & v ) override { v.visit( this ); }
     324        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     325        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     326  private:
     327        virtual const char * typeString() const override;
    327328};
    328329
     
    330331        typedef AggregateDecl Parent;
    331332  public:
    332         EnumDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ) {}
    333         EnumDecl( const EnumDecl &other ) : Parent( other ) {}
     333        EnumDecl( const std::string & name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ) {}
     334        EnumDecl( const EnumDecl & other ) : Parent( other ) {}
    334335
    335336        bool valueOf( Declaration * enumerator, long long int & value );
    336337
    337         virtual EnumDecl *clone() const override { return new EnumDecl( *this ); }
    338         virtual void accept( Visitor & v ) override { v.visit( this ); }
    339         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    340         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     338        virtual EnumDecl * clone() const override { return new EnumDecl( *this ); }
     339        virtual void accept( Visitor & v ) override { v.visit( this ); }
     340        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     341        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    341342  private:
    342343        std::unordered_map< std::string, long long int > enumValues;
    343         virtual std::string typeString() const override;
     344        virtual const char * typeString() const override;
    344345};
    345346
     
    347348        typedef AggregateDecl Parent;
    348349  public:
    349         TraitDecl( const std::string &name, const std::list< Attribute * > & attributes, LinkageSpec::Spec linkage ) : Parent( name, attributes, linkage ) {
     350        TraitDecl( const std::string & name, const std::list< Attribute * > & attributes, LinkageSpec::Spec linkage ) : Parent( name, attributes, linkage ) {
    350351                assertf( attributes.empty(), "attribute unsupported for traits" );
    351352        }
    352         TraitDecl( const TraitDecl &other ) : Parent( other ) {}
    353 
    354         virtual TraitDecl *clone() const override { return new TraitDecl( *this ); }
    355         virtual void accept( Visitor & v ) override { v.visit( this ); }
    356         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    357         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    358   private:
    359         virtual std::string typeString() const override;
     353        TraitDecl( const TraitDecl & other ) : Parent( other ) {}
     354
     355        virtual TraitDecl * clone() const override { return new TraitDecl( *this ); }
     356        virtual void accept( Visitor & v ) override { v.visit( this ); }
     357        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     358        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     359  private:
     360        virtual const char * typeString() const override;
    360361};
    361362
     
    379380class AsmDecl : public Declaration {
    380381  public:
    381         AsmStmt *stmt;
    382 
    383         AsmDecl( AsmStmt *stmt );
    384         AsmDecl( const AsmDecl &other );
     382        AsmStmt * stmt;
     383
     384        AsmDecl( AsmStmt * stmt );
     385        AsmDecl( const AsmDecl & other );
    385386        virtual ~AsmDecl();
    386387
    387         AsmStmt *get_stmt() { return stmt; }
    388         void set_stmt( AsmStmt *newValue ) { stmt = newValue; }
    389 
    390         virtual AsmDecl *clone() const override { return new AsmDecl( *this ); }
    391         virtual void accept( Visitor & v ) override { v.visit( this ); }
    392         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    393         virtual AsmDecl *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    394         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    395         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     388        AsmStmt * get_stmt() { return stmt; }
     389        void set_stmt( AsmStmt * newValue ) { stmt = newValue; }
     390
     391        virtual AsmDecl * clone() const override { return new AsmDecl( *this ); }
     392        virtual void accept( Visitor & v ) override { v.visit( this ); }
     393        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     394        virtual AsmDecl * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     395        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     396        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
    396397};
    397398
     
    408409        virtual void accept( Visitor & v ) override { v.visit( this ); }
    409410        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    410         virtual StaticAssertDecl * acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    411         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    412         virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
     411        virtual StaticAssertDecl * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     412        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     413        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
    413414};
    414415
  • src/SynTree/DeclarationWithType.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:34:35 2017
    13 // Update Count     : 25
     12// Last Modified On : Fri Dec 13 23:45:16 2019
     13// Update Count     : 26
    1414//
    1515
     
    2020#include "Common/utility.h"      // for cloneAll, deleteAll, maybeClone
    2121#include "Declaration.h"         // for DeclarationWithType, Declaration
    22 #include "Parser/LinkageSpec.h"  // for Spec
    23 #include "SynTree/Expression.h"  // for ConstantExpr
     22#include "LinkageSpec.h"         // for Spec
     23#include "Expression.h"          // for ConstantExpr
    2424#include "Type.h"                // for Type, Type::FuncSpecifiers, Type::St...
    2525
  • src/SynTree/Expression.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 15 13:43:00 2019
    13 // Update Count     : 64
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Dec 11 07:55:15 2019
     13// Update Count     : 70
    1414//
    1515
     
    1919#include <iostream>                  // for ostream, operator<<, basic_ostream
    2020#include <list>                      // for list, _List_iterator, list<>::co...
     21#include <set>                       // for set
    2122
    2223#include "Common/utility.h"          // for maybeClone, cloneAll, deleteAll
    23 #include "Declaration.h"             // for ObjectDecl, DeclarationWithType
    2424#include "Expression.h"              // for Expression, ImplicitCopyCtorExpr
    2525#include "InitTweak/InitTweak.h"     // for getCallArg, getPointerBase
     
    6464
    6565bool Expression::get_lvalue() const {
    66         assert( !result->get_lvalue() );
    6766        return false;
    6867}
     
    115114        assert( var->get_type() );
    116115        Type * type = var->get_type()->clone();
    117         type->set_lvalue( true );
    118116
    119117        // xxx - doesn't quite work yet - get different alternatives with the same cost
     
    125123        //      long long int value;
    126124        //      if ( decl->valueOf( var, value ) ) {
    127         //              type->set_lvalue( false );
     125        //              type->set_lvalue( false ); // Would have to move to get_lvalue.
    128126        //      }
    129127        // }
     
    140138
    141139bool VariableExpr::get_lvalue() const {
    142         return result->get_lvalue();
     140        // It isn't always an lvalue, but it is never an rvalue.
     141        return true;
    143142}
    144143
     
    277276
    278277bool CastExpr::get_lvalue() const {
    279         return result->get_lvalue();
     278        // This is actually wrong by C, but it works with our current set-up.
     279        return arg->get_lvalue();
    280280}
    281281
     
    293293}
    294294
    295 KeywordCastExpr::KeywordCastExpr( Expression * arg, Target target ) : Expression(), arg(arg), target( target ) {
     295KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target ) : Expression(), arg(arg), target( target ) {
    296296}
    297297
     
    303303}
    304304
    305 const std::string & KeywordCastExpr::targetString() const {
    306         static const std::string targetStrs[] = {
    307                 "coroutine", "thread", "monitor"
    308         };
    309         static_assert(
    310                 (sizeof(targetStrs) / sizeof(targetStrs[0])) == ((unsigned long)NUMBER_OF_TARGETS),
    311                 "Each KeywordCastExpr::Target should have a corresponding string representation"
    312         );
    313         return targetStrs[(unsigned long)target];
     305const char * KeywordCastExpr::targetString() const {
     306        return AggregateDecl::aggrString( target );
    314307}
    315308
     
    360353}
    361354
     355bool UntypedMemberExpr::get_lvalue() const {
     356        return aggregate->get_lvalue();
     357}
     358
    362359void UntypedMemberExpr::print( std::ostream & os, Indenter indent ) const {
    363360        os << "Untyped Member Expression, with field: " << std::endl << indent+1;
     
    378375        sub.apply( res );
    379376        result = res;
    380         result->set_lvalue( true );
    381377        result->get_qualifiers() |= aggregate->result->get_qualifiers();
    382378}
     
    392388
    393389bool MemberExpr::get_lvalue() const {
    394         assert( result->get_lvalue() );
     390        // This is actually wrong by C, but it works with our current set-up.
    395391        return true;
    396392}
     
    427423                        // if references are still allowed in the AST, dereference returns a reference
    428424                        ret->set_result( new ReferenceType( Type::Qualifiers(), ret->get_result() ) );
    429                 } else {
    430                         // references have been removed, in which case dereference returns an lvalue of the base type.
    431                         ret->result->set_lvalue( true );
    432425                }
    433426        }
     
    447440
    448441bool UntypedExpr::get_lvalue() const {
    449         return result->get_lvalue();
     442        // from src/GenPoly/Lvalue.cc: isIntrinsicReference
     443        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
     444        std::string fname = InitTweak::getFunctionName( const_cast< UntypedExpr * >( this ) );
     445        return lvalueFunctions.count(fname);
    450446}
    451447
     
    510506
    511507bool ConditionalExpr::get_lvalue() const {
    512         return result->get_lvalue();
     508        return false;
    513509}
    514510
     
    523519}
    524520
    525 AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
     521AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( other.inout ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
    526522
    527523
    528524void AsmExpr::print( std::ostream & os, Indenter indent ) const {
    529525        os << "Asm Expression: " << std::endl;
    530         if ( inout ) inout->print( os, indent+1 );
     526        if ( !inout.empty() ) os <<  "[" << inout << "] ";
    531527        if ( constraint ) constraint->print( os, indent+1 );
    532528        if ( operand ) operand->print( os, indent+1 );
     
    570566
    571567bool ConstructorExpr::get_lvalue() const {
    572         return result->get_lvalue();
     568        return false;
    573569}
    574570
     
    582578CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : initializer( initializer ) {
    583579        assert( type && initializer );
    584         type->set_lvalue( true );
    585580        set_result( type );
    586581}
     
    593588
    594589bool CompoundLiteralExpr::get_lvalue() const {
    595         assert( result->get_lvalue() );
    596590        return true;
    597591}
     
    648642}
    649643bool StmtExpr::get_lvalue() const {
    650         return result->get_lvalue();
     644        return false;
    651645}
    652646void StmtExpr::print( std::ostream & os, Indenter indent ) const {
  • src/SynTree/Expression.h

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 15 13:46:00 2019
    13 // Update Count     : 54
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Dec 11 16:50:19 2019
     13// Update Count     : 60
    1414//
    1515
     
    2828#include "Label.h"                // for Label
    2929#include "Mutator.h"              // for Mutator
     30#include "Declaration.h"          // for Aggregate
    3031#include "SynTree.h"              // for UniqueId
    3132#include "Visitor.h"              // for Visitor
     
    229230public:
    230231        Expression * arg;
    231         enum Target {
    232                 Coroutine, Thread, Monitor, NUMBER_OF_TARGETS
    233         } target;
    234 
    235         KeywordCastExpr( Expression * arg, Target target );
     232        struct Concrete {
     233                std::string field;
     234                std::string getter;
     235        };
     236        AggregateDecl::Aggregate target;
     237        Concrete concrete_target;
     238
     239        KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target );
    236240        KeywordCastExpr( const KeywordCastExpr & other );
    237241        virtual ~KeywordCastExpr();
    238242
    239         const std::string & targetString() const;
     243        const char * targetString() const;
    240244
    241245        virtual KeywordCastExpr * clone() const override { return new KeywordCastExpr( * this ); }
     
    274278        UntypedMemberExpr( const UntypedMemberExpr & other );
    275279        virtual ~UntypedMemberExpr();
     280
     281        bool get_lvalue() const final;
    276282
    277283        Expression * get_member() const { return member; }
     
    573579class AsmExpr : public Expression {
    574580  public:
    575         Expression * inout;
     581        std::string inout;
    576582        Expression * constraint;
    577583        Expression * operand;
    578584
    579         AsmExpr( Expression * inout, Expression * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
     585        AsmExpr( const std::string * _inout, Expression * constraint, Expression * operand ) : inout( _inout ? *_inout : "" ), constraint( constraint ), operand( operand ) { delete _inout; }
    580586        AsmExpr( const AsmExpr & other );
    581         virtual ~AsmExpr() { delete inout; delete constraint; delete operand; };
    582 
    583         Expression * get_inout() const { return inout; }
    584         void set_inout( Expression * newValue ) { inout = newValue; }
    585 
    586         Expression * get_constraint() const { return constraint; }
    587         void set_constraint( Expression * newValue ) { constraint = newValue; }
    588 
    589         Expression * get_operand() const { return operand; }
    590         void set_operand( Expression * newValue ) { operand = newValue; }
     587        virtual ~AsmExpr() { delete constraint; delete operand; };
    591588
    592589        virtual AsmExpr * clone() const override { return new AsmExpr( * this ); }
  • src/SynTree/FunctionDecl.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:33:41 2017
    13 // Update Count     : 74
     12// Last Modified On : Mon Dec 16 15:11:20 2019
     13// Update Count     : 77
    1414//
    1515
     
    2323#include "Common/utility.h"      // for maybeClone, printAll
    2424#include "Declaration.h"         // for FunctionDecl, FunctionDecl::Parent
    25 #include "Parser/LinkageSpec.h"  // for Spec, linkageName, Cforall
     25#include "Expression.h"
     26#include "LinkageSpec.h"         // for Spec, linkageName, Cforall
    2627#include "Statement.h"           // for CompoundStmt
    2728#include "Type.h"                // for Type, FunctionType, Type::FuncSpecif...
     
    7273        } // if
    7374        if ( linkage != LinkageSpec::Cforall ) {
    74                 os << LinkageSpec::linkageName( linkage ) << " ";
     75                os << LinkageSpec::name( linkage ) << " ";
    7576        } // if
    7677
  • src/SynTree/LinkageSpec.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Sat May 16 13:24:28 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 10 16:02:34 2019
    13 // Update Count     : 18
     12// Last Modified On : Mon Dec 16 15:03:43 2019
     13// Update Count     : 20
    1414//
    1515
     
    2121
    2222namespace LinkageSpec {
    23         // All linkage specs are some combination of these flags:
    24         enum { Mangle = 1 << 0, Generate = 1 << 1, Overrideable = 1 << 2, Builtin = 1 << 3, GccBuiltin = 1 << 4, NoOfSpecs = 1 << 5, };
     23        // Bitflags for linkage specifiers
     24        enum {
     25                Mangle = 1 << 0,
     26                Generate = 1 << 1,
     27                Overrideable = 1 << 2,
     28                Builtin = 1 << 3,
     29                GccBuiltin = 1 << 4,
     30        };
    2531
     32        // Bitflag type for storage classes
    2633        union Spec {
    2734                unsigned int val;
     
    4249
    4350
    44         Spec linkageUpdate( CodeLocation location, Spec old_spec, const std::string * cmd );
    45         /* If cmd = "C" returns a Spec that is old_spec with is_mangled = false
    46          * If cmd = "Cforall" returns old_spec Spec with is_mangled = true
    47          */
     51        Spec update( CodeLocation location, Spec spec, const std::string * cmd );
     52        // If cmd = "C" returns a Spec that is old_spec with is_mangled = false
     53        // If cmd = "Cforall" returns old_spec Spec with is_mangled = true
    4854
    49         std::string linkageName( Spec );
     55        std::string name( Spec );
    5056
    5157        // To Update: LinkageSpec::isXyz( cur_spec ) -> cur_spec.is_xyz
  • src/SynTree/NamedTypeDecl.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  9 13:28:00 2017
    13 // Update Count     : 14
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Dec 16 15:11:40 2019
     13// Update Count     : 17
    1414//
    1515
     
    2020#include "Common/utility.h"      // for printAll, cloneAll, deleteAll, maybe...
    2121#include "Declaration.h"         // for NamedTypeDecl, DeclarationWithType
    22 #include "Parser/LinkageSpec.h"  // for Spec, Cforall, linkageName
     22#include "LinkageSpec.h"         // for Spec, Cforall, linkageName
    2323#include "Type.h"                // for Type, Type::StorageClasses
    2424
     
    4444
    4545        if ( linkage != LinkageSpec::Cforall ) {
    46                 os << LinkageSpec::linkageName( linkage ) << " ";
     46                os << LinkageSpec::name( linkage ) << " ";
    4747        } // if
    4848        get_storageClasses().print( os );
     
    7878}
    7979
    80 std::string TypedefDecl::typeString() const { return "typedef"; }
     80const char * TypedefDecl::typeString() const { return "typedef"; }
    8181
    8282// Local Variables: //
  • src/SynTree/ObjectDecl.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:34:27 2017
    13 // Update Count     : 59
     12// Last Modified On : Mon Dec 16 15:12:03 2019
     13// Update Count     : 61
    1414//
    1515
     
    2323#include "Expression.h"          // for Expression
    2424#include "Initializer.h"         // for Initializer
    25 #include "Parser/LinkageSpec.h"  // for Spec, linkageName, Cforall
     25#include "LinkageSpec.h"         // for Spec, linkageName, Cforall
    2626#include "Type.h"                // for Type, Type::StorageClasses, Type::Fu...
    2727
     
    4848
    4949        if ( linkage != LinkageSpec::Cforall ) {
    50                 os << LinkageSpec::linkageName( linkage ) << " ";
     50                os << LinkageSpec::name( linkage ) << " ";
    5151        } // if
    5252
  • src/SynTree/Statement.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 20:46:44 2017
    13 // Update Count     : 68
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Jan 20 16:03:00 2020
     13// Update Count     : 71
    1414//
    1515
     
    4646Statement::~Statement() {}
    4747
    48 ExprStmt::ExprStmt( Expression *expr ) : Statement(), expr( expr ) {}
    49 
    50 ExprStmt::ExprStmt( const ExprStmt &other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
     48ExprStmt::ExprStmt( Expression * expr ) : Statement(), expr( expr ) {}
     49
     50ExprStmt::ExprStmt( const ExprStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
    5151
    5252ExprStmt::~ExprStmt() {
     
    5454}
    5555
    56 void ExprStmt::print( std::ostream &os, Indenter indent ) const {
     56void ExprStmt::print( std::ostream & os, Indenter indent ) const {
    5757        os << "Expression Statement:" << endl << indent+1;
    5858        expr->print( os, indent+1 );
     
    6060
    6161
    62 AsmStmt::AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement(), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
     62AsmStmt::AsmStmt( bool voltile, Expression * instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement(), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
    6363
    6464AsmStmt::AsmStmt( const AsmStmt & other ) : Statement( other ), voltile( other.voltile ), instruction( maybeClone( other.instruction ) ), gotolabels( other.gotolabels ) {
     
    7575}
    7676
    77 void AsmStmt::print( std::ostream &os, Indenter indent ) const {
     77void AsmStmt::print( std::ostream & os, Indenter indent ) const {
    7878        os << "Assembler Statement:" << endl;
    7979        os << indent+1 << "instruction: " << endl << indent;
     
    9696DirectiveStmt::DirectiveStmt( const std::string & directive ) : Statement(), directive( directive ) {}
    9797
    98 void DirectiveStmt::print( std::ostream &os, Indenter ) const {
     98void DirectiveStmt::print( std::ostream & os, Indenter ) const {
    9999        os << "GCC Directive:" << directive << endl;
    100100}
    101101
    102102
    103 const char *BranchStmt::brType[] = { "Goto", "Break", "Continue" };
     103const char * BranchStmt::brType[] = {
     104        "Goto", "Break", "Continue", "Fall Through", "Fall Through Default",
     105};
    104106
    105107BranchStmt::BranchStmt( Label target, Type type ) throw ( SemanticErrorException ) :
     
    111113}
    112114
    113 BranchStmt::BranchStmt( Expression *computedTarget, Type type ) throw ( SemanticErrorException ) :
     115BranchStmt::BranchStmt( Expression * computedTarget, Type type ) throw ( SemanticErrorException ) :
    114116        Statement(), computedTarget( computedTarget ), type( type ) {
    115117        if ( type != BranchStmt::Goto || computedTarget == nullptr ) {
     
    118120}
    119121
    120 void BranchStmt::print( std::ostream &os, Indenter indent ) const {
     122void BranchStmt::print( std::ostream & os, Indenter indent ) const {
     123        assert(type < 5);
    121124        os << "Branch (" << brType[type] << ")" << endl ;
    122125        if ( target != "" ) os << indent+1 << "with target: " << target << endl;
     
    125128}
    126129
    127 ReturnStmt::ReturnStmt( Expression *expr ) : Statement(), expr( expr ) {}
     130ReturnStmt::ReturnStmt( Expression * expr ) : Statement(), expr( expr ) {}
    128131
    129132ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
     
    133136}
    134137
    135 void ReturnStmt::print( std::ostream &os, Indenter indent ) const {
     138void ReturnStmt::print( std::ostream & os, Indenter indent ) const {
    136139        os << "Return Statement, returning: ";
    137140        if ( expr != nullptr ) {
     
    142145}
    143146
    144 IfStmt::IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart, std::list<Statement *> initialization ):
     147IfStmt::IfStmt( Expression * condition, Statement * thenPart, Statement * elsePart, std::list<Statement *> initialization ):
    145148        Statement(), condition( condition ), thenPart( thenPart ), elsePart( elsePart ), initialization( initialization ) {}
    146149
     
    157160}
    158161
    159 void IfStmt::print( std::ostream &os, Indenter indent ) const {
     162void IfStmt::print( std::ostream & os, Indenter indent ) const {
    160163        os << "If on condition: " << endl;
    161164        os << indent+1;
     
    176179        thenPart->print( os, indent+1 );
    177180
    178         if ( elsePart != 0 ) {
     181        if ( elsePart != nullptr ) {
    179182                os << indent << "... else: " << endl;
    180183                os << indent+1;
     
    183186}
    184187
    185 SwitchStmt::SwitchStmt( Expression * condition, const std::list<Statement *> &statements ):
     188SwitchStmt::SwitchStmt( Expression * condition, const std::list<Statement *> & statements ):
    186189        Statement(), condition( condition ), statements( statements ) {
    187190}
     
    198201}
    199202
    200 void SwitchStmt::print( std::ostream &os, Indenter indent ) const {
     203void SwitchStmt::print( std::ostream & os, Indenter indent ) const {
    201204        os << "Switch on condition: ";
    202205        condition->print( os );
     
    208211}
    209212
    210 CaseStmt::CaseStmt( Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticErrorException ) :
     213CaseStmt::CaseStmt( Expression * condition, const std::list<Statement *> & statements, bool deflt ) throw ( SemanticErrorException ) :
    211214        Statement(), condition( condition ), stmts( statements ), _isDefault( deflt ) {
    212         if ( isDefault() && condition != 0 ) SemanticError( condition, "default case with condition: " );
     215        if ( isDefault() && condition != nullptr ) SemanticError( condition, "default case with condition: " );
    213216}
    214217
     
    229232}
    230233
    231 void CaseStmt::print( std::ostream &os, Indenter indent ) const {
     234void CaseStmt::print( std::ostream & os, Indenter indent ) const {
    232235        if ( isDefault() ) os << indent << "Default ";
    233236        else {
     
    243246}
    244247
    245 WhileStmt::WhileStmt( Expression *condition, Statement *body, std::list< Statement * > & initialization, bool isDoWhile ):
     248WhileStmt::WhileStmt( Expression * condition, Statement * body, std::list< Statement * > & initialization, bool isDoWhile ):
    246249        Statement(), condition( condition), body( body), initialization( initialization ), isDoWhile( isDoWhile) {
    247250}
     
    256259}
    257260
    258 void WhileStmt::print( std::ostream &os, Indenter indent ) const {
     261void WhileStmt::print( std::ostream & os, Indenter indent ) const {
    259262        os << "While on condition: " << endl ;
    260263        condition->print( os, indent+1 );
     
    262265        os << indent << "... with body: " << endl;
    263266
    264         if ( body != 0 ) body->print( os, indent+1 );
    265 }
    266 
    267 ForStmt::ForStmt( std::list<Statement *> initialization, Expression *condition, Expression *increment, Statement *body ):
     267        if ( body != nullptr ) body->print( os, indent+1 );
     268}
     269
     270ForStmt::ForStmt( std::list<Statement *> initialization, Expression * condition, Expression * increment, Statement * body ):
    268271        Statement(), initialization( initialization ), condition( condition ), increment( increment ), body( body ) {
    269272}
     
    282285}
    283286
    284 void ForStmt::print( std::ostream &os, Indenter indent ) const {
     287void ForStmt::print( std::ostream & os, Indenter indent ) const {
    285288        Statement::print( os, indent ); // print labels
    286289
     
    305308        }
    306309
    307         if ( body != 0 ) {
     310        if ( body != nullptr ) {
    308311                os << "\n" << indent << "... with body: \n" << indent+1;
    309312                body->print( os, indent+1 );
     
    317320}
    318321
    319 ThrowStmt::ThrowStmt( const ThrowStmt &other ) :
     322ThrowStmt::ThrowStmt( const ThrowStmt & other ) :
    320323        Statement ( other ), kind( other.kind ), expr( maybeClone( other.expr ) ), target( maybeClone( other.target ) ) {
    321324}
     
    326329}
    327330
    328 void ThrowStmt::print( std::ostream &os, Indenter indent) const {
     331void ThrowStmt::print( std::ostream & os, Indenter indent) const {
    329332        if ( target ) os << "Non-Local ";
    330333        os << "Throw Statement, raising: ";
     
    336339}
    337340
    338 TryStmt::TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock ) :
     341TryStmt::TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> & handlers, FinallyStmt * finallyBlock ) :
    339342        Statement(), block( tryBlock ),  handlers( handlers ), finallyBlock( finallyBlock ) {
    340343}
    341344
    342 TryStmt::TryStmt( const TryStmt &other ) : Statement( other ), block( maybeClone( other.block ) ), finallyBlock( maybeClone( other.finallyBlock ) ) {
     345TryStmt::TryStmt( const TryStmt & other ) : Statement( other ), block( maybeClone( other.block ) ), finallyBlock( maybeClone( other.finallyBlock ) ) {
    343346        cloneAll( other.handlers, handlers );
    344347}
     
    350353}
    351354
    352 void TryStmt::print( std::ostream &os, Indenter indent ) const {
     355void TryStmt::print( std::ostream & os, Indenter indent ) const {
    353356        os << "Try Statement" << endl;
    354357        os << indent << "... with block:" << endl << indent+1;
     
    363366
    364367        // finally block
    365         if ( finallyBlock != 0 ) {
     368        if ( finallyBlock != nullptr ) {
    366369                os << indent << "... and finally:" << endl << indent+1;
    367370                finallyBlock->print( os, indent+1 );
     
    369372}
    370373
    371 CatchStmt::CatchStmt( Kind kind, Declaration *decl, Expression *cond, Statement *body ) :
     374CatchStmt::CatchStmt( Kind kind, Declaration * decl, Expression * cond, Statement * body ) :
    372375        Statement(), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) {
    373376                assertf( decl, "Catch clause must have a declaration." );
     
    383386}
    384387
    385 void CatchStmt::print( std::ostream &os, Indenter indent ) const {
     388void CatchStmt::print( std::ostream & os, Indenter indent ) const {
    386389        os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl;
    387390
     
    401404
    402405
    403 FinallyStmt::FinallyStmt( CompoundStmt *block ) : Statement(), block( block ) {
     406FinallyStmt::FinallyStmt( CompoundStmt * block ) : Statement(), block( block ) {
    404407}
    405408
     
    411414}
    412415
    413 void FinallyStmt::print( std::ostream &os, Indenter indent ) const {
     416void FinallyStmt::print( std::ostream & os, Indenter indent ) const {
    414417        os << "Finally Statement" << endl;
    415418        os << indent << "... with block:" << endl << indent+1;
     
    458461}
    459462
    460 void WaitForStmt::print( std::ostream &os, Indenter indent ) const {
     463void WaitForStmt::print( std::ostream & os, Indenter indent ) const {
    461464        os << "Waitfor Statement" << endl;
    462465        indent += 1;
     
    514517}
    515518
    516 void NullStmt::print( std::ostream &os, Indenter indent ) const {
     519void NullStmt::print( std::ostream & os, Indenter indent ) const {
    517520        os << "Null Statement" << endl;
    518521        Statement::print( os, indent );
     
    530533}
    531534
    532 void ImplicitCtorDtorStmt::print( std::ostream &os, Indenter indent ) const {
     535void ImplicitCtorDtorStmt::print( std::ostream & os, Indenter indent ) const {
    533536        os << "Implicit Ctor Dtor Statement" << endl;
    534537        os << indent << "... with Ctor/Dtor: ";
  • src/SynTree/Statement.h

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 12 09:01:53 2019
    13 // Update Count     : 83
     12// Last Modified On : Fri Jan 10 14:13:24 2020
     13// Update Count     : 85
    1414//
    1515
     
    257257        Statement * body;
    258258
    259         ForStmt( std::list<Statement *> initialization, Expression * condition = 0, Expression * increment = 0, Statement * body = 0 );
     259        ForStmt( std::list<Statement *> initialization, Expression * condition = nullptr, Expression * increment = nullptr, Statement * body = nullptr );
    260260        ForStmt( const ForStmt & other );
    261261        virtual ~ForStmt();
     
    357357        FinallyStmt * finallyBlock;
    358358
    359         TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> & handlers, FinallyStmt * finallyBlock = 0 );
     359        TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> & handlers, FinallyStmt * finallyBlock = nullptr );
    360360        TryStmt( const TryStmt & other );
    361361        virtual ~TryStmt();
  • src/SynTree/TupleExpr.cc

    r9fb8f01 r3d5701e  
    5858
    5959bool TupleExpr::get_lvalue() const {
    60         return result->get_lvalue();
     60        return false;
    6161}
    6262
     
    7171        assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d in expr %s", type->size(), index, toString( tuple ).c_str() );
    7272        set_result( (*std::next( type->get_types().begin(), index ))->clone() );
    73         // like MemberExpr, TupleIndexExpr is always an lvalue
    74         get_result()->set_lvalue( true );
    7573}
    7674
     
    8381
    8482bool TupleIndexExpr::get_lvalue() const {
    85         assert( result->get_lvalue() );
    86         return true;
     83        return tuple->get_lvalue();
    8784}
    8885
  • src/SynTree/TupleType.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb  1 17:10:58 2017
    13 // Update Count     : 3
     12// Last Modified On : Fri Dec 13 23:44:38 2019
     13// Update Count     : 4
    1414//
    1515
     
    2020#include "Declaration.h"         // for Declaration, ObjectDecl
    2121#include "Initializer.h"         // for ListInit
    22 #include "Parser/LinkageSpec.h"  // for Cforall
     22#include "LinkageSpec.h"         // for Cforall
    2323#include "Type.h"                // for TupleType, Type, Type::Qualifiers
    2424
  • src/SynTree/Type.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug  4 21:05:07 2019
    13 // Update Count     : 45
     12// Last Modified On : Sun Dec 15 16:52:37 2019
     13// Update Count     : 49
    1414//
    1515#include "Type.h"
     
    2424using namespace std;
    2525
     26// GENERATED START, DO NOT EDIT
     27// GENERATED BY BasicTypes-gen.cc
    2628const char * BasicType::typeNames[] = {
    2729        "_Bool",
     
    4547        "float",
    4648        "float _Complex",
    47         //"float _Imaginary",
    4849        "_Float32x",
    4950        "_Float32x _Complex",
     
    5253        "double",
    5354        "double _Complex",
    54         //"double _Imaginary",
    5555        "_Float64x",
    5656        "_Float64x _Complex",
     
    6161        "long double",
    6262        "long double _Complex",
    63         //"long double _Imaginary",
    6463        "_Float128x",
    6564        "_Float128x _Complex",
    6665};
    67 static_assert(
    68         sizeof(BasicType::typeNames) / sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
    69         "Each basic type name should have a corresponding kind enum value"
    70 );
     66// GENERATED END
    7167
    7268Type::Type( const Qualifiers &tq, const std::list< Attribute * > & attributes ) : tq( tq ), attributes( attributes ) {}
     
    8581const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" };
    8682const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" };
    87 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
     83const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "mutex", "_Atomic" };
    8884
    8985Type * Type::stripDeclarator() {
  • src/SynTree/Type.h

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 14 17:11:24 2019
    13 // Update Count     : 169
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Sep  4 09:58:00 2019
     13// Update Count     : 170
    1414//
    1515
     
    102102        }; // StorageClasses
    103103
    104         enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Lvalue = 1 << 3, Mutex = 1 << 4, Atomic = 1 << 5, NumTypeQualifier = 6 };
     104        enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Mutex = 1 << 3, Atomic = 1 << 4, NumTypeQualifier = 5 };
    105105        static const char * QualifiersNames[];
    106106        union Qualifiers {
    107                 enum { Mask = ~(Restrict | Lvalue) };
     107                enum { Mask = ~Restrict };
    108108                unsigned int val;
    109109                struct {
     
    111111                        bool is_restrict : 1;
    112112                        bool is_volatile : 1;
    113                         bool is_lvalue : 1;
    114113                        bool is_mutex : 1;
    115114                        bool is_atomic : 1;
     
    131130                bool operator>( Qualifiers other ) const { return *this != other && *this >= other; }
    132131                BFCommon( Qualifiers, NumTypeQualifier )
     132
     133                Qualifiers unify( Qualifiers const & other ) const {
     134                        int or_flags = Mask & (val | other.val);
     135                        int and_flags = val & other.val;
     136                        return Qualifiers( or_flags | and_flags );
     137                }
    133138        }; // Qualifiers
    134139
     
    147152        bool get_volatile() const { return tq.is_volatile; }
    148153        bool get_restrict() const { return tq.is_restrict; }
    149         bool get_lvalue() const { return tq.is_lvalue; }
    150154        bool get_mutex() const { return tq.is_mutex; }
    151155        bool get_atomic() const { return tq.is_atomic; }
     
    153157        void set_volatile( bool newValue ) { tq.is_volatile = newValue; }
    154158        void set_restrict( bool newValue ) { tq.is_restrict = newValue; }
    155         void set_lvalue( bool newValue ) { tq.is_lvalue = newValue; }
    156159        void set_mutex( bool newValue ) { tq.is_mutex = newValue; }
    157160        void set_atomic( bool newValue ) { tq.is_atomic = newValue; }
  • src/SynTree/TypeDecl.cc

    r9fb8f01 r3d5701e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  9 14:35:00 2017
    13 // Update Count     : 6
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 15:26:14 2019
     13// Update Count     : 21
    1414//
    1515
     
    2121#include "Type.h"            // for Type, Type::StorageClasses
    2222
    23 TypeDecl::TypeDecl( const std::string &name, Type::StorageClasses scs, Type *type, Kind kind, bool sized, Type * init ) : Parent( name, scs, type ), init( init ), sized( kind == Ttype || sized ), kind( kind ) {
     23TypeDecl::TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init ) : Parent( name, scs, type ), kind( kind ), sized( kind == Ttype || sized ), init( init ) {
    2424}
    2525
    26 TypeDecl::TypeDecl( const TypeDecl &other ) : Parent( other ), init( maybeClone( other.init ) ), sized( other.sized ), kind( other.kind ) {
     26TypeDecl::TypeDecl( const TypeDecl & other ) : Parent( other ), kind( other.kind ), sized( other.sized ), init( maybeClone( other.init ) ) {
    2727}
    2828
    2929TypeDecl::~TypeDecl() {
    30   delete init;
     30        delete init;
    3131}
    3232
    33 std::string TypeDecl::typeString() const {
    34         static const std::string kindNames[] = { "object type", "function type", "tuple type" };
    35         assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1, "typeString: kindNames is out of sync." );
    36         assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
    37         return (isComplete() ? "sized " : "") + kindNames[ kind ];
     33const char * TypeDecl::typeString() const {
     34        static const char * kindNames[] = { "sized data type", "sized object type", "sized function type", "sized tuple type" };
     35        static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." );
     36        assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
     37        return isComplete() ? kindNames[ kind ] : &kindNames[ kind ][ sizeof("sized") ]; // sizeof includes '\0'
    3838}
    3939
    40 std::string TypeDecl::genTypeString() const {
    41         static const std::string kindNames[] = { "dtype", "ftype", "ttype" };
    42         assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1, "genTypeString: kindNames is out of sync." );
    43         assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
     40const char * TypeDecl::genTypeString() const {
     41        static const char * kindNames[] = { "dtype", "otype", "ftype", "ttype" };
     42        static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "genTypeString: kindNames is out of sync." );
     43        assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
    4444        return kindNames[ kind ];
    4545}
    4646
    4747void TypeDecl::print( std::ostream &os, Indenter indent ) const {
    48   NamedTypeDecl::print( os, indent );
    49   if ( init ) {
    50     os << std::endl << indent << "with type initializer: ";
    51     init->print( os, indent + 1 );
    52   }
     48        NamedTypeDecl::print( os, indent );
     49        if ( init ) {
     50                os << std::endl << indent << "with type initializer: ";
     51                init->print( os, indent + 1 );
     52        } // if
    5353}
    5454
    55 
    5655std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data ) {
    57   return os << data.kind << ", " << data.isComplete;
     56        return os << data.kind << ", " << data.isComplete;
    5857}
    5958
  • src/SynTree/module.mk

    r9fb8f01 r3d5701e  
    1111## Created On       : Mon Jun  1 17:49:17 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Jun  1 17:54:09 2015
    14 ## Update Count     : 1
     13## Last Modified On : Sat Dec 14 07:26:43 2019
     14## Update Count     : 2
    1515###############################################################################
    1616
    1717SRC_SYNTREE = \
    18       SynTree/Type.cc \
    19       SynTree/VoidType.cc \
     18      SynTree/AddressExpr.cc \
     19      SynTree/AggregateDecl.cc \
     20      SynTree/ApplicationExpr.cc \
     21      SynTree/ArrayType.cc \
     22      SynTree/AttrType.cc \
     23      SynTree/Attribute.cc \
    2024      SynTree/BasicType.cc \
    21       SynTree/PointerType.cc \
    22       SynTree/ArrayType.cc \
    23       SynTree/ReferenceType.cc \
    24       SynTree/FunctionType.cc \
    25       SynTree/ReferenceToType.cc \
    26       SynTree/TupleType.cc \
    27       SynTree/TypeofType.cc \
    28       SynTree/AttrType.cc \
    29       SynTree/VarArgsType.cc \
    30       SynTree/ZeroOneType.cc \
     25      SynTree/CommaExpr.cc \
     26      SynTree/CompoundStmt.cc \
    3127      SynTree/Constant.cc \
    32       SynTree/Expression.cc \
    33       SynTree/TupleExpr.cc \
    34       SynTree/CommaExpr.cc \
    35       SynTree/TypeExpr.cc \
    36       SynTree/ApplicationExpr.cc \
    37       SynTree/AddressExpr.cc \
    38       SynTree/Statement.cc \
    39       SynTree/CompoundStmt.cc \
     28      SynTree/DeclReplacer.cc \
    4029      SynTree/DeclStmt.cc \
    4130      SynTree/Declaration.cc \
    4231      SynTree/DeclarationWithType.cc \
     32      SynTree/Expression.cc \
     33      SynTree/FunctionDecl.cc \
     34      SynTree/FunctionType.cc \
     35      SynTree/Initializer.cc \
     36      SynTree/LinkageSpec.cc \
     37      SynTree/NamedTypeDecl.cc \
    4338      SynTree/ObjectDecl.cc \
    44       SynTree/FunctionDecl.cc \
    45       SynTree/AggregateDecl.cc \
    46       SynTree/NamedTypeDecl.cc \
     39      SynTree/PointerType.cc \
     40      SynTree/ReferenceToType.cc \
     41      SynTree/ReferenceType.cc \
     42      SynTree/Statement.cc \
     43      SynTree/TupleExpr.cc \
     44      SynTree/TupleType.cc \
     45      SynTree/Type.cc \
    4746      SynTree/TypeDecl.cc \
    48       SynTree/Initializer.cc \
     47      SynTree/TypeExpr.cc \
    4948      SynTree/TypeSubstitution.cc \
    50       SynTree/Attribute.cc \
    51       SynTree/DeclReplacer.cc \
    52       SynTree/TopLvalue.cc
     49      SynTree/TypeofType.cc \
     50      SynTree/VarArgsType.cc \
     51      SynTree/VoidType.cc \
     52      SynTree/ZeroOneType.cc
    5353
    5454SRC += $(SRC_SYNTREE)
  • src/Tuples/TupleAssignment.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:43:03 2017
    13 // Update Count     : 8
     12// Last Modified On : Fri Dec 13 23:45:33 2019
     13// Update Count     : 9
    1414//
    1515
     
    3434#include "InitTweak/GenInit.h"             // for genCtorInit
    3535#include "InitTweak/InitTweak.h"           // for getPointerBase, isAssignment
    36 #include "Parser/LinkageSpec.h"            // for Cforall
    3736#include "ResolvExpr/Alternative.h"        // for AltList, Alternative
    3837#include "ResolvExpr/AlternativeFinder.h"  // for AlternativeFinder, simpleC...
     
    4140#include "ResolvExpr/TypeEnvironment.h"    // for TypeEnvironment
    4241#include "ResolvExpr/typeops.h"            // for combos
     42#include "SynTree/LinkageSpec.h"           // for Cforall
    4343#include "SynTree/Declaration.h"           // for ObjectDecl
    4444#include "SynTree/Expression.h"            // for Expression, CastExpr, Name...
  • src/Tuples/TupleExpansion.cc

    r9fb8f01 r3d5701e  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 19 14:39:00 2019
    13 // Update Count     : 22
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:45:51 2019
     13// Update Count     : 24
    1414//
    1515
     
    2727#include "Common/utility.h"       // for CodeLocation
    2828#include "InitTweak/InitTweak.h"  // for getFunction
    29 #include "Parser/LinkageSpec.h"   // for Spec, C, Intrinsic
     29#include "SynTree/LinkageSpec.h"  // for Spec, C, Intrinsic
    3030#include "SynTree/Constant.h"     // for Constant
    3131#include "SynTree/Declaration.h"  // for StructDecl, DeclarationWithType
     
    304304                // produce the TupleType which aggregates the types of the exprs
    305305                std::list< Type * > types;
    306                 Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex );
     306                Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic | Type::Mutex );
    307307                for ( Expression * expr : exprs ) {
    308308                        assert( expr->get_result() );
     
    361361        const ast::TypeInstType * isTtype( const ast::Type * type ) {
    362362                if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
    363                         if ( inst->base && inst->base->kind == ast::TypeVar::Ttype ) {
     363                        if ( inst->base && inst->base->kind == ast::TypeDecl::Ttype ) {
    364364                                return inst;
    365365                        }
  • src/cfa.make

    r9fb8f01 r3d5701e  
    1 
    2 
    31CFACOMPILE = $(CFACC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) $(AM_CFLAGS) $(CFLAGS)
    42LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
    53        $(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \
    6         $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \
    7         $(AM_CFLAGS) $(CFLAGS)
     4        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(AM_CFLAGS) $(CFAFLAGS) $(CFLAGS)
    85
    96AM_V_CFA = $(am__v_CFA_@AM_V@)
     
    2219        $(am__mv) $$depbase.Tpo $$depbase.Plo
    2320
    24 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
    25 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
    26 am__v_JAVAC_0 = @echo "  JAVAC   " $@;
    27 am__v_JAVAC_1 =
    28 
    29 AM_V_GOC = $(am__v_GOC_@AM_V@)
    30 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
    31 am__v_GOC_0 = @echo "  GOC     " $@;
    32 am__v_GOC_1 =
    33 
    3421UPPCC = u++
    3522UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
     
    3926am__v_UPP_0 = @echo "  UPP     " $@;
    4027am__v_UPP_1 =
     28
     29AM_V_GOC = $(am__v_GOC_@AM_V@)
     30am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
     31am__v_GOC_0 = @echo "  GOC     " $@;
     32am__v_GOC_1 =
     33
     34AM_V_PY = $(am__v_PY_@AM_V@)
     35am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
     36am__v_PY_0 = @echo "  PYTHON  " $@;
     37am__v_PY_1 =
     38
     39AM_V_RUST = $(am__v_RUST_@AM_V@)
     40am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
     41am__v_RUST_0 = @echo "  RUST    " $@;
     42am__v_RUST_1 =
     43
     44AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
     45am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
     46am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     47am__v_NODEJS_1 =
     48
     49AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     50am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
     51am__v_JAVAC_0 = @echo "  JAVAC   " $@;
     52am__v_JAVAC_1 =
  • src/main.cc

    r9fb8f01 r3d5701e  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 23 06:50:08 2019
    13 // Update Count     : 607
     12// Last Modified On : Sat Feb  8 08:33:50 2020
     13// Update Count     : 633
    1414//
    1515
     
    2020#include <cstdio>                           // for fopen, FILE, fclose, stdin
    2121#include <cstdlib>                          // for exit, free, abort, EXIT_F...
    22 #include <csignal>                         // for signal, SIGABRT, SIGSEGV
     22#include <csignal>                          // for signal, SIGABRT, SIGSEGV
    2323#include <cstring>                          // for index
    2424#include <fstream>                          // for ofstream
     
    2828#include <list>                             // for list
    2929#include <string>                           // for char_traits, operator<<
     30
     31using namespace std;
     32
    3033
    3134#include "CompilationState.h"
     
    5356#include "InitTweak/GenInit.h"              // for genInit
    5457#include "MakeLibCfa.h"                     // for makeLibCfa
    55 #include "Parser/LinkageSpec.h"             // for Spec, Cforall, Intrinsic
    5658#include "Parser/ParseNode.h"               // for DeclarationNode, buildList
    5759#include "Parser/TypedefTable.h"            // for TypedefTable
     
    5961#include "ResolvExpr/Resolver.h"            // for resolve
    6062#include "SymTab/Validate.h"                // for validate
    61 #include "SynTree/TopLvalue.h"              // for assertTopLvalue, clearInn...
     63#include "SynTree/LinkageSpec.h"            // for Spec, Cforall, Intrinsic
    6264#include "SynTree/Declaration.h"            // for Declaration
    6365#include "SynTree/Visitor.h"                // for acceptAll
     
    6567#include "Virtual/ExpandCasts.h"            // for expandCasts
    6668
    67 
    68 using namespace std;
    6969
    7070static void NewPass( const char * const name ) {
     
    9898static bool waiting_for_gdb = false;                                    // flag to set cfa-cpp to wait for gdb on start
    9999
    100 static std::string PreludeDirector = "";
     100static string PreludeDirector = "";
    101101
    102102static void parse_cmdline( int argc, char *argv[] );
     
    105105
    106106static void backtrace( int start ) {                                    // skip first N stack frames
    107         enum { Frames = 50 };
     107        enum { Frames = 50, };                                                          // maximum number of stack frames
    108108        void * array[Frames];
    109         int size = ::backtrace( array, Frames );
     109        size_t size = ::backtrace( array, Frames );
    110110        char ** messages = ::backtrace_symbols( array, size ); // does not demangle names
    111111
     
    114114
    115115        // skip last 2 stack frames after main
    116         for ( int i = start; i < size - 2 && messages != nullptr; i += 1 ) {
     116        for ( unsigned int i = start; i < size - 2 && messages != nullptr; i += 1 ) {
    117117                char * mangled_name = nullptr, * offset_begin = nullptr, * offset_end = nullptr;
    118                 for ( char *p = messages[i]; *p; ++p ) {        // find parantheses and +offset
     118
     119                for ( char * p = messages[i]; *p; p += 1 ) {    // find parantheses and +offset
    119120                        if ( *p == '(' ) {
    120121                                mangled_name = p;
     
    154155} // backtrace
    155156
    156 static void sigSegvBusHandler( int sig_num ) {
    157         cerr << "*CFA runtime error* program cfa-cpp terminated with "
    158                  <<     (sig_num == SIGSEGV ? "segment fault" : "bus error")
    159                  << "." << endl;
     157#define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused ))
     158
     159static void Signal( int sig, void (*handler)(SIGPARMS), int flags ) {
     160        struct sigaction act;
     161
     162        act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
     163        act.sa_flags = flags;
     164
     165        if ( sigaction( sig, &act, nullptr ) == -1 ) {
     166            cerr << "*CFA runtime error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;
     167            _exit( EXIT_FAILURE );
     168        } // if
     169} // Signal
     170
     171static void sigSegvBusHandler( SIGPARMS ) {
     172        if ( sfp->si_addr == nullptr ) {
     173                cerr << "Null pointer (nullptr) dereference." << endl;
     174        } else {
     175                cerr << (sig == SIGSEGV ? "Segment fault" : "Bus error") << " at memory location " << sfp->si_addr << "." << endl
     176                         << "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript." << endl;
     177        } // if
    160178        backtrace( 2 );                                                                         // skip first 2 stack frames
    161         //_exit( EXIT_FAILURE );
    162179        abort();                                                                                        // cause core dump for debugging
    163180} // sigSegvBusHandler
    164181
    165 static void sigAbortHandler( __attribute__((unused)) int sig_num ) {
     182static void sigFpeHandler( SIGPARMS ) {
     183        const char * msg;
     184
     185        switch ( sfp->si_code ) {
     186          case FPE_INTDIV: case FPE_FLTDIV: msg = "divide by zero"; break;
     187          case FPE_FLTOVF: msg = "overflow"; break;
     188          case FPE_FLTUND: msg = "underflow"; break;
     189          case FPE_FLTRES: msg = "inexact result"; break;
     190          case FPE_FLTINV: msg = "invalid operation"; break;
     191          default: msg = "unknown";
     192        } // choose
     193        cerr << "Computation error " << msg << " at location " << sfp->si_addr << endl
     194                 << "Possible cause is constant-expression evaluation invalid." << endl;
     195        backtrace( 2 );                                                                         // skip first 2 stack frames
     196        abort();                                                                                        // cause core dump for debugging
     197} // sigFpeHandler
     198
     199static void sigAbortHandler( SIGPARMS ) {
    166200        backtrace( 6 );                                                                         // skip first 6 stack frames
    167         signal( SIGABRT, SIG_DFL);                                                      // reset default signal handler
     201        Signal( SIGABRT, (void (*)(SIGPARMS))SIG_DFL, SA_SIGINFO );     // reset default signal handler
    168202        raise( SIGABRT );                                                                       // reraise SIGABRT
    169203} // sigAbortHandler
     
    174208        list< Declaration * > translationUnit;
    175209
    176         signal( SIGSEGV, sigSegvBusHandler );
    177         signal( SIGBUS, sigSegvBusHandler );
    178         signal( SIGABRT, sigAbortHandler );
    179 
    180         // std::cout << "main" << std::endl;
     210        Signal( SIGSEGV, sigSegvBusHandler, SA_SIGINFO );
     211        Signal( SIGBUS, sigSegvBusHandler, SA_SIGINFO );
     212        Signal( SIGFPE, sigFpeHandler, SA_SIGINFO );
     213        Signal( SIGABRT, sigAbortHandler, SA_SIGINFO );
     214
     215        // cout << "main" << endl;
    181216        // for ( int i = 0; i < argc; i += 1 ) {
    182         //      std::cout << '\t' << argv[i] << std::endl;
     217        //      cout << '\t' << argv[i] << endl;
    183218        // } // for
    184219
     
    187222
    188223        if ( waiting_for_gdb ) {
    189                 std::cerr << "Waiting for gdb" << std::endl;
    190                 std::cerr << "run :" << std::endl;
    191                 std::cerr << "  gdb attach " << getpid() << std::endl;
     224                cerr << "Waiting for gdb" << endl;
     225                cerr << "run :" << endl;
     226                cerr << "  gdb attach " << getpid() << endl;
    192227                raise(SIGSTOP);
    193228        } // if
     
    259294                Stats::Time::StopBlock();
    260295
    261                 //std::cerr << "Post-Parse Check" << std::endl;
    262                 clearInnerLvalue( translationUnit );
    263                 assertTopLvalue( translationUnit );
    264 
    265296                // add the assignment statement after the initialization of a type parameter
    266297                PASS( "Validate", SymTab::validate( translationUnit, symtabp ) );
     
    281312                } // if
    282313
    283                 assertTopLvalue( translationUnit );
    284314                PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) );
    285                 assertTopLvalue( translationUnit );
    286315                PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );
    287                 assertTopLvalue( translationUnit );
    288316                PASS( "Gen Init", InitTweak::genInit( translationUnit ) );
    289                 assertTopLvalue( translationUnit );
    290317                PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) );
    291                 assertTopLvalue( translationUnit );
    292318                if ( libcfap ) {
    293319                        // generate the bodies of cfa library functions
     
    313339                } // if
    314340
    315                 assertTopLvalue( translationUnit );
    316 
    317341                PASS( "Resolve", ResolvExpr::resolve( translationUnit ) );
    318342                if ( exprp ) {
     
    321345                } // if
    322346
    323                 clearInnerLvalue( translationUnit );
    324                 assertTopLvalue( translationUnit );
    325 
    326347                // fix ObjectDecl - replaces ConstructorInit nodes
    327348                PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) );
    328                 clearInnerLvalue( translationUnit );
    329                 assertTopLvalue( translationUnit );
    330349                if ( ctorinitp ) {
    331350                        dump ( translationUnit );
     
    334353
    335354                PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
    336                 assertTopLvalue( translationUnit );
    337355
    338356                PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) );
    339                 assertTopLvalue( translationUnit );
    340357
    341358                PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
    342                 clearInnerLvalue( translationUnit );
    343                 assertTopLvalue( translationUnit );
    344359
    345360                PASS( "Convert Specializations",  GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded
    346                 clearInnerLvalue( translationUnit );
    347                 assertTopLvalue( translationUnit );
    348361
    349362                PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?
    350                 assertTopLvalue( translationUnit );
    351363
    352364                if ( tuplep ) {
     
    356368
    357369                PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
    358                 assertTopLvalue( translationUnit );
    359370
    360371                PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) );
     
    363374                        return EXIT_SUCCESS;
    364375                } // if
    365                 clearInnerLvalue( translationUnit );
    366                 assertTopLvalue( translationUnit );
     376
    367377                PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );
    368                 clearInnerLvalue( translationUnit );
    369                 assertTopLvalue( translationUnit );
    370378
    371379                if ( bboxp ) {
     
    374382                } // if
    375383                PASS( "Box", GenPoly::box( translationUnit ) );
    376                 clearInnerLvalue( translationUnit );
    377                 assertTopLvalue( translationUnit );
    378384
    379385                if ( bcodegenp ) {
     
    387393
    388394                CodeTools::fillLocations( translationUnit );
    389                 assertTopLvalue( translationUnit );
    390395                PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) );
    391396
     
    419424                return EXIT_FAILURE;
    420425        } catch ( ... ) {
    421                 std::exception_ptr eptr = std::current_exception();
     426                exception_ptr eptr = current_exception();
    422427                try {
    423428                        if (eptr) {
    424                                 std::rethrow_exception(eptr);
     429                                rethrow_exception(eptr);
    425430                        } else {
    426                                 std::cerr << "Exception Uncaught and Unknown" << std::endl;
    427                         } // if
    428                 } catch(const std::exception& e) {
    429                         std::cerr << "Uncaught Exception \"" << e.what() << "\"\n";
     431                                cerr << "Exception Uncaught and Unknown" << endl;
     432                        } // if
     433                } catch(const exception& e) {
     434                        cerr << "Uncaught Exception \"" << e.what() << "\"\n";
    430435                } // try
    431436                return EXIT_FAILURE;
     
    438443
    439444
    440 static const char optstring[] = ":hlLmNnpP:S:twW:D:";
     445static const char optstring[] = ":c:ghlLmNnpP:S:twW:D:";
    441446
    442447enum { PreludeDir = 128 };
    443448static struct option long_opts[] = {
     449        { "colors", required_argument, nullptr, 'c' },
     450        { "gdb", no_argument, nullptr, 'g' },
    444451        { "help", no_argument, nullptr, 'h' },
    445452        { "libcfa", no_argument, nullptr, 'l' },
     
    453460        { "statistics", required_argument, nullptr, 'S' },
    454461        { "tree", no_argument, nullptr, 't' },
    455         { "gdb", no_argument, nullptr, 'g' },
    456462        { "", no_argument, nullptr, 0 },                                        // -w
    457463        { "", no_argument, nullptr, 0 },                                        // -W
     
    461467
    462468static const char * description[] = {
    463         "print help message",                                                           // -h
    464         "generate libcfa.c",                                                            // -l
    465         "generate line marks",                                                          // -L
    466         "do not replace main",                                                          // -m
    467         "do not generate line marks",                                           // -N
    468         "do not read prelude",                                                          // -n
     469        "diagnostic color: never, always, or auto.",          // -c
     470        "wait for gdb to attach",                             // -g
     471        "print help message",                                 // -h
     472        "generate libcfa.c",                                  // -l
     473        "generate line marks",                                // -L
     474        "do not replace main",                                // -m
     475        "do not generate line marks",                         // -N
     476        "do not read prelude",                                // -n
    469477        "generate prototypes for prelude functions",            // -p
    470         "print",                                                                                        // -P
     478        "print",                                              // -P
    471479        "<directory> prelude directory for debug/nodebug",      // no flag
    472480        "<option-list> enable profiling information:\n          counters,heap,time,all,none", // -S
    473         "building cfa standard lib",                                                                    // -t
    474         "wait for gdb to attach",                                                                       // -g
    475         "",                                                                                                     // -w
    476         "",                                                                                                     // -W
    477         "",                                                                                                     // -D
     481        "building cfa standard lib",                          // -t
     482        "",                                                   // -w
     483        "",                                                   // -W
     484        "",                                                   // -D
    478485}; // description
    479486
     
    543550        while ( (c = getopt_long( argc, argv, optstring, long_opts, nullptr )) != -1 ) {
    544551                switch ( c ) {
     552                  case 'c':                                                                             // diagnostic colors
     553                        if ( strcmp( optarg, "always" ) == 0 ) {
     554                                ErrorHelpers::colors = ErrorHelpers::Colors::Always;
     555                        } else if ( strcmp( optarg, "never" ) == 0 ) {
     556                                ErrorHelpers::colors = ErrorHelpers::Colors::Never;
     557                        } else if ( strcmp( optarg, "auto" ) == 0 ) {
     558                                ErrorHelpers::colors = ErrorHelpers::Colors::Auto;
     559                        } // if
     560                        break;
    545561                  case 'h':                                                                             // help message
    546562                        usage( argv );                                                          // no return
  • tests/.expect/alloc-ERROR.txt

    r9fb8f01 r3d5701e  
    1 alloc.cfa:265:1 error: No reasonable alternatives for expression Applying untyped:
     1alloc.cfa:310:1 error: No reasonable alternatives for expression Applying untyped:
    22  Name: ?=?
    33...to:
     
    1919
    2020
    21 alloc.cfa:266:1 error: No reasonable alternatives for expression Applying untyped:
     21alloc.cfa:311:1 error: No reasonable alternatives for expression Applying untyped:
    2222  Name: ?=?
    2323...to:
     
    3939
    4040
    41 alloc.cfa:267:1 error: No reasonable alternatives for expression Applying untyped:
     41alloc.cfa:312:1 error: No reasonable alternatives for expression Applying untyped:
    4242  Name: ?=?
    4343...to:
     
    5050
    5151
    52 alloc.cfa:268:1 error: No reasonable alternatives for expression Applying untyped:
     52alloc.cfa:313:1 error: No reasonable alternatives for expression Applying untyped:
    5353  Name: ?=?
    5454...to:
  • tests/.expect/alloc.txt

    r9fb8f01 r3d5701e  
    22CFA malloc 0xdeadbeef
    33CFA alloc 0xdeadbeef
    4 CFA alloc, fill ffffffff
     4CFA alloc, fill dededede
     5CFA alloc, fill 3
    56
    67C   array calloc, fill 0
     
    1011CFA array alloc, no fill
    11120xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    12 CFA array alloc, fill 0xff
    13 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff
     13CFA array alloc, fill 0xde
     140xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
     15CFA array alloc, fill 0xef
     160xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef
     17CFA array alloc, fill from array
     180xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef,
    1419
    15 C   realloc
    16 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
     20C realloc
     210xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef
    1722CFA realloc
    18 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101
     230xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101
    1924
    20 CFA resize alloc
     25CFA resize array alloc
    21260xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    2227CFA resize array alloc
     
    2429CFA resize array alloc
    25300xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
     31CFA resize array alloc
     320xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
     33CFA resize array alloc
     340xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    2635CFA resize array alloc, fill
    27 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff
    28 CFA resize array alloc, fill
    29 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff
    30 CFA resize array alloc, fill
    31 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff
     360xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
    3237
    3338C   memalign 42 42.5
     
    3540CFA posix_memalign 42 42.5
    3641CFA posix_memalign 42 42.5
    37 CFA aligned_alloc 42 42.5
    38 CFA align_alloc 42 42.5
    39 CFA align_alloc fill 0xffffffff -nan
     42CFA alloc_align 42 42.5
     43CFA alloc_align 42 42.5
     44CFA alloc_align fill 0xdededede -0x1.ededededededep+494
     45CFA alloc_align fill 42 42.5
     46CFA alloc_align 42 42.5
    4047
    41 CFA array align_alloc
     48CFA array alloc_align
    424942 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5,
    43 CFA array align_alloc, fill
    44 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan,
     50CFA array alloc_align, fill
     510xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494,
     52CFA array alloc_align, fill
     5342 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5,
     54CFA array alloc_align, fill array
     5542 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5,
     56CFA realloc array alloc_align
     5742 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5,
    4558
    46 CFA memset 0xffffffff -nan
    47 CFA memcpy 0xffffffff -nan
     59CFA memset 0xdededede -0x1.ededededededep+494
     60CFA memcpy 0xdededede -0x1.ededededededep+494
    4861
    4962CFA array memset
    50 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan,
     630xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494,
    5164CFA array memcpy
    52 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan,
     650xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494, 0xdededede -0x1.ededededededep+494,
    5366
    5467CFA new initialize
  • tests/.expect/attributes.x64.txt

    r9fb8f01 r3d5701e  
    784784signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)(__attribute__ ((unused)) signed int __anonymous_object24), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object25)(__attribute__ ((unused)) signed int __anonymous_object26));
    785785struct Vad {
    786     __attribute__ ((unused)) signed int __anonymous_object27:4;
    787     __attribute__ ((unused)) signed int __anonymous_object28:4;
    788     __attribute__ ((unused,unused)) signed int __anonymous_object29:6;
     786    __attribute__ ((unused)) signed int :4;
     787    __attribute__ ((unused)) signed int :4;
     788    __attribute__ ((unused,unused)) signed int :6;
    789789};
    790790static inline void _X12_constructorFv_S3Vad_autogen___1(struct Vad *_X4_dstS3Vad_1);
  • tests/.expect/attributes.x86.txt

    r9fb8f01 r3d5701e  
    784784signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object23)(__attribute__ ((unused)) signed int __anonymous_object24), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object25)(__attribute__ ((unused)) signed int __anonymous_object26));
    785785struct Vad {
    786     __attribute__ ((unused)) signed int __anonymous_object27:4;
    787     __attribute__ ((unused)) signed int __anonymous_object28:4;
    788     __attribute__ ((unused,unused)) signed int __anonymous_object29:6;
     786    __attribute__ ((unused)) signed int :4;
     787    __attribute__ ((unused)) signed int :4;
     788    __attribute__ ((unused,unused)) signed int :6;
    789789};
    790790static inline void _X12_constructorFv_S3Vad_autogen___1(struct Vad *_X4_dstS3Vad_1);
  • tests/.expect/gccExtensions.x64.txt

    r9fb8f01 r3d5701e  
    1212    asm volatile ( "mov %1, %0\n\t" "add $1, %0" : "=" "r" ( _X3dsti_2 ) :  :  );
    1313    asm volatile ( "mov %1, %0\n\t" "add $1, %0" : "=r" ( _X3dsti_2 ) : "r" ( _X3srci_2 ) :  );
    14     asm ( "mov %1, %0\n\t" "add $1, %0" : "=r" ( _X3dsti_2 ), "=r" ( _X3srci_2 ) : [ _X3srci_2 ] "r" ( _X3dsti_2 ) : "r0" );
     14    asm ( "mov %1, %0\n\t" "add $1, %0" : "=r" ( _X3dsti_2 ), "=r" ( _X3srci_2 ) : [ src ] "r" ( _X3dsti_2 ) : "r0" );
    1515    L2: L1: asm goto ( "frob %%r5, %1; jc %l[L1]; mov (%2), %%r5" :  : "r" ( _X3srci_2 ), "r" ( (&_X3dsti_2) ) : "r5", "memory" : L1, L2 );
    1616    double _Complex _X2c1Cd_2;
  • tests/.expect/gccExtensions.x86.txt

    r9fb8f01 r3d5701e  
    1212    asm volatile ( "mov %1, %0\n\t" "add $1, %0" : "=" "r" ( _X3dsti_2 ) :  :  );
    1313    asm volatile ( "mov %1, %0\n\t" "add $1, %0" : "=r" ( _X3dsti_2 ) : "r" ( _X3srci_2 ) :  );
    14     asm ( "mov %1, %0\n\t" "add $1, %0" : "=r" ( _X3dsti_2 ), "=r" ( _X3srci_2 ) : [ _X3srci_2 ] "r" ( _X3dsti_2 ) : "r0" );
     14    asm ( "mov %1, %0\n\t" "add $1, %0" : "=r" ( _X3dsti_2 ), "=r" ( _X3srci_2 ) : [ src ] "r" ( _X3dsti_2 ) : "r0" );
    1515    L2: L1: asm goto ( "frob %%r5, %1; jc %l[L1]; mov (%2), %%r5" :  : "r" ( _X3srci_2 ), "r" ( (&_X3dsti_2) ) : "r5", "memory" : L1, L2 );
    1616    double _Complex _X2c1Cd_2;
  • tests/.expect/loopctrl.txt

    r9fb8f01 r3d5701e  
    66A
    77A A A A A A A A A A
     8A A A A A A A A A A A
    89B B B B B
    910C C C C C
     
    1213
    13140 1 2 3 4 5 6 7 8 9
     150 1 2 3 4 5 6 7 8 9 10
    14161 3 5 7 9
    151710 8 6 4 2
     
    2830N N N N N N N N N N
    29310 1 2 3 4 5 6 7 8 9
     320 1 2 3 4 5 6 7 8 9 10
    303310 9 8 7 6 5 4 3 2 1
    3134
  • tests/.expect/nested-types-ERR1.txt

    r9fb8f01 r3d5701e  
    1 nested-types.cfa:70:1 error: Use of undefined type T
     1nested-types.cfa:83:1 error: Use of undefined type T
  • tests/.expect/nested-types-ERR2.txt

    r9fb8f01 r3d5701e  
    1 nested-types.cfa:73:1 error: Use of undefined global type Z
    2 nested-types.cfa:74:1 error: Qualified type requires an aggregate on the left, but has: signed int
    3 nested-types.cfa:75:1 error: Undefined type in qualified type: Qualified Type:
     1nested-types.cfa:86:1 error: Use of undefined global type Z
     2nested-types.cfa:87:1 error: Qualified type requires an aggregate on the left, but has: signed int
     3nested-types.cfa:88:1 error: Undefined type in qualified type: Qualified Type:
    44  instance of struct S with body 1
    55  instance of type Z (not function type)
  • tests/.expect/rational.txt

    r9fb8f01 r3d5701e  
    11constructor
    2 3/1 4/1 0/1
     23/1 4/1 0/1 0/1 1/1
    331/2 5/7
    442/3 -3/2
  • tests/.expect/references.txt

    r9fb8f01 r3d5701e  
    36363
    37373 9 { 1., 7. }, [1, 2, 3]
     384
    3839Destructing a Y
    3940Destructing a Y
  • tests/.expect/time.txt

    r9fb8f01 r3d5701e  
    1818Dividing that by 2 gives 2403.5 seconds
    19194807 seconds is 1 hours, 20 minutes, 7 seconds
     202020 Jan  5 14:01:40 (GMT)
     211970 Jan  5 14:00:00 (GMT)
     221973 Jan  2 06:59:00 (GMT)
  • tests/Makefile.am

    r9fb8f01 r3d5701e  
    2424archiveerrors=
    2525
    26 INSTALL_FLAGS=-in-tree
    2726DEBUG_FLAGS=-debug -O0
    2827
     
    3534
    3635# applies to both programs
     36# since automake doesn't have support for CFA we have to
    3737AM_CFLAGS = $(if $(test), 2> $(test), ) \
    3838        -g \
     
    4242        -DIN_DIR="${abs_srcdir}/.in/"
    4343
    44 AM_CFLAGS += ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
    45 CC = @CFACC@
     44# get the desired cfa to test
     45TARGET_CFA = $(if $(filter $(installed),yes), @CFACC_INSTALL@, @CFACC@)
     46
     47# adjust CC to current flags
     48CC = $(if $(DISTCC_CFA_PATH),distcc $(DISTCC_CFA_PATH) ${ARCH_FLAGS},$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
     49CFACC = $(CC)
     50
     51# get local binary for depedencies
     52CFACCBIN = @CFACC@
     53
     54# adjusted CC but without the actual distcc call
     55CFACCLOCAL = $(if $(DISTCC_CFA_PATH),$(DISTCC_CFA_PATH) ${ARCH_FLAGS},$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
    4656
    4757PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
     
    5767#----------------------------------------------------------------------------------------------------------------
    5868all-local :
    59         @+${TEST_PY} --debug=${debug}  --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} ${quick_test}
     69        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} ${quick_test}
    6070
    6171all-tests :
    62         @+${TEST_PY} --debug=${debug}  --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
     72        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
    6373
    6474clean-local :
     
    8797
    8898# Use for all tests, make sure the path are correct and all flags are added
    89 CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g'))
    90 
    91 # Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail
    92 CFATEST_STDOUT=$(CFACOMPILETEST) -o $(abspath ${@})
    93 
    94 # Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr
    95 CFATEST_STDERR=$(CFACOMPILETEST) 2> $(abspath ${@})
     99CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g'))
    96100
    97101#----------------------------------------------------------------------------------------------------------------
    98102
    99103# implicit rule so not all test require a rule
    100 % : %.cfa $(CFACC)
    101         $(CFATEST_STDOUT)
     104# split into two steps to support compiling remotely using distcc
     105# don't use distcc to do the linking because distcc doesn't do linking
     106% : %.cfa $(CFACCBIN)
     107        $(CFACOMPILETEST) -c -o $(abspath ${@}).o
     108        $(CFACCLOCAL) $($(shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g')) $(abspath ${@}).o -o $(abspath ${@})
    102109
     110# implicit rule for c++ test
     111# convient for testing the testsuite itself but not actuall used
    103112% : %.cpp
    104113        $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
    105114
    106115#------------------------------------------------------------------------------
    107 # TARGET WITH STANDARD RULE BUT CUSTOM FLAGS
     116# TARGETS WITH CUSTOM FLAGS
    108117#------------------------------------------------------------------------------
    109 # Expected failures
    110 declarationSpecifier_FLAGS= -CFA -XCFA -p
    111 gccExtensions_FLAGS= -CFA -XCFA -p
    112 extension_FLAGS= -CFA -XCFA -p
    113 attributes_FLAGS= -CFA -XCFA -p
    114 functions_FLAGS= -CFA -XCFA -p
    115 KRfunctions_FLAGS= -CFA -XCFA -p
    116 gmp_FLAGS= -lgmp
     118# custom libs
     119gmp_FLAGSLD= -lgmp
    117120
    118121#------------------------------------------------------------------------------
    119 # Expected failures
    120 completeTypeError_FLAGS= -DERR1
     122# Generated code
     123GENERATED_CODE = declarationSpecifier gccExtensions extension attributes functions KRfunctions
     124$(GENERATED_CODE): % : %.cfa $(CFACCBIN)
     125        $(CFACOMPILETEST) -CFA -XCFA -p -c -fsyntax-only -o $(abspath ${@})
     126
     127# Use for tests where the make command is expected to succeed but the expected.txt should be compared to stderr
     128EXPECT_STDERR = builtins/sync warnings/self-assignment
     129$(EXPECT_STDERR): % : %.cfa $(CFACCBIN)
     130        $(CFACOMPILETEST) -c -fsyntax-only 2> $(abspath ${@})
    121131
    122132#------------------------------------------------------------------------------
    123133# CUSTOM TARGET
    124134#------------------------------------------------------------------------------
    125 typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
    126         $(CFATEST_STDOUT) -DERR1
     135# expected failures
     136# use custom target since they require a custom define and custom dependencies
     137alloc-ERROR : alloc.cfa $(CFACCBIN)
     138        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    127139
    128 alloc-ERROR: alloc.cfa $(CFACC)
    129         $(CFATEST_STDOUT) -DERR1
     140typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN)
     141        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    130142
    131 nested-types-ERR1: nested-types.cfa $(CFACC)
    132         $(CFATEST_STDOUT) -DERR1
     143nested-types-ERR1 : nested-types.cfa $(CFACCBIN)
     144        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    133145
    134 nested-types-ERR2: nested-types.cfa $(CFACC)
    135         $(CFATEST_STDOUT) -DERR2
     146nested-types-ERR2 : nested-types.cfa $(CFACCBIN)
     147        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
    136148
    137 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
    138         $(CFATEST_STDOUT) -DERR1
     149raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN)
     150        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    139151
    140 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
    141         $(CFATEST_STDOUT) -DERR2
     152raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN)
     153        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    142154
    143 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
    144         $(CFATEST_STDOUT) -DERR1
     155raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN)
     156        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    145157
    146 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
    147         $(CFATEST_STDOUT) -DERR1
     158raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN)
     159        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
    148160
    149 #builtins
    150 builtins/sync: builtins/sync.cfa $(CFACC)
    151         $(CFATEST_STDERR) -fsyntax-only
    152 
    153 # Warnings
    154 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
    155         $(CFATEST_STDERR) -fsyntax-only
     161#------------------------------------------------------------------------------
     162# Other targets
  • tests/Makefile.in

    r9fb8f01 r3d5701e  
    212212AWK = @AWK@
    213213BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@
    214 CC = @CFACC@
     214
     215# adjust CC to current flags
     216CC = $(if $(DISTCC_CFA_PATH),distcc $(DISTCC_CFA_PATH) ${ARCH_FLAGS},$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
    215217CCAS = @CCAS@
    216218CCASDEPMODE = @CCASDEPMODE@
    217219CCASFLAGS = @CCASFLAGS@
    218220CCDEPMODE = @CCDEPMODE@
    219 CFACC = @CFACC@
     221CFACC = $(CC)
     222CFACC_INSTALL = @CFACC_INSTALL@
    220223CFACPP = @CFACPP@
    221224CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    248251FGREP = @FGREP@
    249252GREP = @GREP@
     253HAS_DISTCC = @HAS_DISTCC@
    250254HOST_FLAGS = @HOST_FLAGS@
    251255INSTALL = @INSTALL@
     
    354358LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
    355359        $(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \
    356         $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \
    357         $(AM_CFLAGS) $(CFLAGS)
     360        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(AM_CFLAGS) $(CFAFLAGS) $(CFLAGS)
    358361
    359362AM_V_CFA = $(am__v_CFA_@AM_V@)
     
    361364am__v_CFA_0 = @echo "  CFA     " $@;
    362365am__v_CFA_1 =
    363 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
    364 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
    365 am__v_JAVAC_0 = @echo "  JAVAC   " $@;
    366 am__v_JAVAC_1 =
    367 AM_V_GOC = $(am__v_GOC_@AM_V@)
    368 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
    369 am__v_GOC_0 = @echo "  GOC     " $@;
    370 am__v_GOC_1 =
    371366UPPCC = u++
    372367UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
     
    375370am__v_UPP_0 = @echo "  UPP     " $@;
    376371am__v_UPP_1 =
     372AM_V_GOC = $(am__v_GOC_@AM_V@)
     373am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
     374am__v_GOC_0 = @echo "  GOC     " $@;
     375am__v_GOC_1 =
     376AM_V_PY = $(am__v_PY_@AM_V@)
     377am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
     378am__v_PY_0 = @echo "  PYTHON  " $@;
     379am__v_PY_1 =
     380AM_V_RUST = $(am__v_RUST_@AM_V@)
     381am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
     382am__v_RUST_0 = @echo "  RUST    " $@;
     383am__v_RUST_1 =
     384AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
     385am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
     386am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     387am__v_NODEJS_1 =
     388AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     389am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
     390am__v_JAVAC_0 = @echo "  JAVAC   " $@;
     391am__v_JAVAC_1 =
    377392debug = yes
    378393installed = no
    379394archiveerrors =
    380 INSTALL_FLAGS = -in-tree
    381395DEBUG_FLAGS = -debug -O0
    382396quick_test = avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes
     
    386400
    387401# applies to both programs
    388 AM_CFLAGS = $(if $(test), 2> $(test), ) -g -Wall -Wno-unused-function \
    389         -quiet @CFA_FLAGS@ -DIN_DIR="${abs_srcdir}/.in/" \
    390         ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
     402# since automake doesn't have support for CFA we have to
     403AM_CFLAGS = $(if $(test), 2> $(test), ) \
     404        -g \
     405        -Wall \
     406        -Wno-unused-function \
     407        -quiet @CFA_FLAGS@ \
     408        -DIN_DIR="${abs_srcdir}/.in/"
     409
     410
     411# get the desired cfa to test
     412TARGET_CFA = $(if $(filter $(installed),yes), @CFACC_INSTALL@, @CFACC@)
     413
     414# get local binary for depedencies
     415CFACCBIN = @CFACC@
     416
     417# adjusted CC but without the actual distcc call
     418CFACCLOCAL = $(if $(DISTCC_CFA_PATH),$(DISTCC_CFA_PATH) ${ARCH_FLAGS},$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
    391419PRETTY_PATH = mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
    392420avl_test_SOURCES = avltree/avl_test.cfa avltree/avl0.cfa avltree/avl1.cfa avltree/avl2.cfa avltree/avl3.cfa avltree/avl4.cfa avltree/avl-private.cfa
     
    397425
    398426# Use for all tests, make sure the path are correct and all flags are added
    399 CFACOMPILETEST = $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g'))
    400 
    401 # Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail
    402 CFATEST_STDOUT = $(CFACOMPILETEST) -o $(abspath ${@})
    403 
    404 # Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr
    405 CFATEST_STDERR = $(CFACOMPILETEST) 2> $(abspath ${@})
     427CFACOMPILETEST = $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g'))
    406428
    407429#------------------------------------------------------------------------------
    408 # TARGET WITH STANDARD RULE BUT CUSTOM FLAGS
     430# TARGETS WITH CUSTOM FLAGS
    409431#------------------------------------------------------------------------------
    410 # Expected failures
    411 declarationSpecifier_FLAGS = -CFA -XCFA -p
    412 gccExtensions_FLAGS = -CFA -XCFA -p
    413 extension_FLAGS = -CFA -XCFA -p
    414 attributes_FLAGS = -CFA -XCFA -p
    415 functions_FLAGS = -CFA -XCFA -p
    416 KRfunctions_FLAGS = -CFA -XCFA -p
    417 gmp_FLAGS = -lgmp
     432# custom libs
     433gmp_FLAGSLD = -lgmp
    418434
    419435#------------------------------------------------------------------------------
    420 # Expected failures
    421 completeTypeError_FLAGS = -DERR1
     436# Generated code
     437GENERATED_CODE = declarationSpecifier gccExtensions extension attributes functions KRfunctions
     438
     439# Use for tests where the make command is expected to succeed but the expected.txt should be compared to stderr
     440EXPECT_STDERR = builtins/sync warnings/self-assignment
    422441all: all-am
    423442
     
    771790#----------------------------------------------------------------------------------------------------------------
    772791all-local :
    773         @+${TEST_PY} --debug=${debug}  --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} ${quick_test}
     792        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} ${quick_test}
    774793
    775794all-tests :
    776         @+${TEST_PY} --debug=${debug}  --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
     795        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
    777796
    778797clean-local :
     
    801820
    802821# implicit rule so not all test require a rule
    803 % : %.cfa $(CFACC)
    804         $(CFATEST_STDOUT)
    805 
     822# split into two steps to support compiling remotely using distcc
     823# don't use distcc to do the linking because distcc doesn't do linking
     824% : %.cfa $(CFACCBIN)
     825        $(CFACOMPILETEST) -c -o $(abspath ${@}).o
     826        $(CFACCLOCAL) $($(shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g')) $(abspath ${@}).o -o $(abspath ${@})
     827
     828# implicit rule for c++ test
     829# convient for testing the testsuite itself but not actuall used
    806830% : %.cpp
    807831        $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     832$(GENERATED_CODE): % : %.cfa $(CFACCBIN)
     833        $(CFACOMPILETEST) -CFA -XCFA -p -c -fsyntax-only -o $(abspath ${@})
     834$(EXPECT_STDERR): % : %.cfa $(CFACCBIN)
     835        $(CFACOMPILETEST) -c -fsyntax-only 2> $(abspath ${@})
    808836
    809837#------------------------------------------------------------------------------
    810838# CUSTOM TARGET
    811839#------------------------------------------------------------------------------
    812 typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
    813         $(CFATEST_STDOUT) -DERR1
    814 
    815 alloc-ERROR: alloc.cfa $(CFACC)
    816         $(CFATEST_STDOUT) -DERR1
    817 
    818 nested-types-ERR1: nested-types.cfa $(CFACC)
    819         $(CFATEST_STDOUT) -DERR1
    820 
    821 nested-types-ERR2: nested-types.cfa $(CFACC)
    822         $(CFATEST_STDOUT) -DERR2
    823 
    824 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
    825         $(CFATEST_STDOUT) -DERR1
    826 
    827 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
    828         $(CFATEST_STDOUT) -DERR2
    829 
    830 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
    831         $(CFATEST_STDOUT) -DERR1
    832 
    833 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
    834         $(CFATEST_STDOUT) -DERR1
    835 
    836 #builtins
    837 builtins/sync: builtins/sync.cfa $(CFACC)
    838         $(CFATEST_STDERR) -fsyntax-only
    839 
    840 # Warnings
    841 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
    842         $(CFATEST_STDERR) -fsyntax-only
     840# expected failures
     841# use custom target since they require a custom define and custom dependencies
     842alloc-ERROR : alloc.cfa $(CFACCBIN)
     843        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     844
     845typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN)
     846        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     847
     848nested-types-ERR1 : nested-types.cfa $(CFACCBIN)
     849        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     850
     851nested-types-ERR2 : nested-types.cfa $(CFACCBIN)
     852        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
     853
     854raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN)
     855        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     856
     857raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN)
     858        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     859
     860raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN)
     861        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     862
     863raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN)
     864        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
     865
     866#------------------------------------------------------------------------------
     867# Other targets
    843868
    844869# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • tests/alloc.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Feb  3 07:56:22 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Nov  6 17:50:52 2018
    13 // Update Count     : 339
     12// Last Modified On : Sun Feb 16 09:21:13 2020
     13// Update Count     : 405
    1414//
    1515
     
    1919#include <stdlib.h>                                                                             // posix_memalign
    2020#include <fstream.hfa>
    21 #include <stdlib.hfa>                                                                           // access C malloc, realloc
     21#include <stdlib.hfa>                                                                   // access C malloc, realloc
    2222
    2323int * foo( int * p, int c ) { return p; }
     
    2727int main( void ) {
    2828        size_t dim = 10;
    29         char fill = '\xff';
    30         int * p;
     29        char fill = '\xde';
     30        int * p, * p1;
    3131
    3232        // allocation, non-array types
    33 
    34         // int & r = malloc();
    35         // r = 0xdeadbeef;
    36         // printf( "C   malloc %#x\n", r );
    37         // free( &r );
    3833
    3934        p = (int *)malloc( sizeof(*p) );                                        // C malloc, type unsafe
     
    5247        free( p );
    5348
    54         p = alloc( fill );                                  // CFA alloc, fill
     49        p = alloc_set( fill );                                                          // CFA alloc, fill
    5550        printf( "CFA alloc, fill %08x\n", *p );
     51        free( p );
     52
     53        p = alloc_set( 3 );                                                                     // CFA alloc, fill
     54        printf( "CFA alloc, fill %d\n", *p );
    5655        free( p );
    5756
     
    7978        free( p );
    8079
    81         p = alloc( 2 * dim, fill );                         // CFA array alloc, fill
     80        p = alloc_set( 2 * dim, fill );                                         // CFA array alloc, fill
    8281        printf( "CFA array alloc, fill %#hhx\n", fill );
    8382        for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
    8483        printf( "\n" );
    85         // do not free
     84        free( p );
     85
     86        p = alloc_set( 2 * dim, 0xdeadbeef );                           // CFA array alloc, fill
     87        printf( "CFA array alloc, fill %#hhx\n", 0xdeadbeef );
     88        for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
     89        printf( "\n" );
     90        // do not free
     91
     92        p1 = alloc_set( 2 * dim, p );                                           // CFA array alloc, fill
     93        printf( "CFA array alloc, fill from array\n" );
     94        for ( i; 2 * dim ) { printf( "%#x %#x, ", p[i], p1[i] ); }
     95        free( p1 );
     96        printf( "\n" );
    8697
    8798
     
    90101
    91102        p = (int *)realloc( p, dim * sizeof(*p) );                      // C realloc
    92         for ( i; dim ) { p[i] = 0xdeadbeef; }
    93         printf( "C   realloc\n" );
    94         for ( i; dim ) { printf( "%#x ", p[i] ); }
    95         printf( "\n" );
     103        printf( "C realloc\n" );
     104        for ( i; dim ) { printf( "%#x ", p[i] ); }
     105        printf( "\n" );
     106        // do not free
    96107
    97108        p = realloc( p, 2 * dim * sizeof(*p) );             // CFA realloc
     
    108119        p = alloc( p, dim );                                // CFA resize array alloc
    109120        for ( i; dim ) { p[i] = 0xdeadbeef; }
    110         printf( "CFA resize alloc\n" );
    111         for ( i; dim ) { printf( "%#x ", p[i] ); }
    112         printf( "\n" );
     121        printf( "CFA resize array alloc\n" );
     122        for ( i; dim ) { printf( "%#x ", p[i] ); }
     123        printf( "\n" );
     124        // do not free
    113125
    114126        p = alloc( p, 2 * dim );                            // CFA resize array alloc
    115         for ( i; dim ~ 2 * dim ) { p[i] = 0x1010101; }
     127        for ( i; dim ~ 2 * dim ) { p[i] = 0x1010101; }          // fill upper part
    116128        printf( "CFA resize array alloc\n" );
    117129        for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
    118130        printf( "\n" );
    119 
    120         p = alloc( p, dim );                                // CFA array alloc
    121         printf( "CFA resize array alloc\n" );
    122         for ( i; dim ) { printf( "%#x ", p[i] ); }
    123         printf( "\n" );
    124 
    125         free( p );
    126         p = 0;
    127 
    128         p = alloc( p, dim, fill );                          // CFA array alloc, fill
     131        // do not free
     132
     133        p = alloc( p, dim );                                // CFA resize array alloc
     134        printf( "CFA resize array alloc\n" );
     135        for ( i; dim ) { printf( "%#x ", p[i] ); }
     136        printf( "\n" );
     137        // do not free
     138
     139        p = alloc_set( p, 3 * dim, fill );                                      // CFA resize array alloc, fill
     140        printf( "CFA resize array alloc\n" );
     141        for ( i; 3 * dim ) { printf( "%#x ", p[i] ); }
     142        printf( "\n" );
     143        // do not free
     144
     145        p = alloc_set( p, dim, fill );                                          // CFA resize array alloc, fill
     146        printf( "CFA resize array alloc\n" );
     147        for ( i; dim ) { printf( "%#x ", p[i] ); }
     148        printf( "\n" );
     149        // do not free
     150
     151        p = alloc_set( p, 3 * dim, fill );                                      // CFA resize array alloc, fill
    129152        printf( "CFA resize array alloc, fill\n" );
    130         for ( i; dim ) { printf( "%#x ", p[i] ); }
    131         printf( "\n" );
    132 
    133         p = alloc( p, 2 * dim, fill );                      // CFA array alloc, fill
    134         printf( "CFA resize array alloc, fill\n" );
    135         for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
    136         printf( "\n" );
    137 
    138         p = alloc( p, dim, fill );                          // CFA array alloc, fill
    139         printf( "CFA resize array alloc, fill\n" );
    140         for ( i; dim ) { printf( "%#x ", p[i] );; }
     153        for ( i; 3 * dim ) { printf( "%#x ", p[i] );; }
    141154        printf( "\n" );
    142155        free( p );
     
    172185        free( stp );
    173186
    174         stp = &(*aligned_alloc( Alignment )){ 42, 42.5 };     // CFA aligned_alloc
    175         assert( (uintptr_t)stp % Alignment == 0 );
    176         printf( "CFA aligned_alloc %d %g\n", stp->x, stp->y );
    177         free( stp );
    178 
    179         stp = &(*align_alloc( Alignment )){ 42, 42.5 };       // CFA align_alloc
    180         assert( (uintptr_t)stp % Alignment == 0 );
    181         printf( "CFA align_alloc %d %g\n", stp->x, stp->y );
    182         free( stp );
    183 
    184         stp = align_alloc( Alignment, fill );               // CFA memalign, fill
    185         assert( (uintptr_t)stp % Alignment == 0 );
    186         printf( "CFA align_alloc fill %#x %a\n", stp->x, stp->y );
     187        stp = &(*alloc_align( Alignment)){ 42, 42.5 };          // CFA alloc_align
     188        assert( (uintptr_t)stp % Alignment == 0 );
     189        printf( "CFA alloc_align %d %g\n", stp->x, stp->y );
     190        free( stp );
     191
     192        stp = &(*alloc_align( Alignment )){ 42, 42.5 };         // CFA alloc_align
     193        assert( (uintptr_t)stp % Alignment == 0 );
     194        printf( "CFA alloc_align %d %g\n", stp->x, stp->y );
     195        free( stp );
     196
     197        stp = alloc_align_set( Alignment, fill );                       // CFA memalign, fill
     198        assert( (uintptr_t)stp % Alignment == 0 );
     199        printf( "CFA alloc_align fill %#x %a\n", stp->x, stp->y );
     200        free( stp );
     201
     202        stp = alloc_align_set( Alignment, (Struct){ 42, 42.5 } ); // CFA memalign, fill
     203        assert( (uintptr_t)stp % Alignment == 0 );
     204        printf( "CFA alloc_align fill %d %g\n", stp->x, stp->y );
     205        // do not free
     206
     207        stp = &(*alloc_align( stp, 4096 )){ 42, 42.5 };         // CFA realign
     208        assert( (uintptr_t)stp % 4096 == 0 );
     209        printf( "CFA alloc_align %d %g\n", stp->x, stp->y );
    187210        free( stp );
    188211
     
    191214        printf( "\n" );
    192215
    193         stp = align_alloc( Alignment, dim );                // CFA array memalign
     216        stp = alloc_align( Alignment, dim );                // CFA array memalign
    194217        assert( (uintptr_t)stp % Alignment == 0 );
    195218        for ( i; dim ) { stp[i] = (Struct){ 42, 42.5 }; }
    196         printf( "CFA array align_alloc\n" );
     219        printf( "CFA array alloc_align\n" );
    197220        for ( i; dim ) { printf( "%d %g, ", stp[i].x, stp[i].y ); }
    198221        printf( "\n" );
    199222        free( stp );
    200223
    201         stp = align_alloc( Alignment, dim, fill );          // CFA array memalign, fill
    202         assert( (uintptr_t)stp % Alignment == 0 );
    203         printf( "CFA array align_alloc, fill\n" );
     224        stp = alloc_align_set( Alignment, dim, fill );          // CFA array memalign, fill
     225        assert( (uintptr_t)stp % Alignment == 0 );
     226        printf( "CFA array alloc_align, fill\n" );
    204227        for ( i; dim ) { printf( "%#x %a, ", stp[i].x, stp[i].y ); }
     228        printf( "\n" );
     229        free( stp );
     230
     231        stp = alloc_align_set( Alignment, dim, (Struct){ 42, 42.5 } ); // CFA array memalign, fill
     232        assert( (uintptr_t)stp % Alignment == 0 );
     233        printf( "CFA array alloc_align, fill\n" );
     234        for ( i; dim ) { printf( "%d %g, ", stp[i].x, stp[i].y ); }
     235        printf( "\n" );
     236        // do not free
     237
     238        stp1 = alloc_align_set( Alignment, dim, stp );          // CFA array memalign, fill
     239        assert( (uintptr_t)stp % Alignment == 0 );
     240        printf( "CFA array alloc_align, fill array\n" );
     241        for ( i; dim ) { printf( "%d %g, ", stp1[i].x, stp1[i].y ); }
     242        printf( "\n" );
     243        free( stp1 );
     244
     245        stp = alloc_align( stp, 4096, dim );                            // CFA aligned realloc array
     246        assert( (uintptr_t)stp % 4096 == 0 );
     247        for ( i; dim ) { stp[i] = (Struct){ 42, 42.5 }; }
     248        printf( "CFA realloc array alloc_align\n" );
     249        for ( i; dim ) { printf( "%d %g, ", stp[i].x, stp[i].y ); }
    205250        printf( "\n" );
    206251        free( stp );
  • tests/builtins/sync.cfa

    r9fb8f01 r3d5701e  
    44void foo() {
    55        volatile _Bool * vpB = 0; _Bool vB = 0;
    6         volatile char * vp1 = 0; char * rp1 = 0; char v1 = 0;
    7         volatile short * vp2 = 0; short * rp2 = 0; short v2 = 0;
    8         volatile int * vp4 = 0; int * rp4 = 0; int v4 = 0;
    9         volatile long long int * vp8 = 0; long long int * rp8 = 0; long long int v8 = 0;
    10         #if defined(__SIZEOF_INT128__)
    11         volatile __int128 * vp16 = 0; __int128 * rp16 = 0; __int128 v16 = 0;
     6        volatile char * vpc = 0; char * rpc = 0; char vc = 0;
     7        volatile short * vps = 0; short * rps = 0; short vs = 0;
     8        volatile int * vpi = 0; int * rpi = 0; int vi = 0;
     9        volatile long int * vpl = 0; long int * rpl = 0; long int vl = 0;
     10        volatile long long int * vpll = 0; long long int * rpll = 0; long long int vll = 0;
     11        #if defined(__SIZEOF_INT128__)
     12        volatile __int128 * vplll = 0; __int128 * rplll = 0; __int128 vlll = 0;
    1213        #endif
    1314        struct type * volatile * vpp = 0; struct type ** rpp = 0; struct type * vp = 0;
    1415
    15         { char ret; ret = __sync_fetch_and_add(vp1, v1); }
    16         { char ret; ret = __sync_fetch_and_add_1(vp1, v1); }
    17         { short ret; ret = __sync_fetch_and_add(vp2, v2); }
    18         { short ret; ret = __sync_fetch_and_add_2(vp2, v2); }
    19         { int ret; ret = __sync_fetch_and_add(vp4, v4); }
    20         { int ret; ret = __sync_fetch_and_add_4(vp4, v4); }
    21         { long long int ret; ret = __sync_fetch_and_add(vp8, v8); }
    22         { long long int ret; ret = __sync_fetch_and_add_8(vp8, v8); }
    23         #if defined(__SIZEOF_INT128__)
    24         { __int128 ret; ret = __sync_fetch_and_add(vp16, v16); }
    25         { __int128 ret; ret = __sync_fetch_and_add_16(vp16, v16); }
    26         #endif
    27 
    28         { char ret; ret = __sync_fetch_and_sub(vp1, v1); }
    29         { char ret; ret = __sync_fetch_and_sub_1(vp1, v1); }
    30         { short ret; ret = __sync_fetch_and_sub(vp2, v2); }
    31         { short ret; ret = __sync_fetch_and_sub_2(vp2, v2); }
    32         { int ret; ret = __sync_fetch_and_sub(vp4, v4); }
    33         { int ret; ret = __sync_fetch_and_sub_4(vp4, v4); }
    34         { long long int ret; ret = __sync_fetch_and_sub(vp8, v8); }
    35         { long long int ret; ret = __sync_fetch_and_sub_8(vp8, v8); }
    36         #if defined(__SIZEOF_INT128__)
    37         { __int128 ret; ret = __sync_fetch_and_sub(vp16, v16); }
    38         { __int128 ret; ret = __sync_fetch_and_sub_16(vp16, v16); }
    39         #endif
    40 
    41         { char ret; ret = __sync_fetch_and_or(vp1, v1); }
    42         { char ret; ret = __sync_fetch_and_or_1(vp1, v1); }
    43         { short ret; ret = __sync_fetch_and_or(vp2, v2); }
    44         { short ret; ret = __sync_fetch_and_or_2(vp2, v2); }
    45         { int ret; ret = __sync_fetch_and_or(vp4, v4); }
    46         { int ret; ret = __sync_fetch_and_or_4(vp4, v4); }
    47         { long long int ret; ret = __sync_fetch_and_or(vp8, v8); }
    48         { long long int ret; ret = __sync_fetch_and_or_8(vp8, v8); }
    49         #if defined(__SIZEOF_INT128__)
    50         { __int128 ret; ret = __sync_fetch_and_or(vp16, v16); }
    51         { __int128 ret; ret = __sync_fetch_and_or_16(vp16, v16); }
    52         #endif
    53 
    54         { char ret; ret = __sync_fetch_and_and(vp1, v1); }
    55         { char ret; ret = __sync_fetch_and_and_1(vp1, v1); }
    56         { short ret; ret = __sync_fetch_and_and(vp2, v2); }
    57         { short ret; ret = __sync_fetch_and_and_2(vp2, v2); }
    58         { int ret; ret = __sync_fetch_and_and(vp4, v4); }
    59         { int ret; ret = __sync_fetch_and_and_4(vp4, v4); }
    60         { long long int ret; ret = __sync_fetch_and_and(vp8, v8); }
    61         { long long int ret; ret = __sync_fetch_and_and_8(vp8, v8); }
    62         #if defined(__SIZEOF_INT128__)
    63         { __int128 ret; ret = __sync_fetch_and_and(vp16, v16); }
    64         { __int128 ret; ret = __sync_fetch_and_and_16(vp16, v16); }
    65         #endif
    66 
    67         { char ret; ret = __sync_fetch_and_xor(vp1, v1); }
    68         { char ret; ret = __sync_fetch_and_xor_1(vp1, v1); }
    69         { short ret; ret = __sync_fetch_and_xor(vp2, v2); }
    70         { short ret; ret = __sync_fetch_and_xor_2(vp2, v2); }
    71         { int ret; ret = __sync_fetch_and_xor(vp4, v4); }
    72         { int ret; ret = __sync_fetch_and_xor_4(vp4, v4); }
    73         { long long int ret; ret = __sync_fetch_and_xor(vp8, v8); }
    74         { long long int ret; ret = __sync_fetch_and_xor_8(vp8, v8); }
    75         #if defined(__SIZEOF_INT128__)
    76         { __int128 ret; ret = __sync_fetch_and_xor(vp16, v16); }
    77         { __int128 ret; ret = __sync_fetch_and_xor_16(vp16, v16); }
    78         #endif
    79 
    80         { char ret; ret = __sync_fetch_and_nand(vp1, v1); }
    81         { char ret; ret = __sync_fetch_and_nand_1(vp1, v1); }
    82         { short ret; ret = __sync_fetch_and_nand(vp2, v2); }
    83         { short ret; ret = __sync_fetch_and_nand_2(vp2, v2); }
    84         { int ret; ret = __sync_fetch_and_nand(vp4, v4); }
    85         { int ret; ret = __sync_fetch_and_nand_4(vp4, v4); }
    86         { long long int ret; ret = __sync_fetch_and_nand(vp8, v8); }
    87         { long long int ret; ret = __sync_fetch_and_nand_8(vp8, v8); }
    88         #if defined(__SIZEOF_INT128__)
    89         { __int128 ret; ret = __sync_fetch_and_nand(vp16, v16); }
    90         { __int128 ret; ret = __sync_fetch_and_nand_16(vp16, v16); }
    91         #endif
    92 
    93         { char ret; ret = __sync_add_and_fetch(vp1, v1); }
    94         { char ret; ret = __sync_add_and_fetch_1(vp1, v1); }
    95         { short ret; ret = __sync_add_and_fetch(vp2, v2); }
    96         { short ret; ret = __sync_add_and_fetch_2(vp2, v2); }
    97         { int ret; ret = __sync_add_and_fetch(vp4, v4); }
    98         { int ret; ret = __sync_add_and_fetch_4(vp4, v4); }
    99         { long long int ret; ret = __sync_add_and_fetch(vp8, v8); }
    100         { long long int ret; ret = __sync_add_and_fetch_8(vp8, v8); }
    101         #if defined(__SIZEOF_INT128__)
    102         { __int128 ret; ret = __sync_add_and_fetch(vp16, v16); }
    103         { __int128 ret; ret = __sync_add_and_fetch_16(vp16, v16); }
    104         #endif
    105 
    106         { char ret; ret = __sync_sub_and_fetch(vp1, v1); }
    107         { char ret; ret = __sync_sub_and_fetch_1(vp1, v1); }
    108         { short ret; ret = __sync_sub_and_fetch(vp2, v2); }
    109         { short ret; ret = __sync_sub_and_fetch_2(vp2, v2); }
    110         { int ret; ret = __sync_sub_and_fetch(vp4, v4); }
    111         { int ret; ret = __sync_sub_and_fetch_4(vp4, v4); }
    112         { long long int ret; ret = __sync_sub_and_fetch(vp8, v8); }
    113         { long long int ret; ret = __sync_sub_and_fetch_8(vp8, v8); }
    114         #if defined(__SIZEOF_INT128__)
    115         { __int128 ret; ret = __sync_sub_and_fetch(vp16, v16); }
    116         { __int128 ret; ret = __sync_sub_and_fetch_16(vp16, v16); }
    117         #endif
    118 
    119         { char ret; ret = __sync_or_and_fetch(vp1, v1); }
    120         { char ret; ret = __sync_or_and_fetch_1(vp1, v1); }
    121         { short ret; ret = __sync_or_and_fetch(vp2, v2); }
    122         { short ret; ret = __sync_or_and_fetch_2(vp2, v2); }
    123         { int ret; ret = __sync_or_and_fetch(vp4, v4); }
    124         { int ret; ret = __sync_or_and_fetch_4(vp4, v4); }
    125         { long long int ret; ret = __sync_or_and_fetch(vp8, v8); }
    126         { long long int ret; ret = __sync_or_and_fetch_8(vp8, v8); }
    127         #if defined(__SIZEOF_INT128__)
    128         { __int128 ret; ret = __sync_or_and_fetch(vp16, v16); }
    129         { __int128 ret; ret = __sync_or_and_fetch_16(vp16, v16); }
    130         #endif
    131 
    132         { char ret; ret = __sync_and_and_fetch(vp1, v1); }
    133         { char ret; ret = __sync_and_and_fetch_1(vp1, v1); }
    134         { short ret; ret = __sync_and_and_fetch(vp2, v2); }
    135         { short ret; ret = __sync_and_and_fetch_2(vp2, v2); }
    136         { int ret; ret = __sync_and_and_fetch(vp4, v4); }
    137         { int ret; ret = __sync_and_and_fetch_4(vp4, v4); }
    138         { long long int ret; ret = __sync_and_and_fetch(vp8, v8); }
    139         { long long int ret; ret = __sync_and_and_fetch_8(vp8, v8); }
    140         #if defined(__SIZEOF_INT128__)
    141         { __int128 ret; ret = __sync_and_and_fetch(vp16, v16); }
    142         { __int128 ret; ret = __sync_and_and_fetch_16(vp16, v16); }
    143         #endif
    144 
    145         { char ret; ret = __sync_xor_and_fetch(vp1, v1); }
    146         { char ret; ret = __sync_xor_and_fetch_1(vp1, v1); }
    147         { short ret; ret = __sync_xor_and_fetch(vp2, v2); }
    148         { short ret; ret = __sync_xor_and_fetch_2(vp2, v2); }
    149         { int ret; ret = __sync_xor_and_fetch(vp4, v4); }
    150         { int ret; ret = __sync_xor_and_fetch_4(vp4, v4); }
    151         { long long int ret; ret = __sync_xor_and_fetch(vp8, v8); }
    152         { long long int ret; ret = __sync_xor_and_fetch_8(vp8, v8); }
    153         #if defined(__SIZEOF_INT128__)
    154         { __int128 ret; ret = __sync_xor_and_fetch(vp16, v16); }
    155         { __int128 ret; ret = __sync_xor_and_fetch_16(vp16, v16); }
    156         #endif
    157 
    158         { char ret; ret = __sync_nand_and_fetch(vp1, v1); }
    159         { char ret; ret = __sync_nand_and_fetch_1(vp1, v1); }
    160         { short ret; ret = __sync_nand_and_fetch(vp2, v2); }
    161         { short ret; ret = __sync_nand_and_fetch_2(vp2, v2); }
    162         { int ret; ret = __sync_nand_and_fetch(vp4, v4); }
    163         { int ret; ret = __sync_nand_and_fetch_4(vp4, v4); }
    164         { long long int ret; ret = __sync_nand_and_fetch(vp8, v8); }
    165         { long long int ret; ret = __sync_nand_and_fetch_8(vp8, v8); }
    166         #if defined(__SIZEOF_INT128__)
    167         { __int128 ret; ret = __sync_nand_and_fetch(vp16, v16); }
    168         { __int128 ret; ret = __sync_nand_and_fetch_16(vp16, v16); }
    169         #endif
    170 
    171         { _Bool ret; ret = __sync_bool_compare_and_swap(vp1, v1, v1); }
    172         { _Bool ret; ret = __sync_bool_compare_and_swap_1(vp1, v1, v1); }
    173         { _Bool ret; ret = __sync_bool_compare_and_swap(vp2, v2, v2); }
    174         { _Bool ret; ret = __sync_bool_compare_and_swap_2(vp2, v2, v2); }
    175         { _Bool ret; ret = __sync_bool_compare_and_swap(vp4, v4, v4); }
    176         { _Bool ret; ret = __sync_bool_compare_and_swap_4(vp4, v4, v4); }
    177         { _Bool ret; ret = __sync_bool_compare_and_swap(vp8, v8, v8); }
    178         { _Bool ret; ret = __sync_bool_compare_and_swap_8(vp8, v8, v8); }
    179         #if defined(__SIZEOF_INT128__)
    180         { _Bool ret; ret = __sync_bool_compare_and_swap(vp16, v16, v16); }
    181         { _Bool ret; ret = __sync_bool_compare_and_swap_16(vp16, v16,v16); }
     16        { char ret; ret = __sync_fetch_and_add(vpc, vc); }
     17        { short ret; ret = __sync_fetch_and_add(vps, vs); }
     18        { int ret; ret = __sync_fetch_and_add(vpi, vi); }
     19        { long int ret; ret = __sync_fetch_and_add(vpl, vl); }
     20        { long long int ret; ret = __sync_fetch_and_add(vpll, vll); }
     21        #if defined(__SIZEOF_INT128__)
     22        { __int128 ret; ret = __sync_fetch_and_add(vplll, vlll); }
     23        #endif
     24
     25        { char ret; ret = __sync_fetch_and_sub(vpc, vc); }
     26        { short ret; ret = __sync_fetch_and_sub(vps, vs); }
     27        { int ret; ret = __sync_fetch_and_sub(vpi, vi); }
     28        { long int ret; ret = __sync_fetch_and_sub(vpl, vl); }
     29        { long long int ret; ret = __sync_fetch_and_sub(vpll, vll); }
     30        #if defined(__SIZEOF_INT128__)
     31        { __int128 ret; ret = __sync_fetch_and_sub(vplll, vlll); }
     32        #endif
     33
     34        { char ret; ret = __sync_fetch_and_or(vpc, vc); }
     35        { short ret; ret = __sync_fetch_and_or(vps, vs); }
     36        { int ret; ret = __sync_fetch_and_or(vpi, vi); }
     37        { long int ret; ret = __sync_fetch_and_or(vpl, vl); }
     38        { long long int ret; ret = __sync_fetch_and_or(vpll, vll); }
     39        #if defined(__SIZEOF_INT128__)
     40        { __int128 ret; ret = __sync_fetch_and_or(vplll, vlll); }
     41        #endif
     42
     43        { char ret; ret = __sync_fetch_and_and(vpc, vc); }
     44        { short ret; ret = __sync_fetch_and_and(vps, vs); }
     45        { int ret; ret = __sync_fetch_and_and(vpi, vi); }
     46        { long int ret; ret = __sync_fetch_and_and(vpl, vl); }
     47        { long long int ret; ret = __sync_fetch_and_and(vpll, vll); }
     48        #if defined(__SIZEOF_INT128__)
     49        { __int128 ret; ret = __sync_fetch_and_and(vplll, vlll); }
     50        #endif
     51
     52        { char ret; ret = __sync_fetch_and_xor(vpc, vc); }
     53        { short ret; ret = __sync_fetch_and_xor(vps, vs); }
     54        { int ret; ret = __sync_fetch_and_xor(vpi, vi); }
     55        { long int ret; ret = __sync_fetch_and_xor(vpl, vl); }
     56        { long long int ret; ret = __sync_fetch_and_xor(vpll, vll); }
     57        #if defined(__SIZEOF_INT128__)
     58        { __int128 ret; ret = __sync_fetch_and_xor(vplll, vlll); }
     59        #endif
     60
     61        { char ret; ret = __sync_fetch_and_nand(vpc, vc); }
     62        { short ret; ret = __sync_fetch_and_nand(vps, vs); }
     63        { int ret; ret = __sync_fetch_and_nand(vpi, vi); }
     64        { long int ret; ret = __sync_fetch_and_nand(vpl, vl); }
     65        { long long int ret; ret = __sync_fetch_and_nand(vpll, vll); }
     66        #if defined(__SIZEOF_INT128__)
     67        { __int128 ret; ret = __sync_fetch_and_nand(vplll, vlll); }
     68        { __int128 ret; ret = __sync_fetch_and_nand_16(vplll, vlll); }
     69        #endif
     70
     71        { char ret; ret = __sync_add_and_fetch(vpc, vc); }
     72        { short ret; ret = __sync_add_and_fetch(vps, vs); }
     73        { int ret; ret = __sync_add_and_fetch(vpi, vi); }
     74        { long int ret; ret = __sync_add_and_fetch(vpl, vl); }
     75        { long long int ret; ret = __sync_add_and_fetch(vpll, vll); }
     76        #if defined(__SIZEOF_INT128__)
     77        { __int128 ret; ret = __sync_add_and_fetch(vplll, vlll); }
     78        #endif
     79
     80        { char ret; ret = __sync_sub_and_fetch(vpc, vc); }
     81        { short ret; ret = __sync_sub_and_fetch(vps, vs); }
     82        { int ret; ret = __sync_sub_and_fetch(vpi, vi); }
     83        { long int ret; ret = __sync_sub_and_fetch(vpl, vl); }
     84        { long long int ret; ret = __sync_sub_and_fetch(vpll, vll); }
     85        #if defined(__SIZEOF_INT128__)
     86        { __int128 ret; ret = __sync_sub_and_fetch(vplll, vlll); }
     87        #endif
     88
     89        { char ret; ret = __sync_or_and_fetch(vpc, vc); }
     90        { short ret; ret = __sync_or_and_fetch(vps, vs); }
     91        { int ret; ret = __sync_or_and_fetch(vpi, vi); }
     92        { long int ret; ret = __sync_or_and_fetch(vpl, vl); }
     93        { long long int ret; ret = __sync_or_and_fetch(vpll, vll); }
     94        #if defined(__SIZEOF_INT128__)
     95        { __int128 ret; ret = __sync_or_and_fetch(vplll, vlll); }
     96        #endif
     97
     98        { char ret; ret = __sync_and_and_fetch(vpc, vc); }
     99        { short ret; ret = __sync_and_and_fetch(vps, vs); }
     100        { int ret; ret = __sync_and_and_fetch(vpi, vi); }
     101        { long int ret; ret = __sync_and_and_fetch(vpl, vl); }
     102        { long long int ret; ret = __sync_and_and_fetch(vpll, vll); }
     103        #if defined(__SIZEOF_INT128__)
     104        { __int128 ret; ret = __sync_and_and_fetch(vplll, vlll); }
     105        #endif
     106
     107        { char ret; ret = __sync_xor_and_fetch(vpc, vc); }
     108        { short ret; ret = __sync_xor_and_fetch(vps, vs); }
     109        { int ret; ret = __sync_xor_and_fetch(vpi, vi); }
     110        { long int ret; ret = __sync_xor_and_fetch(vpl, vl); }
     111        { long long int ret; ret = __sync_xor_and_fetch(vpll, vll); }
     112        #if defined(__SIZEOF_INT128__)
     113        { __int128 ret; ret = __sync_xor_and_fetch(vplll, vlll); }
     114        #endif
     115
     116        { char ret; ret = __sync_nand_and_fetch(vpc, vc); }
     117        { short ret; ret = __sync_nand_and_fetch(vps, vs); }
     118        { int ret; ret = __sync_nand_and_fetch(vpi, vi); }
     119        { long int ret; ret = __sync_nand_and_fetch(vpl, vl); }
     120        { long long int ret; ret = __sync_nand_and_fetch(vpll, vll); }
     121        #if defined(__SIZEOF_INT128__)
     122        { __int128 ret; ret = __sync_nand_and_fetch(vplll, vlll); }
     123        #endif
     124
     125        { _Bool ret; ret = __sync_bool_compare_and_swap(vpc, vc, vc); }
     126        { _Bool ret; ret = __sync_bool_compare_and_swap(vps, vs, vs); }
     127        { _Bool ret; ret = __sync_bool_compare_and_swap(vpi, vi, vi); }
     128        { _Bool ret; ret = __sync_bool_compare_and_swap(vpl, vl, vl); }
     129        { _Bool ret; ret = __sync_bool_compare_and_swap(vpll, vll, vll); }
     130        #if defined(__SIZEOF_INT128__)
     131        { _Bool ret; ret = __sync_bool_compare_and_swap(vplll, vlll, vlll); }
    182132        #endif
    183133        { _Bool ret; ret = __sync_bool_compare_and_swap(vpp, vp, vp); }
    184134
    185         { char ret; ret = __sync_val_compare_and_swap(vp1, v1, v1); }
    186         { char ret; ret = __sync_val_compare_and_swap_1(vp1, v1, v1); }
    187         { short ret; ret = __sync_val_compare_and_swap(vp2, v2, v2); }
    188         { short ret; ret = __sync_val_compare_and_swap_2(vp2, v2, v2); }
    189         { int ret; ret = __sync_val_compare_and_swap(vp4, v4, v4); }
    190         { int ret; ret = __sync_val_compare_and_swap_4(vp4, v4, v4); }
    191         { long long int ret; ret = __sync_val_compare_and_swap(vp8, v8, v8); }
    192         { long long int ret; ret = __sync_val_compare_and_swap_8(vp8, v8, v8); }
    193         #if defined(__SIZEOF_INT128__)
    194         { __int128 ret; ret = __sync_val_compare_and_swap(vp16, v16, v16); }
    195         { __int128 ret; ret = __sync_val_compare_and_swap_16(vp16, v16,v16); }
     135        { char ret; ret = __sync_val_compare_and_swap(vpc, vc, vc); }
     136        { short ret; ret = __sync_val_compare_and_swap(vps, vs, vs); }
     137        { int ret; ret = __sync_val_compare_and_swap(vpi, vi, vi); }
     138        { long int ret; ret = __sync_val_compare_and_swap(vpl, vl, vl); }
     139        { long long int ret; ret = __sync_val_compare_and_swap(vpll, vll, vll); }
     140        #if defined(__SIZEOF_INT128__)
     141        { __int128 ret; ret = __sync_val_compare_and_swap(vplll, vlll, vlll); }
    196142        #endif
    197143        { struct type * ret; ret = __sync_val_compare_and_swap(vpp, vp, vp); }
    198144
    199145
    200         { char ret; ret = __sync_lock_test_and_set(vp1, v1); }
    201         { char ret; ret = __sync_lock_test_and_set_1(vp1, v1); }
    202         { short ret; ret = __sync_lock_test_and_set(vp2, v2); }
    203         { short ret; ret = __sync_lock_test_and_set_2(vp2, v2); }
    204         { int ret; ret = __sync_lock_test_and_set(vp4, v4); }
    205         { int ret; ret = __sync_lock_test_and_set_4(vp4, v4); }
    206         { long long int ret; ret = __sync_lock_test_and_set(vp8, v8); }
    207         { long long int ret; ret = __sync_lock_test_and_set_8(vp8, v8); }
    208         #if defined(__SIZEOF_INT128__)
    209         { __int128 ret; ret = __sync_lock_test_and_set(vp16, v16); }
    210         { __int128 ret; ret = __sync_lock_test_and_set_16(vp16, v16); }
    211         #endif
    212 
    213         { __sync_lock_release(vp1); }
    214         { __sync_lock_release_1(vp1); }
    215         { __sync_lock_release(vp2); }
    216         { __sync_lock_release_2(vp2); }
    217         { __sync_lock_release(vp4); }
    218         { __sync_lock_release_4(vp4); }
    219         { __sync_lock_release(vp8); }
    220         { __sync_lock_release_8(vp8); }
    221         #if defined(__SIZEOF_INT128__)
    222         { __sync_lock_release(vp16); }
    223         { __sync_lock_release_16(vp16); }
     146        { char ret; ret = __sync_lock_test_and_set(vpc, vc); }
     147        { short ret; ret = __sync_lock_test_and_set(vps, vs); }
     148        { int ret; ret = __sync_lock_test_and_set(vpi, vi); }
     149        { long int ret; ret = __sync_lock_test_and_set(vpl, vl); }
     150        { long long int ret; ret = __sync_lock_test_and_set(vpll, vll); }
     151        #if defined(__SIZEOF_INT128__)
     152        { __int128 ret; ret = __sync_lock_test_and_set(vplll, vlll); }
     153        #endif
     154
     155        { __sync_lock_release(vpc); }
     156        { __sync_lock_release(vps); }
     157        { __sync_lock_release(vpi); }
     158        { __sync_lock_release(vpl); }
     159        { __sync_lock_release(vpll); }
     160        #if defined(__SIZEOF_INT128__)
     161        { __sync_lock_release(vplll); }
    224162        #endif
    225163
     
    230168
    231169        { _Bool ret; ret = __atomic_test_and_set(vpB, vB); }
    232         { _Bool ret; ret = __atomic_test_and_set(vp1, v1); }
     170        { _Bool ret; ret = __atomic_test_and_set(vpc, vc); }
    233171        { __atomic_clear(vpB, vB); }
    234         { __atomic_clear(vp1, v1); }
    235 
    236         { char ret; ret = __atomic_exchange_n(vp1, v1, __ATOMIC_SEQ_CST); }
    237         { char ret; ret = __atomic_exchange_1(vp1, v1, __ATOMIC_SEQ_CST); }
    238         { char ret; __atomic_exchange(vp1, &v1, &ret, __ATOMIC_SEQ_CST); }
    239         { short ret; ret = __atomic_exchange_n(vp2, v2, __ATOMIC_SEQ_CST); }
    240         { short ret; ret = __atomic_exchange_2(vp2, v2, __ATOMIC_SEQ_CST); }
    241         { short ret; __atomic_exchange(vp2, &v2, &ret, __ATOMIC_SEQ_CST); }
    242         { int ret; ret = __atomic_exchange_n(vp4, v4, __ATOMIC_SEQ_CST); }
    243         { int ret; ret = __atomic_exchange_4(vp4, v4, __ATOMIC_SEQ_CST); }
    244         { int ret; __atomic_exchange(vp4, &v4, &ret, __ATOMIC_SEQ_CST); }
    245         { long long int ret; ret = __atomic_exchange_n(vp8, v8, __ATOMIC_SEQ_CST); }
    246         { long long int ret; ret = __atomic_exchange_8(vp8, v8, __ATOMIC_SEQ_CST); }
    247         { long long int ret; __atomic_exchange(vp8, &v8, &ret, __ATOMIC_SEQ_CST); }
    248         #if defined(__SIZEOF_INT128__)
    249         { __int128 ret; ret = __atomic_exchange_n(vp16, v16, __ATOMIC_SEQ_CST); }
    250         { __int128 ret; ret = __atomic_exchange_16(vp16, v16, __ATOMIC_SEQ_CST); }
    251         { __int128 ret; __atomic_exchange(vp16, &v16, &ret, __ATOMIC_SEQ_CST); }
     172        { __atomic_clear(vpc, vc); }
     173
     174        { char ret; ret = __atomic_exchange_n(vpc, vc, __ATOMIC_SEQ_CST); }
     175        { char ret; __atomic_exchange(vpc, &vc, &ret, __ATOMIC_SEQ_CST); }
     176        { short ret; ret = __atomic_exchange_n(vps, vs, __ATOMIC_SEQ_CST); }
     177        { short ret; __atomic_exchange(vps, &vs, &ret, __ATOMIC_SEQ_CST); }
     178        { int ret; ret = __atomic_exchange_n(vpi, vi, __ATOMIC_SEQ_CST); }
     179        { int ret; __atomic_exchange(vpi, &vi, &ret, __ATOMIC_SEQ_CST); }
     180        { long int ret; ret = __atomic_exchange_n(vpl, vl, __ATOMIC_SEQ_CST); }
     181        { long int ret; __atomic_exchange(vpl, &vl, &ret, __ATOMIC_SEQ_CST); }
     182        { long long int ret; ret = __atomic_exchange_n(vpll, vll, __ATOMIC_SEQ_CST); }
     183        { long long int ret; __atomic_exchange(vpll, &vll, &ret, __ATOMIC_SEQ_CST); }
     184        #if defined(__SIZEOF_INT128__)
     185        { __int128 ret; ret = __atomic_exchange_n(vplll, vlll, __ATOMIC_SEQ_CST); }
     186        { __int128 ret; __atomic_exchange(vplll, &vlll, &ret, __ATOMIC_SEQ_CST); }
    252187        #endif
    253188        { struct type * ret; ret = __atomic_exchange_n(vpp, vp, __ATOMIC_SEQ_CST); }
    254189        { struct type * ret; __atomic_exchange(vpp, &vp, &ret, __ATOMIC_SEQ_CST); }
    255190
    256         { char ret; ret = __atomic_load_n(vp1, __ATOMIC_SEQ_CST); }
    257         { char ret; ret = __atomic_load_1(vp1, __ATOMIC_SEQ_CST); }
    258         { char ret; __atomic_load(vp1, &ret, __ATOMIC_SEQ_CST); }
    259         { short ret; ret = __atomic_load_n(vp2, __ATOMIC_SEQ_CST); }
    260         { short ret; ret = __atomic_load_2(vp2, __ATOMIC_SEQ_CST); }
    261         { short ret; __atomic_load(vp2, &ret, __ATOMIC_SEQ_CST); }
    262         { int ret; ret = __atomic_load_n(vp4, __ATOMIC_SEQ_CST); }
    263         { int ret; ret = __atomic_load_4(vp4, __ATOMIC_SEQ_CST); }
    264         { int ret; __atomic_load(vp4, &ret, __ATOMIC_SEQ_CST); }
    265         { long long int ret; ret = __atomic_load_n(vp8, __ATOMIC_SEQ_CST); }
    266         { long long int ret; ret = __atomic_load_8(vp8, __ATOMIC_SEQ_CST); }
    267         { long long int ret; __atomic_load(vp8, &ret, __ATOMIC_SEQ_CST); }
    268         #if defined(__SIZEOF_INT128__)
    269         { __int128 ret; ret = __atomic_load_n(vp16, __ATOMIC_SEQ_CST); }
    270         { __int128 ret; ret = __atomic_load_16(vp16, __ATOMIC_SEQ_CST); }
    271         { __int128 ret; __atomic_load(vp16, &ret, __ATOMIC_SEQ_CST); }
     191        { char ret; ret = __atomic_load_n(vpc, __ATOMIC_SEQ_CST); }
     192        { char ret; __atomic_load(vpc, &ret, __ATOMIC_SEQ_CST); }
     193        { short ret; ret = __atomic_load_n(vps, __ATOMIC_SEQ_CST); }
     194        { short ret; __atomic_load(vps, &ret, __ATOMIC_SEQ_CST); }
     195        { int ret; ret = __atomic_load_n(vpi, __ATOMIC_SEQ_CST); }
     196        { int ret; __atomic_load(vpi, &ret, __ATOMIC_SEQ_CST); }
     197        { long int ret; ret = __atomic_load_n(vpl, __ATOMIC_SEQ_CST); }
     198        { long int ret; __atomic_load(vpl, &ret, __ATOMIC_SEQ_CST); }
     199        { long long int ret; ret = __atomic_load_n(vpll, __ATOMIC_SEQ_CST); }
     200        { long long int ret; __atomic_load(vpll, &ret, __ATOMIC_SEQ_CST); }
     201        #if defined(__SIZEOF_INT128__)
     202        { __int128 ret; ret = __atomic_load_n(vplll, __ATOMIC_SEQ_CST); }
     203        { __int128 ret; __atomic_load(vplll, &ret, __ATOMIC_SEQ_CST); }
    272204        #endif
    273205        { struct type * ret; ret = __atomic_load_n(vpp, __ATOMIC_SEQ_CST); }
    274206        { struct type * ret; __atomic_load(vpp, &ret, __ATOMIC_SEQ_CST); }
    275207
    276         { _Bool ret; ret = __atomic_compare_exchange_n(vp1, rp1, v1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    277         { _Bool ret; ret = __atomic_compare_exchange_1(vp1, rp1, v1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    278         { _Bool ret; ret = __atomic_compare_exchange(vp1, rp1, &v1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    279         { _Bool ret; ret = __atomic_compare_exchange_n(vp2, rp2, v2, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    280         { _Bool ret; ret = __atomic_compare_exchange_2(vp2, rp2, v2, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    281         { _Bool ret; ret = __atomic_compare_exchange(vp2, rp2, &v2, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    282         { _Bool ret; ret = __atomic_compare_exchange_n(vp4, rp4, v4, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    283         { _Bool ret; ret = __atomic_compare_exchange_4(vp4, rp4, v4, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    284         { _Bool ret; ret = __atomic_compare_exchange(vp4, rp4, &v4, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    285         { _Bool ret; ret = __atomic_compare_exchange_n(vp8, rp8, v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    286         { _Bool ret; ret = __atomic_compare_exchange_8(vp8, rp8, v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    287         { _Bool ret; ret = __atomic_compare_exchange(vp8, rp8, &v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    288         #if defined(__SIZEOF_INT128__)
    289         { _Bool ret; ret = __atomic_compare_exchange_n(vp16, rp16, v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    290         { _Bool ret; ret = __atomic_compare_exchange_16(vp16, rp16, v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    291         { _Bool ret; ret = __atomic_compare_exchange(vp16, rp16, &v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     208        { _Bool ret; ret = __atomic_compare_exchange_n(vpc, rpc, vc, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     209        { _Bool ret; ret = __atomic_compare_exchange(vpc, rpc, &vc, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     210        { _Bool ret; ret = __atomic_compare_exchange_n(vps, rps, vs, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     211        { _Bool ret; ret = __atomic_compare_exchange(vps, rps, &vs, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     212        { _Bool ret; ret = __atomic_compare_exchange_n(vpi, rpi, vi, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     213        { _Bool ret; ret = __atomic_compare_exchange(vpi, rpi, &vi, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     214        { _Bool ret; ret = __atomic_compare_exchange_n(vpl, rpl, vl, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     215        { _Bool ret; ret = __atomic_compare_exchange(vpl, rpl, &vl, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     216        { _Bool ret; ret = __atomic_compare_exchange_n(vpll, rpll, vll, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     217        { _Bool ret; ret = __atomic_compare_exchange(vpll, rpll, &vll, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     218        #if defined(__SIZEOF_INT128__)
     219        { _Bool ret; ret = __atomic_compare_exchange_n(vplll, rplll, vlll, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     220        { _Bool ret; ret = __atomic_compare_exchange(vplll, rplll, &vlll, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    292221        #endif
    293222        { _Bool ret; ret = __atomic_compare_exchange_n(vpp, rpp, vp, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    294223        { _Bool ret; ret = __atomic_compare_exchange(vpp, rpp, &vp, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    295224
    296         { __atomic_store_n(vp1, v1, __ATOMIC_SEQ_CST); }
    297         { __atomic_store_1(vp1, v1, __ATOMIC_SEQ_CST); }
    298         { __atomic_store(vp1, &v1, __ATOMIC_SEQ_CST); }
    299         { __atomic_store_n(vp2, v2, __ATOMIC_SEQ_CST); }
    300         { __atomic_store_2(vp2, v2, __ATOMIC_SEQ_CST); }
    301         { __atomic_store(vp2, &v2, __ATOMIC_SEQ_CST); }
    302         { __atomic_store_n(vp4, v4, __ATOMIC_SEQ_CST); }
    303         { __atomic_store_4(vp4, v4, __ATOMIC_SEQ_CST); }
    304         { __atomic_store(vp4, &v4, __ATOMIC_SEQ_CST); }
    305         { __atomic_store_n(vp8, v8, __ATOMIC_SEQ_CST); }
    306         { __atomic_store_8(vp8, v8, __ATOMIC_SEQ_CST); }
    307         { __atomic_store(vp8, &v8, __ATOMIC_SEQ_CST); }
    308         #if defined(__SIZEOF_INT128__)
    309         { __atomic_store_n(vp16, v16, __ATOMIC_SEQ_CST); }
    310         { __atomic_store_16(vp16, v16, __ATOMIC_SEQ_CST); }
    311         { __atomic_store(vp16, &v16, __ATOMIC_SEQ_CST); }
     225        { __atomic_store_n(vpc, vc, __ATOMIC_SEQ_CST); }
     226        { __atomic_store(vpc, &vc, __ATOMIC_SEQ_CST); }
     227        { __atomic_store_n(vps, vs, __ATOMIC_SEQ_CST); }
     228        { __atomic_store(vps, &vs, __ATOMIC_SEQ_CST); }
     229        { __atomic_store_n(vpi, vi, __ATOMIC_SEQ_CST); }
     230        { __atomic_store(vpi, &vi, __ATOMIC_SEQ_CST); }
     231        { __atomic_store_n(vpl, vl, __ATOMIC_SEQ_CST); }
     232        { __atomic_store(vpl, &vl, __ATOMIC_SEQ_CST); }
     233        { __atomic_store_n(vpll, vll, __ATOMIC_SEQ_CST); }
     234        { __atomic_store(vpll, &vll, __ATOMIC_SEQ_CST); }
     235        #if defined(__SIZEOF_INT128__)
     236        { __atomic_store_n(vplll, vlll, __ATOMIC_SEQ_CST); }
     237        { __atomic_store(vplll, &vlll, __ATOMIC_SEQ_CST); }
    312238        #endif
    313239        { __atomic_store_n(vpp, vp, __ATOMIC_SEQ_CST); }
    314240        { __atomic_store(vpp, &vp, __ATOMIC_SEQ_CST); }
    315241
    316         { char ret; ret = __atomic_add_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
    317         { char ret; ret = __atomic_add_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
    318         { short ret; ret = __atomic_add_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
    319         { short ret; ret = __atomic_add_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
    320         { int ret; ret = __atomic_add_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
    321         { int ret; ret = __atomic_add_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
    322         { long long int ret; ret = __atomic_add_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    323         { long long int ret; ret = __atomic_add_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
    324         #if defined(__SIZEOF_INT128__)
    325         { __int128 ret; ret = __atomic_add_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    326         { __int128 ret; ret = __atomic_add_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
    327         #endif
    328 
    329         { char ret; ret = __atomic_sub_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
    330         { char ret; ret = __atomic_sub_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
    331         { short ret; ret = __atomic_sub_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
    332         { short ret; ret = __atomic_sub_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
    333         { int ret; ret = __atomic_sub_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
    334         { int ret; ret = __atomic_sub_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
    335         { long long int ret; ret = __atomic_sub_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    336         { long long int ret; ret = __atomic_sub_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
    337         #if defined(__SIZEOF_INT128__)
    338         { __int128 ret; ret = __atomic_sub_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    339         { __int128 ret; ret = __atomic_sub_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
    340         #endif
    341 
    342         { char ret; ret = __atomic_and_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
    343         { char ret; ret = __atomic_and_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
    344         { short ret; ret = __atomic_and_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
    345         { short ret; ret = __atomic_and_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
    346         { int ret; ret = __atomic_and_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
    347         { int ret; ret = __atomic_and_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
    348         { long long int ret; ret = __atomic_and_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    349         { long long int ret; ret = __atomic_and_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
    350         #if defined(__SIZEOF_INT128__)
    351         { __int128 ret; ret = __atomic_and_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    352         { __int128 ret; ret = __atomic_and_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
    353         #endif
    354 
    355         { char ret; ret = __atomic_nand_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
    356         { char ret; ret = __atomic_nand_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
    357         { short ret; ret = __atomic_nand_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
    358         { short ret; ret = __atomic_nand_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
    359         { int ret; ret = __atomic_nand_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
    360         { int ret; ret = __atomic_nand_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
    361         { long long int ret; ret = __atomic_nand_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    362         { long long int ret; ret = __atomic_nand_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
    363         #if defined(__SIZEOF_INT128__)
    364         { __int128 ret; ret = __atomic_nand_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    365         { __int128 ret; ret = __atomic_nand_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
    366         #endif
    367 
    368         { char ret; ret = __atomic_xor_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
    369         { char ret; ret = __atomic_xor_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
    370         { short ret; ret = __atomic_xor_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
    371         { short ret; ret = __atomic_xor_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
    372         { int ret; ret = __atomic_xor_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
    373         { int ret; ret = __atomic_xor_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
    374         { long long int ret; ret = __atomic_xor_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    375         { long long int ret; ret = __atomic_xor_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
    376         #if defined(__SIZEOF_INT128__)
    377         { __int128 ret; ret = __atomic_xor_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    378         { __int128 ret; ret = __atomic_xor_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
    379         #endif
    380 
    381         { char ret; ret = __atomic_or_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
    382         { char ret; ret = __atomic_or_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
    383         { short ret; ret = __atomic_or_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
    384         { short ret; ret = __atomic_or_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
    385         { int ret; ret = __atomic_or_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
    386         { int ret; ret = __atomic_or_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
    387         { long long int ret; ret = __atomic_or_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    388         { long long int ret; ret = __atomic_or_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
    389         #if defined(__SIZEOF_INT128__)
    390         { __int128 ret; ret = __atomic_or_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    391         { __int128 ret; ret = __atomic_or_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
    392         #endif
    393 
    394         { char ret; ret = __atomic_fetch_add(vp1, v1, __ATOMIC_SEQ_CST); }
    395         { char ret; ret = __atomic_fetch_add_1(vp1, v1, __ATOMIC_SEQ_CST); }
    396         { short ret; ret = __atomic_fetch_add(vp2, v2, __ATOMIC_SEQ_CST); }
    397         { short ret; ret = __atomic_fetch_add_2(vp2, v2, __ATOMIC_SEQ_CST); }
    398         { int ret; ret = __atomic_fetch_add(vp4, v4, __ATOMIC_SEQ_CST); }
    399         { int ret; ret = __atomic_fetch_add_4(vp4, v4, __ATOMIC_SEQ_CST); }
    400         { long long int ret; ret = __atomic_fetch_add(vp8, v8, __ATOMIC_SEQ_CST); }
    401         { long long int ret; ret = __atomic_fetch_add_8(vp8, v8, __ATOMIC_SEQ_CST); }
    402         #if defined(__SIZEOF_INT128__)
    403         { __int128 ret; ret = __atomic_fetch_add(vp16, v16, __ATOMIC_SEQ_CST); }
    404         { __int128 ret; ret = __atomic_fetch_add_16(vp16, v16, __ATOMIC_SEQ_CST); }
    405         #endif
    406 
    407         { char ret; ret = __atomic_fetch_sub(vp1, v1, __ATOMIC_SEQ_CST); }
    408         { char ret; ret = __atomic_fetch_sub_1(vp1, v1, __ATOMIC_SEQ_CST); }
    409         { short ret; ret = __atomic_fetch_sub(vp2, v2, __ATOMIC_SEQ_CST); }
    410         { short ret; ret = __atomic_fetch_sub_2(vp2, v2, __ATOMIC_SEQ_CST); }
    411         { int ret; ret = __atomic_fetch_sub(vp4, v4, __ATOMIC_SEQ_CST); }
    412         { int ret; ret = __atomic_fetch_sub_4(vp4, v4, __ATOMIC_SEQ_CST); }
    413         { long long int ret; ret = __atomic_fetch_sub(vp8, v8, __ATOMIC_SEQ_CST); }
    414         { long long int ret; ret = __atomic_fetch_sub_8(vp8, v8, __ATOMIC_SEQ_CST); }
    415         #if defined(__SIZEOF_INT128__)
    416         { __int128 ret; ret = __atomic_fetch_sub(vp16, v16, __ATOMIC_SEQ_CST); }
    417         { __int128 ret; ret = __atomic_fetch_sub_16(vp16, v16, __ATOMIC_SEQ_CST); }
    418         #endif
    419 
    420         { char ret; ret = __atomic_fetch_and(vp1, v1, __ATOMIC_SEQ_CST); }
    421         { char ret; ret = __atomic_fetch_and_1(vp1, v1, __ATOMIC_SEQ_CST); }
    422         { short ret; ret = __atomic_fetch_and(vp2, v2, __ATOMIC_SEQ_CST); }
    423         { short ret; ret = __atomic_fetch_and_2(vp2, v2, __ATOMIC_SEQ_CST); }
    424         { int ret; ret = __atomic_fetch_and(vp4, v4, __ATOMIC_SEQ_CST); }
    425         { int ret; ret = __atomic_fetch_and_4(vp4, v4, __ATOMIC_SEQ_CST); }
    426         { long long int ret; ret = __atomic_fetch_and(vp8, v8, __ATOMIC_SEQ_CST); }
    427         { long long int ret; ret = __atomic_fetch_and_8(vp8, v8, __ATOMIC_SEQ_CST); }
    428         #if defined(__SIZEOF_INT128__)
    429         { __int128 ret; ret = __atomic_fetch_and(vp16, v16, __ATOMIC_SEQ_CST); }
    430         { __int128 ret; ret = __atomic_fetch_and_16(vp16, v16, __ATOMIC_SEQ_CST); }
    431         #endif
    432 
    433         { char ret; ret = __atomic_fetch_nand(vp1, v1, __ATOMIC_SEQ_CST); }
    434         { char ret; ret = __atomic_fetch_nand_1(vp1, v1, __ATOMIC_SEQ_CST); }
    435         { short ret; ret = __atomic_fetch_nand(vp2, v2, __ATOMIC_SEQ_CST); }
    436         { short ret; ret = __atomic_fetch_nand_2(vp2, v2, __ATOMIC_SEQ_CST); }
    437         { int ret; ret = __atomic_fetch_nand(vp4, v4, __ATOMIC_SEQ_CST); }
    438         { int ret; ret = __atomic_fetch_nand_4(vp4, v4, __ATOMIC_SEQ_CST); }
    439         { long long int ret; ret = __atomic_fetch_nand(vp8, v8, __ATOMIC_SEQ_CST); }
    440         { long long int ret; ret = __atomic_fetch_nand_8(vp8, v8, __ATOMIC_SEQ_CST); }
    441         #if defined(__SIZEOF_INT128__)
    442         { __int128 ret; ret = __atomic_fetch_nand(vp16, v16, __ATOMIC_SEQ_CST); }
    443         { __int128 ret; ret = __atomic_fetch_nand_16(vp16, v16, __ATOMIC_SEQ_CST); }
    444         #endif
    445 
    446         { char ret; ret = __atomic_fetch_xor(vp1, v1, __ATOMIC_SEQ_CST); }
    447         { char ret; ret = __atomic_fetch_xor_1(vp1, v1, __ATOMIC_SEQ_CST); }
    448         { short ret; ret = __atomic_fetch_xor(vp2, v2, __ATOMIC_SEQ_CST); }
    449         { short ret; ret = __atomic_fetch_xor_2(vp2, v2, __ATOMIC_SEQ_CST); }
    450         { int ret; ret = __atomic_fetch_xor(vp4, v4, __ATOMIC_SEQ_CST); }
    451         { int ret; ret = __atomic_fetch_xor_4(vp4, v4, __ATOMIC_SEQ_CST); }
    452         { long long int ret; ret = __atomic_fetch_xor(vp8, v8, __ATOMIC_SEQ_CST); }
    453         { long long int ret; ret = __atomic_fetch_xor_8(vp8, v8, __ATOMIC_SEQ_CST); }
    454         #if defined(__SIZEOF_INT128__)
    455         { __int128 ret; ret = __atomic_fetch_xor(vp16, v16, __ATOMIC_SEQ_CST); }
    456         { __int128 ret; ret = __atomic_fetch_xor_16(vp16, v16, __ATOMIC_SEQ_CST); }
    457         #endif
    458 
    459         { char ret; ret = __atomic_fetch_or(vp1, v1, __ATOMIC_SEQ_CST); }
    460         { char ret; ret = __atomic_fetch_or_1(vp1, v1, __ATOMIC_SEQ_CST); }
    461         { short ret; ret = __atomic_fetch_or(vp2, v2, __ATOMIC_SEQ_CST); }
    462         { short ret; ret = __atomic_fetch_or_2(vp2, v2, __ATOMIC_SEQ_CST); }
    463         { int ret; ret = __atomic_fetch_or(vp4, v4, __ATOMIC_SEQ_CST); }
    464         { int ret; ret = __atomic_fetch_or_4(vp4, v4, __ATOMIC_SEQ_CST); }
    465         { long long int ret; ret = __atomic_fetch_or(vp8, v8, __ATOMIC_SEQ_CST); }
    466         { long long int ret; ret = __atomic_fetch_or_8(vp8, v8, __ATOMIC_SEQ_CST); }
    467         #if defined(__SIZEOF_INT128__)
    468         { __int128 ret; ret = __atomic_fetch_or(vp16, v16, __ATOMIC_SEQ_CST); }
    469         { __int128 ret; ret = __atomic_fetch_or_16(vp16, v16, __ATOMIC_SEQ_CST); }
    470         #endif
    471 
    472         { _Bool ret; ret = __atomic_always_lock_free(sizeof(int), vp4); }
    473         { _Bool ret; ret = __atomic_is_lock_free(sizeof(int), vp4); }
     242        { char ret; ret = __atomic_add_fetch(vpc, vc, __ATOMIC_SEQ_CST); }
     243        { short ret; ret = __atomic_add_fetch(vps, vs, __ATOMIC_SEQ_CST); }
     244        { int ret; ret = __atomic_add_fetch(vpi, vi, __ATOMIC_SEQ_CST); }
     245        { long int ret; ret = __atomic_add_fetch(vpl, vl, __ATOMIC_SEQ_CST); }
     246        { long long int ret; ret = __atomic_add_fetch(vpll, vll, __ATOMIC_SEQ_CST); }
     247        #if defined(__SIZEOF_INT128__)
     248        { __int128 ret; ret = __atomic_add_fetch(vplll, vlll, __ATOMIC_SEQ_CST); }
     249        #endif
     250
     251        { char ret; ret = __atomic_sub_fetch(vpc, vc, __ATOMIC_SEQ_CST); }
     252        { short ret; ret = __atomic_sub_fetch(vps, vs, __ATOMIC_SEQ_CST); }
     253        { int ret; ret = __atomic_sub_fetch(vpi, vi, __ATOMIC_SEQ_CST); }
     254        { long int ret; ret = __atomic_sub_fetch(vpl, vl, __ATOMIC_SEQ_CST); }
     255        { long long int ret; ret = __atomic_sub_fetch(vpll, vll, __ATOMIC_SEQ_CST); }
     256        #if defined(__SIZEOF_INT128__)
     257        { __int128 ret; ret = __atomic_sub_fetch(vplll, vlll, __ATOMIC_SEQ_CST); }
     258        #endif
     259
     260        { char ret; ret = __atomic_and_fetch(vpc, vc, __ATOMIC_SEQ_CST); }
     261        { short ret; ret = __atomic_and_fetch(vps, vs, __ATOMIC_SEQ_CST); }
     262        { int ret; ret = __atomic_and_fetch(vpi, vi, __ATOMIC_SEQ_CST); }
     263        { long int ret; ret = __atomic_and_fetch(vpl, vl, __ATOMIC_SEQ_CST); }
     264        { long long int ret; ret = __atomic_and_fetch(vpll, vll, __ATOMIC_SEQ_CST); }
     265        #if defined(__SIZEOF_INT128__)
     266        { __int128 ret; ret = __atomic_and_fetch(vplll, vlll, __ATOMIC_SEQ_CST); }
     267        #endif
     268
     269        { char ret; ret = __atomic_nand_fetch(vpc, vc, __ATOMIC_SEQ_CST); }
     270        { short ret; ret = __atomic_nand_fetch(vps, vs, __ATOMIC_SEQ_CST); }
     271        { int ret; ret = __atomic_nand_fetch(vpi, vi, __ATOMIC_SEQ_CST); }
     272        { long int ret; ret = __atomic_nand_fetch(vpl, vl, __ATOMIC_SEQ_CST); }
     273        { long long int ret; ret = __atomic_nand_fetch(vpll, vll, __ATOMIC_SEQ_CST); }
     274        #if defined(__SIZEOF_INT128__)
     275        { __int128 ret; ret = __atomic_nand_fetch(vplll, vlll, __ATOMIC_SEQ_CST); }
     276        #endif
     277
     278        { char ret; ret = __atomic_xor_fetch(vpc, vc, __ATOMIC_SEQ_CST); }
     279        { short ret; ret = __atomic_xor_fetch(vps, vs, __ATOMIC_SEQ_CST); }
     280        { int ret; ret = __atomic_xor_fetch(vpi, vi, __ATOMIC_SEQ_CST); }
     281        { long int ret; ret = __atomic_xor_fetch(vpl, vl, __ATOMIC_SEQ_CST); }
     282        { long long int ret; ret = __atomic_xor_fetch(vpll, vll, __ATOMIC_SEQ_CST); }
     283        #if defined(__SIZEOF_INT128__)
     284        { __int128 ret; ret = __atomic_xor_fetch(vplll, vlll, __ATOMIC_SEQ_CST); }
     285        #endif
     286
     287        { char ret; ret = __atomic_or_fetch(vpc, vc, __ATOMIC_SEQ_CST); }
     288        { short ret; ret = __atomic_or_fetch(vps, vs, __ATOMIC_SEQ_CST); }
     289        { int ret; ret = __atomic_or_fetch(vpi, vi, __ATOMIC_SEQ_CST); }
     290        { long int ret; ret = __atomic_or_fetch(vpl, vl, __ATOMIC_SEQ_CST); }
     291        { long long int ret; ret = __atomic_or_fetch(vpll, vll, __ATOMIC_SEQ_CST); }
     292        #if defined(__SIZEOF_INT128__)
     293        { __int128 ret; ret = __atomic_or_fetch(vplll, vlll, __ATOMIC_SEQ_CST); }
     294        #endif
     295
     296        { char ret; ret = __atomic_fetch_add(vpc, vc, __ATOMIC_SEQ_CST); }
     297        { short ret; ret = __atomic_fetch_add(vps, vs, __ATOMIC_SEQ_CST); }
     298        { int ret; ret = __atomic_fetch_add(vpi, vi, __ATOMIC_SEQ_CST); }
     299        { long int ret; ret = __atomic_fetch_add(vpl, vl, __ATOMIC_SEQ_CST); }
     300        { long long int ret; ret = __atomic_fetch_add(vpll, vll, __ATOMIC_SEQ_CST); }
     301        #if defined(__SIZEOF_INT128__)
     302        { __int128 ret; ret = __atomic_fetch_add(vplll, vlll, __ATOMIC_SEQ_CST); }
     303        #endif
     304
     305        { char ret; ret = __atomic_fetch_sub(vpc, vc, __ATOMIC_SEQ_CST); }
     306        { short ret; ret = __atomic_fetch_sub(vps, vs, __ATOMIC_SEQ_CST); }
     307        { int ret; ret = __atomic_fetch_sub(vpi, vi, __ATOMIC_SEQ_CST); }
     308        { long int ret; ret = __atomic_fetch_sub(vpl, vl, __ATOMIC_SEQ_CST); }
     309        { long long int ret; ret = __atomic_fetch_sub(vpll, vll, __ATOMIC_SEQ_CST); }
     310        #if defined(__SIZEOF_INT128__)
     311        { __int128 ret; ret = __atomic_fetch_sub(vplll, vlll, __ATOMIC_SEQ_CST); }
     312        #endif
     313
     314        { char ret; ret = __atomic_fetch_and(vpc, vc, __ATOMIC_SEQ_CST); }
     315        { short ret; ret = __atomic_fetch_and(vps, vs, __ATOMIC_SEQ_CST); }
     316        { int ret; ret = __atomic_fetch_and(vpi, vi, __ATOMIC_SEQ_CST); }
     317        { long int ret; ret = __atomic_fetch_and(vpl, vl, __ATOMIC_SEQ_CST); }
     318        { long long int ret; ret = __atomic_fetch_and(vpll, vll, __ATOMIC_SEQ_CST); }
     319        #if defined(__SIZEOF_INT128__)
     320        { __int128 ret; ret = __atomic_fetch_and(vplll, vlll, __ATOMIC_SEQ_CST); }
     321        #endif
     322
     323        { char ret; ret = __atomic_fetch_nand(vpc, vc, __ATOMIC_SEQ_CST); }
     324        { short ret; ret = __atomic_fetch_nand(vps, vs, __ATOMIC_SEQ_CST); }
     325        { int ret; ret = __atomic_fetch_nand(vpi, vi, __ATOMIC_SEQ_CST); }
     326        { long int ret; ret = __atomic_fetch_nand(vpl, vl, __ATOMIC_SEQ_CST); }
     327        { long long int ret; ret = __atomic_fetch_nand(vpll, vll, __ATOMIC_SEQ_CST); }
     328        #if defined(__SIZEOF_INT128__)
     329        { __int128 ret; ret = __atomic_fetch_nand(vplll, vlll, __ATOMIC_SEQ_CST); }
     330        #endif
     331
     332        { char ret; ret = __atomic_fetch_xor(vpc, vc, __ATOMIC_SEQ_CST); }
     333        { short ret; ret = __atomic_fetch_xor(vps, vs, __ATOMIC_SEQ_CST); }
     334        { int ret; ret = __atomic_fetch_xor(vpi, vi, __ATOMIC_SEQ_CST); }
     335        { long int ret; ret = __atomic_fetch_xor(vpl, vl, __ATOMIC_SEQ_CST); }
     336        { long long int ret; ret = __atomic_fetch_xor(vpll, vll, __ATOMIC_SEQ_CST); }
     337        #if defined(__SIZEOF_INT128__)
     338        { __int128 ret; ret = __atomic_fetch_xor(vplll, vlll, __ATOMIC_SEQ_CST); }
     339        #endif
     340
     341        { char ret; ret = __atomic_fetch_or(vpc, vc, __ATOMIC_SEQ_CST); }
     342        { short ret; ret = __atomic_fetch_or(vps, vs, __ATOMIC_SEQ_CST); }
     343        { int ret; ret = __atomic_fetch_or(vpi, vi, __ATOMIC_SEQ_CST); }
     344        { long int ret; ret = __atomic_fetch_or(vpl, vl, __ATOMIC_SEQ_CST); }
     345        { long long int ret; ret = __atomic_fetch_or(vpll, vll, __ATOMIC_SEQ_CST); }
     346        #if defined(__SIZEOF_INT128__)
     347        { __int128 ret; ret = __atomic_fetch_or(vplll, vlll, __ATOMIC_SEQ_CST); }
     348        #endif
     349
     350        { _Bool ret; ret = __atomic_always_lock_free(sizeof(int), vpi); }
     351        { _Bool ret; ret = __atomic_is_lock_free(sizeof(int), vpi); }
    474352        { __atomic_thread_fence(__ATOMIC_SEQ_CST); }
    475353        { __atomic_signal_fence(__ATOMIC_SEQ_CST); }
  • tests/concurrent/examples/.expect/datingService.txt

    r9fb8f01 r3d5701e  
    1 Girl:17 is dating Boy at 2 with ccode 17
    2  Boy:2 is dating Girl 17 with ccode 17
    3  Boy:14 is dating Girl 5 with ccode 5
    4 Girl:5 is dating Boy at 14 with ccode 5
    5  Boy:9 is dating Girl 10 with ccode 10
    6 Girl:10 is dating Boy at 9 with ccode 10
    7  Boy:1 is dating Girl 18 with ccode 18
    8 Girl:18 is dating Boy at 1 with ccode 18
    9  Boy:16 is dating Girl 3 with ccode 3
    10 Girl:3 is dating Boy at 16 with ccode 3
    11  Boy:5 is dating Girl 14 with ccode 14
    12 Girl:14 is dating Boy at 5 with ccode 14
    13  Boy:15 is dating Girl 4 with ccode 4
    14 Girl:4 is dating Boy at 15 with ccode 4
    15 Girl:0 is dating Boy at 19 with ccode 0
    16  Boy:19 is dating Girl 0 with ccode 0
    17 Girl:9 is dating Boy at 10 with ccode 9
    18  Boy:10 is dating Girl 9 with ccode 9
    19 Girl:11 is dating Boy at 8 with ccode 11
    20  Boy:8 is dating Girl 11 with ccode 11
    21  Boy:12 is dating Girl 7 with ccode 7
    22 Girl:7 is dating Boy at 12 with ccode 7
    23  Boy:11 is dating Girl 8 with ccode 8
    24 Girl:8 is dating Boy at 11 with ccode 8
    25 Girl:16 is dating Boy at 3 with ccode 16
    26  Boy:3 is dating Girl 16 with ccode 16
    27 Girl:15 is dating Boy at 4 with ccode 15
    28  Boy:4 is dating Girl 15 with ccode 15
    29 Girl:19 is dating Boy at 0 with ccode 19
    30  Boy:0 is dating Girl 19 with ccode 19
    31 Girl:2 is dating Boy at 17 with ccode 2
    32  Boy:17 is dating Girl 2 with ccode 2
    33  Boy:13 is dating Girl 6 with ccode 6
    34 Girl:6 is dating Boy at 13 with ccode 6
    35  Boy:7 is dating Girl 12 with ccode 12
    36 Girl:12 is dating Boy at 7 with ccode 12
    37 Girl:13 is dating Boy at 6 with ccode 13
    38  Boy:6 is dating Girl 13 with ccode 13
    39 Girl:1 is dating Boy at 18 with ccode 1
    40  Boy:18 is dating Girl 1 with ccode 1
  • tests/concurrent/examples/boundedBufferEXT.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Apr 18 22:52:12 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 08:19:20 2019
    13 // Update Count     : 14
     12// Last Modified On : Thu Jan 16 22:36:34 2020
     13// Update Count     : 15
    1414//
    1515
     
    3737
    3838        void insert( Buffer(T) & mutex buffer, T elem ) with( buffer ) {
    39                 if ( count == BufferSize ) waitfor( remove, buffer );
     39                if ( count == BufferSize ) waitfor( remove : buffer );
    4040                elements[back] = elem;
    4141                back = ( back + 1 ) % BufferSize;
     
    4444
    4545        T remove( Buffer(T) & mutex buffer ) with( buffer ) {
    46                 if ( count == 0 ) waitfor( insert, buffer );
     46                if ( count == 0 ) waitfor( insert : buffer );
    4747                T elem = elements[front];
    4848                front = ( front + 1 ) % BufferSize;
  • tests/concurrent/examples/boundedBufferTHREAD.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Apr 18 22:52:12 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 11:50:12 2019
    13 // Update Count     : 24
     12// Last Modified On : Thu Jan 16 23:09:43 2020
     13// Update Count     : 25
    1414//
    1515
     
    4444        void main( Buffer & buffer ) with( buffer ) {
    4545                for () {
    46                         waitfor( ^?{}, buffer ) {
     46                        waitfor( ^?{} : buffer ) {
    4747                                break;
    48                         } or when ( count != 20 ) waitfor( insert, buffer ) {
     48                        } or when ( count != 20 ) waitfor( insert : buffer ) {
    4949                                back = (back + 1) % 20;
    5050                                count += 1;
    51                         } or when ( count != 0 ) waitfor( remove, buffer ) {
     51                        } or when ( count != 0 ) waitfor( remove : buffer ) {
    5252                                front = (front + 1) % 20;
    5353                                count -= 1;
  • tests/concurrent/examples/datingService.cfa

    r9fb8f01 r3d5701e  
    11//
    22// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
    3 // 
     3//
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
     
    3535                signal_block( Boys[ccode] );                                    // restart boy to set phone number
    3636        } // if
    37         sout | "Girl:" | PhoneNo | "is dating Boy at" | BoyPhoneNo | "with ccode" | ccode;
     37        //sout | "Girl:" | PhoneNo | "is dating Boy at" | BoyPhoneNo | "with ccode" | ccode;
    3838        return BoyPhoneNo;
    3939} // DatingService girl
     
    4747                signal_block( Girls[ccode] );                                   // restart girl to set phone number
    4848        } // if
    49         sout | " Boy:" | PhoneNo | "is dating Girl" | GirlPhoneNo | "with ccode" | ccode;
     49        //sout | " Boy:" | PhoneNo | "is dating Girl" | GirlPhoneNo | "with ccode" | ccode;
    5050        return GirlPhoneNo;
    5151} // DatingService boy
  • tests/concurrent/examples/gortn.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Feb 20 08:02:37 2019
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 08:25:03 2019
    13 // Update Count     : 4
     12// Last Modified On : Thu Jan 16 22:43:40 2020
     13// Update Count     : 5
    1414//
    1515
     
    2626void main( GoRtn & gortn ) with( gortn ) {
    2727        for () {
    28                 waitfor( mem1, gortn ) sout | i;
    29                 or waitfor( mem2, gortn ) sout | f;
    30                 or waitfor( mem3, gortn ) sout | m.i | m.j;
    31                 or waitfor( ^?{}, gortn ) break;
     28                waitfor( mem1 : gortn ) sout | i;
     29                or waitfor( mem2 : gortn ) sout | f;
     30                or waitfor( mem3 : gortn ) sout | m.i | m.j;
     31                or waitfor( ^?{} : gortn ) break;
    3232        }
    3333}
  • tests/concurrent/examples/quickSort.cfa

    r9fb8f01 r3d5701e  
    1111// Created On       : Wed Dec  6 12:15:52 2017
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Fri Jun 21 08:27:45 2019
    14 // Update Count     : 172
     13// Last Modified On : Wed Feb 12 18:24:47 2020
     14// Update Count     : 177
    1515//
    1616
     
    2727
    2828void ?{}( Quicksort & qs, int values[], int size, int depth ) {
    29         qs.values = values;  qs.low = 0;  qs.high = size;  qs.depth = depth;
     29        qs.[values, low, high, depth] = [values, 0, size, depth];
    3030} // Quicksort
    3131
     
    6666                        if ( depth > 0 ) {
    6767                                depth -= 1;
    68                                 Quicksort rqs = { values, low, right, depth }; // concurrently sort upper half
    69                                 //Quicksort lqs( values, left, high, depth ); // concurrently sort lower half
    70                                 sort( values, left, high, depth );              // concurrently sort lower half
     68                                Quicksort lqs = { values, low, right, depth }; // concurrently sort lower half
     69                                Quicksort rqs = { values, left, high, depth }; // concurrently sort upper half
     70                                // Quicksort lqs = { values, low, right, depth }; // concurrently sort lower half
     71                                // sort( values, left, high, depth );           // concurrently sort upper half
    7172                        } else {
    7273                                sort( values, low, right, 0 );                  // sequentially sort lower half
     
    162163                processor processors[ (1 << depth) - 1 ] __attribute__(( unused )); // create 2^depth-1 kernel threads
    163164
    164                 int * values = alloc( size );                           // values to be sorted, too large to put on stack
    165                 for ( counter; size ) {                                         // generate unsorted numbers
     165                int * values = alloc( size );                                   // values to be sorted, too large to put on stack
     166                for ( counter; size ) {                                                 // generate unsorted numbers
    166167                        values[counter] = size - counter;                       // descending values
     168                } // for
     169                for ( i; 200 ) {                                                                // random shuffle a few values
     170                        swap( values[rand() % size], values[rand() % size] );
    167171                } // for
    168172                {
     
    178182} // main
    179183
     184// for depth in 0 1 2 3 4 5 ; do echo "sort 500000000 values with ${depth} depth" ; time -f "%Uu %Ss %E %Mkb" a.out -t 500000000 ${depth} ; done
     185
    180186// Local Variables: //
    181187// tab-width: 4 //
  • tests/concurrent/multi-monitor.cfa

    r9fb8f01 r3d5701e  
    1111
    1212void increment( monitor_t & mutex p1, monitor_t & mutex p2, int & value ) {
     13        assert(active_thread() == get_monitor(p1)->owner);
     14        assert(active_thread() == get_monitor(p2)->owner);
    1315        value += 1;
     16        assert(active_thread() == get_monitor(p1)->owner);
     17        assert(active_thread() == get_monitor(p2)->owner);
    1418}
    1519
  • tests/concurrent/preempt.cfa

    r9fb8f01 r3d5701e  
    3636                if( (counter % 7) == this.value ) {
    3737                        __cfaabi_check_preemption();
    38                         int next = __atomic_add_fetch_4(&counter, 1, __ATOMIC_SEQ_CST);
     38                        int next = __atomic_add_fetch( &counter, 1, __ATOMIC_SEQ_CST );
    3939                        __cfaabi_check_preemption();
    4040                        if( (next % 100) == 0 ) printf("%d\n", (int)next);
  • tests/concurrent/signal/block.cfa

    r9fb8f01 r3d5701e  
    3333
    3434monitor global_data_t {
    35         thread_desc * last_thread;
    36         thread_desc * last_signaller;
     35        $thread * last_thread;
     36        $thread * last_signaller;
    3737};
    3838
     
    8282        if( !is_empty( cond ) ) {
    8383
    84                 thread_desc * next = front( cond );
     84                $thread * next = front( cond );
    8585
    8686                if( ! signal_block( cond ) ) {
  • tests/concurrent/signal/wait.cfa

    r9fb8f01 r3d5701e  
    9898        }
    9999
    100         __sync_fetch_and_sub_4( &waiter_left, 1);
     100        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
    101101}
    102102
     
    109109        }
    110110
    111         __sync_fetch_and_sub_4( &waiter_left, 1);
     111        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
    112112}
    113113
     
    120120        }
    121121
    122         __sync_fetch_and_sub_4( &waiter_left, 1);
     122        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
    123123}
    124124
     
    131131        }
    132132
    133         __sync_fetch_and_sub_4( &waiter_left, 1);
     133        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
    134134}
    135135
  • tests/concurrent/thread.cfa

    r9fb8f01 r3d5701e  
    77thread Second { semaphore* lock; };
    88
    9 void ?{}( First  & this, semaphore & lock ) { ((thread&)this){"Thread 1"}; this.lock = &lock; }
    10 void ?{}( Second & this, semaphore & lock ) { ((thread&)this){"Thread 2"}; this.lock = &lock; }
     9void ?{}( First  & this, semaphore & lock ) { ((thread&)this){ "Thread 1" }; this.lock = &lock; }
     10void ?{}( Second & this, semaphore & lock ) { ((thread&)this){ "Thread 2" }; this.lock = &lock; }
    1111
    1212void main(First& this) {
  • tests/concurrent/waitfor/barge.cfa

    r9fb8f01 r3d5701e  
    6565                yield(random( 10 ));
    6666                this.state = WAITFOR;
    67                 waitfor(do_call, this) {
     67                waitfor(do_call : this) {
    6868                        sout | i;
    6969                }
  • tests/concurrent/waitfor/dtor.cfa

    r9fb8f01 r3d5701e  
    4747        yield(random( 10 ));
    4848        set_state( this, MAIN );
    49         waitfor( ^?{}, this ) {
     49        waitfor( ^?{} : this ) {
    5050                set_state( this, AFTER );
    5151        }
  • tests/concurrent/waitfor/else.cfa

    r9fb8f01 r3d5701e  
    1414        sout | "Starting";
    1515
    16         when( false ) waitfor( notcalled, m );
     16        when( false ) waitfor( notcalled : m );
    1717
    1818        sout | "Step" | i++;
    1919
    20         waitfor( notcalled, m ); or else {
     20        waitfor( notcalled : m ); or else {
    2121                sout | "else called";
    2222        }
     
    2424        sout | "Step" | i++;
    2525
    26         when( true ) waitfor( notcalled, m ); or when( true ) else {
     26        when( true ) waitfor( notcalled : m ); or when( true ) else {
    2727                sout | "else called";
    2828        }
     
    3030        sout | "Step" | i++;
    3131
    32         when( false ) waitfor( notcalled, m ); or when( true ) else {
     32        when( false ) waitfor( notcalled : m ); or when( true ) else {
    3333                sout | "else called";
    3434        }
     
    3636        sout | "Step" | i++;
    3737
    38         when( false ) waitfor( notcalled, m ); or when( false ) else {
     38        when( false ) waitfor( notcalled : m ); or when( false ) else {
    3939                sout | "else called";
    4040        }
  • tests/concurrent/waitfor/parse.cfa

    r9fb8f01 r3d5701e  
    2424
    2525        //---------------------------------------
    26         waitfor( f1, a ) {
     26        waitfor( f1 : a ) {
    2727                1;
    2828        }
    2929
    3030        //---------------------------------------
    31         waitfor( f1, a ) {
     31        waitfor( f1 : a ) {
    3232                2;
    3333        }
    34         waitfor( f2, a ) {
     34        waitfor( f2 : a ) {
    3535                3;
    3636        }
    3737
    3838        //---------------------------------------
    39         when( 1 < 3 ) waitfor( f2, a, a ) {
     39        when( 1 < 3 ) waitfor( f2 : a, a ) {
    4040                4;
    4141        }
     
    4545
    4646        //---------------------------------------
    47         when( 2 < 3 ) waitfor( f3, a ) {
     47        when( 2 < 3 ) waitfor( f3 : a ) {
    4848                5;
    4949        }
     
    5353
    5454        //---------------------------------------
    55         when( 3 < 3 ) waitfor( f3, a, a ) {
     55        when( 3 < 3 ) waitfor( f3 : a, a ) {
    5656                7;
    5757        }
     
    6464
    6565        //---------------------------------------
    66         when( 6 < 3 ) waitfor( f3, a, a, a ) {
     66        when( 6 < 3 ) waitfor( f3 : a, a, a ) {
    6767                10;
    6868        }
    69         or when( 7 < 3 ) waitfor( f1, a  ) {
     69        or when( 7 < 3 ) waitfor( f1 : a  ) {
    7070                11;
    7171        }
     
    7575
    7676        //---------------------------------------
    77         when( 8 < 3 ) waitfor( f3, a, a ) {
     77        when( 8 < 3 ) waitfor( f3 : a, a ) {
    7878                13;
    7979        }
    80         or waitfor( f1, a  ) {
     80        or waitfor( f1 : a  ) {
    8181                14;
    8282        }
     
    8686
    8787        //---------------------------------------
    88         when( 10 < 3 ) waitfor( f1, a ) {
     88        when( 10 < 3 ) waitfor( f1 : a ) {
    8989                16;
    9090        }
    91         or waitfor( f2, a, a ) {
     91        or waitfor( f2 : a, a ) {
    9292                17;
    9393        }
     
    100100}
    101101
    102 int main() {
    103 
    104 }
     102int main() {}
  • tests/concurrent/waitfor/parse2.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Aug 30 17:53:29 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 22 13:42:11 2019
    13 // Update Count     : 3
     12// Last Modified On : Thu Jan 16 23:13:37 2020
     13// Update Count     : 6
    1414//
    1515
     
    2626        }
    2727
    28         waitfor( x, z ) {
     28        waitfor( x : z ) {
    2929        }
    3030
     
    3737        or waitfor( y );
    3838
    39         waitfor( x, z );
     39        waitfor( x : z );
    4040        or waitfor( y );
    4141
     
    4343        or when( true ) waitfor( y );
    4444
    45         when( true ) waitfor( x, z );
     45        when( true ) waitfor( x : z );
    4646        or when( true ) waitfor( y );
    4747
     
    5050        }
    5151
    52         waitfor( x, z ) {
     52        waitfor( x : z ) {
    5353        } or waitfor( y ) {
    5454        }
     
    8080        or else;
    8181
    82         when( true ) waitfor( x, z );
     82        when( true ) waitfor( x : z );
    8383        or else;
    8484
     
    9999        }
    100100
    101         when( true ) waitfor( x, z );
     101        when( true ) waitfor( x : z );
    102102        or else {
    103103        }
     
    115115        or when( true ) else;
    116116
    117         when( true ) waitfor( x, z );
     117        when( true ) waitfor( x : z );
    118118        or when( true ) else;
    119119
     
    134134        }
    135135
    136         when( true ) waitfor( x, z );
     136        when( true ) waitfor( x : z );
    137137        or when( true ) else {
    138138        }
     
    149149        or timeout( 3 );
    150150
    151         waitfor( x, z );
     151        waitfor( x : z );
    152152        or timeout( 3 );
    153153
     
    163163        }
    164164
    165         when( true ) waitfor( x, z ) {
     165        when( true ) waitfor( x : z ) {
    166166        } or timeout( 3 ) {
    167167        }
     
    171171        }
    172172
    173         when( true ) waitfor( x, z ) {
     173        when( true ) waitfor( x : z ) {
    174174        } or when ( true ) timeout( 3 ) {
    175175        }
     
    229229
    230230        int or, timeout;
    231         waitfor( timeout, 7 ) 3;
    232         waitfor( timeout, 7 ) 3; or waitfor( timeout, 7 ) 3;
    233         when( or ) waitfor( or, ) { 4; } or timeout( 1 ) 3;
    234         when( 3 ) waitfor( or, 2 ) 4; or else 4;
    235         when( 3 ) waitfor( or, 3 ) 4; or when( or ) timeout( or ) 4; or when( or ) else timeout;
    236         when( 3 ) waitfor( or, or ) 3; or when( or ) waitfor( or, timeout ) 4; or else 4;
    237         when( 3 ) waitfor( or, or ) 3; or waitfor( or, 9 ) 4; or when( or ) timeout( timeout ) 4;
    238         when( 3 ) waitfor( or, 3 ) 3; or waitfor( or, 7 ) or; or timeout( 1 ) or; or when( 3 ) else or;
     231        waitfor( timeout : 7 ) 3;
     232        waitfor( timeout : 7 ) 3; or waitfor( timeout : 7 ) 3;
     233        when( or ) waitfor( or : ) { 4; } or timeout( 1 ) 3;
     234        when( 3 ) waitfor( or : 2 ) 4; or else 4;
     235        when( 3 ) waitfor( or : 3 ) 4; or when( or ) timeout( or ) 4; or when( or ) else timeout;
     236        when( 3 ) waitfor( or : or ) 3; or when( or ) waitfor( or : timeout ) 4; or else 4;
     237        when( 3 ) waitfor( or : or ) 3; or waitfor( or : 9 ) 4; or when( or ) timeout( timeout ) 4;
     238        when( 3 ) waitfor( or : 3 ) 3; or waitfor( or : 7 ) or; or timeout( 1 ) or; or when( 3 ) else or;
    239239
    240240        // test else selection
  • tests/concurrent/waitfor/recurse.cfa

    r9fb8f01 r3d5701e  
    6666
    6767        rand_yield();
    68         waitfor( call4, this );
     68        waitfor( call4 : this );
    6969        rand_yield();
    7070
     
    7878
    7979        rand_yield();
    80         waitfor( call3, this );
     80        waitfor( call3 : this );
    8181        rand_yield();
    8282
     
    9292
    9393        rand_yield();
    94         waitfor( call2, this );
     94        waitfor( call2 : this );
    9595        rand_yield();
    9696
  • tests/concurrent/waitfor/statment.cfa

    r9fb8f01 r3d5701e  
    101101
    102102        while( !done ) {
    103                    waitfor( get_index, this );
    104                 or waitfor( call1, this ) { sout | "Statement"; if( this.last_val != 1 ) { serr | "Incorrect index: expected" | 1 | "got" | this.last_val; } }
    105                 or waitfor( call2, this ) { sout | "Statement"; if( this.last_val != 2 ) { serr | "Incorrect index: expected" | 2 | "got" | this.last_val; } }
    106                 or waitfor( call3, this ) { sout | "Statement"; if( this.last_val != 3 ) { serr | "Incorrect index: expected" | 3 | "got" | this.last_val; } }
    107                 or waitfor( call4, this ) { sout | "Statement"; if( this.last_val != 4 ) { serr | "Incorrect index: expected" | 4 | "got" | this.last_val; } }
    108                 or waitfor( call5, this ) { sout | "Statement"; if( this.last_val != 5 ) { serr | "Incorrect index: expected" | 5 | "got" | this.last_val; } }
    109                 or waitfor( call6, this ) { sout | "Statement"; if( this.last_val != 6 ) { serr | "Incorrect index: expected" | 6 | "got" | this.last_val; } }
    110                 or waitfor( call7, this ) { sout | "Statement"; if( this.last_val != 7 ) { serr | "Incorrect index: expected" | 7 | "got" | this.last_val; } }
     103                   waitfor( get_index : this );
     104                or waitfor( call1 : this ) { sout | "Statement"; if( this.last_val != 1 ) { serr | "Incorrect index: expected" | 1 | "got" | this.last_val; } }
     105                or waitfor( call2 : this ) { sout | "Statement"; if( this.last_val != 2 ) { serr | "Incorrect index: expected" | 2 | "got" | this.last_val; } }
     106                or waitfor( call3 : this ) { sout | "Statement"; if( this.last_val != 3 ) { serr | "Incorrect index: expected" | 3 | "got" | this.last_val; } }
     107                or waitfor( call4 : this ) { sout | "Statement"; if( this.last_val != 4 ) { serr | "Incorrect index: expected" | 4 | "got" | this.last_val; } }
     108                or waitfor( call5 : this ) { sout | "Statement"; if( this.last_val != 5 ) { serr | "Incorrect index: expected" | 5 | "got" | this.last_val; } }
     109                or waitfor( call6 : this ) { sout | "Statement"; if( this.last_val != 6 ) { serr | "Incorrect index: expected" | 6 | "got" | this.last_val; } }
     110                or waitfor( call7 : this ) { sout | "Statement"; if( this.last_val != 7 ) { serr | "Incorrect index: expected" | 7 | "got" | this.last_val; } }
    111111
    112112                done = true;
  • tests/concurrent/waitfor/when.cfa

    r9fb8f01 r3d5701e  
    5858void arbiter( global_t & mutex this ) {
    5959        for( int i = 0; i < N; i++ ) {
    60                    when( this.last_call == 6 ) waitfor( call1, this ) { if( this.last_call != 1) { serr | "Expected last_call to be 1 got" | this.last_call; } }
    61                 or when( this.last_call == 1 ) waitfor( call2, this ) { if( this.last_call != 2) { serr | "Expected last_call to be 2 got" | this.last_call; } }
    62                 or when( this.last_call == 2 ) waitfor( call3, this ) { if( this.last_call != 3) { serr | "Expected last_call to be 3 got" | this.last_call; } }
    63                 or when( this.last_call == 3 ) waitfor( call4, this ) { if( this.last_call != 4) { serr | "Expected last_call to be 4 got" | this.last_call; } }
    64                 or when( this.last_call == 4 ) waitfor( call5, this ) { if( this.last_call != 5) { serr | "Expected last_call to be 5 got" | this.last_call; } }
    65                 or when( this.last_call == 5 ) waitfor( call6, this ) { if( this.last_call != 6) { serr | "Expected last_call to be 6 got" | this.last_call; } }
     60                   when( this.last_call == 6 ) waitfor( call1 : this ) { if( this.last_call != 1) { serr | "Expected last_call to be 1 got" | this.last_call; } }
     61                or when( this.last_call == 1 ) waitfor( call2 : this ) { if( this.last_call != 2) { serr | "Expected last_call to be 2 got" | this.last_call; } }
     62                or when( this.last_call == 2 ) waitfor( call3 : this ) { if( this.last_call != 3) { serr | "Expected last_call to be 3 got" | this.last_call; } }
     63                or when( this.last_call == 3 ) waitfor( call4 : this ) { if( this.last_call != 4) { serr | "Expected last_call to be 4 got" | this.last_call; } }
     64                or when( this.last_call == 4 ) waitfor( call5 : this ) { if( this.last_call != 5) { serr | "Expected last_call to be 5 got" | this.last_call; } }
     65                or when( this.last_call == 5 ) waitfor( call6 : this ) { if( this.last_call != 6) { serr | "Expected last_call to be 6 got" | this.last_call; } }
    6666
    6767                sout | this.last_call;
  • tests/config.py.in

    r9fb8f01 r3d5701e  
    88BUILDDIR = "@abs_builddir@"
    99HOSTARCH = "@host_cpu@"
     10DISTRIBUTE = @HAS_DISTCC@
  • tests/errors/.expect/completeType.txt

    r9fb8f01 r3d5701e  
    1 completeTypeError.cfa:34:1 error: Cannot choose between 2 alternatives for expression
     1errors/completeType.cfa:34:1 error: Cannot choose between 2 alternatives for expression
    22Generated Cast of:
    33  Applying untyped:
     
    1010      Application of
    1111        Variable Expression: *?: forall
    12           DT: object type
     12          DT: data type
    1313          function
    1414        ... with parameters
     
    3333      Application of
    3434        Variable Expression: *?: forall
    35           DT: object type
     35          DT: data type
    3636          function
    3737        ... with parameters
     
    5454
    5555
    56 completeTypeError.cfa:35:1 error: No reasonable alternatives for expression Applying untyped:
     56errors/completeType.cfa:35:1 error: No reasonable alternatives for expression Applying untyped:
    5757  Name: foo
    5858...to:
    5959  Name: v
    6060
    61 completeTypeError.cfa:36:1 error: No reasonable alternatives for expression Applying untyped:
     61errors/completeType.cfa:36:1 error: No reasonable alternatives for expression Applying untyped:
    6262  Name: baz
    6363...to:
    6464  Name: v
    6565
    66 completeTypeError.cfa:37:1 error: No reasonable alternatives for expression Applying untyped:
     66errors/completeType.cfa:37:1 error: No reasonable alternatives for expression Applying untyped:
    6767  Name: quux
    6868...to:
    6969  Name: v
    7070
    71 completeTypeError.cfa:59:1 error: No reasonable alternatives for expression Applying untyped:
     71errors/completeType.cfa:59:1 error: No reasonable alternatives for expression Applying untyped:
    7272  Name: baz
    7373...to:
    7474  Name: y
    7575
    76 completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped:
     76errors/completeType.cfa:60:1 error: No reasonable alternatives for expression Applying untyped:
    7777  Name: quux
    7878...to:
    7979  Name: y
    8080
    81 completeTypeError.cfa:72:1 error: No alternatives with satisfiable assertions for Applying untyped:
     81errors/completeType.cfa:72:1 error: No alternatives with satisfiable assertions for Applying untyped:
    8282  Name: baz
    8383...to:
     
    8787Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of
    8888            Variable Expression: baz: forall
    89               T: sized object type
     89              T: sized data type
    9090              ... with assertions
    9191                ?=?: pointer to function
  • tests/exceptions/except-0.cfa

    r9fb8f01 r3d5701e  
    1919};
    2020
    21 void ?{}(signal_exit * this, const char * area) {
    22         this->area = area;
    23 }
    24 
    25 void ^?{}(signal_exit * this) {
    26         printf("Exiting: %s\n", this->area);
     21void ?{}(signal_exit & this, const char * area) {
     22        this.area = area;
     23}
     24
     25void ^?{}(signal_exit & this) {
     26        printf("Exiting: %s\n", this.area);
    2727//      sout | "Exiting:" | this->area;
    2828}
     
    242242
    243243        // Uncaught termination test.
     244        /* Removed due to non-deterministic output.
    244245        printf("Throw uncaught.\n");
    245246        yang z;
    246247        terminate(&z);
    247 }
     248        */
     249}
  • tests/exceptions/except-2.cfa

    r9fb8f01 r3d5701e  
    1212        struct TABLE(BASE_EXCEPT) const * parent;
    1313        size_t size;
    14         void (*copy)(num_error *this, num_error * other);
    15         void (*free)(num_error *this);
     14        void (*copy)(num_error &this, num_error & other);
     15        void (*free)(num_error &this);
    1616        const char * (*msg)(num_error *this);
    1717        int (*code)(num_error *this);
     
    2828        if ( ! this->msg ) {
    2929                static const char * base = "Num Error with code: X";
    30                 this->msg = malloc(22);
     30                this->msg = (char *)malloc(22);
    3131                for (int i = 0 ; (this->msg[i] = base[i]) ; ++i);
    3232        }
     
    3434        return this->msg;
    3535}
    36 void ?{}(num_error * this, int num) {
    37         this->virtual_table = &INSTANCE(num_error);
    38         this->msg = 0;
    39         this->num = num;
     36void ?{}(num_error & this, int num) {
     37        this.virtual_table = &INSTANCE(num_error);
     38        this.msg = 0;
     39        this.num = num;
    4040}
    41 void ?{}(num_error * this, num_error * other) {
    42         this->virtual_table = other->virtual_table;
    43         this->msg = 0;
    44         this->num = other->num;
     41void ?{}(num_error & this, num_error & other) {
     42        this.virtual_table = other.virtual_table;
     43        this.msg = 0;
     44        this.num = other.num;
    4545}
    46 void ^?{}(num_error * this) {
    47         if( this->msg ) free( this->msg );
     46void ^?{}(num_error & this) {
     47        if( this.msg ) free( this.msg );
    4848}
    4949int num_error_code( num_error * this ) {
  • tests/expression.cfa

    r9fb8f01 r3d5701e  
     1struct S { int i; };
     2void ?{}( S & s, int i ) { s.i = i; }
     3int ?`mary( int );
     4int ?`mary( S );
     5[int] ?`mary( [int, int] );
     6int & ?`jane( int & );
     7int jack( int );
     8
    19int main() {
    2     struct s { int i; } x, *p = &x;
    3     int i = 3;
     10    int a[3] = { 0, 0, 0 };
     11    S s = { 3 }, * ps = &s;
     12    [int] t = { 3 };
     13    * [int] pt = &t;
     14    int i = 1, j = 2;
    415
    516    // operators
    617
    7     ! i;
     18    !i;
    819    ~i;
    920    +i;
    1021    -i;
    11     *p;
    12     ++p;
    13     --p;
    14     p++;
    15     p--;
     22    *ps;
     23    ++ps;
     24    --ps;
     25    ps++;
     26    ps--;
    1627
    17     i+i;
    18     i-i;
    19     i*i;
     28    i + j;
     29    i - j;
     30    i * j;
    2031
    21     i/i;
    22     i%i;
    23     i^i;
    24     i&i;
    25     i|i;
    26     i<i;
    27     i>i;
    28     i=i;
     32    i / j;
     33    i % j;
     34    i ^ j;
     35    i & j;
     36    i | j;
     37    i < j;
     38    i > j;
     39    i = j;
    2940
    30     i==i;
    31     i!=i;
    32     i<<i;
    33     i>>i;
    34     i<=i;
    35     i>=i;
    36     i&&i;
    37     i||i;
    38     p->i;
    39     i*=i;
    40     i/=i;
    41     i%=i;
    42     i+=i;
    43     i-=i;
    44     i&=i;
    45     i|=i;
    46     i^=i;
    47     i<<=i;
    48     i>>=i;
     41    i == j;
     42    i != j;
     43    i << j;
     44    i >> j;
     45    i <= j;
     46    i >= j;
     47    i && j;
     48    i || j;
     49    ps->i;
    4950
    50     i?i:i;
     51    i *= j;
     52    i /= j;
     53    i %= j;
     54    i += j;
     55    i -= j;
     56    i &= j;
     57    i |= j;
     58    i ^= j;
     59    i <<= j;
     60    i >>= j;
     61
     62    i ? i : j;
     63
     64    // postfix function call
     65
     66    (3 + 4)`mary;
     67    ({3 + 4;})`mary;
     68    [3, 4]`mary;
     69    3`mary;
     70    a[0]`mary;
     71    a[0]`mary`mary;
     72    s{0}`mary;
     73    a[3]`jane++;
     74    jack(3)`mary;
     75    s.i`mary;
     76    t.0`mary;
     77    s.[i]`mary;
     78    ps->i`mary;
     79    pt->0`mary;
     80    ps->[i]`mary;
     81    i++`mary;
     82    i--`mary;
     83    (S){2}`mary;
     84    (S)@{2}`mary;
    5185} // main
  • tests/heap.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Nov  6 17:54:56 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 19 08:22:34 2019
    13 // Update Count     : 19
     12// Last Modified On : Sun Nov 24 12:34:51 2019
     13// Update Count     : 28
    1414//
    1515
     
    3838        enum { NoOfAllocs = 5000, NoOfMmaps = 10 };
    3939        char * locns[NoOfAllocs];
    40         int i;
     40        size_t amount;
     41        enum { limit = 64 * 1024 };                                                     // check alignments up to here
    4142
    4243        // check alloc/free
     
    7475                size_t s = (i + 1) * 20;
    7576                char * area = (char *)malloc( s );
    76                 if ( area == 0 ) abort( "malloc/free out of memory" );
     77                if ( area == 0p ) abort( "malloc/free out of memory" );
    7778                area[0] = '\345'; area[s - 1] = '\345';                 // fill first/last
    7879                area[malloc_usable_size( area ) - 1] = '\345';  // fill ultimate byte
     
    8384                size_t s = i + 1;                                                               // +1 to make initialization simpler
    8485                locns[i] = (char *)malloc( s );
    85                 if ( locns[i] == 0 ) abort( "malloc/free out of memory" );
     86                if ( locns[i] == 0p ) abort( "malloc/free out of memory" );
    8687                locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last
    8788                locns[i][malloc_usable_size( locns[i] ) - 1] = '\345'; // fill ultimate byte
     
    99100                size_t s = i + default_mmap_start();                    // cross over point
    100101                char * area = (char *)malloc( s );
    101                 if ( area == 0 ) abort( "malloc/free out of memory" );
     102                if ( area == 0p ) abort( "malloc/free out of memory" );
    102103                area[0] = '\345'; area[s - 1] = '\345';                 // fill first/last
    103104                area[malloc_usable_size( area ) - 1] = '\345';  // fill ultimate byte
     
    108109                size_t s = i + default_mmap_start();                    // cross over point
    109110                locns[i] = (char *)malloc( s );
    110                 if ( locns[i] == 0 ) abort( "malloc/free out of memory" );
     111                if ( locns[i] == 0p ) abort( "malloc/free out of memory" );
    111112                locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last
    112113                locns[i][malloc_usable_size( locns[i] ) - 1] = '\345'; // fill ultimate byte
     
    124125                size_t s = (i + 1) * 20;
    125126                char * area = (char *)calloc( 5, s );
    126                 if ( area == 0 ) abort( "calloc/free out of memory" );
     127                if ( area == 0p ) abort( "calloc/free out of memory" );
    127128                if ( area[0] != '\0' || area[s - 1] != '\0' ||
    128129                         area[malloc_usable_size( area ) - 1] != '\0' ||
     
    136137                size_t s = i + 1;
    137138                locns[i] = (char *)calloc( 5, s );
    138                 if ( locns[i] == 0 ) abort( "calloc/free out of memory" );
     139                if ( locns[i] == 0p ) abort( "calloc/free out of memory" );
    139140                if ( locns[i][0] != '\0' || locns[i][s - 1] != '\0' ||
    140141                         locns[i][malloc_usable_size( locns[i] ) - 1] != '\0' ||
     
    155156                size_t s = i + default_mmap_start();                    // cross over point
    156157                char * area = (char *)calloc( 1, s );
    157                 if ( area == 0 ) abort( "calloc/free out of memory" );
     158                if ( area == 0p ) abort( "calloc/free out of memory" );
    158159                if ( area[0] != '\0' || area[s - 1] != '\0' ) abort( "calloc/free corrupt storage4.1" );
    159160                if ( area[malloc_usable_size( area ) - 1] != '\0' ) abort( "calloc/free corrupt storage4.2" );
     
    167168                size_t s = i + default_mmap_start();                    // cross over point
    168169                locns[i] = (char *)calloc( 1, s );
    169                 if ( locns[i] == 0 ) abort( "calloc/free out of memory" );
     170                if ( locns[i] == 0p ) abort( "calloc/free out of memory" );
    170171                if ( locns[i][0] != '\0' || locns[i][s - 1] != '\0' ||
    171172                         locns[i][malloc_usable_size( locns[i] ) - 1] != '\0' ||
     
    183184        // check memalign/free (sbrk)
    184185
    185         enum { limit = 64 * 1024 };                                                     // check alignments up to here
    186 
    187186        for ( a; libAlign() ~= limit ~ a ) {                            // generate powers of 2
    188187                //sout | alignments[a];
    189188                for ( s; 1 ~ NoOfAllocs ) {                                             // allocation of size 0 can return null
    190189                        char * area = (char *)memalign( a, s );
    191                         if ( area == 0 ) abort( "memalign/free out of memory" );
    192                         //sout | i | " " | area;
     190                        if ( area == 0p ) abort( "memalign/free out of memory" );
     191                        //sout | i | area;
    193192                        if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
    194193                                abort( "memalign/free bad alignment : memalign(%d,%d) = %p", (int)a, s, area );
    195194                        } // if
    196                         area[0] = '\345'; area[s - 1] = '\345'; // fill first/last byte
     195                        area[0] = '\345'; area[s - 1] = '\345';         // fill first/last byte
    197196                        area[malloc_usable_size( area ) - 1] = '\345'; // fill ultimate byte
    198197                        free( area );
     
    207206                        size_t s = i + default_mmap_start();            // cross over point
    208207                        char * area = (char *)memalign( a, s );
    209                         if ( area == 0 ) abort( "memalign/free out of memory" );
    210                         //sout | i | " " | area;
     208                        if ( area == 0p ) abort( "memalign/free out of memory" );
     209                        //sout | i | area;
    211210                        if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
    212211                                abort( "memalign/free bad alignment : memalign(%d,%d) = %p", (int)a, (int)s, area );
     
    223222                // initial N byte allocation
    224223                char * area = (char *)calloc( 5, i );
    225                 if ( area == 0 ) abort( "calloc/realloc/free out of memory" );
     224                if ( area == 0p ) abort( "calloc/realloc/free out of memory" );
    226225                if ( area[0] != '\0' || area[i - 1] != '\0' ||
    227226                         area[malloc_usable_size( area ) - 1] != '\0' ||
     
    231230                for ( s; i ~ 256 * 1024 ~ 26 ) {                                // start at initial memory request
    232231                        area = (char *)realloc( area, s );                      // attempt to reuse storage
    233                         if ( area == 0 ) abort( "calloc/realloc/free out of memory" );
     232                        if ( area == 0p ) abort( "calloc/realloc/free out of memory" );
    234233                        if ( area[0] != '\0' || area[s - 1] != '\0' ||
    235234                                 area[malloc_usable_size( area ) - 1] != '\0' ||
     
    245244                size_t s = i + default_mmap_start();                    // cross over point
    246245                char * area = (char *)calloc( 1, s );
    247                 if ( area == 0 ) abort( "calloc/realloc/free out of memory" );
     246                if ( area == 0p ) abort( "calloc/realloc/free out of memory" );
    248247                if ( area[0] != '\0' || area[s - 1] != '\0' ||
    249248                         area[malloc_usable_size( area ) - 1] != '\0' ||
     
    253252                for ( r; i ~ 256 * 1024 ~ 26 ) {                                // start at initial memory request
    254253                        area = (char *)realloc( area, r );                      // attempt to reuse storage
    255                         if ( area == 0 ) abort( "calloc/realloc/free out of memory" );
     254                        if ( area == 0p ) abort( "calloc/realloc/free out of memory" );
    256255                        if ( area[0] != '\0' || area[r - 1] != '\0' ||
    257256                                 area[malloc_usable_size( area ) - 1] != '\0' ||
     
    263262        // check memalign/realloc/free
    264263
    265         size_t amount = 2;
     264        amount = 2;
    266265        for ( a; libAlign() ~= limit ~ a ) {                            // generate powers of 2
    267266                // initial N byte allocation
    268267                char * area = (char *)memalign( a, amount );    // aligned N-byte allocation
    269                 if ( area == 0 ) abort( "memalign/realloc/free out of memory" ); // no storage ?
    270                 //sout | alignments[a] | " " | area;
     268                if ( area == 0p ) abort( "memalign/realloc/free out of memory" ); // no storage ?
     269                //sout | alignments[a] | area;
    271270                if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
    272271                        abort( "memalign/realloc/free bad alignment : memalign(%d,%d) = %p", (int)a, (int)amount, area );
     
    278277                        if ( area[0] != '\345' || area[s - 2] != '\345' ) abort( "memalign/realloc/free corrupt storage" );
    279278                        area = (char *)realloc( area, s );                      // attempt to reuse storage
    280                         if ( area == 0 ) abort( "memalign/realloc/free out of memory" ); // no storage ?
    281                         //sout | i | " " | area;
     279                        if ( area == 0p ) abort( "memalign/realloc/free out of memory" ); // no storage ?
     280                        //sout | i | area;
    282281                        if ( (size_t)area % a != 0 ) {                          // check for initial alignment
    283282                                abort( "memalign/realloc/free bad alignment %p", area );
     
    294293                for ( s; 1 ~ limit ) {                                                  // allocation of size 0 can return null
    295294                        char * area = (char *)cmemalign( a, 1, s );
    296                         if ( area == 0 ) abort( "cmemalign/free out of memory" );
    297                         //sout | i | " " | area;
     295                        if ( area == 0p ) abort( "cmemalign/free out of memory" );
     296                        //sout | i | area;
    298297                        if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
    299298                                abort( "cmemalign/free bad alignment : cmemalign(%d,%d) = %p", (int)a, s, area );
     
    313312                // initial N byte allocation
    314313                char * area = (char *)cmemalign( a, 1, amount ); // aligned N-byte allocation
    315                 if ( area == 0 ) abort( "cmemalign/realloc/free out of memory" ); // no storage ?
    316                 //sout | alignments[a] | " " | area;
     314                if ( area == 0p ) abort( "cmemalign/realloc/free out of memory" ); // no storage ?
     315                //sout | alignments[a] | area;
    317316                if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
    318317                        abort( "cmemalign/realloc/free bad alignment : cmemalign(%d,%d) = %p", (int)a, (int)amount, area );
     
    327326                        if ( area[0] != '\345' || area[s - 2] != '\345' ) abort( "cmemalign/realloc/free corrupt storage2" );
    328327                        area = (char *)realloc( area, s );                      // attempt to reuse storage
    329                         if ( area == 0 ) abort( "cmemalign/realloc/free out of memory" ); // no storage ?
    330                         //sout | i | " " | area;
     328                        if ( area == 0p ) abort( "cmemalign/realloc/free out of memory" ); // no storage ?
     329                        //sout | i | area;
    331330                        if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
    332331                                abort( "cmemalign/realloc/free bad alignment %p", area );
     
    339338                free( area );
    340339        } // for
     340
     341        // check memalign/realloc with align/free
     342
     343        amount = 2;
     344        for ( a; libAlign() ~= limit ~ a ) {                            // generate powers of 2
     345                // initial N byte allocation
     346                char * area = (char *)memalign( a, amount );    // aligned N-byte allocation
     347                if ( area == 0p ) abort( "memalign/realloc with align/free out of memory" ); // no storage ?
     348                //sout | alignments[a] | area | endl;
     349                if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
     350                        abort( "memalign/realloc with align/free bad alignment : memalign(%d,%d) = %p", (int)a, (int)amount, area );
     351                } // if
     352                area[0] = '\345'; area[amount - 2] = '\345';    // fill first/penultimate byte
     353
     354                // Do not start this loop index at 0 because realloc of 0 bytes frees the storage.
     355                for ( s; amount ~ 256 * 1024 ) {                                // start at initial memory request
     356                        if ( area[0] != '\345' || area[s - 2] != '\345' ) abort( "memalign/realloc/free corrupt storage" );
     357                        area = (char *)realloc( area, a * 2, s );       // attempt to reuse storage
     358                        if ( area == 0p ) abort( "memalign/realloc with align/free out of memory" ); // no storage ?
     359                        //sout | i | area | endl;
     360                        if ( (size_t)area % a * 2 != 0 ) {                      // check for initial alignment
     361                                abort( "memalign/realloc with align/free bad alignment %p", area );
     362                        } // if
     363                        area[s - 1] = '\345';                                           // fill last byte
     364                } // for
     365                free( area );
     366        } // for
     367
     368        // check cmemalign/realloc with align/free
     369
     370        amount = 2;
     371        for ( size_t a = libAlign() + libAlign(); a <= limit; a += a ) { // generate powers of 2
     372                // initial N byte allocation
     373                char *area = (char *)cmemalign( a, 1, amount ); // aligned N-byte allocation
     374                if ( area == 0p ) abort( "cmemalign/realloc with align/free out of memory" ); // no storage ?
     375                //sout | alignments[a] | area | endl;
     376                if ( (size_t)area % a != 0 || malloc_alignment( area ) != a ) { // check for initial alignment
     377                        abort( "cmemalign/realloc with align/free bad alignment : cmemalign(%d,%d) = %p", (int)a, (int)amount, area );
     378                } // if
     379                if ( area[0] != '\0' || area[amount - 1] != '\0' ||
     380                         area[malloc_usable_size( area ) - 1] != '\0' ||
     381                         ! malloc_zero_fill( area ) ) abort( "cmemalign/realloc with align/free corrupt storage1" );
     382                area[0] = '\345'; area[amount - 2] = '\345';    // fill first/penultimate byte
     383
     384                // Do not start this loop index at 0 because realloc of 0 bytes frees the storage.
     385                for ( int s = amount; s < 256 * 1024; s += 1 ) { // start at initial memory request
     386                        if ( area[0] != '\345' || area[s - 2] != '\345' ) abort( "cmemalign/realloc with align/free corrupt storage2" );
     387                        area = (char *)realloc( area, a * 2, s );       // attempt to reuse storage
     388                        if ( area == 0p ) abort( "cmemalign/realloc with align/free out of memory" ); // no storage ?
     389                        //sout | i | area | endl;
     390                        if ( (size_t)area % a * 2 != 0 || malloc_alignment( area ) != a * 2 ) { // check for initial alignment
     391                                abort( "cmemalign/realloc with align/free bad alignment %p %jd %jd", area, malloc_alignment( area ), a * 2 );
     392                        } // if
     393                        if ( area[s - 1] != '\0' || area[s - 1] != '\0' ||
     394                                 area[malloc_usable_size( area ) - 1] != '\0' ||
     395                                 ! malloc_zero_fill( area ) ) abort( "cmemalign/realloc/free corrupt storage3" );
     396                        area[s - 1] = '\345';                                           // fill last byte
     397                } // for
     398                free( area );
     399        } // for
     400
    341401        //sout | "worker" | thisTask() | "successful completion";
    342402} // Worker main
  • tests/labelledExit.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Aug 10 07:29:39 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Nov  6 17:57:42 2018
    13 // Update Count     : 4
     12// Last Modified On : Wed Feb  5 16:49:48 2020
     13// Update Count     : 9
    1414//
    1515
     
    136136        }
    137137
     138        // all nested control options, labelled exits
     139
     140  Comp: {
     141          Try: try {
     142                  For: for ( ;; ) {
     143                          While: while ( true ) {
     144                                  Do: do {
     145                                          If: if ( true ) {
     146                                                  Switch2: switch ( 3 ) {
     147                                                          case 3:
     148                                                                break Try;
     149                                                                break Comp;
     150                                                                break For;              continue For;
     151                                                                break While;    continue While;
     152                                                                break Do;               continue Do;
     153                                                                break If;
     154                                                                break Switch2;
     155                                                        } // switch
     156                                                } // if
     157                                        } while ( true );
     158                                } // while
     159                        } // for
     160                } finally {} // always executed
     161        } // compound
     162
    138163        // computed goto
    139         // {
    140         //      void *array[] = { &&foo, &&bar, &&hack };
    141         //   foo: bar: hack:
    142         //      &&foo;
    143         //      &&bar;
    144         //      goto *array[i];
    145         // }
     164        {
     165                void *array[] = { &&foo, &&bar, &&hack };
     166          foo: bar: hack:
     167                &&foo;
     168                &&bar;
     169                goto *array[i];
     170        }
    146171
    147172  Q: if ( i > 5 ) {
  • tests/linking/withthreads.cfa

    r9fb8f01 r3d5701e  
    3434// Local Variables: //
    3535// tab-width: 4 //
    36 // compile-command: "cfa nothreads.cfa" //
     36// compile-command: "cfa withthreads.cfa" //
    3737// End: //
  • tests/loopctrl.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed Aug  8 18:32:59 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 12:05:05 2019
    13 // Update Count     : 106
     12// Last Modified On : Thu Dec 12 17:55:26 2019
     13// Update Count     : 108
    1414//
    1515
     
    4343        for ( 1 ) { sout | "A"; }                                                       sout | nl;
    4444        for ( 10 ) { sout | "A"; }                                                      sout | nl;
     45        for ( = 10 ) { sout | "A"; }                                            sout | nl;
    4546        for ( 1 ~= 10 ~ 2 ) { sout | "B"; }                                     sout | nl;
    4647        for ( 10 -~= 1 ~ 2 ) { sout | "C"; }                            sout | nl;
     
    4950
    5051        for ( i; 10 ) { sout | i; }                                                     sout | nl;
     52        for ( i; = 10 ) { sout | i; }                                           sout | nl;
    5153        for ( i; 1 ~= 10 ~ 2 ) { sout | i; }                            sout | nl;
    5254        for ( i; 10 -~= 1 ~ 2 ) { sout | i; }                           sout | nl;
     
    8789        for ( N ) { sout | "N"; }                                                       sout | nl;
    8890        for ( i; N ) { sout | i; }                                                      sout | nl;
     91        for ( i; = N ) { sout | i; }                                            sout | nl;
    8992        for ( i; N -~ 0 ) { sout | i; }                                         sout | nl | nl;
    9093
  • tests/nested-types.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Jul 9 10:20:03 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Nov  6 17:59:40 2018
    13 // Update Count     : 2
     12// Last Modified On : Wed Feb 12 18:21:15 2020
     13// Update Count     : 3
    1414//
    1515
     
    5050//   double d;
    5151// };
     52
     53// struct S {
     54//     enum C { R, G, B };
     55//     int i;
     56//     struct T {
     57//      int i;
     58//     };
     59//     T t;
     60// };
     61
     62// S s;
     63// S.C c;
     64// S.T t;
    5265
    5366int main() {
  • tests/pybin/settings.py

    r9fb8f01 r3d5701e  
    1414        SRCDIR = os.path.abspath(config.SRCDIR)
    1515        BUILDDIR = os.path.abspath(config.BUILDDIR)
     16        distribute = config.DISTRIBUTE
    1617        os.chdir(testpath)
    1718
     
    8889                self.string = "debug" if value else "no debug"
    8990                self.flags  = """DEBUG_FLAGS=%s""" % ("-debug -O0" if value else "-nodebug -O2")
     91                self.path   = "debug" if value else "nodebug"
    9092
    9193class Install:
    9294        def __init__(self, value):
    93                 self.string = "installed" if value else "in-tree"
    94                 self.flags  = """INSTALL_FLAGS=%s""" % ("" if value else "-in-tree")
     95                if value:
     96                        distribute = False
     97
     98                self.string = "installed" if value else "in tree"
     99                self.flags  = """installed=%s""" % ("yes" if value else "no")
    95100
    96101class Timeouts:
     
    109114def init( options ):
    110115        global arch
     116        global archive
     117        global debug
     118        global distcc
    111119        global dry_run
    112120        global generating
     121        global install
    113122        global make
    114         global debug
    115         global install
     123        global output_width
    116124        global timeout
    117         global output_width
    118         global archive
    119125
    120         dry_run      = options.dry_run
     126        arch         = Architecture(options.arch)
     127        archive      = os.path.abspath(os.path.join(original_path, options.archive_errors)) if options.archive_errors else None
     128        debug        = Debug(options.debug)
     129        dry_run      = options.dry_run # must be called before tools.config_hash()
     130        distcc       = "DISTCC_CFA_PATH=~/.cfadistcc/%s/cfa" % tools.config_hash()
    121131        generating   = options.regenerate_expected
     132        install      = Install(options.install)
    122133        make         = ['make']
    123         debug        = Debug(options.debug)
    124         install      = Install(options.install)
    125         arch         = Architecture(options.arch)
     134        output_width = 24
    126135        timeout      = Timeouts(options.timeout, options.global_timeout)
    127         output_width = 24
    128         archive      = os.path.abspath(os.path.join(original_path, options.archive_errors)) if options.archive_errors else None
    129136
     137        # if we distribute, distcc errors will fail tests, use log file for distcc
     138        # don't use "'DISTCC_LOG' not in os.environ" because it can be set to ''
     139        if distribute and not os.environ.get('DISTCC_LOG'):
     140                os.putenv('DISTCC_LOG', os.path.join(BUILDDIR, 'distcc_error.log'))
    130141
    131142def update_make_cmd(force, jobs):
     
    136147def validate():
    137148        errf = os.path.join(BUILDDIR, ".validate.err")
    138         make_ret, out = tools.make( ".validate", error_file = errf, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
     149        make_ret, out = tools.make( ".validate", error_file = errf, output_file=subprocess.DEVNULL, error=subprocess.DEVNULL )
    139150        if make_ret != 0:
    140151                with open (errf, "r") as myfile:
  • tests/pybin/tools.py

    r9fb8f01 r3d5701e  
    2323
    2424# helper functions to run terminal commands
    25 def sh(*cmd, timeout = False, output = None, input = None, error = subprocess.STDOUT):
    26         cmd = list(cmd)
    27 
    28         # if this is a dry_run, only print the commands that would be ran
    29         if settings.dry_run :
    30                 cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd))
    31                 if output and not isinstance(output, int):
    32                         cmd += " > "
    33                         cmd += output
    34 
    35                 if error and not isinstance(error, int):
    36                         cmd += " 2> "
    37                         cmd += error
    38 
    39                 if input and not isinstance(input, int) and os.path.isfile(input):
    40                         cmd += " < "
    41                         cmd += input
    42 
    43                 print(cmd)
    44                 return 0, None
    45 
    46         with contextlib.ExitStack() as onexit:
    47                 # add input redirection if needed
    48                 input = openfd(input, 'r', onexit, True)
    49 
    50                 # add output redirection if needed
    51                 output = openfd(output, 'w', onexit, False)
    52 
    53                 # add error redirection if needed
    54                 error = openfd(error, 'w', onexit, False)
    55 
    56                 # run the desired command
    57                 try:
    58                         proc = subprocess.run(
     25def sh(*cmd, timeout = False, output_file = None, input_file = None, input_text = None, error = subprocess.STDOUT, ignore_dry_run = False):
     26        try:
     27                cmd = list(cmd)
     28
     29                if input_file and input_text:
     30                        return 401, "Cannot use both text and file inputs"
     31
     32                # if this is a dry_run, only print the commands that would be ran
     33                if settings.dry_run and not ignore_dry_run:
     34                        cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd))
     35                        if output_file and not isinstance(output_file, int):
     36                                cmd += " > "
     37                                cmd += output_file
     38
     39                        if error and not isinstance(error, int):
     40                                cmd += " 2> "
     41                                cmd += error
     42
     43                        if input_file and not isinstance(input_file, int) and os.path.isfile(input_file):
     44                                cmd += " < "
     45                                cmd += input_file
     46
     47                        print(cmd)
     48                        return 0, None
     49
     50                with contextlib.ExitStack() as onexit:
     51                        # add input redirection if needed
     52                        input_file = openfd(input_file, 'r', onexit, True)
     53
     54                        # add output redirection if needed
     55                        output_file = openfd(output_file, 'w', onexit, False)
     56
     57                        # add error redirection if needed
     58                        error = openfd(error, 'w', onexit, False)
     59
     60                        # run the desired command
     61                        # use with statement to make sure proc is cleaned
     62                        # don't use subprocess.run because we want to send SIGABRT on exit
     63                        with subprocess.Popen(
    5964                                cmd,
    60                                 stdin =input,
    61                                 stdout=output,
    62                                 stderr=error,
    63                                 timeout=settings.timeout.single if timeout else None
    64                         )
    65                         return proc.returncode, proc.stdout.decode("utf-8") if proc.stdout else None
    66                 except subprocess.TimeoutExpired:
    67                         return 124, str(None)
     65                                **({'input' : bytes(input_text, encoding='utf-8')} if input_text else {'stdin' : input_file}),
     66                                stdout  = output_file,
     67                                stderr  = error
     68                        ) as proc:
     69
     70                                try:
     71                                        out, _ = proc.communicate(
     72                                                timeout = settings.timeout.single if timeout else None
     73                                        )
     74
     75                                        return proc.returncode, out.decode("utf-8") if out else None
     76                                except subprocess.TimeoutExpired:
     77                                        proc.send_signal(signal.SIGABRT)
     78                                        proc.communicate()
     79                                        return 124, str(None)
     80
     81        except Exception as ex:
     82                print ("Unexpected error: %s" % ex)
     83                raise
    6884
    6985def is_ascii(fname):
     
    7591                return False
    7692
    77         code, out = sh("file %s" % fname, output=subprocess.PIPE)
     93        code, out = sh("file %s" % fname, output_file=subprocess.PIPE)
    7894        if code != 0:
    7995                return False
     
    107123        if isinstance(files, str ): files = [ files ]
    108124        for file in files:
    109                 sh( 'rm', '-f', file, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
     125                sh( 'rm', '-f', file, output_file=subprocess.DEVNULL, error=subprocess.DEVNULL )
    110126
    111127# Create 1 or more directory
     
    115131                p = os.path.normpath( file )
    116132                d = os.path.dirname ( p )
    117                 sh( 'mkdir', '-p', d, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
     133                sh( 'mkdir', '-p', d, output_file=subprocess.DEVNULL, error=subprocess.DEVNULL )
    118134
    119135
     
    138154                lhs,
    139155                rhs,
    140                 output=subprocess.PIPE
     156                output_file=subprocess.PIPE
    141157        )
    142158
    143159# call make
    144 def make(target, *, flags = '', output = None, error = None, error_file = None, silent = False):
     160def make(target, *, flags = '', output_file = None, error = None, error_file = None, silent = False):
    145161        test_param = """test="%s" """ % (error_file) if error_file else None
    146162        cmd = [
     
    151167                settings.debug.flags,
    152168                settings.install.flags,
     169                settings.distcc if settings.distribute else None,
    153170                flags,
    154171                target
    155172        ]
    156173        cmd = [s for s in cmd if s]
    157         return sh(*cmd, output=output, error=error)
     174        return sh(*cmd, output_file=output_file, error=error)
    158175
    159176def which(program):
    160     fpath, fname = os.path.split(program)
    161     if fpath:
    162         if is_exe(program):
    163             return program
    164     else:
    165         for path in os.environ["PATH"].split(os.pathsep):
    166             exe_file = os.path.join(path, program)
    167             if is_exe(exe_file):
    168                 return exe_file
    169 
    170     return None
     177        fpath, fname = os.path.split(program)
     178        if fpath:
     179                if is_exe(program):
     180                        return program
     181        else:
     182                for path in os.environ["PATH"].split(os.pathsep):
     183                        exe_file = os.path.join(path, program)
     184                        if is_exe(exe_file):
     185                                return exe_file
     186        return None
    171187
    172188@contextlib.contextmanager
     
    201217# cat one file into the other
    202218def cat(source, dest):
    203         ret, _ = sh("cat", source, output=dest)
     219        ret, _ = sh("cat", source, output_file=dest)
    204220        return ret
    205221
     
    256272                        os.write(int(make_jobs_fds.group(3)), tokens)
    257273                else :
    258                         options.jobs = multiprocessing.cpu_count()
     274                        if settings.distribute:
     275                                ret, jstr = sh("distcc", "-j", output_file=subprocess.PIPE, ignore_dry_run=True)
     276                                if ret == 0:
     277                                        options.jobs = int(jstr.strip())
     278                                else :
     279                                        options.jobs = multiprocessing.cpu_count()
     280                        else:
     281                                options.jobs = multiprocessing.cpu_count()
    259282        else :
    260283                force = True
     
    274297################################################################################
    275298
     299# get hash for given configuration
     300def config_hash():
     301        path = os.path.normpath(os.path.join(
     302                settings.SRCDIR,
     303        ))
     304
     305        distcc_hash = os.path.join(settings.SRCDIR, '../tools/build/distcc_hash')
     306        config = "%s-%s" % (settings.arch.target, settings.debug.path)
     307        _, out = sh(distcc_hash, config, output_file=subprocess.PIPE, ignore_dry_run=True)
     308        return out.strip()
     309
     310# get pretty string for time of day
    276311def pretty_now():
    277312        ts = time.time()
     
    308343                return 1, "ERR No core dump"
    309344
    310         return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output=subprocess.PIPE)
     345        return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output_file=subprocess.PIPE)
    311346
    312347def core_archive(dst, name, exe):
    313         # Get the files to copy
     348        # Get the core dump
    314349        core = os.path.join(os.getcwd(), "core" )
    315350
    316         # Uncomment if we want timestamps on coredumps
    317         # dst  = os.path.join(dst, "%s_%s" % (name, pretty_now()))
     351        # update the path for this test
     352        dst  = os.path.join(dst, name)
    318353
    319354        # make a directory for this test
    320         mkdir(os.path.join(dst, "dir"))
     355        # mkdir makes the parent directory only so add a dummy
     356        mkdir(os.path.join(dst, name ))
    321357
    322358        # moves the files
     
    328364
    329365class Timed:
    330     def __enter__(self):
    331         self.start = time.time()
    332         return self
    333 
    334     def __exit__(self, *args):
    335         self.end = time.time()
    336         self.duration = self.end - self.start
     366        def __enter__(self):
     367                self.start = time.time()
     368                return self
     369
     370        def __exit__(self, *args):
     371                self.end = time.time()
     372                self.duration = self.end - self.start
    337373
    338374def timed(src, timeout):
    339375        expire = time.time() + timeout
    340376        i = iter(src)
    341         while True:
    342                 yield i.next(max(expire - time.time(), 0))
     377        with contextlib.suppress(StopIteration):
     378                while True:
     379                        yield i.next(max(expire - time.time(), 0))
  • tests/quotedKeyword.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  4 21:45:53 2018
    13 // Update Count     : 23
     12// Last Modified On : Fri Feb  7 19:07:07 2020
     13// Update Count     : 25
    1414//
    1515
     
    1717
    1818struct {
    19         int `otype`;
    20         int `struct`;
     19        int ``otype;
     20        int ``struct;
    2121} st = { 10, 10 };
    2222
    23 typedef int `forall`;
    24 `forall` xxx = 10;
     23typedef int ``forall;
     24``forall xxx = 10;
    2525
    26 int `_Alignas`, `_Alignof`, `__alignof`, `__alignof__`, `asm`, `__asm`, `__asm__`, `_At`, `_Atomic`, `__attribute`,
    27         `__attribute__`, `auto`, `_Bool`, `break`, `case`, `catch`, `catchResume`, `char`, `choose`, `_Complex`, `__complex`,
    28         `__complex__`, `const`, `__const`, `__const__`, `continue`, `default`, `disable`, `do`, `double`, `dtype`, `else`,
    29         `enable`, `enum`, `__extension__`, `extern`, `fallthru`, `finally`, `float`, `__float128`, `for`, `forall`, `fortran`,
    30         `ftype`, `_Generic`, `goto`, `if`, `_Imaginary`, `__imag`, `__imag__`, `inline`, `__inline`, `__inline__`, `int`,
    31         `__int128`, `__label__`, `long`, `lvalue`, `_Noreturn`, `__builtin_offsetof`, `otype`, `register`, `restrict`,
    32         `__restrict`, `__restrict__`, `return`, `short`, `signed`, `__signed`, `__signed__`, `sizeof`, `static`,
    33         `_Static_assert`, `struct`, `switch`, `_Thread_local`, `throw`, `throwResume`, `trait`, `try`, `typedef`,
    34         `typeof`, `__typeof`, `__typeof__`, `union`, `unsigned`, `__builtin_va_list`, `void`, `volatile`, `__volatile`,
    35         `__volatile__`, `while`;
     26int ``_Alignas, ``_Alignof, ``__alignof, ``__alignof__, ``asm, ``__asm, ``__asm__, ``_At, ``_Atomic, ``__attribute,
     27        ``__attribute__, ``auto, ``_Bool, ``break, ``case, ``catch, ``catchResume, ``char, ``choose, ``_Complex, ``__complex,
     28        ``__complex__, ``const, ``__const, ``__const__, ``continue, ``default, ``disable, ``do, ``double, ``dtype, ``else,
     29        ``enable, ``enum, ``__extension__, ``extern, ``fallthru, ``finally, ``float, ``__float128, ``for, ``forall, ``fortran,
     30        ``ftype, ``_Generic, ``goto, ``if, ``_Imaginary, ``__imag, ``__imag__, ``inline, ``__inline, ``__inline__, ``int,
     31        ``__int128, ``__label__, ``long, ``lvalue, ``_Noreturn, ``__builtin_offsetof, ``otype, ``register, ``restrict,
     32        ``__restrict, ``__restrict__, ``return, ``short, ``signed, ``__signed, ``__signed__, ``sizeof, ``static,
     33        ``_Static_assert, ``struct, ``switch, ``_Thread_local, ``throw, ``throwResume, ``trait, ``try, ``typedef,
     34        ``typeof, ``__typeof, ``__typeof__, ``union, ``unsigned, ``__builtin_va_list, ``void, ``volatile, ``__volatile,
     35        ``__volatile__, ``while;
    3636
    3737int main() {
    38         int `if` = 0;
    39         `catch` = 1;
    40         st.`otype` = 2;
    41         st.`struct` = 3;
    42         `throw` = 4;
    43         sout | `catch` + st.`otype` + st.`struct` + `throw`;
     38        int ``if = 0;
     39        ``catch = 1;
     40        st.``otype = 2;
     41        st.``struct = 3;
     42        ``throw = 4;
     43        sout | ``catch + st.``otype + st.``struct + ``throw;
    4444}
    4545
  • tests/raii/dtor-early-exit.cfa

    r9fb8f01 r3d5701e  
    217217}
    218218
     219void i() {
     220        // potential loop
     221        for() {
     222                if(true) continue;
     223                int t = 0;
     224        }
     225}
     226
    219227// TODO: implement __label__ and uncomment these lines
    220228void computedGoto() {
  • tests/rational.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar 27 07:37:17 2019
    13 // Update Count     : 80
     12// Last Modified On : Sat Feb  8 18:46:23 2020
     13// Update Count     : 86
    1414//
    1515
     
    1919#include <fstream.hfa>
    2020
    21 double convert( int i ) { return (double)i; }
     21typedef Rational(int) RatInt;
     22double convert( int i ) { return (double)i; }                   // used by narrow/widen
    2223int convert( double d ) { return (int)d; }
    2324
    2425int main() {
    2526        sout | "constructor";
    26         Rational(int) a = { 3 }, b = { 4 }, c;
    27         sout | a | b | c;
     27        RatInt a = { 3 }, b = { 4 }, c, d = 0, e = 1;
     28        sout | a | b | c | d | e;
    2829
    29         a = (Rational(int)){ 4, 8 };
    30         b = (Rational(int)){ 5, 7 };
     30        a = (RatInt){ 4, 8 };
     31        b = (RatInt){ 5, 7 };
    3132        sout | a | b;
    32         a = (Rational(int)){ -2, -3 };
    33         b = (Rational(int)){ 3, -2 };
     33        a = (RatInt){ -2, -3 };
     34        b = (RatInt){ 3, -2 };
    3435        sout | a | b;
    35         a = (Rational(int)){ -2, 3 };
    36         b = (Rational(int)){ 3, 2 };
     36        a = (RatInt){ -2, 3 };
     37        b = (RatInt){ 3, 2 };
    3738        sout | a | b;
    3839
    3940        sout | "logical";
    40         a = (Rational(int)){ -2 };
    41         b = (Rational(int)){ -3, 2 };
     41        a = (RatInt){ -2 };
     42        b = (RatInt){ -3, 2 };
    4243        sout | a | b;
    4344//      sout | a == 1; // FIX ME
     
    5859
    5960        sout | "conversion";
    60         a = (Rational(int)){ 3, 4 };
     61        a = (RatInt){ 3, 4 };
    6162        sout | widen( a );
    62         a = (Rational(int)){ 1, 7 };
     63        a = (RatInt){ 1, 7 };
    6364        sout | widen( a );
    64         a = (Rational(int)){ 355, 113 };
     65        a = (RatInt){ 355, 113 };
    6566        sout | widen( a );
    6667        sout | narrow( 0.75, 4 );
     
    7475
    7576        sout | "more tests";
    76         Rational(int) x = { 1, 2 }, y = { 2 };
     77        RatInt x = { 1, 2 }, y = { 2 };
    7778        sout | x - y;
    7879        sout | x > y;
     
    8081        sout | y | denominator( y, -2 ) | y;
    8182
    82         Rational(int) z = { 0, 5 };
     83        RatInt z = { 0, 5 };
    8384        sout | z;
    8485
    8586        sout | x | numerator( x, 0 ) | x;
    8687
    87         x = (Rational(int)){ 1, MAX } + (Rational(int)){ 1, MAX };
     88        x = (RatInt){ 1, MAX } + (RatInt){ 1, MAX };
    8889        sout | x;
    89         x = (Rational(int)){ 3, MAX } + (Rational(int)){ 2, MAX };
     90        x = (RatInt){ 3, MAX } + (RatInt){ 2, MAX };
    9091        sout | x;
    9192
  • tests/references.cfa

    r9fb8f01 r3d5701e  
    119119                f( 3, a + b, (S){ 1.0, 7.0 }, (int [3]){ 1, 2, 3 } ); // two rvalue to reference
    120120        }
     121
     122        {
     123                int a = 3;
     124                int *p = &a;
     125                asm (
     126                        "incl %[p]\n\t"
     127                        : [p] "+m" (*p)
     128                );
     129                printf("%d\n", a);
     130        }
    121131}
    122132
  • tests/test.py

    r9fb8f01 r3d5701e  
    1010import tempfile
    1111import time
     12
     13import os
     14import psutil
     15import signal
    1216
    1317################################################################################
     
    143147        # build, skipping to next test on error
    144148        with Timed() as comp_dur:
    145                 make_ret, _ = make( test.target(), output=subprocess.DEVNULL, error=out_file, error_file = err_file )
     149                make_ret, _ = make( test.target(), output_file=subprocess.DEVNULL, error=out_file, error_file = err_file )
    146150
    147151        run_dur = None
    148152        # run everything in a temp directory to make sure core file are handled properly
    149153        with tempdir():
    150                 # if the make command succeds continue otherwise skip to diff
     154                # if the make command succeeds continue otherwise skip to diff
    151155                if success(make_ret):
    152156                        with Timed() as run_dur:
    153157                                if settings.dry_run or is_exe(exe_file):
    154158                                        # run test
    155                                         retcode, _ = sh(exe_file, output=out_file, input=in_file, timeout=True)
     159                                        retcode, _ = sh(exe_file, output_file=out_file, input_file=in_file, timeout=True)
    156160                                else :
    157161                                        # simply cat the result into the output
     
    210214        except KeyboardInterrupt:
    211215                return False, ""
    212         except:
    213                 print("Unexpected error in worker thread", file=sys.stderr)
     216        except Exception as ex:
     217                print("Unexpected error in worker thread: %s" % ex, file=sys.stderr)
    214218                sys.stderr.flush()
    215219                return False, ""
     
    219223def run_tests(tests, jobs) :
    220224        # clean the sandbox from previous commands
    221         make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL)
     225        make('clean', output_file=subprocess.DEVNULL, error=subprocess.DEVNULL)
     226
     227        # since python prints stacks by default on a interrupt, redo the interrupt handling to be silent
     228        def worker_init():
     229                def sig_int(signal_num, frame):
     230                        pass
     231
     232                signal.signal(signal.SIGINT, sig_int)
    222233
    223234        # create the executor for our jobs and handle the signal properly
    224         pool = multiprocessing.Pool(jobs)
     235        pool = multiprocessing.Pool(jobs, worker_init)
    225236
    226237        failed = False
     238
     239        def stop(x, y):
     240                print("Tests interrupted by user", file=sys.stderr)
     241                sys.exit(1)
     242        signal.signal(signal.SIGINT, stop)
    227243
    228244        # for each test to run
     
    260276
    261277        # clean the workspace
    262         make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL)
     278        make('clean', output_file=subprocess.DEVNULL, error=subprocess.DEVNULL)
    263279
    264280        return 1 if failed else 0
  • tests/time.cfa

    r9fb8f01 r3d5701e  
    1010// Created On       : Tue Mar 27 17:24:56 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Dec 20 23:09:21 2018
    13 // Update Count     : 23
     12// Last Modified On : Sun Jan  5 18:27:37 2020
     13// Update Count     : 34
    1414//
    1515
     
    2020        Duration d1 = 3`h, d2 = 2`s, d3 = 3.375`s, d4 = 12`s, d5 = 1`s + 10_000`ns;
    2121        sout | d1 | d2 | d3 | d4 | d5;
    22         int i;
    2322        d1 = 0;
    2423        sout | d1 | d2 | d3;
     
    3534        sout | t;
    3635        t = t + d1;
    37         sout | t | t.tv;
     36        sout | t | t`ns;
    3837        Time t1 = (timespec){ 104_414, 10_000_000 };
    39         sout | t1 | t1.tv;
    40         sout | t - t  | t + d5 | t.tv;
    41         char buf[16];
     38        sout | t1 | t1`ns;
     39        sout | t - t  | t + d5 | t`ns;
     40        char buf[64];
    4241        sout | "yy/mm/dd" | [t, buf]`ymd | nonl;                        // shared buf => separate calls
    4342        sout | "mm/dd/yy" | mm_dd_yy( t, buf ) | nonl;
     
    4645        sout | "dd/yy/mm" | [t, buf]`dmy;
    4746        Time t2 = { 2001, 7, 4, 0, 0, 1, 0 }, t3 = (timeval){ 994_219_201 };
    48         sout | t2 | t2.tv | nl | t3 | t3.tv;
     47        sout | t2 | t2`ns | nl | t3 | t3`ns;
    4948        sout | nl;
    5049
     
    6362        sout | "Dividing that by 2 gives" | s / 2 | "seconds";
    6463        sout | s | "seconds is" | s`h | "hours," | (s % 1`h)`m | "minutes," | (s % 1`m)`s | "seconds";
     64
     65    t1 = (Time){ 2020, 1, 5, 9, 0, 0, 100000000000LL };
     66    t2 = (Time){ 1969, 13, 5, 9 };
     67    t3 = (Time){ 1970, 25, 366, 48, 120, -120, 60000000000LL };
     68    strftime( buf, 128, "%Y %b %e %H:%M:%S (GMT)", t1 );
     69    sout | buf;
     70    strftime( buf, 128, "%Y %b %e %H:%M:%S (GMT)", t2 );
     71    sout | buf;
     72    strftime( buf, 128, "%Y %b %e %H:%M:%S (GMT)", t3 );
     73    sout | buf;
    6574} // main
    6675
  • tests/userLiterals.cfa

    r9fb8f01 r3d5701e  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // user_literals.cfa --
     7// userLiterals.cfa --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed Sep  6 21:40:50 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  4 22:03:10 2018
    13 // Update Count     : 56
     12// Last Modified On : Wed Feb 19 07:48:45 2020
     13// Update Count     : 74
    1414//
    1515
     
    2424int ?`__thingy_( int x ) { sout | "_thingy_" | x; return x; }
    2525
    26 int ?`s( const char * s ) { sout | "secs" | s; return 0; }
    27 int ?`m( const char16_t * m ) { sout | "mins" | m; return 0;}
    28 int ?`h( const char32_t * h ) { sout | "hours" | h; return 0; }
     26int ?`s( const char * s ) { sout | "s" | s; return 0; }
     27int ?`m( const char16_t * m ) { sout | "m" | m; return 0;}
     28int ?`h( const char32_t * h ) { sout | "h" | h; return 0; }
    2929int ?`_A_( const wchar_t * str ) { sout | "_A_" | str; return 0; }
    3030int ?`__thingy_( const char * str ) { sout | "_thingy_" | str; return 0; }
     
    3737        return (Weight){ l.stones + r.stones };
    3838}
    39 ofstream & ?|?( ofstream & os, Weight w ) { return os | w.stones; }
     39ofstream & ?|?( ofstream & os, Weight w ) { return os | wd(1,1, w.stones); }
     40void ?|?( ofstream & os, Weight w ) { (ofstream)(os | w); ends( os ); }
    4041
    4142Weight ?`st( double w ) { return (Weight){ w }; }               // backquote for user literals
     
    6061        sout | w;
    6162
    62 //      0`secs;
     63        0`s;
    6364        1`s;
    6465        23`s;
     
    8283
    8384        "abc"`s;
    84 //      u"abc"`m;
    85 //      U_"abc"`h;
    86 //      L"abc"`_A_;
     85        // FIX ME: requires char16_t, char32_t, and wchar_t be unique types
     86        // u"abc"`m;
     87        // U_"abc"`h;
     88        // L"abc"`_A_;
    8789        u8_"abc"`__thingy_;
    8890} // main
     
    9092// Local Variables: //
    9193// tab-width: 4 //
    92 // compile-command: "cfa user_literals.cfa" //
     94// compile-command: "cfa userLiterals.cfa" //
    9395// End: //
  • tools/Makefile.in

    r9fb8f01 r3d5701e  
    208208CCDEPMODE = @CCDEPMODE@
    209209CFACC = @CFACC@
     210CFACC_INSTALL = @CFACC_INSTALL@
    210211CFACPP = @CFACPP@
    211212CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    238239FGREP = @FGREP@
    239240GREP = @GREP@
     241HAS_DISTCC = @HAS_DISTCC@
    240242HOST_FLAGS = @HOST_FLAGS@
    241243INSTALL = @INSTALL@
  • tools/catchsig.c

    r9fb8f01 r3d5701e  
    2121        printf("Starting...\n");
    2222        sig(SIGHUP);
    23       sig(SIGINT);
    24       sig(SIGQUIT);
    25       sig(SIGILL);
    26       sig(SIGABRT);
    27       sig(SIGFPE);
    28       sig(SIGSEGV);
    29       sig(SIGPIPE);
    30       sig(SIGALRM);
    31       sig(SIGTERM);
    32       sig(SIGUSR1);
    33       sig(SIGUSR2);
    34       sig(SIGCHLD);
    35       sig(SIGCONT);
    36       sig(SIGTSTP);
    37       sig(SIGTTIN);
    38       sig(SIGTTOU);
     23        sig(SIGINT);
     24        sig(SIGQUIT);
     25        sig(SIGILL);
     26        sig(SIGABRT);
     27        sig(SIGFPE);
     28        sig(SIGSEGV);
     29        sig(SIGPIPE);
     30        sig(SIGALRM);
     31        sig(SIGTERM);
     32        sig(SIGUSR1);
     33        sig(SIGUSR2);
     34        sig(SIGCHLD);
     35        sig(SIGCONT);
     36        sig(SIGTSTP);
     37        sig(SIGTTIN);
     38        sig(SIGTTOU);
    3939        while(1);
    4040        return 0;
  • tools/prettyprinter/Makefile.in

    r9fb8f01 r3d5701e  
    237237CCDEPMODE = @CCDEPMODE@
    238238CFACC = @CFACC@
     239CFACC_INSTALL = @CFACC_INSTALL@
    239240CFACPP = @CFACPP@
    240241CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    267268FGREP = @FGREP@
    268269GREP = @GREP@
     270HAS_DISTCC = @HAS_DISTCC@
    269271HOST_FLAGS = @HOST_FLAGS@
    270272INSTALL = @INSTALL@
  • tools/stat.py

    r9fb8f01 r3d5701e  
    1717                avg = numpy.mean  (content)
    1818                std = numpy.std   (content)
    19                 print "median {0:.1f} avg {1:.1f} stddev {2:.2f}".format( med, avg, std )
     19                print "median {0:.1f} avg {1:.1f} stddev {2:.1f}".format( med, avg, std )
    2020
    2121
Note: See TracChangeset for help on using the changeset viewer.