Changeset 4a60488


Ignore:
Timestamp:
Sep 27, 2019, 3:35:46 PM (3 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
90ce35aa
Parents:
8e1467d (diff), 849720f (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:

Merged from master taking the lvalue changes to expression and everything before that.

Files:
15 added
1 deleted
83 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r8e1467d r4a60488  
    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

    r8e1467d r4a60488  
    132132
    133133<img src="https://cforall.uwaterloo.ca/jenkins/job/Cforall/job/master/plot/Compilation/getPlot?index=0" >
     134<img src="https://cforall.uwaterloo.ca/jenkins/job/Cforall/job/master/plot/Compilation/getPlot?index=1" >
    134135
    135136<p>- Logs ----------------------------------------------------------------</p>
  • Jenkinsfile_disabled

    r8e1467d r4a60488  
    106106
    107107def build() {
    108         // build_stage('Build', true) {
    109         //      // Build outside of the src tree to ease cleaning
    110         //      dir (BuildDir) {
    111         //              //Configure the conpilation (Output is not relevant)
    112         //              //Use the current directory as the installation target so nothing escapes the sandbox
    113         //              //Also specify the compiler by hand
    114         //              targets=""
    115         //              if( Settings.RunAllTests || Settings.RunBenchmark ) {
    116         //                      targets="--with-target-hosts='host:debug,host:nodebug'"
    117         //              } else {
    118         //                      targets="--with-target-hosts='host:debug'"
    119         //              }
    120 
    121         //              sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
    122 
    123         //              //Compile the project
    124         //              sh 'make -j 8 --no-print-directory'
    125         //      }
    126         // }
    127 
    128108        debug = true
    129109        release = Settings.RunAllTests || Settings.RunBenchmark
     
    175155
    176156def test() {
    177         build_stage('Test: short', !Settings.RunAllTests) {
     157        try {
     158                build_stage('Test: short', !Settings.RunAllTests) {
     159                        dir (BuildDir) {
     160                                //Run the tests from the tests directory
     161                                sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
     162                        }
     163                }
     164
     165                build_stage('Test: full', Settings.RunAllTests) {
     166                        dir (BuildDir) {
     167                                        //Run the tests from the tests directory
     168                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
     169                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
     170                        }
     171                }
     172        }
     173        catch (Exception err) {
     174                echo "Archiving core dumps"
    178175                dir (BuildDir) {
    179                         //Run the tests from the tests directory
    180                         sh 'make --no-print-directory -C tests'
    181                 }
    182         }
    183 
    184         build_stage('Test: full', Settings.RunAllTests) {
    185                 dir (BuildDir) {
    186                         //Run the tests from the tests directory
    187                         sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes'
    188                         sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no '
    189                 }
     176                        archiveArtifacts artifacts: "tests/crashes/**/*", fingerprint: true
     177                }
     178                throw err
    190179        }
    191180}
     
    195184                dir (BuildDir) {
    196185                        //Append bench results
    197                         sh "make --no-print-directory -C benchmark jenkins"
     186                        sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
    198187                }
    199188        }
     
    217206                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
    218207
    219                 def groupCompile = new PlotGroup('Compilation', 'seconds', true)
    220                 def groupConcurrency = new PlotGroup('Concurrency', 'nanoseconds', false)
     208                def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
     209                def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
    221210
    222211                //Then publish the results
    223                 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'  , groupCompile    , 'Compilation')
    224                 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch', groupConcurrency, 'Context Switching')
    225                 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'    , groupConcurrency, 'Mutual Exclusion')
    226                 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal'   , groupConcurrency, 'Internal and External Scheduling')
     212                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'       , groupCompile    , false, 'Compilation')
     213                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff'  , groupCompile    , true , 'Compilation (relative)')
     214                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch'     , groupConcurrency, false, 'Context Switching')
     215                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff', groupConcurrency, true , 'Context Switching (relative)')
     216                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'         , groupConcurrency, false, 'Mutual Exclusion')
     217                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff'    , groupConcurrency, true , 'Mutual Exclusion (relative)')
     218                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal'        , groupConcurrency, false, 'Internal and External Scheduling')
     219                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal.diff'   , groupConcurrency, true , 'Internal and External Scheduling (relative)')
    227220        }
    228221}
     
    482475}
    483476
    484 def do_plot(boolean new_data, String file, PlotGroup group, String title) {
     477def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
    485478
    486479        if(new_data) {
     
    505498                        exclZero: false,
    506499                        keepRecords: false,
    507                         logarithmic: group.log,
     500                        logarithmic: !relative && group.log,
    508501                        numBuilds: '120',
    509502                        useDescr: true,
  • Makefile.in

    r8e1467d r4a60488  
    264264CCDEPMODE = @CCDEPMODE@
    265265CFACC = @CFACC@
     266CFACC_INSTALL = @CFACC_INSTALL@
    266267CFACPP = @CFACPP@
    267268CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    281282CYGPATH_W = @CYGPATH_W@
    282283DEFS = @DEFS@
     284DEMANGLER = @DEMANGLER@
    283285DEPDIR = @DEPDIR@
    284286DLLTOOL = @DLLTOOL@
     
    293295FGREP = @FGREP@
    294296GREP = @GREP@
     297HAS_DISTCC = @HAS_DISTCC@
    295298HOST_FLAGS = @HOST_FLAGS@
    296299INSTALL = @INSTALL@
     
    306309LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    307310LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     311LIBDEMANGLE = @LIBDEMANGLE@
    308312LIBOBJS = @LIBOBJS@
    309313LIBS = @LIBS@
  • automake/cfa.m4

    r8e1467d r4a60488  
    6666                "x86-64"     ) cannon_arch_name="x64";;
    6767                "x86_64"     ) cannon_arch_name="x64";;
     68                "aarch64"    ) cannon_arch_name="arm";;
    6869                "x86"        ) cannon_arch_name="x86";;
    6970                "i386"       ) cannon_arch_name="x86";;
     
    7576                "armv7l"     ) cannon_arch_name="arm";;
    7677                *)
    77                 >&2 echo "Unkown architecture " $arch_name;
     78                >&2 echo "Unknown architecture " $arch_name;
    7879                exit 1
    7980                ;;
  • benchmark/Makefile.am

    r8e1467d r4a60488  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Jun 24 16:45:42 2019
    14 ## Update Count     : 53
     13## Last Modified On : Mon Jul 29 18:02:19 2019
     14## Update Count     : 54
    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
     
    5050REPEAT   = ${abs_top_builddir}/tools/repeat
    5151STATS    = ${abs_top_srcdir}/tools/stat.py
    52 repeats  = 3 # 30
     52# NEED AT LEAST 4 DATA VALUES FOR BENCHMARKS BECAUSE THE MAX AND MIN VALUES ARE REMOVED
     53repeats  = 5 # 31 for benchmarks
     54arch     = x64
    5355skipcompile = no
    5456TIME_FORMAT = "%E"
     
    99101@DOifskipcompile@
    100102        @+make compile.csv
     103        @-+make compile.diff.csv
    101104@DOendif@
    102105        @+make ctxswitch.csv
     106        @-+make ctxswitch.diff.csv
    103107        @+make mutex.csv
     108        @-+make mutex.diff.csv
    104109        @+make signal.csv
     110        @-+make signal.diff.csv
    105111@DOifskipcompile@
    106         @cat compile.csv
     112        cat compile.csv
     113        -cat compile.diff.csv
    107114@DOendif@
    108         @cat ctxswitch.csv
    109         @cat mutex.csv
    110         @cat signal.csv
     115        cat ctxswitch.csv
     116        -cat ctxswitch.diff.csv
     117        cat mutex.csv
     118        -cat mutex.diff.csv
     119        cat signal.csv
     120        -cat signal.diff.csv
    111121
    112122compile.csv:
     
    142152        @+make waitfor-cfa2.runquiet >> $@
    143153        @$(srcdir)/fixcsv.sh $@
     154
     155%.diff.csv: %.csv
     156        @test -e $(srcdir)/baselines/$(arch)/$< || (echo "Error : Missing baseline for ${<}" && false)
     157        @$(srcdir)/baselines/calc.py $(srcdir)/baselines/$(arch)/$(<) $(<) > $@
     158
    144159
    145160## =========================================================================================================
  • benchmark/Makefile.in

    r8e1467d r4a60488  
    214214CCDEPMODE = @CCDEPMODE@
    215215CFACC = @CFACC@
     216CFACC_INSTALL = @CFACC_INSTALL@
    216217CFACPP = @CFACPP@
    217218CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    231232CYGPATH_W = @CYGPATH_W@
    232233DEFS = @DEFS@
     234DEMANGLER = @DEMANGLER@
    233235DEPDIR = @DEPDIR@
    234236DLLTOOL = @DLLTOOL@
     
    243245FGREP = @FGREP@
    244246GREP = @GREP@
     247HAS_DISTCC = @HAS_DISTCC@
    245248HOST_FLAGS = @HOST_FLAGS@
    246249INSTALL = @INSTALL@
     
    256259LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    257260LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     261LIBDEMANGLE = @LIBDEMANGLE@
    258262LIBOBJS = @LIBOBJS@
    259263LIBS = @LIBS@
     
    372376# applies to both programs
    373377AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror
    374 AM_CFAFLAGS = -quiet -nodebug -in-tree
     378AM_CFAFLAGS = -quiet -nodebug
    375379AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
    376380BENCH_V_CC = $(__bench_v_CC_$(__quiet))
     
    396400REPEAT = ${abs_top_builddir}/tools/repeat
    397401STATS = ${abs_top_srcdir}/tools/stat.py
    398 repeats = 3 # 30
     402# NEED AT LEAST 4 DATA VALUES FOR BENCHMARKS BECAUSE THE MAX AND MIN VALUES ARE REMOVED
     403repeats = 5 # 31 for benchmarks
     404arch = x64
    399405skipcompile = no
    400406TIME_FORMAT = "%E"
     
    761767@DOifskipcompile@
    762768        @+make compile.csv
     769        @-+make compile.diff.csv
    763770@DOendif@
    764771        @+make ctxswitch.csv
     772        @-+make ctxswitch.diff.csv
    765773        @+make mutex.csv
     774        @-+make mutex.diff.csv
    766775        @+make signal.csv
     776        @-+make signal.diff.csv
    767777@DOifskipcompile@
    768         @cat compile.csv
     778        cat compile.csv
     779        -cat compile.diff.csv
    769780@DOendif@
    770         @cat ctxswitch.csv
    771         @cat mutex.csv
    772         @cat signal.csv
     781        cat ctxswitch.csv
     782        -cat ctxswitch.diff.csv
     783        cat mutex.csv
     784        -cat mutex.diff.csv
     785        cat signal.csv
     786        -cat signal.diff.csv
    773787
    774788compile.csv:
     
    805819        @$(srcdir)/fixcsv.sh $@
    806820
     821%.diff.csv: %.csv
     822        @test -e $(srcdir)/baselines/$(arch)/$< || (echo "Error : Missing baseline for ${<}" && false)
     823        @$(srcdir)/baselines/calc.py $(srcdir)/baselines/$(arch)/$(<) $(<) > $@
     824
    807825loop$(EXEEXT):
    808826        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=5000000000 $(srcdir)/loop.c
  • benchmark/creation/JavaThread.java

    r8e1467d r4a60488  
    11public class JavaThread {
     2        // Simplistic low-quality Marsaglia Shift-XOR pseudo-random number generator.
     3        // Bijective   
     4        // Cycle length for non-zero values is 4G-1.
     5        // 0 is absorbing and should be avoided -- fixed point.
     6        // The returned value is typically masked to produce a positive value.
     7        static volatile int Ticket = 0 ;
     8
     9        private static int nextRandom (int x) {
     10                if (x == 0) {
     11                        // reseed the PRNG
     12                        // Ticket is accessed infrequently and does not constitute a coherence hot-spot.
     13                        // Note that we use a non-atomic racy increment -- the race is rare and benign.
     14                        // If the race is a concern switch to an AtomicInteger. 
     15                        // In addition accesses to the RW volatile global "Ticket"  variable are not
     16                        // (readily) predictable at compile-time so the JIT will not be able to elide
     17                        // nextRandom() invocations. 
     18                        x = ++Ticket ;
     19                        if (x == 0) x = 1 ;
     20                }
     21                x ^= x << 6;
     22                x ^= x >>> 21;
     23                x ^= x << 7;
     24                return x ;   
     25        }
     26        static int x = 2;
     27
     28        static private final int NoOfTimes = Integer.parseInt("10000") ;
     29
    230        public static class MyThread extends Thread {
    331                @Override
    432                public void run() {}
    533        }
    6 
    7         public static void main(String[] args) throws InterruptedException {
    8                 int NoOfTimes = 50000;
    9                 long start = System.nanoTime();
     34        public static void helper() throws InterruptedException {
    1035                for(int i = 1; i <= NoOfTimes; i += 1) {
    11                         JavaThread.MyThread m = new JavaThread.MyThread();
    12                         m.start();
     36                        MyThread m = new MyThread();
     37                        x = nextRandom( x );
     38                        m.start();
    1339                        m.join();
    1440                }
     41        }
     42        public static void InnerMain() throws InterruptedException {
     43                long start = System.nanoTime();
     44                helper();
    1545                long end = System.nanoTime();
    16                 System.out.println( (end - start) / NoOfTimes);
     46                System.out.println( (end - start) / NoOfTimes );
     47        }
     48        public static void main(String[] args) throws InterruptedException {
     49                for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
     50                        InnerMain();
     51                        Thread.sleep(2000);     // 2 seconds
     52                        x = nextRandom(x);
     53                }
     54                if ( x == 0 ) System.out.println(x);
    1755        }
    1856}
  • benchmark/ctxswitch/JavaThread.java

    r8e1467d r4a60488  
    11public class JavaThread {
    2         public static void main(String[] args) {
    3                 int NoOfTimes = 5000000;
    4                 long start = System.nanoTime();
     2        // Simplistic low-quality Marsaglia Shift-XOR pseudo-random number generator.
     3        // Bijective   
     4        // Cycle length for non-zero values is 4G-1.
     5        // 0 is absorbing and should be avoided -- fixed point.
     6        // The returned value is typically masked to produce a positive value.
     7        static volatile int Ticket = 0 ;
     8
     9        private static int nextRandom (int x) {
     10                if (x == 0) {
     11                        // reseed the PRNG
     12                        // Ticket is accessed infrequently and does not constitute a coherence hot-spot.
     13                        // Note that we use a non-atomic racy increment -- the race is rare and benign.
     14                        // If the race is a concern switch to an AtomicInteger. 
     15                        // In addition accesses to the RW volatile global "Ticket"  variable are not
     16                        // (readily) predictable at compile-time so the JIT will not be able to elide
     17                        // nextRandom() invocations. 
     18                        x = ++Ticket ;
     19                        if (x == 0) x = 1 ;
     20                }
     21                x ^= x << 6;
     22                x ^= x >>> 21;
     23                x ^= x << 7;
     24                return x ;   
     25        }
     26        static int x = 2;
     27
     28        static private final int NoOfTimes = Integer.parseInt("1000000") ;
     29
     30        public static void helper() {
    531                for(int i = 1; i <= NoOfTimes; i += 1) {
    632                        Thread.yield();
    733                }
     34        }
     35        public static void InnerMain() {
     36                long start = System.nanoTime();
     37                helper();
    838                long end = System.nanoTime();
    9                 System.out.println( (end - start) / NoOfTimes);
     39                System.out.println( (end - start) / NoOfTimes );
     40        }
     41        public static void main(String[] args) throws InterruptedException {
     42                for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
     43                        InnerMain();
     44                        Thread.sleep(2000);     // 2 seconds
     45                        x = nextRandom(x);
     46                }
     47                if ( x == 0 ) System.out.println(x);
    1048        }
    1149}
  • benchmark/mutex/JavaThread.java

    r8e1467d r4a60488  
    11public class JavaThread {
    2         public synchronized void noop() {}
     2        // Simplistic low-quality Marsaglia Shift-XOR pseudo-random number generator.
     3        // Bijective   
     4        // Cycle length for non-zero values is 4G-1.
     5        // 0 is absorbing and should be avoided -- fixed point.
     6        // The returned value is typically masked to produce a positive value.
     7        static volatile int Ticket = 0 ;
    38
    4         public static void main(String[] args) {
    5                 int NoOfTimes = 5000000;
     9        private static int nextRandom (int x) {
     10                if (x == 0) {
     11                        // reseed the PRNG
     12                        // Ticket is accessed infrequently and does not constitute a coherence hot-spot.
     13                        // Note that we use a non-atomic racy increment -- the race is rare and benign.
     14                        // If the race is a concern switch to an AtomicInteger. 
     15                        // In addition accesses to the RW volatile global "Ticket"  variable are not
     16                        // (readily) predictable at compile-time so the JIT will not be able to elide
     17                        // nextRandom() invocations. 
     18                        x = ++Ticket ;
     19                        if (x == 0) x = 1 ;
     20                }
     21                x ^= x << 6;
     22                x ^= x >>> 21;
     23                x ^= x << 7;
     24                return x ;   
     25        }
     26        static int x = 2;
     27
     28        static private final int NoOfTimes = Integer.parseInt("100000000") ;
     29
     30        public synchronized void noop() {
     31                x = nextRandom( x );
     32        }
     33        public static void helper() throws InterruptedException {
    634                JavaThread j = new JavaThread();
    7                 long start = System.nanoTime();
     35                // Inhibit biased locking ...
     36                x = (j.hashCode() ^ System.identityHashCode(j)) | 1 ;     
    837                for(int i = 1; i <= NoOfTimes; i += 1) {
     38                        x = nextRandom(x);
    939                        j.noop();
    1040                }
     41        }
     42        public static void InnerMain() throws InterruptedException {
     43                long start = System.nanoTime();
     44                helper();
    1145                long end = System.nanoTime();
    12                 System.out.println( (end - start) / NoOfTimes);
     46                System.out.println( (end - start) / NoOfTimes );
     47        }
     48        public static void main(String[] args) throws InterruptedException {
     49                for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
     50                        InnerMain();
     51                        Thread.sleep(2000);     // 2 seconds
     52                        x = nextRandom(x);
     53                }
     54                if ( x == 0 ) System.out.println(x);
    1355        }
    1456}
  • benchmark/schedint/JavaThread.java

    r8e1467d r4a60488  
    11class Monitor {
    22        public static volatile Boolean go = false;
     3        public static volatile Boolean next = false;
    34}
    45
     
    1314                while( Monitor.go ) {
    1415                        synchronized(this.m) {
     16                                Monitor.next = false;
    1517                                this.m.notify();
    1618                        }
     19                        while( ! Monitor.next && Monitor.go );  // spin until woken
    1720                }
    1821        }
     
    2023
    2124public class JavaThread {
    22         public static void main(String[] args) throws InterruptedException {
    23                 int NoOfTimes = 50000;
     25        // Simplistic low-quality Marsaglia Shift-XOR pseudo-random number generator.
     26        // Bijective   
     27        // Cycle length for non-zero values is 4G-1.
     28        // 0 is absorbing and should be avoided -- fixed point.
     29        // The returned value is typically masked to produce a positive value.
     30        static volatile int Ticket = 0 ;
     31
     32        private static int nextRandom (int x) {
     33                if (x == 0) {
     34                        // reseed the PRNG
     35                        // Ticket is accessed infrequently and does not constitute a coherence hot-spot.
     36                        // Note that we use a non-atomic racy increment -- the race is rare and benign.
     37                        // If the race is a concern switch to an AtomicInteger. 
     38                        // In addition accesses to the RW volatile global "Ticket"  variable are not
     39                        // (readily) predictable at compile-time so the JIT will not be able to elide
     40                        // nextRandom() invocations. 
     41                        x = ++Ticket ;
     42                        if (x == 0) x = 1 ;
     43                }
     44                x ^= x << 6;
     45                x ^= x >>> 21;
     46                x ^= x << 7;
     47                return x ;   
     48        }
     49        static int x = 2;
     50
     51        static private final int NoOfTimes = Integer.parseInt("1000000") ;
     52
     53        public static void helper( Monitor m ) throws InterruptedException {
     54                for(int i = 1; i <= NoOfTimes; i += 1) {
     55                        m.wait();               // relase monitor lock
     56                        m.next = true;
     57                }
     58        }
     59        public static void InnerMain() throws InterruptedException {
    2460                Monitor m = new Monitor();
    2561                long start, end;
     
    3167                        }
    3268                        start = System.nanoTime();
    33                         for(int i = 1; i <= NoOfTimes; i += 1) {
    34                                 m.wait();
    35                         }
     69                        helper( m );
    3670                        end = System.nanoTime();
    3771                }
     
    4074                System.out.println( (end - start) / NoOfTimes);
    4175        }
     76        public static void main(String[] args) throws InterruptedException {
     77                for (int n = Integer.parseInt("5"); --n >= 0 ; ) {
     78                        InnerMain();
     79                        Thread.sleep(2000);     // 2 seconds
     80                        x = nextRandom(x);
     81                }
     82                if ( x == 0 ) System.out.println(x);
     83        }
    4284}
  • configure

    r8e1467d r4a60488  
    637637LIBOBJS
    638638CFA_BACKEND_CC
     639DEMANGLER
     640LIBDEMANGLE
    639641WITH_LIBTCMALLOC_FALSE
    640642WITH_LIBTCMALLOC_TRUE
     
    661663ac_ct_DUMPBIN
    662664DUMPBIN
    663 LD
    664665FGREP
    665666EGREP
     
    699700LDFLAGS
    700701CXXFLAGS
    701 CXX
    702702CFA_FLAGS
    703703LIBCFA_TARGET_MAKEFILES
     
    715715BUILD_IN_TREE_FLAGS
    716716CFACPP
     717CFACC_INSTALL
    717718CFACC
    718719DRIVER_DIR
     
    721722CFA_INCDIR
    722723CFA_PREFIX
     724HAS_DISTCC
     725LD
     726CXX
     727ENABLE_DISTCC_FALSE
     728ENABLE_DISTCC_TRUE
    723729DOendif
    724730DOifskipcompile
     
    795801enable_silent_rules
    796802with_cfa_name
     803enable_distcc
    797804with_target_hosts
    798805enable_gprofiler
     806enable_demangler
    799807enable_dependency_tracking
    800808enable_shared
     
    14561464  --enable-silent-rules   less verbose build output (undo: "make V=1")
    14571465  --disable-silent-rules  verbose build output (undo: "make V=0")
     1466  --enable-distcc     whether or not to enable distributed compilation
    14581467  --enable-gprofiler     whether or not to enable gprofiler tools (if available)
     1468  --enable-demangler     whether or not to build the demangler (executable and library)
    14591469  --enable-dependency-tracking
    14601470                          do not reject slow dependency extractors
     
    31803190
    31813191#==============================================================================
     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#==============================================================================
    31823224# Installation paths
    31833225
     
    32623304DRIVER_DIR=${TOP_BUILDDIR}driver/
    32633305CFACC=${DRIVER_DIR}cfa
     3306CFACC_INSTALL=${CFA_BINDIR}${CFA_NAME}
    32643307CFACPP=${DRIVER_DIR}cfa-cpp
     3308
    32653309
    32663310
     
    34013445
    34023446
     3447# Check whether --enable-demangler was given.
     3448if test "${enable_demangler+set}" = set; then :
     3449  enableval=$enable_demangler; enable_demangler=$enableval
     3450else
     3451  enable_demangler=yes
     3452fi
     3453
     3454
    34033455TARGET_HOSTS=${target_hosts}
    34043456
     
    34333485                "x86-64"     ) cannon_arch_name="x64";;
    34343486                "x86_64"     ) cannon_arch_name="x64";;
     3487                "aarch64"    ) cannon_arch_name="arm";;
    34353488                "x86"        ) cannon_arch_name="x86";;
    34363489                "i386"       ) cannon_arch_name="x86";;
     
    34423495                "armv7l"     ) cannon_arch_name="arm";;
    34433496                *)
    3444                 >&2 echo "Unkown architecture " $arch_name;
     3497                >&2 echo "Unknown architecture " $arch_name;
    34453498                exit 1
    34463499                ;;
     
    34743527                "x86-64"     ) cannon_arch_name="x64";;
    34753528                "x86_64"     ) cannon_arch_name="x64";;
     3529                "aarch64"    ) cannon_arch_name="arm";;
    34763530                "x86"        ) cannon_arch_name="x86";;
    34773531                "i386"       ) cannon_arch_name="x86";;
     
    34833537                "armv7l"     ) cannon_arch_name="arm";;
    34843538                *)
    3485                 >&2 echo "Unkown architecture " $arch_name;
     3539                >&2 echo "Unknown architecture " $arch_name;
    34863540                exit 1
    34873541                ;;
     
    1677816832
    1677916833
     16834# conditionnally build the demangler
     16835if test "x$enable_demangler" == xyes; then
     16836        LIBDEMANGLE="libdemangle.a"
     16837        DEMANGLER="demangler"
     16838else
     16839        LIBDEMANGLE=""
     16840        DEMANGLER=""
     16841fi
     16842
     16843
     16844
    1678016845# Checks for header files.
    1678116846for ac_header in libintl.h malloc.h unistd.h
     
    1699217057fi
    1699317058
     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
    1699417063if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
    1699517064  as_fn_error $? "conditional \"AMDEP\" was never defined.
  • configure.ac

    r8e1467d r4a60488  
    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
     
    133156        enable_gprofiler=$enableval, enable_gprofiler=yes)
    134157
     158AC_ARG_ENABLE(demangler,
     159        [  --enable-demangler     whether or not to build the demangler (executable and library)],
     160        enable_demangler=$enableval, enable_demangler=yes)
     161
    135162AC_SUBST(TARGET_HOSTS, ${target_hosts})
    136163
     
    205232AM_CONDITIONAL([WITH_LIBTCMALLOC], [test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBTCMALLOC" -eq 1])
    206233
     234# conditionnally build the demangler
     235if test "x$enable_demangler" == xyes; then
     236        LIBDEMANGLE="libdemangle.a"
     237        DEMANGLER="demangler"
     238else
     239        LIBDEMANGLE=""
     240        DEMANGLER=""
     241fi
     242AC_SUBST([LIBDEMANGLE])
     243AC_SUBST([DEMANGLER])
     244
    207245# Checks for header files.
    208246AC_CHECK_HEADERS([libintl.h malloc.h unistd.h], [], [echo "Error: Missing required header"; exit 1])
  • doc/bibliography/pl.bib

    r8e1467d r4a60488  
    943943}
    944944
    945 @misc{Cforall,
    946     contributer = {pabuhr@plg},
    947     key         = {Cforall},
    948     author      = {{\textsf{C}{$\mathbf{\forall}$} Features}},
    949     howpublished= {\href{https://plg.uwaterloo.ca/~cforall/features}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-features}},
    950 }
    951 
    952 @misc{CforallBenchMarks,
    953     contributer = {pabuhr@plg},
    954     key         = {Cforall Benchmarks},
    955     author      = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}},
    956     howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmark.tar}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmark.tar}},
    957 }
    958 
    959 @mastersthesis{Esteves04,
    960     keywords    = {Cforall, parametric polymorphism, overloading},
    961     contributer = {pabuhr@plg},
    962     author      = {Rodolfo Gabriel Esteves},
    963     title       = {\textsf{C}$\mathbf{\forall}$, a Study in Evolutionary Design in Programming Languages},
    964     school      = {School of Computer Science, University of Waterloo},
    965     year        = 2004,
    966     address     = {Waterloo, Ontario, Canada, N2L 3G1},
    967     note        = {\href{http://plg.uwaterloo.ca/theses/EstevesThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-EstevesThesis.pdf}},
    968 }
    969 
    970 @misc{CFAStackEvaluation,
    971     contributer = {a3moss@plg},
    972     author      = {Aaron Moss},
    973     title       = {\textsf{C}$\mathbf{\forall}$ Stack Evaluation Programs},
    974     year        = 2018,
    975     howpublished= {\href{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}{https://cforall.uwaterloo.ca/\-CFAStackEvaluation.zip}},
    976 }
    977 
    978945@article{Moss18,
    979946    keywords    = {type systems, polymorphism, tuples, Cforall},
     
    988955    pages       = {2111-2146},
    989956    note        = {\href{http://dx.doi.org/10.1002/spe.2624}{http://\-dx.doi.org/\-10.1002/\-spe.2624}},
     957}
     958
     959@misc{CforallBenchMarks,
     960    contributer = {pabuhr@plg},
     961    key         = {Cforall Benchmarks},
     962    author      = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}},
     963    howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmark.tar}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmark.tar}},
     964}
     965
     966@misc{Cforall,
     967    contributer = {pabuhr@plg},
     968    key         = {Cforall},
     969    author      = {{\textsf{C}{$\mathbf{\forall}$} Features}},
     970    howpublished= {\href{https://plg.uwaterloo.ca/~cforall/features}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-features}},
     971}
     972
     973@misc{CFAStackEvaluation,
     974    contributer = {a3moss@plg},
     975    author      = {Aaron Moss},
     976    title       = {\textsf{C}$\mathbf{\forall}$ Stack Evaluation Programs},
     977    year        = 2018,
     978    howpublished= {\href{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}{https://cforall.uwaterloo.ca/\-CFAStackEvaluation.zip}},
     979}
     980
     981@mastersthesis{Esteves04,
     982    keywords    = {Cforall, parametric polymorphism, overloading},
     983    contributer = {pabuhr@plg},
     984    author      = {Rodolfo Gabriel Esteves},
     985    title       = {\textsf{C}$\mathbf{\forall}$, a Study in Evolutionary Design in Programming Languages},
     986    school      = {School of Computer Science, University of Waterloo},
     987    year        = 2004,
     988    address     = {Waterloo, Ontario, Canada, N2L 3G1},
     989    note        = {\href{http://plg.uwaterloo.ca/theses/EstevesThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-EstevesThesis.pdf}},
     990}
     991
     992@phdthesis{Moss19,
     993    keywords    = {type system, generic type, resolution algorithm, type environment, Cforall},
     994    author      = {Aaron Moss},
     995    title       = {\textsf{C}$\mathbf{\forall}$ Type System Implementation},
     996    school      = {School of Computer Science, University of Waterloo},
     997    year        = 2019,
     998    optaddress  = {Waterloo, Ontario, Canada, N2L 3G1},
     999    note        = {\href{https://uwspace.uwaterloo.ca/handle/10012/14584}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-14584}},
    9901000}
    9911001
     
    11011111
    11021112@techreport{Prokopec11,
    1103   keywords = {ctrie, concurrent map},
    1104   contributer = {a3moss@uwaterloo.ca},
    1105   title={Cache-aware lock-free concurrent hash tries},
    1106   author={Prokopec, Aleksandar and Bagwell, Phil and Odersky, Martin},
    1107   institution={EPFL},
    1108   year={2011}
     1113    keywords    = {ctrie, concurrent map},
     1114    contributer = {a3moss@uwaterloo.ca},
     1115    title       ={Cache-aware lock-free concurrent hash tries},
     1116    author      ={Prokopec, Aleksandar and Bagwell, Phil and Odersky, Martin},
     1117    institution ={EPFL},
     1118    year        ={2011}
    11091119}
    11101120
     
    11581168
    11591169@phdthesis{Norrish98,
    1160   title={C formalised in HOL},
    1161   author={Norrish, Michael},
    1162   year={1998},
    1163   school={University of Cambridge}
     1170    title       = {C formalised in HOL},
     1171    author      = {Norrish, Michael},
     1172    year        = {1998},
     1173    school      = {University of Cambridge}
    11641174}
    11651175
     
    11701180    title       = {Checked C: Making C Safe by Extension},
    11711181    booktitle   = {2018 IEEE Cybersecurity Development (SecDev)},
     1182    publisher   = {IEEE},
    11721183    year        = {2018},
    1173     month       = {September},
     1184    month       = sep,
    11741185    pages       = {53-60},
    1175     publisher   = {IEEE},
    11761186    url         = {https://www.microsoft.com/en-us/research/publication/checkedc-making-c-safe-by-extension/},
    11771187}
     
    12851295
    12861296@inproceedings{Odersky01,
    1287  keywords = {Scala},
    1288  contributer = {a3moss@uwaterloo.ca},
    1289  author = {Odersky, Martin and Zenger, Christoph and Zenger, Matthias},
    1290  title = {Colored Local Type Inference},
    1291  booktitle = {Proceedings of the 28th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages},
    1292  series = {POPL '01},
    1293  year = {2001},
    1294  isbn = {1-58113-336-7},
    1295  location = {London, United Kingdom},
    1296  pages = {41--53},
    1297  numpages = {13},
    1298  url = {http://doi.acm.org/10.1145/360204.360207},
    1299  doi = {10.1145/360204.360207},
    1300  acmid = {360207},
    1301  publisher = {ACM},
    1302  address = {New York, NY, USA},
     1297    keywords    = {Scala},
     1298    contributer = {a3moss@uwaterloo.ca},
     1299    author      = {Odersky, Martin and Zenger, Christoph and Zenger, Matthias},
     1300    title       = {Colored Local Type Inference},
     1301    booktitle   = {Proceedings of the 28th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages},
     1302    series      = {POPL '01},
     1303    year        = {2001},
     1304    isbn        = {1-58113-336-7},
     1305    location    = {London, United Kingdom},
     1306    pages       = {41--53},
     1307    numpages    = {13},
     1308    url         = {http://doi.acm.org/10.1145/360204.360207},
     1309    doi         = {10.1145/360204.360207},
     1310    acmid       = {360207},
     1311    publisher   = {ACM},
     1312    address     = {New York, NY, USA},
    13031313}
    13041314
     
    16931703
    16941704@inproceedings{Prokopec12,
    1695   keywords={ctrie, hash trie, concurrent map},
    1696   contributer={a3moss@uwaterloo.ca},
    1697   title={Concurrent tries with efficient non-blocking snapshots},
    1698   author={Prokopec, Aleksandar and Bronson, Nathan Grasso and Bagwell, Phil and Odersky, Martin},
    1699   booktitle={ACM SIGPLAN Notices},
    1700   volume={47},
    1701   number={8},
    1702   pages={151--160},
    1703   year={2012},
    1704   organization={ACM}
     1705    keywords    = {ctrie, hash trie, concurrent map},
     1706    contributer = {a3moss@uwaterloo.ca},
     1707    title       = {Concurrent tries with efficient non-blocking snapshots},
     1708    author      = {Prokopec, Aleksandar and Bronson, Nathan Grasso and Bagwell, Phil and Odersky, Martin},
     1709    booktitle   = {ACM SIGPLAN Notices},
     1710    volume      = {47},
     1711    number      = {8},
     1712    pages       = {151--160},
     1713    year        = {2012},
     1714    organization={ACM}
    17051715}
    17061716
     
    17291739}
    17301740
    1731 @article{Delisle18b,
     1741@article{Delisle19,
    17321742    keywords    = {concurrency, Cforall},
    17331743    contributer = {pabuhr@plg},
    17341744    author      = {Thierry Delisle and Peter A. Buhr},
    1735     title       = {Concurrency in \textsf{C}$\mathbf{\forall}$},
    1736     year        = 2018,
     1745    title       = {Advanced Control-flow and Concurrency in \textsf{C}$\mathbf{\forall}$},
     1746    year        = 2019,
    17371747    journal     = spe,
    1738     pages       = {1-32},
     1748    pages       = {1-33},
    17391749    note        = {submitted},
    17401750}
     
    25002510
    25012511@misc{Dotty-github,
    2502     keywords = {dotty,scala},
    2503     contributer = {a3moss@uwaterloo.ca},
    2504     author = {Martin Odersky},
    2505     title = {Dotty},
    2506     howpublished = {\href{https://github.com/lampepfl/dotty}{https://\-github.com/\-lampepfl/\-dotty}},
    2507     note = {Acessed: 2019-02-22}
     2512    keywords    = {dotty,scala},
     2513    contributer = {a3moss@uwaterloo.ca},
     2514    author      = {Martin Odersky},
     2515    title       = {Dotty},
     2516    howpublished= {\href{https://github.com/lampepfl/dotty}{https://\-github.com/\-lampepfl/\-dotty}},
     2517    note        = {Acessed: 2019-02-22}
    25082518}
    25092519
     
    26562666    volume      = 10,
    26572667    number      = 3,
    2658     pages        = {120-123},
     2668    pages       = {120-123},
    26592669    comment     = {
    26602670        The ``two-pass'' algorithm.  An upward pass over a parse tree
     
    32363246
    32373247@article{Leroy09,
    3238  keywords = {C formalization},
    3239  contributer = {a3moss@uwaterloo.ca},
    3240  author = {Leroy, Xavier},
    3241  title = {Formal Verification of a Realistic Compiler},
    3242  journal = {Commun. ACM},
    3243  issue_date = {July 2009},
    3244  volume = {52},
    3245  number = {7},
    3246  month = jul,
    3247  year = {2009},
    3248  issn = {0001-0782},
    3249  pages = {107--115},
    3250  numpages = {9},
    3251  url = {http://doi.acm.org/10.1145/1538788.1538814},
    3252  doi = {10.1145/1538788.1538814},
    3253  acmid = {1538814},
    3254  publisher = {ACM},
    3255  address = {New York, NY, USA},
     3248    keywords    = {C formalization},
     3249    contributer = {a3moss@uwaterloo.ca},
     3250    author      = {Leroy, Xavier},
     3251    title       = {Formal Verification of a Realistic Compiler},
     3252    journal     = {Commun. ACM},
     3253    issue_date  = {July 2009},
     3254    volume      = {52},
     3255    number      = {7},
     3256    month       = jul,
     3257    year        = {2009},
     3258    issn        = {0001-0782},
     3259    pages       = {107--115},
     3260    numpages    = {9},
     3261    url         = {http://doi.acm.org/10.1145/1538788.1538814},
     3262    doi         = {10.1145/1538788.1538814},
     3263    acmid       = {1538814},
     3264    publisher   = {ACM},
     3265    address     = {New York, NY, USA},
    32563266}
    32573267
     
    41814191
    41824192@article{Morgado13,
    4183   keywords = {expression resolution},
    4184   contributer = {a3moss@uwaterloo.ca},
    4185   title={Iterative and core-guided {MaxSAT} solving: A survey and assessment},
    4186   author={Morgado, Antonio and Heras, Federico and Liffiton, Mark and Planes, Jordi and Marques-Silva, Joao},
    4187   journal={Constraints},
    4188   volume={18},
    4189   number={4},
    4190   pages={478--534},
    4191   year={2013},
    4192   publisher={Springer}
     4193    keywords    = {expression resolution},
     4194    contributer = {a3moss@uwaterloo.ca},
     4195    title       = {Iterative and core-guided {MaxSAT} solving: A survey and assessment},
     4196    author      = {Morgado, Antonio and Heras, Federico and Liffiton, Mark and Planes, Jordi and Marques-Silva, Joao},
     4197    journal     = {Constraints},
     4198    volume      = {18},
     4199    number      = {4},
     4200    pages       = {478--534},
     4201    year        = {2013},
     4202    publisher   = {Springer}
    41934203}
    41944204
     
    43894399}
    43904400
    4391 
    43924401@article{Liskov86,
    43934402    keywords    = {synchronous communication, concurrency},
     
    44484457
    44494458@article{Pierce00,
    4450  keywords = {Scala},
    4451  contributer = {a3moss@uwaterloo.ca},
    4452  author = {Pierce, Benjamin C. and Turner, David N.},
    4453  title = {Local Type Inference},
    4454  journal = {ACM Trans. Program. Lang. Syst.},
    4455  issue_date = {Jan. 2000},
    4456  volume = {22},
    4457  number = {1},
    4458  month = jan,
    4459  year = {2000},
    4460  issn = {0164-0925},
    4461  pages = {1--44},
    4462  numpages = {44},
    4463  url = {http://doi.acm.org/10.1145/345099.345100},
    4464  doi = {10.1145/345099.345100},
    4465  acmid = {345100},
    4466  publisher = {ACM},
    4467  address = {New York, NY, USA},
    4468  keywords = {polymorphism, subtyping, type inference},
     4459    keywords    = {Scala},
     4460    contributer = {a3moss@uwaterloo.ca},
     4461    author      = {Pierce, Benjamin C. and Turner, David N.},
     4462    title       = {Local Type Inference},
     4463    journal     = {ACM Trans. Program. Lang. Syst.},
     4464    issue_date  = {Jan. 2000},
     4465    volume      = {22},
     4466    number      = {1},
     4467    month       = jan,
     4468    year        = {2000},
     4469    issn        = {0164-0925},
     4470    pages       = {1--44},
     4471    numpages    = {44},
     4472    url         = {http://doi.acm.org/10.1145/345099.345100},
     4473    doi         = {10.1145/345099.345100},
     4474    acmid       = {345100},
     4475    publisher   = {ACM},
     4476    address     = {New York, NY, USA},
     4477    keywords    = {polymorphism, subtyping, type inference},
    44694478}
    44704479
     
    54495458
    54505459@inproceedings{Krebbers14,
    5451  keywords = {c formalization},
    5452  contributer = {a3moss@uwaterloo.ca},
    5453  author = {Krebbers, Robbert},
    5454  title = {An Operational and Axiomatic Semantics for Non-determinism and Sequence Points in C},
    5455  booktitle = {Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages},
    5456  series = {POPL '14},
    5457  year = {2014},
    5458  isbn = {978-1-4503-2544-8},
    5459  location = {San Diego, California, USA},
    5460  pages = {101--112},
    5461  numpages = {12},
    5462  url = {http://doi.acm.org/10.1145/2535838.2535878},
    5463  doi = {10.1145/2535838.2535878},
    5464  acmid = {2535878},
    5465  publisher = {ACM},
    5466  address = {New York, NY, USA},
     5460    keywords    = {c formalization},
     5461    contributer = {a3moss@uwaterloo.ca},
     5462    author      = {Krebbers, Robbert},
     5463    title       = {An Operational and Axiomatic Semantics for Non-determinism and Sequence Points in C},
     5464    booktitle   = {Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages},
     5465    series      = {POPL '14},
     5466    year        = {2014},
     5467    isbn        = {978-1-4503-2544-8},
     5468    location    = {San Diego, California, USA},
     5469    pages       = {101--112},
     5470    numpages    = {12},
     5471    url         = {http://doi.acm.org/10.1145/2535838.2535878},
     5472    doi         = {10.1145/2535838.2535878},
     5473    acmid       = {2535878},
     5474    publisher   = {ACM},
     5475    address     = {New York, NY, USA},
    54675476}
    54685477
     
    75317540
    75327541@article{SysVABI,
    7533   keywords = {System V ABI},
    7534   contributer = {a3moss@uwaterloo.ca},
    7535   title={System {V} application binary interface},
    7536   author={Matz, Michael and Hubicka, Jan and Jaeger, Andreas and Mitchell, Mark},
    7537   journal={AMD64 Architecture Processor Supplement, Draft v0},
    7538   volume={99},
    7539   year={2013}
     7542    keywords    = {System V ABI},
     7543    contributer = {a3moss@uwaterloo.ca},
     7544    title       = {System {V} application binary interface},
     7545    author      = {Matz, Michael and Hubicka, Jan and Jaeger, Andreas and Mitchell, Mark},
     7546    journal     = {AMD64 Architecture Processor Supplement, Draft v0},
     7547    volume      = {99},
     7548    year        = {2013}
    75407549}
    75417550
     
    77647773
    77657774@techreport{Black90,
    7766   title={Typechecking polymorphism in {Emerald}},
    7767   author={Black, Andrew P and Hutchinson, Norman C},
    7768   year={1990},
    7769   institution={Cambridge Research Laboratory, Digital Equipment Corporation}
     7775    title       = {Typechecking polymorphism in {Emerald}},
     7776    author      = {Black, Andrew P and Hutchinson, Norman C},
     7777    year        = {1990},
     7778    institution = {Cambridge Research Laboratory, Digital Equipment Corporation}
    77707779}
    77717780
  • doc/papers/concurrency/Paper.tex

    r8e1467d r4a60488  
    307307In many ways, \CFA is to C as Scala~\cite{Scala} is to Java, providing a \emph{research vehicle} for new typing and control-flow capabilities on top of a highly popular programming language allowing immediate dissemination.
    308308Within the \CFA framework, new control-flow features are created from scratch because ISO \Celeven defines only a subset of the \CFA extensions, where the overlapping features are concurrency~\cite[\S~7.26]{C11}.
    309 However, \Celeven concurrency is largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}, and \Celeven and pthreads concurrency is simple, based on thread fork/join in a function and a few locks, which is low-level and error-prone;
     309However, \Celeven concurrency is largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}, and \Celeven and pthreads concurrency is simple, based on thread fork/join in a function and mutex/condition locks, which is low-level and error-prone;
    310310no high-level language concurrency features are defined.
    311 Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-9 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach.
     311Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-9 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach (possibly because the effort to add concurrency to \CC).
    312312Finally, while the \Celeven standard does not state a threading model, the historical association with pthreads suggests implementations would adopt kernel-level threading (1:1)~\cite{ThreadModel}.
    313313
     
    333333
    334334Finally, it is important for a language to provide safety over performance \emph{as the default}, allowing careful reduction of safety for performance when necessary.
    335 Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging} (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie once there is spurious wakeup, signals-as-hints follow.
     335Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging}\footnote{
     336The notion of competitive succession instead of direct handoff, \ie a lock owner releases the lock and an arriving thread acquires it ahead of preexisting waiter threads.
     337} (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie once there is spurious wakeup, signals-as-hints follow.
    336338However, spurious wakeup is \emph{not} a foundational concurrency property~\cite[\S~8]{Buhr05a}, it is a performance design choice.
    337339Similarly, signals-as-hints are often a performance decision.
     
    351353We present comparative examples so the reader can judge if the \CFA control-flow extensions are better and safer than those in other concurrent, imperative programming languages, and perform experiments to show the \CFA runtime is competitive with other similar mechanisms.
    352354The main contributions of this work are:
    353 \begin{itemize}
     355\begin{itemize}[topsep=3pt,itemsep=1pt]
    354356\item
    355357language-level generators, coroutines and user-level threading, which respect the expectations of C programmers.
     
    370372\end{itemize}
    371373
     374Section~\ref{s:StatefulFunction} begins advanced control by introducing sequential functions that retain data and execution state between calls, which produces constructs @generator@ and @coroutine@.
     375Section~\ref{s:Concurrency} begins concurrency, or how to create (fork) and destroy (join) a thread, which produces the @thread@ construct.
     376Section~\ref{s:MutualExclusionSynchronization} discusses the two mechanisms to restricted nondeterminism when controlling shared access to resources (mutual exclusion) and timing relationships among threads (synchronization).
     377Section~\ref{s:Monitor} shows how both mutual exclusion and synchronization are safely embedded in the @monitor@ and @thread@ constructs.
     378Section~\ref{s:CFARuntimeStructure} describes the large-scale mechanism to structure (cluster) threads and virtual processors (kernel threads).
     379Section~\ref{s:Performance} uses a series of microbenchmarks to compare \CFA threading with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0.
     380
    372381
    373382\section{Stateful Function}
     383\label{s:StatefulFunction}
    374384
    375385The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg plugin, device driver, finite-state machine.
     
    617627Figure~\ref{f:CFibonacciSim} shows the C implementation of the \CFA generator only needs one additional field, @next@, to handle retention of execution state.
    618628The computed @goto@ at the start of the generator main, which branches after the previous suspend, adds very little cost to the resume call.
    619 Finally, an explicit generator type provides both design and performance benefits, such as multiple type-safe interface functions taking and returning arbitrary types.
     629Finally, an explicit generator type provides both design and performance benefits, such as multiple type-safe interface functions taking and returning arbitrary types.\footnote{
     630The \CFA operator syntax uses \lstinline|?| to denote operands, which allows precise definitions for pre, post, and infix operators, \eg \lstinline|++?|, \lstinline|?++|, and \lstinline|?+?|, in addition \lstinline|?\{\}| denotes a constructor, as in \lstinline|foo `f` = `\{`...`\}`|, \lstinline|^?\{\}| denotes a destructor, and \lstinline|?()| is \CC function call \lstinline|operator()|.
     631}%
    620632\begin{cfa}
    621633int ?()( Fib & fib ) { return `resume( fib )`.fn; } $\C[3.9in]{// function-call interface}$
     
    15111523
    15121524\section{Mutual Exclusion / Synchronization}
     1525\label{s:MutualExclusionSynchronization}
    15131526
    15141527Unrestricted nondeterminism is meaningless as there is no way to know when the result is completed without synchronization.
     
    15511564higher-level mechanisms often simplify usage by adding better coupling between synchronization and data, \eg receive-specific versus receive-any thread in message passing or offering specialized solutions, \eg barrier lock.
    15521565Often synchronization is used to order access to a critical section, \eg ensuring a waiting writer thread enters the critical section before a calling reader thread.
    1553 If the calling reader is scheduled before the waiting writer, the reader has \newterm{barged}.
     1566If the calling reader is scheduled before the waiting writer, the reader has barged.
    15541567Barging can result in staleness/freshness problems, where a reader barges ahead of a writer and reads temporally stale data, or a writer barges ahead of another writer overwriting data with a fresh value preventing the previous value from ever being read (lost computation).
    15551568Preventing or detecting barging is an involved challenge with low-level locks, which is made easier through higher-level constructs.
     
    21202133
    21212134
    2122 \subsection{Extended \protect\lstinline@waitfor@}
    2123 
    2124 Figure~\ref{f:ExtendedWaitfor} show the extended form of the @waitfor@ statement to conditionally accept one of a group of mutex functions, with an optional statement to be performed \emph{after} the mutex function finishes.
     2135\subsection{\texorpdfstring{Extended \protect\lstinline@waitfor@}{Extended waitfor}}
     2136
     2137Figure~\ref{f:ExtendedWaitfor} shows the extended form of the @waitfor@ statement to conditionally accept one of a group of mutex functions, with an optional statement to be performed \emph{after} the mutex function finishes.
    21252138For a @waitfor@ clause to be executed, its @when@ must be true and an outstanding call to its corresponding member(s) must exist.
    21262139The \emph{conditional-expression} of a @when@ may call a function, but the function must not block or context switch.
     
    21312144Hence, the terminating @else@ clause allows a conditional attempt to accept a call without blocking.
    21322145If both @timeout@ and @else@ clause are present, the @else@ must be conditional, or the @timeout@ is never triggered.
     2146There is also a traditional future wait queue (not shown) (\eg Microsoft (@WaitForMultipleObjects@)), to wait for a specified number of future elements in the queue.
    21332147
    21342148\begin{figure}
     
    23552369
    23562370
    2357 \subsection{\protect\lstinline@mutex@ Threads}
     2371\subsection{\texorpdfstring{\protect\lstinline@mutex@ Threads}{mutex Threads}}
    23582372
    23592373Threads in \CFA can also be monitors to allow \emph{direct communication} among threads, \ie threads can have mutex functions that are called by other threads.
     
    24992513\renewcommand{\arraystretch}{1.25}
    25002514%\setlength{\tabcolsep}{5pt}
    2501 \begin{tabular}{c|c|l|l}
    2502 \multicolumn{2}{c|}{object properties} & \multicolumn{2}{c}{mutual exclusion} \\
     2515\begin{tabular}{c|c||l|l}
     2516\multicolumn{2}{c||}{object properties} & \multicolumn{2}{c}{mutual exclusion} \\
    25032517\hline
    25042518thread  & stateful                              & \multicolumn{1}{c|}{No} & \multicolumn{1}{c}{Yes} \\
     
    26052619
    26062620
    2607 \section{\protect\CFA Runtime Structure}
     2621\section{Runtime Structure}
    26082622\label{s:CFARuntimeStructure}
    26092623
     
    27092723
    27102724\section{Performance}
    2711 \label{results}
     2725\label{s:Performance}
    27122726
    27132727To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0.
     
    27152729The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \CFA/\uC are compiled with gcc 6.5.
    27162730
    2717 All benchmarks are run using the following harness.
     2731All benchmarks are run using the following harness. (The Java harness is augmented to circumvent JIT issues.)
    27182732\begin{cfa}
    27192733unsigned int N = 10_000_000;
     
    27542768\begin{tabular}[t]{@{}r*{3}{D{.}{.}{5.2}}@{}}
    27552769\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2756 \CFA Coroutine Lazy             & 14.3          & 14.3          & 0.32          \\
    2757 \CFA Coroutine Eager    & 522.8         & 525.3         & 5.81          \\
    2758 \CFA Thread                             & 1257.8        & 1291.2        & 86.19         \\
    2759 \uC Coroutine                   & 92.2          & 91.4          & 1.58          \\
    2760 \uC Thread                              & 499.5         & 500.1         & 5.67          \\
    2761 Goroutine                               & 4397.0        & 4362.8        & 390.77        \\
    2762 Java Thread                             & 107405.0      & 107794.8      & 1601.33       \\
    2763 % Qthreads                              & 159.9         & 159.6         & 0.73          \\
    2764 Pthreads                                & 32920.9       & 32882.7       & 213.55
     2770\CFA Coroutine Lazy             & 13.2          & 13.1          & 0.44          \\
     2771\CFA Coroutine Eager    & 531.3         & 536.0         & 26.54         \\
     2772\CFA Thread                             & 2074.9        & 2066.5        & 170.76        \\
     2773\uC Coroutine                   & 89.6          & 90.5          & 1.83          \\
     2774\uC Thread                              & 528.2         & 528.5         & 4.94          \\
     2775Goroutine                               & 4068.0        & 4113.1        & 414.55        \\
     2776Java Thread                             & 103848.5      & 104295.4      & 2637.57       \\
     2777Pthreads                                & 33112.6       & 33127.1       & 165.90
     2778\end{tabular}
     2779\end{multicols}
     2780
     2781
     2782\paragraph{Context-Switching}
     2783
     2784In procedural programming, the cost of a function call is important as modularization (refactoring) increases.
     2785(In many cases, a compiler inlines function calls to eliminate this cost.)
     2786Similarly, when modularization extends to coroutines/tasks, the time for a context switch becomes a relevant factor.
     2787The coroutine test is from resumer to suspender and from suspender to resumer, which is two context switches.
     2788The thread test is using yield to enter and return from the runtime kernel, which is two context switches.
     2789The difference in performance between coroutine and thread context-switch is the cost of scheduling for threads, whereas coroutines are self-scheduling.
     2790Figure~\ref{f:ctx-switch} only shows the \CFA code for coroutines/threads (other systems are similar) with all results in Table~\ref{tab:ctx-switch}.
     2791
     2792\begin{multicols}{2}
     2793\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2794\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     2795@coroutine@ C {} c;
     2796void main( C & ) { for ( ;; ) { @suspend;@ } }
     2797int main() { // coroutine test
     2798        BENCH( for ( N ) { @resume( c );@ } )
     2799        sout | result`ns;
     2800}
     2801int main() { // task test
     2802        BENCH( for ( N ) { @yield();@ } )
     2803        sout | result`ns;
     2804}
     2805\end{cfa}
     2806\captionof{figure}{\CFA context-switch benchmark}
     2807\label{f:ctx-switch}
     2808
     2809\columnbreak
     2810
     2811\vspace*{-16pt}
     2812\captionof{table}{Context switch comparison (nanoseconds)}
     2813\label{tab:ctx-switch}
     2814\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
     2815\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2816C function              & 1.8   & 1.8   & 0.01  \\
     2817\CFA generator  & 2.4   & 2.2   & 0.25  \\
     2818\CFA Coroutine  & 36.2  & 36.2  & 0.25  \\
     2819\CFA Thread             & 93.2  & 93.5  & 2.09  \\
     2820\uC Coroutine   & 52.0  & 52.1  & 0.51  \\
     2821\uC Thread              & 96.2  & 96.3  & 0.58  \\
     2822Goroutine               & 141.0 & 141.3 & 3.39  \\
     2823Java Thread             & 374.0 & 375.8 & 10.38 \\
     2824Pthreads Thread & 361.0 & 365.3 & 13.19
     2825\end{tabular}
     2826\end{multicols}
     2827
     2828
     2829\paragraph{Mutual-Exclusion}
     2830
     2831Uncontented mutual exclusion, which frequently occurs, is measured by entering/leaving a critical section.
     2832For monitors, entering and leaving a monitor function is measured.
     2833To put the results in context, the cost of entering a non-inline function and the cost of acquiring and releasing a @pthread_mutex@ lock is also measured.
     2834Figure~\ref{f:mutex} shows the code for \CFA with all results in Table~\ref{tab:mutex}.
     2835Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
     2836
     2837\begin{multicols}{2}
     2838\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2839\begin{cfa}
     2840@monitor@ M {} m1/*, m2, m3, m4*/;
     2841void __attribute__((noinline))
     2842do_call( M & @mutex m/*, m2, m3, m4*/@ ) {}
     2843int main() {
     2844        BENCH(
     2845                for( N ) do_call( m1/*, m2, m3, m4*/ );
     2846        )
     2847        sout | result`ns;
     2848}
     2849\end{cfa}
     2850\captionof{figure}{\CFA acquire/release mutex benchmark}
     2851\label{f:mutex}
     2852
     2853\columnbreak
     2854
     2855\vspace*{-16pt}
     2856\captionof{table}{Mutex comparison (nanoseconds)}
     2857\label{tab:mutex}
     2858\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
     2859\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2860test and test-and-test lock             & 19.1  & 18.9  & 0.40  \\
     2861\CFA @mutex@ function, 1 arg.   & 45.9  & 46.6  & 1.45  \\
     2862\CFA @mutex@ function, 2 arg.   & 105.0 & 104.7 & 3.08  \\
     2863\CFA @mutex@ function, 4 arg.   & 165.0 & 167.6 & 5.65  \\
     2864\uC @monitor@ member rtn.               & 54.0  & 53.7  & 0.82  \\
     2865Java synchronized method                & 31.0  & 31.1  & 0.50  \\
     2866Pthreads Mutex Lock                             & 33.6  & 32.6  & 1.14
     2867\end{tabular}
     2868\end{multicols}
     2869
     2870
     2871\paragraph{External Scheduling}
     2872
     2873External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement.
     2874Figure~\ref{f:ext-sched} shows the code for \CFA, with results in Table~\ref{tab:ext-sched}.
     2875Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
     2876
     2877\begin{multicols}{2}
     2878\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
     2879\vspace*{-16pt}
     2880\begin{cfa}
     2881volatile int go = 0;
     2882@monitor@ M {} m;
     2883thread T {};
     2884void __attribute__((noinline))
     2885do_call( M & @mutex@ ) {}
     2886void main( T & ) {
     2887        while ( go == 0 ) { yield(); }
     2888        while ( go == 1 ) { do_call( m ); }
     2889}
     2890int __attribute__((noinline))
     2891do_wait( M & @mutex@ m ) {
     2892        go = 1; // continue other thread
     2893        BENCH( for ( N ) { @waitfor( do_call, m );@ } )
     2894        go = 0; // stop other thread
     2895        sout | result`ns;
     2896}
     2897int main() {
     2898        T t;
     2899        do_wait( m );
     2900}
     2901\end{cfa}
     2902\captionof{figure}{\CFA external-scheduling benchmark}
     2903\label{f:ext-sched}
     2904
     2905\columnbreak
     2906
     2907\vspace*{-16pt}
     2908\captionof{table}{External-scheduling comparison (nanoseconds)}
     2909\label{tab:ext-sched}
     2910\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
     2911\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
     2912\CFA @waitfor@, 1 @monitor@     & 376.4 & 376.8 & 7.63  \\
     2913\CFA @waitfor@, 2 @monitor@     & 491.4 & 492.0 & 13.31 \\
     2914\CFA @waitfor@, 4 @monitor@     & 681.0 & 681.7 & 19.10 \\
     2915\uC @_Accept@                           & 331.1 & 331.4 & 2.66
    27652916\end{tabular}
    27662917\end{multicols}
     
    28102961\begin{tabular}{@{}r*{3}{D{.}{.}{5.2}}@{}}
    28112962\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2812 \CFA @signal@, 1 @monitor@      & 367.0         & 371.5         & 17.34         \\
    2813 \CFA @signal@, 2 @monitor@      & 477.2         & 478.6         & 8.31          \\
    2814 \CFA @signal@, 4 @monitor@      & 725.8         & 734.0         & 17.98         \\
    2815 \uC @signal@                            & 322.8         & 323.0         & 3.64          \\
    2816 Java @notify@                           & 16520.0       & 20096.7       & 9378.53       \\
    2817 Pthreads Cond. Variable         & 4931.3        & 5057.0        & 326.80
    2818 \end{tabular}
    2819 \end{multicols}
    2820 
    2821 
    2822 \paragraph{External Scheduling}
    2823 
    2824 External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement.
    2825 Figure~\ref{f:ext-sched} shows the code for \CFA, with results in Table~\ref{tab:ext-sched}.
    2826 Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
    2827 
    2828 \begin{multicols}{2}
    2829 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    2830 \vspace*{-16pt}
    2831 \begin{cfa}
    2832 volatile int go = 0;
    2833 @monitor@ M {} m;
    2834 thread T {};
    2835 void __attribute__((noinline))
    2836 do_call( M & @mutex@ ) {}
    2837 void main( T & ) {
    2838         while ( go == 0 ) { yield(); }
    2839         while ( go == 1 ) { do_call( m ); }
    2840 }
    2841 int __attribute__((noinline))
    2842 do_wait( M & @mutex@ m ) {
    2843         go = 1; // continue other thread
    2844         BENCH( for ( N ) { @waitfor( do_call, m );@ } )
    2845         go = 0; // stop other thread
    2846         sout | result`ns;
    2847 }
    2848 int main() {
    2849         T t;
    2850         do_wait( m );
    2851 }
    2852 \end{cfa}
    2853 \captionof{figure}{\CFA external-scheduling benchmark}
    2854 \label{f:ext-sched}
    2855 
    2856 \columnbreak
    2857 
    2858 \vspace*{-16pt}
    2859 \captionof{table}{External-scheduling comparison (nanoseconds)}
    2860 \label{tab:ext-sched}
    2861 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
    2862 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2863 \CFA @waitfor@, 1 @monitor@     & 366.7         & 369.5 & 7.52  \\
    2864 \CFA @waitfor@, 2 @monitor@     & 453.6         & 455.8 & 12.38 \\
    2865 \CFA @waitfor@, 4 @monitor@     & 671.6         & 672.4 & 14.16 \\
    2866 \uC @_Accept@                           & 336.0         & 335.8         & 3.22
    2867 \end{tabular}
    2868 \end{multicols}
    2869 
    2870 
    2871 \paragraph{Context-Switching}
    2872 
    2873 In procedural programming, the cost of a function call is important as modularization (refactoring) increases.
    2874 (In many cases, a compiler inlines function calls to eliminate this cost.)
    2875 Similarly, when modularization extends to coroutines/tasks, the time for a context switch becomes a relevant factor.
    2876 The coroutine test is from resumer to suspender and from suspender to resumer, which is two context switches.
    2877 The thread test is using yield to enter and return from the runtime kernel, which is two context switches.
    2878 The difference in performance between coroutine and thread context-switch is the cost of scheduling for threads, whereas coroutines are self-scheduling.
    2879 Figure~\ref{f:ctx-switch} only shows the \CFA code for coroutines/threads (other systems are similar) with all results in Table~\ref{tab:ctx-switch}.
    2880 
    2881 \begin{multicols}{2}
    2882 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    2883 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    2884 @coroutine@ C {} c;
    2885 void main( C & ) { for ( ;; ) { @suspend;@ } }
    2886 int main() { // coroutine test
    2887         BENCH( for ( N ) { @resume( c );@ } )
    2888         sout | result`ns;
    2889 }
    2890 int main() { // task test
    2891         BENCH( for ( N ) { @yield();@ } )
    2892         sout | result`ns;
    2893 }
    2894 \end{cfa}
    2895 \captionof{figure}{\CFA context-switch benchmark}
    2896 \label{f:ctx-switch}
    2897 
    2898 \columnbreak
    2899 
    2900 \vspace*{-16pt}
    2901 \captionof{table}{Context switch comparison (nanoseconds)}
    2902 \label{tab:ctx-switch}
    2903 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
    2904 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2905 C function              & 1.8           & 1.8   & 0             \\
    2906 \CFA generator  & 2.7           & 2.4   & 0.27  \\
    2907 \CFA Coroutine  & 37.8          & 37.7  & 0.22  \\
    2908 \CFA Thread             & 93.6          & 93.8  & 1.46  \\
    2909 \uC Coroutine   & 52.7          & 52.8  & 0.28  \\
    2910 \uC Thread              & 93.4          & 93.7  & 1.04  \\
    2911 Goroutine               & 140.0         & 139.7 & 2.93  \\
    2912 Java Thread             & 374.0         & 375.8 & 10.38 \\
    2913 % Qthreads Thread       & 159.5         & 159.3 & 0.71  \\
    2914 Pthreads Thread & 334.4         & 335.0 & 1.95  \\
    2915 \end{tabular}
    2916 \end{multicols}
    2917 
    2918 
    2919 \paragraph{Mutual-Exclusion}
    2920 
    2921 Uncontented mutual exclusion, which frequently occurs, is measured by entering/leaving a critical section.
    2922 For monitors, entering and leaving a monitor function is measured.
    2923 To put the results in context, the cost of entering a non-inline function and the cost of acquiring and releasing a @pthread_mutex@ lock is also measured.
    2924 Figure~\ref{f:mutex} shows the code for \CFA with all results in Table~\ref{tab:mutex}.
    2925 Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
    2926 
    2927 \begin{multicols}{2}
    2928 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    2929 \begin{cfa}
    2930 @monitor@ M {} m1/*, m2, m3, m4*/;
    2931 void __attribute__((noinline))
    2932 do_call( M & @mutex m/*, m2, m3, m4*/@ ) {}
    2933 int main() {
    2934         BENCH(
    2935                 for( N ) do_call( m1/*, m2, m3, m4*/ );
    2936         )
    2937         sout | result`ns;
    2938 }
    2939 \end{cfa}
    2940 \captionof{figure}{\CFA acquire/release mutex benchmark}
    2941 \label{f:mutex}
    2942 
    2943 \columnbreak
    2944 
    2945 \vspace*{-16pt}
    2946 \captionof{table}{Mutex comparison (nanoseconds)}
    2947 \label{tab:mutex}
    2948 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
    2949 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2950 test and test-and-test lock             & 19.1  & 19.0  & 0.36  \\
    2951 \CFA @mutex@ function, 1 arg.   & 46.6  & 46.8  & 0.86  \\
    2952 \CFA @mutex@ function, 2 arg.   & 84.1  & 85.3  & 1.86  \\
    2953 \CFA @mutex@ function, 4 arg.   & 158.6 & 160.7 & 3.07  \\
    2954 \uC @monitor@ member rtn.               & 54.0  & 53.7  & 0.83  \\
    2955 Java synchronized method                & 27.0  & 27.1  & 0.25  \\
    2956 Pthreads Mutex Lock                             & 33.6  & 32.7  & 1.12
     2963\CFA @signal@, 1 @monitor@      & 372.6         & 374.3         & 14.17         \\
     2964\CFA @signal@, 2 @monitor@      & 492.7         & 494.1         & 12.99         \\
     2965\CFA @signal@, 4 @monitor@      & 749.4         & 750.4         & 24.74         \\
     2966\uC @signal@                            & 320.5         & 321.0         & 3.36          \\
     2967Java @notify@                           & 10160.5       & 10169.4       & 267.71        \\
     2968Pthreads Cond. Variable         & 4949.6        & 5065.2        & 363
    29572969\end{tabular}
    29582970\end{multicols}
  • driver/Makefile.in

    r8e1467d r4a60488  
    201201CCDEPMODE = @CCDEPMODE@
    202202CFACC = @CFACC@
     203CFACC_INSTALL = @CFACC_INSTALL@
    203204CFACPP = @CFACPP@
    204205CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    218219CYGPATH_W = @CYGPATH_W@
    219220DEFS = @DEFS@
     221DEMANGLER = @DEMANGLER@
    220222DEPDIR = @DEPDIR@
    221223DLLTOOL = @DLLTOOL@
     
    230232FGREP = @FGREP@
    231233GREP = @GREP@
     234HAS_DISTCC = @HAS_DISTCC@
    232235HOST_FLAGS = @HOST_FLAGS@
    233236INSTALL = @INSTALL@
     
    243246LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    244247LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     248LIBDEMANGLE = @LIBDEMANGLE@
    245249LIBOBJS = @LIBOBJS@
    246250LIBS = @LIBS@
  • driver/cc1.cc

    r8e1467d r4a60488  
    1010// Created On       : Fri Aug 26 14:23:51 2005
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep  3 16:57:05 2018
    13 // Update Count     : 125
     12// Last Modified On : Mon Sep  9 17:50:53 2019
     13// Update Count     : 384
    1414//
    1515
     
    1919#include <string>
    2020using std::string;
     21#include <algorithm>                                                                    // find
    2122#include <cstdio>                                                                               // stderr, stdout, perror, fprintf
    2223#include <cstdlib>                                                                              // getenv, exit, mkstemp
    2324#include <unistd.h>                                                                             // execvp, fork, unlink
    2425#include <sys/wait.h>                                                                   // wait
     26#include <fcntl.h>
     27
    2528
    2629#include "config.h"                                                                             // configure info
     
    3033
    3134
    32 string compiler_name( CFA_BACKEND_CC );                                 // path/name of C compiler
    33 
    34 string D__GCC_BPREFIX__( "-D__GCC_BPREFIX__=" );
    35 string D__CFA_FLAGPREFIX__( "-D__CFA_FLAG__=" );
    36 
    37 char tmpname[] = P_tmpdir "/CFAXXXXXX";
    38 int tmpfilefd = -1;
    39 
    40 
    41 bool prefix( string arg, string pre ) {
     35static string compiler_path( CFA_BACKEND_CC );                  // C compiler path/name
     36static bool CFA_flag = false;                                                   // -CFA flag
     37static bool save_temps = false;                                                 // -save-temps flag
     38static string o_file;
     39static string bprefix;
     40
     41
     42static bool prefix( const string & arg, const string & pre ) {
    4243        return arg.substr( 0, pre.size() ) == pre;
    4344} // prefix
    4445
    45 enum { NumSuffixes = 2 };
    46 const string suffixes[NumSuffixes] = { "cfa", "hfa", };
    47 
    48 void suffix( string arg, const char * args[], int & nargs ) {
    49         //std::cerr << arg << std::endl;
     46static void suffix( const string & arg, const char * args[], int & nargs ) {
     47        enum { NumSuffixes = 3 };
     48        static const string suffixes[NumSuffixes] = { "cfa", "hfa", "ifa" };
     49
    5050        size_t dot = arg.find_last_of( "." );
    51         //std::cerr << dot << " " << (dot != string::npos ? arg.substr( dot + 1 ) : "fred" ) << std::endl;
    5251        if ( dot == string::npos ) return;
    53         string sx = arg.substr( dot + 1 );
    54         for ( int i = 0; i < NumSuffixes; i += 1 ) {
    55                 if ( sx == suffixes[i] ) {
    56                         args[nargs] = "-x";
    57                         nargs += 1;
    58                         args[nargs] = "c";
    59                         nargs += 1;
    60                         return;
    61                 } // if
    62         } // for
     52        const string * end = suffixes + NumSuffixes;
     53        if ( std::find( suffixes, end, arg.substr( dot + 1 ) ) != end ) {
     54                args[nargs++] = "-x";
     55                args[nargs++] = "c";
     56        } // if
    6357} // suffix
    6458
    6559
    66 void checkEnv( const char * args[], int & nargs ) {
    67         char *value;
    68 
    69         value = getenv( "__CFA_COMPILER__" );
    70         if ( value != NULL ) {
    71                 compiler_name = value;
    72                 #ifdef __DEBUG_H__
    73                 cerr << "env arg:\"" << compiler_name << "\"" << endl;
    74                 #endif // __DEBUG_H__
    75         } // if
    76 
    77         value = getenv( "__GCC_MACHINE__" );
    78         if ( value != NULL ) {
    79                 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
    80                 #ifdef __DEBUG_H__
    81                 cerr << "env arg:\"" << args[nargs] << "\"" << endl;
    82                 #endif // __DEBUG_H__
    83                 nargs += 1;
    84         } // if
    85 
    86         value = getenv( "__GCC_VERSION__" );
    87         if ( value != NULL ) {
    88                 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
    89                 #ifdef __DEBUG_H__
    90                 cerr << "env arg:\"" << args[nargs] << "\"" << endl;
    91                 #endif // __DEBUG_H__
    92                 nargs += 1;
    93         } // if
    94 } // checkEnv
    95 
    96 
    97 void rmtmpfile() {
     60static string __CFA_FLAGPREFIX__( "__CFA_FLAG" );               // "N__=" suffix
     61
     62static void checkEnv1( const char * args[], int & nargs ) { // stage 1
     63        extern char ** environ;
     64
     65        for ( int i = 0; environ[i]; i += 1 ) {
     66                string arg( environ[i] );
     67                #ifdef __DEBUG_H__
     68                cerr << "env arg:\"" << arg << "\"" << endl;
     69                #endif // __DEBUG_H__
     70
     71                if ( prefix( arg, __CFA_FLAGPREFIX__ ) ) {
     72                        string val( arg.substr( arg.find_first_of( "=" ) + 1 ) );
     73                        if ( prefix( val, "-compiler=" ) ) {
     74                                compiler_path = val.substr( 10 );
     75                        } // if
     76                } // if
     77        } // for
     78} // checkEnv1
     79
     80
     81static void checkEnv2( const char * args[], int & nargs ) { // stage 2
     82        extern char ** environ;
     83
     84        for ( int i = 0; environ[i]; i += 1 ) {
     85                string arg( environ[i] );
     86                #ifdef __DEBUG_H__
     87                cerr << "env arg:\"" << arg << "\"" << endl;
     88                #endif // __DEBUG_H__
     89
     90                if ( prefix( arg, __CFA_FLAGPREFIX__ ) ) {
     91                        string val( arg.substr( arg.find_first_of( "=" ) + 1 ) );
     92                        if ( prefix( val, "-compiler=" ) ) {
     93                                compiler_path = val.substr( 10 );
     94                        } else if ( val == "-CFA" ) {
     95                                CFA_flag = true;
     96                        } else if ( val == "-save-temps" ) {
     97                                save_temps = true;
     98                        } else if ( prefix( val, "-o=" ) ) {            // output file for -CFA
     99                                o_file = val.substr( 3 );
     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();
     104                        } // if
     105                } // if
     106        } // for
     107} // checkEnv2
     108
     109
     110static char tmpname[] = P_tmpdir "/CFAXXXXXX.ifa";
     111static int tmpfilefd = -1;
     112static bool startrm = false;
     113
     114static void rmtmpfile() {
     115        if ( tmpfilefd == -1 ) return;                                          // RACE, file created ?
     116
     117        startrm = true;                                                                         // RACE with C-c C-c
    98118        if ( unlink( tmpname ) == -1 ) {                                        // remove tmpname
    99                 perror ( "CFA Translator error: cpp failed" );
    100                 exit( EXIT_FAILURE );
    101         } // if
    102         tmpfilefd = -1;                                                                         // mark closed
     119                perror ( "CC1 Translator error: failed, unlink" );
     120                exit( EXIT_FAILURE );
     121        } // if
     122        tmpfilefd = -1;                                                                         // mark removed
    103123} // rmtmpfile
    104124
    105125
    106 void sigTermHandler( __attribute__((unused)) int signal ) {
     126static void sigTermHandler( int ) {                                             // C-c C-c
     127        if ( startrm ) return;                                                          // return and let rmtmpfile finish, and then program finishes
     128
    107129        if ( tmpfilefd != -1 ) {                                                        // RACE, file created ?
    108                 rmtmpfile();                                                                    // remove
    109                 exit( EXIT_FAILURE );                                                   // terminate
    110         } // if
     130                rmtmpfile();                                                                    // remove tmpname
     131        } // if
     132        exit( EXIT_FAILURE );                                                           // terminate
    111133} // sigTermHandler
    112134
    113135
    114 void Stage1( const int argc, const char * const argv[] ) {
     136static void Stage1( const int argc, const char * const argv[] ) {
    115137        int code;
    116 
    117138        string arg;
    118         string bprefix;
    119 
    120         const char *cpp_in = NULL;
    121         const char *cpp_out = NULL;
    122 
    123         bool CFA_flag = false;
     139
     140        const char * cpp_in = nullptr;
     141        const char * cpp_out = nullptr;
     142
    124143        bool cpp_flag = false;
    125         const char *o_name = NULL;
    126 
    127         const char *args[argc + 100];                                           // leave space for 100 additional cpp command line values
     144        bool o_flag = false;
     145
     146        const char * args[argc + 100];                                          // leave space for 100 additional cpp command line values
    128147        int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
    129         const char *cargs[20];                                                          // leave space for 20 additional cfa-cpp command line values
    130         int ncargs = 1;                                                                         // 0 => command name
    131 
    132         signal( SIGINT,  sigTermHandler );
    133         signal( SIGTERM, sigTermHandler );
    134148
    135149        #ifdef __DEBUG_H__
    136150        cerr << "Stage1" << endl;
    137151        #endif // __DEBUG_H__
    138         checkEnv( args, nargs );                                                        // arguments passed via environment variables
     152        checkEnv1( args, nargs );                                                       // arguments passed via environment variables
    139153        #ifdef __DEBUG_H__
    140154        for ( int i = 1; i < argc; i += 1 ) {
     
    168182                                i += 1;                                                                 // and the argument
    169183                                cpp_flag = true;
    170                         } else if ( arg == "-D__CFA_PREPROCESS__" ) {
    171                                 CFA_flag = true;
    172                         } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA_PREPROCESS__" ) {
    173                                 i += 1;                                                                 // and the argument
    174                                 CFA_flag = true;
    175                         } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) {
    176                                 cargs[ncargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();
    177                                 ncargs += 1;
    178                         } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) {
    179                                 cargs[ncargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
    180                                 ncargs += 1;
    181                                 i += 1;                                                                 // and the argument
    182                         } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {
    183                                 bprefix = arg.substr( D__GCC_BPREFIX__.size() );
    184                         } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_BPREFIX__.substr(2) ) ) {
    185                                 bprefix = string( argv[i + 1] ).substr( D__GCC_BPREFIX__.size() - 2 );
    186                                 i += 1;                                                                 // and the argument
    187 
    188                         // all other flags
     184
     185                                // all other flags
    189186
    190187                        } else if ( arg == "-o" ) {
    191188                                i += 1;
    192                                 o_name = argv[i];
     189                                o_flag = true;
     190                                cpp_out = argv[i];
    193191                        } else {
    194                                 args[nargs] = argv[i];                                  // pass the flag along
    195                                 nargs += 1;
     192                                args[nargs++] = argv[i];                                // pass the flag along
    196193                                // CPP flags with an argument
    197194                                if ( arg == "-D" || arg == "-U" || arg == "-I" || arg == "-MF" || arg == "-MT" || arg == "-MQ" ||
     
    199196                                         arg == "-iwithprefix" || arg == "-iwithprefixbefore" || arg == "-isystem" || arg == "-isysroot" ) {
    200197                                        i += 1;
    201                                         args[nargs] = argv[i];                          // pass the argument along
    202                                         nargs += 1;
     198                                        args[nargs++] = argv[i];                        // pass the argument along
    203199                                        #ifdef __DEBUG_H__
    204200                                        cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
    205201                                        #endif // __DEBUG_H__
    206202                                } else if ( arg == "-MD" || arg == "-MMD" ) {
    207                                         args[nargs] = "-MF";                            // insert before file
    208                                         nargs += 1;
     203                                        args[nargs++] = "-MF";                          // insert before file
    209204                                        i += 1;
    210                                         args[nargs] = argv[i];                          // pass the argument along
    211                                         nargs += 1;
     205                                        args[nargs++] = argv[i];                        // pass the argument along
    212206                                        #ifdef __DEBUG_H__
    213207                                        cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
     
    216210                        } // if
    217211                } else {                                                                                // obtain input and possibly output files
    218                         if ( cpp_in == NULL ) {
     212                        if ( cpp_in == nullptr ) {
    219213                                cpp_in = argv[i];
    220214                                #ifdef __DEBUG_H__
    221215                                cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
    222216                                #endif // __DEBUG_H__
    223                         } else if ( cpp_out == NULL ) {
     217                        } else if ( cpp_out == nullptr ) {
    224218                                cpp_out = argv[i];
    225219                                #ifdef __DEBUG_H__
     
    238232                cerr << " " << args[i];
    239233        } // for
    240         if ( cpp_in != NULL ) cerr << " " << cpp_in;
    241         if ( cpp_out != NULL ) cerr << " " << cpp_out;
     234        if ( cpp_in != nullptr ) cerr << " " << cpp_in;
     235        if ( cpp_out != nullptr ) cerr << " " << cpp_out;
    242236        cerr << endl;
    243237        #endif // __DEBUG_H__
    244238
    245         if ( cpp_in == NULL ) {
     239        if ( cpp_in == nullptr ) {
    246240                cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
    247241                exit( EXIT_FAILURE );
     
    252246                // output or -o. The call to cfa has a -E so it does not have to be added to the argument list.
    253247
    254                 args[0] = compiler_name.c_str();
     248                args[0] = compiler_path.c_str();
    255249                suffix( cpp_in, args, nargs );                                  // check suffix
    256                 args[nargs] = cpp_in;
    257                 nargs += 1;
    258                 if ( o_name != NULL ) {                                                 // location for output
    259                         args[nargs] = "-o";
    260                         nargs += 1;
    261                         args[nargs] = o_name;
    262                         nargs += 1;
    263                 } // if
    264                 args[nargs] = NULL;                                                             // terminate argument list
     250                args[nargs++] = cpp_in;
     251                if ( o_flag ) {                                                                 // location for output
     252                        args[nargs++] = "-o";
     253                } // if
     254                args[nargs++] = cpp_out;
     255                args[nargs] = nullptr;                                                  // terminate argument list
    265256
    266257                #ifdef __DEBUG_H__
    267258                cerr << "nargs: " << nargs << endl;
    268                 for ( int i = 0; args[i] != NULL; i += 1 ) {
     259                for ( int i = 0; args[i] != nullptr; i += 1 ) {
    269260                        cerr << args[i] << " ";
    270261                } // for
     
    272263                #endif // __DEBUG_H__
    273264
    274                 execvp( args[0], (char *const *)args );                 // should not return
    275                 perror( "CFA Translator error: cpp level, execvp" );
    276                 exit( EXIT_FAILURE );
    277         } // if
    278 
    279         // Create a temporary file to store output of the C preprocessor.
    280 
    281         tmpfilefd = mkstemp( tmpname );
    282         if ( tmpfilefd == -1 ) {
    283                 perror( "CFA Translator error: cpp level, mkstemp" );
    284                 exit( EXIT_FAILURE );
    285         } // if
    286 
    287         #ifdef __DEBUG_H__
    288         cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl;
    289         #endif // __DEBUG_H__
    290 
    291         // Run the C preprocessor and save the output in tmpfile.
     265                execvp( args[0], (char * const *)args );                // should not return
     266                perror( "CC1 Translator error: stage 1, execvp" );
     267                exit( EXIT_FAILURE );
     268        } // if
     269
     270        // Run the C preprocessor and save the output in the given file.
    292271
    293272        if ( fork() == 0 ) {                                                             // child process ?
     
    295274                // an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error,
    296275                // when cpp writes to stdout. Hence, stdout is redirected into the temporary file.
    297                 if ( freopen( tmpname, "w", stdout ) == NULL ) { // redirect stdout to tmpname
    298                         perror( "CFA Translator error: cpp level, freopen" );
     276                if ( freopen( cpp_out, "w", stdout ) == nullptr ) { // redirect stdout to output file
     277                        perror( "CC1 Translator error: stage 1, freopen" );
    299278                        exit( EXIT_FAILURE );
    300279                } // if
    301280
    302                 args[0] = compiler_name.c_str();
     281                args[0] = compiler_path.c_str();
    303282                suffix( cpp_in, args, nargs );                                  // check suffix
    304                 args[nargs] = cpp_in;                                                   // input to cpp
    305                 nargs += 1;
    306                 args[nargs] = NULL;                                                             // terminate argument list
     283                args[nargs++] = cpp_in;                                                 // input to cpp
     284                args[nargs] = nullptr;                                                  // terminate argument list
    307285
    308286                #ifdef __DEBUG_H__
    309287                cerr << "cpp nargs: " << nargs << endl;
    310                 for ( int i = 0; args[i] != NULL; i += 1 ) {
     288                for ( int i = 0; args[i] != nullptr; i += 1 ) {
    311289                        cerr << args[i] << " ";
    312290                } // for
     
    314292                #endif // __DEBUG_H__
    315293
    316                 execvp( args[0], (char *const *)args );                 // should not return
    317                 perror( "CFA Translator error: cpp level, execvp" );
     294                execvp( args[0], (char * const *)args );                // should not return
     295                perror( "CC1 Translator error: stage 1 cpp, execvp" );
     296                cerr << " invoked " << args[0] << endl;
    318297                exit( EXIT_FAILURE );
    319298        } // if
     
    325304        #endif // __DEBUG_H__
    326305
    327         if ( WIFSIGNALED(code) != 0 ) {                                         // child failed ?
    328                 rmtmpfile();                                                                    // remove tmpname
    329                 cerr << "CFA Translator error: cpp failed with signal " << WTERMSIG(code) << endl;
    330                 exit( EXIT_FAILURE );
    331         } // if
    332 
    333         if ( WEXITSTATUS(code) != 0 ) {                                         // child error ?
    334                 rmtmpfile();                                                                    // remove tmpname
    335                 exit( WEXITSTATUS( code ) );                                    // do not continue
    336         } // if
    337 
    338         // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard
    339         // output.  Otherwise, run the cfa-cpp preprocessor on the temporary file and save the result into the output file.
    340 
    341         if ( fork() == 0 ) {                                                            // child runs CFA
    342                 cargs[0] = ( *new string( bprefix + "cfa-cpp" ) ).c_str();
    343 
    344                 // Source file-name used to generate routine names containing global initializations for TU.
    345                 cargs[ncargs] = ( *new string( "-F" ) ).c_str();
    346                 ncargs += 1;
    347                 cargs[ncargs] = ( *new string( string( cpp_in ) ) ).c_str();
    348                 ncargs += 1;
    349 
    350                 cargs[ncargs] = tmpname;
    351                 ncargs += 1;
    352                 if ( o_name != NULL ) {
    353                         cargs[ncargs] = o_name;
    354                         ncargs += 1;
    355                 } else if ( ! CFA_flag ) {                                              // run cfa-cpp ?
    356                         cargs[ncargs] = cpp_out;
    357                         ncargs += 1;
    358                 } // if
    359                 cargs[ncargs] = NULL;                                                   // terminate argument list
    360 
    361                 #ifdef __DEBUG_H__
    362                 cerr << "cfa-cpp ncargs: " << (o_name ? o_name : "No -o") << " " << CFA_flag << " " << ncargs << endl;
    363                 for ( int i = 0; cargs[i] != NULL; i += 1 ) {
    364                         cerr << cargs[i] << " ";
    365                 } // for
    366                 cerr << endl;
    367                 #endif // __DEBUG_H__
    368 
    369                 execvp( cargs[0], (char * const *)cargs );              // should not return
    370                 perror( "CFA Translator error: cpp level, execvp" );
    371                 exit( EXIT_FAILURE );
    372         } // if
    373 
    374         wait( &code );                                                                          // wait for child to finish
    375 
    376         #ifdef __DEBUG_H__
    377         cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl;
    378         #endif // __DEBUG_H__
    379 
    380         // Must unlink here because file must exist across execvp.
    381         rmtmpfile();                                                                            // remove tmpname
    382 
    383306        if ( WIFSIGNALED(code) ) {                                                      // child failed ?
    384                 cerr << "CFA Translator error: cfa-cpp failed with signal " << WTERMSIG(code) << endl;
    385                 exit( EXIT_FAILURE );
    386         } // if
    387 
    388         exit( WEXITSTATUS(code) );
     307                cerr << "CC1 Translator error: stage 1, child failed " << WTERMSIG(code) << endl;
     308                exit( EXIT_FAILURE );
     309        } // if
     310
     311        exit( WEXITSTATUS(code) );                                                      // bad cpp result stops top-level gcc
    389312} // Stage1
    390313
    391314
    392 void Stage2( const int argc, const char * const * argv ) {
     315static void Stage2( const int argc, const char * const * argv ) {
     316        int code;
    393317        string arg;
    394318
    395         const char *cpp_in = NULL;
    396 
    397         const char *args[argc + 100];                                           // leave space for 100 additional cfa command line values
     319        const char * cpp_in = nullptr;
     320        const char * cpp_out = nullptr;
     321
     322        const char * args[argc + 100];                                          // leave space for 100 additional cfa command line values
    398323        int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
     324        const char * cargs[20];                                                         // leave space for 20 additional cfa-cpp command line values
     325        int ncargs = 1;                                                                         // 0 => command name
    399326
    400327        #ifdef __DEBUG_H__
    401328        cerr << "Stage2" << endl;
    402329        #endif // __DEBUG_H__
    403         checkEnv( args, nargs );                                                        // arguments passed via environment variables
     330        checkEnv2( cargs, ncargs );                                                     // arguments passed via environment variables
    404331        #ifdef __DEBUG_H__
    405332        for ( int i = 1; i < argc; i += 1 ) {
     
    430357
    431358                        } else {
    432                                 args[nargs] = argv[i];                                  // pass the flag along
    433                                 nargs += 1;
     359                                args[nargs++] = argv[i];                                // pass the flag along
    434360                                if ( arg == "-o" ) {
    435361                                        i += 1;
    436                                         args[nargs] = argv[i];                          // pass the argument along
    437                                         nargs += 1;
     362                                        cpp_out = argv[i];
     363                                        args[nargs++] = argv[i];                        // pass the argument along
    438364                                        #ifdef __DEBUG_H__
    439365                                        cerr << "arg:\"" << argv[i] << "\"" << endl;
     
    442368                        } // if
    443369                } else {                                                                                // obtain input and possibly output files
    444                         if ( cpp_in == NULL ) {
     370                        if ( cpp_in == nullptr ) {
    445371                                cpp_in = argv[i];
    446372                                #ifdef __DEBUG_H__
    447373                                cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
    448374                                #endif // __DEBUG_H__
     375                        } else if ( cpp_out == nullptr ) {
     376                                cpp_out = argv[i];
     377                                #ifdef __DEBUG_H__
     378                                cerr << "cpp_out:\"" << cpp_out << "\""<< endl;
     379                                #endif // __DEBUG_H__
    449380                        } else {
    450                                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
     381                                cerr << "Usage: " << argv[0] << " more than two files specified" << endl;
    451382                                exit( EXIT_FAILURE );
    452383                        } // if
    453384                } // if
    454385        } // for
     386
     387        if ( cpp_in == nullptr ) {
     388                cerr << "Usage: " << argv[0] << " missing input file" << endl;
     389                exit( EXIT_FAILURE );
     390        } // if
     391        if ( cpp_out == nullptr ) {
     392                cerr << "Usage: " << argv[0] << " missing output file" << endl;
     393                exit( EXIT_FAILURE );
     394        } // if
     395
     396        // Create a temporary file, if needed, to store output of the cfa-cpp preprocessor. Cannot be created in forked
     397        // process because variables tmpname and tmpfilefd are cloned.
     398
     399        string cfa_cpp_out;
     400
     401        if ( ! CFA_flag ) {                                                                     // run compiler ?
     402                if ( save_temps ) {
     403                        cfa_cpp_out = cpp_in;
     404                        size_t dot = cfa_cpp_out.find_last_of( "." );
     405                        if ( dot == string::npos ) {
     406                                cerr << "CC1 Translator error: stage 2, bad file name " << endl;
     407                                exit( EXIT_FAILURE );
     408                        } // if
     409
     410                        cfa_cpp_out = cfa_cpp_out.substr( 0, dot ) + ".ifa";
     411                        if ( creat( cfa_cpp_out.c_str(), 0666 ) == -1 ) {
     412                                perror( "CC1 Translator error: stage 2, creat" );
     413                                exit( EXIT_FAILURE );
     414                        } // if
     415                } else {
     416                        tmpfilefd = mkstemps( tmpname, 4 );
     417                        if ( tmpfilefd == -1 ) {
     418                                perror( "CC1 Translator error: stage 2, mkstemp" );
     419                                exit( EXIT_FAILURE );
     420                        } // if
     421                        cfa_cpp_out = tmpname;
     422                } // if
     423                #ifdef __DEBUG_H__
     424                cerr << "cfa_cpp_out: " << cfa_cpp_out << endl;
     425                #endif // __DEBUG_H__
     426        } // if
     427
     428        // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard
     429        // output.  Otherwise, run the cfa-cpp preprocessor on the temporary file and save the result into the output file.
     430
     431        if ( fork() == 0 ) {                                                            // child runs CFA
     432                cargs[0] = ( *new string( bprefix + "cfa-cpp" ) ).c_str();
     433                cargs[ncargs++] = cpp_in;
     434
     435                if ( CFA_flag ) {                                                               // run cfa-cpp ?
     436                        if ( o_file.size() != 0 ) {                                     // location for output
     437                                cargs[ncargs++] = ( *new string( o_file.c_str() ) ).c_str();
     438                        } // if
     439                } else {
     440                        cargs[ncargs++] = cfa_cpp_out.c_str();
     441                } // if
     442                cargs[ncargs] = nullptr;                                                // terminate argument list
     443
     444                #ifdef __DEBUG_H__
     445                for ( int i = 0; cargs[i] != nullptr; i += 1 ) {
     446                        cerr << cargs[i] << " ";
     447                } // for
     448                cerr << endl;
     449                #endif // __DEBUG_H__
     450
     451                execvp( cargs[0], (char * const *)cargs );              // should not return
     452                perror( "CC1 Translator error: stage 2 cfa-cpp, execvp" );
     453                cerr << " invoked " << cargs[0] << endl;
     454                exit( EXIT_FAILURE );
     455        } // if
     456
     457        wait( &code );                                                                          // wait for child to finish
     458
     459        if ( WIFSIGNALED(code) ) {                                                      // child failed ?
     460                rmtmpfile();                                                                    // remove tmpname
     461                cerr << "CC1 Translator error: stage 2, child failed " << WTERMSIG(code) << endl;
     462                exit( EXIT_FAILURE );
     463        } // if
     464
     465        if ( CFA_flag ) {                                                                       // no tmpfile created
     466                exit( WEXITSTATUS( code ) );                                    // stop regardless of success or failure
     467        } // if
     468
     469        #ifdef __DEBUG_H__
     470        cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl;
     471        #endif // __DEBUG_H__
     472
     473        if ( WEXITSTATUS(code) ) {                                                      // child error ?
     474                rmtmpfile();                                                                    // remove tmpname
     475                exit( WEXITSTATUS( code ) );                                    // do not continue
     476        } // if
    455477
    456478        #ifdef __DEBUG_H__
     
    459481                cerr << " " << args[i];
    460482        } // for
    461         cerr << endl;
    462         if ( cpp_in != NULL ) cerr << " " << cpp_in;
    463         #endif // __DEBUG_H__
    464 
    465         args[0] = compiler_name.c_str();
    466         args[nargs] = "-S";                                                                     // only compile and put assembler output in specified file
    467         nargs += 1;
    468         args[nargs] = cpp_in;
    469         nargs += 1;
    470         args[nargs] = NULL;                                                                     // terminate argument list
    471 
    472         #ifdef __DEBUG_H__
    473         cerr << "stage2 nargs: " << nargs << endl;
    474         for ( int i = 0; args[i] != NULL; i += 1 ) {
    475                 cerr << args[i] << " ";
    476         } // for
    477         cerr << endl;
    478         #endif // __DEBUG_H__
    479 
    480         execvp( args[0], (char * const *)args );                        // should not return
    481         perror( "CFA Translator error: cpp level, execvp" );
    482         exit( EXIT_FAILURE );                                                           // tell gcc not to go any further
     483        cerr << " " << cpp_in << endl;
     484        #endif // __DEBUG_H__
     485
     486        if ( fork() == 0 ) {                                                            // child runs CFA
     487                args[0] = compiler_path.c_str();
     488                args[nargs++] = "-S";                                                   // only compile and put assembler output in specified file
     489                args[nargs++] = "-x";
     490                args[nargs++] = "cpp-output";
     491
     492                args[nargs++] = cfa_cpp_out.c_str();
     493                args[nargs] = nullptr;                                                  // terminate argument list
     494
     495                #ifdef __DEBUG_H__
     496                cerr << "stage2 nargs: " << nargs << endl;
     497                for ( int i = 0; args[i] != nullptr; i += 1 ) {
     498                        cerr << args[i] << " ";
     499                } // for
     500                cerr << endl;
     501                #endif // __DEBUG_H__
     502
     503                execvp( args[0], (char * const *)args );                // should not return
     504                perror( "CC1 Translator error: stage 2 cc1, execvp" );
     505                cerr << " invoked " << cargs[0] << endl;
     506                exit( EXIT_FAILURE );                                                   // tell gcc not to go any further
     507        } // if
     508
     509        wait( &code );                                                                          // wait for child to finish
     510        rmtmpfile();                                                                            // remove tmpname
     511
     512        if ( WIFSIGNALED(code) ) {                                                      // child failed ?
     513                cerr << "CC1 Translator error: stage 2, child failed " << WTERMSIG(code) << endl;
     514                exit( EXIT_FAILURE );
     515        } // if
     516
     517        #ifdef __DEBUG_H__
     518        cerr << "return code from gcc cc1:" << WEXITSTATUS(code) << endl;
     519        #endif // __DEBUG_H__
     520
     521        exit( WEXITSTATUS( code ) );                                            // stop regardless of success or failure
    483522} // Stage2
    484523
    485524
     525// This program is called twice because of the -no-integrated-cpp. The calls are differentiated by the first
     526// command-line argument. The first call replaces the traditional cpp pass to preprocess the C program. The second call
     527// is to the compiler, which is broken into two steps: preprocess again with cfa-cpp and then call gcc to compile the
     528// doubly preprocessed program.
     529
    486530int main( const int argc, const char * const argv[], __attribute__((unused)) const char * const env[] ) {
    487531        #ifdef __DEBUG_H__
    488         for ( int i = 0; env[i] != NULL; i += 1 ) {
     532        for ( int i = 0; env[i] != nullptr; i += 1 ) {
    489533                cerr << env[i] << endl;
    490534        } // for
    491535        #endif // __DEBUG_H__
    492536
    493         string arg = argv[1];
     537        signal( SIGINT,  sigTermHandler );
     538        signal( SIGTERM, sigTermHandler );
     539
     540        string arg( argv[1] );
    494541
    495542        // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed.
  • driver/cfa.cc

    r8e1467d r4a60488  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 10 08:28:09 2019
    13 // Update Count     : 281
     12// Last Modified On : Tue Sep 10 17:00:15 2019
     13// Update Count     : 420
    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
     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
    2224
    2325#include <sys/types.h>
     
    3234using std::to_string;
    3335
    34 
    35 //#define __DEBUG_H__
    36 
    37 
    38 bool prefix( string arg, string pre ) {
     36// #define __DEBUG_H__
     37
     38// "N__=" suffix
     39static string __CFA_FLAGPREFIX__( "__CFA_FLAG" );
     40
     41void Putenv( char * argv[], string arg ) {
     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() ) ) {
     46                cerr << argv[0] << " error, cannot set environment variable." << endl;
     47                exit( EXIT_FAILURE );
     48        } // if
     49} // Putenv
     50
     51// check if string has prefix
     52bool prefix( const string & arg, const string & pre ) {
    3953        return arg.substr( 0, pre.size() ) == pre;
    4054} // prefix
    4155
    42 enum { NumSuffixes = 2 };
    43 const string suffixes[NumSuffixes] = { "cfa", "hfa", };
    44 
    45 bool suffix( string arg, const char * args[], int & nargs ) {
    46         //std::cerr << arg << std::endl;
     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 ) {
     63        enum { NumSuffixes = 3 };
     64        static const string suffixes[NumSuffixes] = { "cfa", "hfa", "ifa" };
     65
    4766        size_t dot = arg.find_last_of( "." );
    48         //std::cerr << dot << " " << (dot != string::npos ? arg.substr( dot + 1 ) : "fred" ) << std::endl;
    4967        if ( dot == string::npos ) return false;
    50         string sx = arg.substr( dot + 1 );
    51         for ( int i = 0; i < NumSuffixes; i += 1 ) {
    52                 if ( sx == suffixes[i] ) {
    53                         args[nargs] = "-x";
    54                         nargs += 1;
    55                         args[nargs] = "c";
    56                         nargs += 1;
    57                         return true;
    58                 } // if
    59         } // for
    60         return false;
     68        const string * end = suffixes + NumSuffixes;
     69        return std::find( suffixes, end, arg.substr( dot + 1 ) ) != end;
    6170} // suffix
    6271
    6372
    64 void shuffle( const char *args[], int S, int E, int N ) {
    65         // S & E index 1 passed the end so adjust with -1
    66         #ifdef __DEBUG_H__
    67         cerr << "shuffle:" << S << " " << E << " " << N << endl;
    68         #endif // __DEBUG_H__
    69         for ( int j = E-1 + N; j > S-1 + N; j -=1 ) {
    70                 #ifdef __DEBUG_H__
    71                 cerr << "\t" << j << " " << j-N << endl;
    72                 #endif // __DEBUG_H__
    73                 args[j] = args[j-N];
    74         } // for
    75 } // shuffle
    76 
    77 static inline bool dirExists(const string & path) {
     73static inline bool dirExists( const string & path ) {   // check if directory exists
    7874    struct stat info;
    79     if(stat( path.c_str(), &info ) != 0)
    80         return false;
    81     else if(info.st_mode & S_IFDIR)
    82         return true;
    83     else
    84         return false;
    85 } //dirExists
    86 
    87 
     75    if ( stat( path.c_str(), &info ) != 0 ) return false;
     76        return (info.st_mode & S_IFDIR) != 0;
     77} // 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}
     119
     120
     121#define xstr(s) str(s)
    88122#define str(s) #s
    89123
    90 int main( int argc, char *argv[] ) {
     124int main( int argc, char * argv[] ) {
    91125        string Version( CFA_VERSION_LONG );                                     // current version number from CONFIG
    92         string Major( str( CFA_VERSION_MAJOR ) ), Minor( str( CFA_VERSION_MINOR ) ), Patch( str( CFA_VERSION_PATCH ) );
     126        string Major( xstr( CFA_VERSION_MAJOR ) ), Minor( xstr( CFA_VERSION_MINOR ) ), Patch( xstr( CFA_VERSION_PATCH ) );
    93127
    94128        string installincdir( CFA_INCDIR );                                     // fixed location of include files
     
    98132        string heading;                                                                         // banner printed at start of cfa compilation
    99133        string arg;                                                                                     // current command-line argument during command-line parsing
    100         string Bprefix;                                                                         // path where gcc looks for compiler command steps
     134        string bprefix;                                                                         // path where gcc looks for compiler steps
    101135        string langstd;                                                                         // language standard
    102136
     
    104138        string compiler_name;                                                           // name of C compiler
    105139
    106         bool nonoptarg = false;                                                         // indicates non-option argument specified
    107         bool link = true;                                                                       // linking as well as compiling
     140        bool x_flag = false;                                                            // -x flag
     141        bool nonoptarg = false;                                                         // no non-option arguments specified, i.e., no file names
     142        bool link = true;                                                                       // link stage occurring
    108143        bool verbose = false;                                                           // -v flag
    109         bool quiet = false;                                                             // -quiet flag
    110         bool debug = true;                                                              // -debug flag
    111         bool nolib = false;                                                             // -nolib flag
    112         bool help = false;                                                              // -help flag
     144        bool quiet = false;                                                                     // -quiet flag
     145        bool debug = true;                                                                      // -debug flag
     146        bool nolib = false;                                                                     // -nolib flag
     147        bool help = false;                                                                      // -help flag
    113148        bool CFA_flag = false;                                                          // -CFA flag
    114149        bool cpp_flag = false;                                                          // -E or -M flag, preprocessor only
     
    116151        bool noincstd_flag = false;                                                     // -no-include-stdhdr= flag
    117152        bool debugging __attribute(( unused )) = false;         // -g flag
    118         bool m32 = false;                                    // -m32 flag
    119         bool m64 = false;                                    // -m64 flag
    120         bool intree = false;
     153        bool m32 = false;                                                                       // -m32 flag
     154        bool m64 = false;                                                                       // -m64 flag
     155        bool compiling_libs = false;
     156        int o_file = 0;                                                                         // -o filename position
     157
     158        PathMode path = FromProc();
    121159
    122160        const char *args[argc + 100];                                           // cfa command line values, plus some space for additional flags
     
    142180
    143181                        if ( arg == "-Xlinker" || arg == "-o" ) {
    144                                 args[nargs] = argv[i];                                  // pass the argument along
    145                                 nargs += 1;
     182                                args[nargs++] = argv[i];                                // pass argument along
    146183                                i += 1;
    147184                                if ( i == argc ) continue;                              // next argument available ?
    148                                 args[nargs] = argv[i];                                  // pass the argument along
    149                                 nargs += 1;
     185                                args[nargs++] = argv[i];                                // pass argument along
     186                                if ( arg == "-o" ) o_file = i;                  // remember file
    150187                        } else if ( arg == "-XCFA" ) {                          // CFA pass through
    151188                                i += 1;
    152                                 args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + argv[i] ) ).c_str();
    153                                 nargs += 1;
     189                                Putenv( argv, argv[i] );
    154190
    155191                                // CFA specific arguments
     
    158194                                CFA_flag = true;                                                // strip the -CFA flag
    159195                                link = false;
    160                                 args[nargs] = "-E";                                             // replace the argument with -E
    161                                 nargs += 1;
     196                                args[nargs++] = "-fsyntax-only";                // stop after stage 2
    162197                        } else if ( arg == "-debug" ) {
    163198                                debug = true;                                                   // strip the debug flag
    164199                        } else if ( arg == "-nodebug" ) {
    165                                 debug = false;                                                  // strip the debug flag
     200                                debug = false;                                                  // strip the nodebug flag
    166201                        } else if ( arg == "-nolib" ) {
    167202                                nolib = true;                                                   // strip the nodebug flag
     
    176211                        } else if ( arg == "-no-include-stdhdr" ) {
    177212                                noincstd_flag = true;                                   // strip the no-include-stdhdr flag
    178                         } else if ( arg == "-in-tree" ) {
    179                                 intree = true;
     213                        } else if ( arg == "-cfalib") {
     214                                compiling_libs = true;
    180215                        } else if ( arg == "-compiler" ) {
    181216                                // use the user specified compiler
     
    183218                                if ( i == argc ) continue;                              // next argument available ?
    184219                                compiler_path = argv[i];
    185                                 if ( putenv( (char *)( *new string( string( "__CFA_COMPILER__=" ) + argv[i]) ).c_str() ) != 0 ) {
    186                                         cerr << argv[0] << " error, cannot set environment variable." << endl;
    187                                         exit( EXIT_FAILURE );
    188                                 } // if
     220                                Putenv( argv, arg + "=" + argv[i] );
    189221
    190222                                // C specific arguments
     
    192224                        } else if ( arg == "-v" ) {
    193225                                verbose = true;                                                 // verbosity required
    194                                 args[nargs] = argv[i];                                  // pass the argument along
    195                                 nargs += 1;
     226                                args[nargs++] = argv[i];                                // pass argument along
    196227                        } else if ( arg == "-g" ) {
    197228                                debugging = true;                                               // symbolic debugging required
    198                                 args[nargs] = argv[i];                                  // pass the argument along
    199                                 nargs += 1;
     229                                args[nargs++] = argv[i];                                // pass argument along
     230                        } else if ( arg == "-save-temps" ) {
     231                                args[nargs++] = argv[i];                                // pass argument along
     232                                Putenv( argv, arg );                                    // save cfa-cpp output
     233                        } else if ( prefix( arg, "-x" ) ) {                     // file suffix ?
     234                                string lang;
     235                                args[nargs++] = argv[i];                                // pass argument along
     236                                if ( arg.length() == 2 ) {                              // separate argument ?
     237                                        i += 1;
     238                                        if ( i == argc ) continue;                      // next argument available ?
     239                                        lang = argv[i];
     240                                        args[nargs++] = argv[i];                        // pass argument along
     241                                } else {
     242                                        lang = arg.substr( 2 );
     243                                } // if
     244                                x_flag = lang != "none";
    200245                        } else if ( prefix( arg, "-std=" ) || prefix( arg, "--std=" ) ) {
    201246                                std_flag = true;                                                // -std=XX provided
    202                                 args[nargs] = argv[i];                                  // pass the argument along
    203                                 nargs += 1;
     247                                args[nargs++] = argv[i];                                // pass argument along
    204248                        } else if ( arg == "-w" ) {
    205                                 args[nargs] = argv[i];                                  // pass the argument along
    206                                 nargs += 1;
    207                                 args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + arg ) ).c_str(); // add the argument for cfa-cpp
    208                                 nargs += 1;
     249                                args[nargs++] = argv[i];                                // pass argument along
     250                                Putenv( argv, arg );
    209251                        } else if ( prefix( arg, "-W" ) ) {                     // check before next tests
    210252                                if ( arg == "-Werror" || arg == "-Wall" ) {
    211                                         args[nargs] = argv[i];                          // pass the argument along
    212                                         nargs += 1;
    213                                         args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + arg ) ).c_str(); // add the argument for cfa-cpp
    214                                         nargs += 1;
     253                                        args[nargs++] = argv[i];                        // pass argument along
     254                                        Putenv( argv, argv[i] );
    215255                                } else {
    216256                                        unsigned int adv = prefix( arg, "-Wno-" ) ? 5 : 2;
    217                                         args[nargs] = argv[i];                          // conditionally pass the argument along
    218                                         const char * warning = argv[i] + adv;    // extract warning
     257                                        args[nargs] = argv[i];                          // conditionally pass argument along
     258                                        const char * warning = argv[i] + adv; // extract warning
    219259                                        if ( SemanticWarning_Exist( warning ) ) { // replace the argument for cfa-cpp
    220                                                 args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + arg ) ).c_str();
     260                                                Putenv( argv, arg );
    221261                                        } // if
    222262                                        nargs += 1;
    223263                                } // if
    224264                        } else if ( prefix( arg, "-B" ) ) {
    225                                 Bprefix = arg.substr(2);                                // strip the -B flag
    226                                 args[nargs] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
    227                                 nargs += 1;
    228                         } else if ( prefix( arg, "-b" ) ) {
    229                                 if ( arg.length() == 2 ) {                              // separate argument ?
    230                                         i += 1;
    231                                         if ( i == argc ) continue;                      // next argument available ?
    232                                         arg += argv[i];                                         // concatenate argument
    233                                 } // if
    234                                 // later versions of gcc require the -b option to appear at the start of the command line
    235                                 shuffle( args, sargs, nargs, 1 );               // make room at front of argument list
    236                                 args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
    237                                 if ( putenv( (char *)( *new string( string( "__GCC_MACHINE__=" ) + arg ) ).c_str() ) != 0 ) {
    238                                         cerr << argv[0] << " error, cannot set environment variable." << endl;
    239                                         exit( EXIT_FAILURE );
    240                                 } // if
    241                                 sargs += 1;
    242                                 nargs += 1;
    243                         } else if ( prefix( arg, "-V" ) ) {
    244                                 if ( arg.length() == 2 ) {                              // separate argument ?
    245                                         i += 1;
    246                                         if ( i == argc ) continue;                      // next argument available ?
    247                                         arg += argv[i];                                         // concatenate argument
    248                                 } // if
    249                                 // later versions of gcc require the -V option to appear at the start of the command line
    250                                 shuffle( args, sargs, nargs, 1 );               // make room at front of argument list
    251                                 args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
    252                                 if ( putenv( (char *)( *new string( string( "__GCC_VERSION__=" ) + arg ) ).c_str() ) != 0 ) {
    253                                         cerr << argv[0] << " error, cannot set environment variable." << endl;
    254                                         exit( EXIT_FAILURE );
    255                                 } // if
    256                                 sargs += 1;
    257                                 nargs += 1;
     265                                bprefix = arg.substr(2);                                // strip the -B flag
    258266                        } else if ( arg == "-c" || arg == "-S" || arg == "-E" || arg == "-M" || arg == "-MM" ) {
    259                                 args[nargs] = argv[i];                                  // pass the argument along
    260                                 nargs += 1;
     267                                args[nargs++] = argv[i];                                // pass argument along
    261268                                if ( arg == "-E" || arg == "-M" || arg == "-MM" ) {
    262269                                        cpp_flag = true;                                        // cpp only
     
    265272                        } else if ( arg[1] == 'l' ) {
    266273                                // if the user specifies a library, load it after user code
    267                                 libs[nlibs] = argv[i];
    268                                 nlibs += 1;
     274                                libs[nlibs++] = argv[i];
    269275                        } else if ( arg == "-m32" ) {
    270276                                m32 = true;
    271277                                m64 = false;
    272                                 args[nargs] = argv[i];
    273                                 nargs += 1;
     278                                args[nargs++] = argv[i];
    274279                        } else if ( arg == "-m64" ) {
    275280                                m64 = true;
    276281                                m32 = false;
    277                                 args[nargs] = argv[i];
    278                                 nargs += 1;
     282                                args[nargs++] = argv[i];
    279283                        } else {
    280284                                // concatenate any other arguments
    281                                 args[nargs] = argv[i];
    282                                 nargs += 1;
     285                                args[nargs++] = argv[i];
    283286                        } // if
    284287                } else {
    285                         bool cfa = suffix( arg, args, nargs );          // check suffix
    286                         args[nargs] = argv[i];                                          // concatenate file
    287                         nargs += 1;
    288                         if ( cfa ) {
    289                                 args[nargs] = "-x";
    290                                 nargs += 1;
    291                                 args[nargs] = "none";
    292                                 nargs += 1;
     288                        bool cfa = suffix( arg );                                       // check suffix
     289                        if ( ! x_flag && cfa ) {                                        // no explicit suffix and cfa suffix ?
     290                                args[nargs++] = "-x";
     291                                args[nargs++] = "c";
     292                        } // if
     293                        args[nargs++] = argv[i];                                        // concatenate files
     294                        if ( ! x_flag && cfa ) {                                        // no explicit suffix and cfa suffix ?
     295                                args[nargs++] = "-x";
     296                                args[nargs++] = "none";
    293297                        } // if
    294298                        nonoptarg = true;
     
    296300        } // for
    297301
    298     args[nargs] = "-x";                                                                 // turn off language
    299     nargs += 1;
    300     args[nargs] = "none";
    301     nargs += 1;
    302 
    303302        #ifdef __x86_64__
    304         args[nargs] = "-mcx16";                                                         // allow double-wide CAA
    305         nargs += 1;
     303        args[nargs++] = "-mcx16";                                                       // allow double-wide CAA
    306304        #endif // __x86_64__
    307305
     
    314312        #endif // __DEBUG_H__
    315313
     314        // -E flag stops at cc1 stage 1, so cfa-cpp in cc1 stage 2 is never executed.
    316315        if ( cpp_flag && CFA_flag ) {
    317                 cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
    318                 exit( EXIT_FAILURE );
     316                CFA_flag = false;
     317                cerr << argv[0] << " warning, both -E and -CFA flags specified, using -E and ignoring -CFA." << endl;
    319318        } // if
    320319
    321320        // add the CFA include-library paths, which allow direct access to header files without directory qualification
    322         if( !intree ) {
    323                 args[nargs] = "-I" CFA_INCDIR;
    324                 nargs += 1;
    325                 if ( ! noincstd_flag ) {                                                // do not use during build
    326                         args[nargs] = "-I" CFA_INCDIR "stdhdr";
    327                         nargs += 1;
    328                 } // if
    329                 args[nargs] = "-I" CFA_INCDIR "concurrency";
    330                 nargs += 1;
    331                 args[nargs] = "-I" CFA_INCDIR "containers";
    332                 nargs += 1;
    333         } else {
    334                 args[nargs] = "-I" TOP_SRCDIR "libcfa/src";
    335                 nargs += 1;
    336                 if ( ! noincstd_flag ) {                                                // do not use during build
    337                         args[nargs] = "-I" TOP_SRCDIR "libcfa/src" "/stdhdr";
    338                         nargs += 1;
    339                 } // if
    340                 args[nargs] = "-I" TOP_SRCDIR "libcfa/src" "/concurrency";
    341                 nargs += 1;
    342                 args[nargs] = "-I" TOP_SRCDIR "libcfa/src" "/containers";
    343                 nargs += 1;
    344         }
     321        string libbase;
     322        switch(path) {
     323        case Installed:
     324                args[nargs++] = "-I" CFA_INCDIR;
     325                // do not use during build
     326                if ( ! noincstd_flag ) {
     327                        args[nargs++] = "-I" CFA_INCDIR "stdhdr";
     328                } // if
     329                args[nargs++] = "-I" CFA_INCDIR "concurrency";
     330                args[nargs++] = "-I" CFA_INCDIR "containers";
     331                libbase = CFA_LIBDIR;
     332                break;
     333        case BuildTree:
     334        case Distributed:
     335                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src";
     336                // do not use during build
     337                if ( ! noincstd_flag ) {
     338                        args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/stdhdr";
     339                } // if
     340                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/concurrency";
     341                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/containers";
     342
     343                libbase = TOP_BUILDDIR "libcfa/";
     344
     345                break;
     346        } // if
    345347
    346348        // add stdbool to get defines for bool/true/false
    347         args[nargs] = "-imacros";
    348         nargs += 1;
    349         args[nargs] = "stdbool.h";
    350         nargs += 1;
    351 
    352         string libbase;
    353         if( !intree ) {
    354                 libbase = CFA_LIBDIR;
    355         } else {
    356                 libbase = TOP_BUILDDIR "libcfa/";
    357                 args[nargs] = "-D__CFA_FLAG__=-t";
    358                 nargs += 1;
    359         }
    360 
    361         string arch = m32 ? CFA_32_CPU : (m64 ? CFA_64_CPU : CFA_DEFAULT_CPU);
     349        args[nargs++] = "-imacros";
     350        args[nargs++] = "stdbool.h";
     351
     352        if( compiling_libs ) {
     353                Putenv( argv, "-t" );
     354        } // if
     355
     356        string arch( m32 ? CFA_32_CPU : (m64 ? CFA_64_CPU : CFA_DEFAULT_CPU) );
    362357        if ( ! m32 && ! m64 ) {
    363358                if ( arch == "x86" ) {
    364                         args[nargs] = "-m32";
    365                         nargs += 1;
     359                        args[nargs++] = "-m32";
    366360                } else if ( arch == "x64" ) {
    367                         args[nargs] = "-m64";
    368                         nargs += 1;
     361                        args[nargs++] = "-m64";
    369362                }  // if
    370363        } // if
     364
    371365        const char * config = nolib ? "nolib" : (debug ? "debug": "nodebug");
    372366        string libdir = libbase + arch + "-" + config;
    373367
    374         if ( ! nolib && ! dirExists( libdir ) ) {
    375                 cerr << argv[0] << " internal error, configuration " << config << " not installed." << endl;
    376                 cerr << "Was looking for " << libdir << 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 
    386         args[nargs] = ( *new string( string("-D__CFA_FLAG__=--prelude-dir=" ) + libdir + (intree ? "/prelude" : "")) ).c_str();
    387         nargs += 1;
     368        if (path != Distributed) {
     369                if ( ! nolib && ! dirExists( libdir ) ) {
     370                        cerr << argv[0] << " internal error, configuration " << config << " not installed." << endl;
     371                        cerr << "Was looking for " << libdir << endl;
     372                        for(int i = 1; i < argc; i++) {
     373                                cerr << argv[i] << " ";
     374                        }
     375                        cerr << endl;
     376                        libdir = libbase + arch + "-" + "nolib";
     377                } // if
     378
     379                if ( ! dirExists( libdir ) ) {
     380                        cerr << argv[0] << " internal error, cannot find prelude directory." << endl;
     381                        cerr << "Was looking for " << libdir << endl;
     382                        exit( EXIT_FAILURE );
     383                } // if
     384        } // if
     385
     386        switch(path) {
     387        case Installed   : Putenv( argv, "--prelude-dir=" + libdir ); break;
     388        case BuildTree   : Putenv( argv, "--prelude-dir=" + libdir + "/prelude" ); break;
     389        case Distributed : Putenv( argv, "--prelude-dir=" + dir(argv[0]) ); break;
     390        }
    388391
    389392        for ( int i = 0; i < nlibs; i += 1 ) {                          // copy non-user libraries after all user libraries
    390                 args[nargs] = libs[i];
    391                 nargs += 1;
     393                args[nargs++] = libs[i];
    392394        } // for
    393395
    394396        if ( link ) {
    395                 args[nargs] = "-Xlinker";
    396                 nargs += 1;
    397                 args[nargs] = "--undefined=__cfaabi_dbg_bits_write";
    398                 nargs += 1;
    399                 args[nargs] = "-Xlinker";
    400                 nargs += 1;
    401                 args[nargs] = "--undefined=__cfaabi_interpose_startup";
    402                 nargs += 1;
    403                 args[nargs] = "-Xlinker";
    404                 nargs += 1;
    405                 args[nargs] = "--undefined=__cfaabi_appready_startup";
    406                 nargs += 1;
    407 
    408                 // include the cfa library in case it's needed
    409                 args[nargs] = ( *new string( string("-L" ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
    410                 nargs += 1;
    411                 args[nargs] = ( *new string( string("-Wl,-rpath," ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
    412                 nargs += 1;
    413                 args[nargs] = "-Wl,--push-state,--as-needed";
    414                 nargs += 1;
    415                 args[nargs] = "-lcfathread";
    416                 nargs += 1;
    417                 args[nargs] = "-Wl,--pop-state";
    418                 nargs += 1;
    419                 args[nargs] = "-lcfa";
    420                 nargs += 1;
    421                 args[nargs] = "-lpthread";
    422                 nargs += 1;
    423                 args[nargs] = "-ldl";
    424                 nargs += 1;
    425                 args[nargs] = "-lrt";
    426                 nargs += 1;
    427                 args[nargs] = "-lm";
    428                 nargs += 1;
    429         } // if
    430 
    431         // Add exception flags (unconditionally)
    432         args[nargs] = "-fexceptions";
    433         nargs += 1;
    434 
    435         // add the correct set of flags based on the type of compile this is
    436 
    437         args[nargs] = ( *new string( string("-D__CFA_MAJOR__=") + Major ) ).c_str();
    438         nargs += 1;
    439         args[nargs] = ( *new string( string("-D__CFA_MINOR__=") + Minor ) ).c_str();
    440         nargs += 1;
    441         args[nargs] = ( *new string( string("-D__CFA_PATCH__=") + Patch ) ).c_str();
    442         nargs += 1;
    443         args[nargs] = "-D__CFA__";
    444         nargs += 1;
    445         args[nargs] = "-D__CFORALL__";
    446         nargs += 1;
    447         args[nargs] = "-D__cforall";
    448         nargs += 1;
     397                args[nargs++] = "-Xlinker";
     398                args[nargs++] = "--undefined=__cfaabi_dbg_bits_write";
     399                args[nargs++] = "-Xlinker";
     400                args[nargs++] = "--undefined=__cfaabi_interpose_startup";
     401                args[nargs++] = "-Xlinker";
     402                args[nargs++] = "--undefined=__cfaabi_appready_startup";
     403
     404                // include the cfa library in case it is needed
     405                args[nargs++] = ( *new string( string("-L" ) + libdir + (path != Installed ? "/src/.libs" : "")) ).c_str();
     406                args[nargs++] = ( *new string( string("-Wl,-rpath," ) + libdir + (path != Installed ? "/src/.libs" : "")) ).c_str();
     407                args[nargs++] = "-Wl,--push-state,--as-needed";
     408                args[nargs++] = "-lcfathread";
     409                args[nargs++] = "-Wl,--pop-state";
     410                args[nargs++] = "-lcfa";
     411                args[nargs++] = "-lpthread";
     412                args[nargs++] = "-ldl";
     413                args[nargs++] = "-lrt";
     414                args[nargs++] = "-lm";
     415        } // if
     416
     417        args[nargs++] = "-fexceptions";                                         // add exception flags (unconditionally)
     418
     419        // add flags based on the type of compile
     420
     421        args[nargs++] = ( *new string( string("-D__CFA_MAJOR__=") + Major ) ).c_str();
     422        args[nargs++] = ( *new string( string("-D__CFA_MINOR__=") + Minor ) ).c_str();
     423        args[nargs++] = ( *new string( string("-D__CFA_PATCH__=") + Patch ) ).c_str();
     424        args[nargs++] = "-D__CFA__";
     425        args[nargs++] = "-D__CFORALL__";
     426        args[nargs++] = "-D__cforall";
    449427
    450428        if ( cpp_flag ) {
    451                 args[nargs] = "-D__CPP__";
    452                 nargs += 1;
    453         } // if
    454 
    455         shuffle( args, sargs, nargs, 1 );                                       // make room at front of argument list
    456         nargs += 1;
     429                args[nargs++] = "-D__CPP__";
     430        } // if
     431
    457432        if ( CFA_flag ) {
    458                 args[sargs] = "-D__CFA_FLAG__=-N";
    459                 args[nargs] = "-D__CFA_PREPROCESS_";
    460                 nargs += 1;
     433                Putenv( argv, "-N" );
     434                Putenv( argv, "-CFA" );
     435                // -CFA implies cc1 stage 2, but gcc does not pass the -o file to this stage because it believe the file is for
     436                // the linker. Hence, the -o file is explicit passed to cc1 stage 2 and used as cfa-cpp's output file.
     437                if ( o_file ) Putenv( argv, string( "-o=" ) + argv[o_file] );
    461438        } else {
    462                 args[sargs] = "-D__CFA_FLAG__=-L";
    463         } // if
    464         sargs += 1;
     439                Putenv( argv, "-L" );
     440        } // if
    465441
    466442        if ( debug ) {
    467443                heading += " (debug)";
    468                 args[nargs] = "-D__CFA_DEBUG__";
    469                 nargs += 1;
     444                args[nargs++] = "-D__CFA_DEBUG__";
    470445        } else {
    471446                heading += " (no debug)";
    472447        } // if
    473448
    474         if ( Bprefix.length() == 0 ) {
    475                 Bprefix = ! intree ? installlibdir : srcdriverdir;
    476                 if ( Bprefix[Bprefix.length() - 1] != '/' ) Bprefix += '/';
    477                 args[nargs] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
    478                 nargs += 1;
    479         } // if
    480 
    481         args[nargs] = "-Xlinker";                                                       // used by backtrace
    482         nargs += 1;
    483         args[nargs] = "-export-dynamic";
    484         nargs += 1;
     449        if ( bprefix.length() == 0 ) {
     450                switch(path) {
     451                case Installed   : bprefix = installlibdir; break;
     452                case BuildTree   : bprefix = srcdriverdir ; break;
     453                case Distributed : bprefix = dir(argv[0]) ; break;
     454                }
     455                if ( bprefix[bprefix.length() - 1] != '/' ) bprefix += '/';
     456                Putenv( argv, string("-B=") + bprefix );
     457        } // if
     458
     459        args[nargs++] = "-Xlinker";                                                     // used by backtrace
     460        args[nargs++] = "-export-dynamic";
    485461
    486462        // execute the compilation command
     
    496472
    497473        if ( prefix( compiler_name, "gcc" ) ) {                         // allow suffix on gcc name
    498                 args[nargs] = "-no-integrated-cpp";
    499                 nargs += 1;
    500                 args[nargs] = "-Wno-deprecated";
    501                 nargs += 1;
    502 #ifdef HAVE_CAST_FUNCTION_TYPE
    503                 args[nargs] = "-Wno-cast-function-type";
    504                 nargs += 1;
    505 #endif // HAVE_CAST_FUNCTION_TYPE
     474                args[nargs++] = "-no-integrated-cpp";
     475                args[nargs++] = "-Wno-deprecated";
     476                #ifdef HAVE_CAST_FUNCTION_TYPE
     477                args[nargs++] = "-Wno-cast-function-type";
     478                #endif // HAVE_CAST_FUNCTION_TYPE
    506479                if ( ! std_flag ) {                                                             // default c11, if none specified
    507                         args[nargs] = "-std=gnu11";
    508                         nargs += 1;
    509                 } // if
    510                 args[nargs] = "-fgnu89-inline";
    511                 nargs += 1;
    512                 args[nargs] = "-D__int8_t_defined";                             // prevent gcc type-size attributes
    513                 nargs += 1;
    514                 args[nargs] = ( *new string( string("-B") + Bprefix ) ).c_str();
    515                 nargs += 1;
     480                        args[nargs++] = "-std=gnu11";
     481                } // if
     482                args[nargs++] = "-fgnu89-inline";
     483                args[nargs++] = "-D__int8_t_defined";                   // prevent gcc type-size attributes
     484                args[nargs++] = ( *new string( string("-B") + bprefix ) ).c_str();
    516485        } else {
    517486                cerr << argv[0] << " error, compiler \"" << compiler_name << "\" unsupported." << endl;
     
    519488        } // if
    520489
    521         args[nargs] = NULL;                                                                     // terminate with NULL
     490        args[nargs] = nullptr;                                                          // terminate
    522491
    523492        #ifdef __DEBUG_H__
    524493        cerr << "nargs: " << nargs << endl;
    525494        cerr << "args:" << endl;
    526         for ( int i = 0; args[i] != NULL; i += 1 ) {
     495        for ( int i = 0; args[i] != nullptr; i += 1 ) {
    527496                cerr << " \"" << args[i] << "\"" << endl;
    528497        } // for
     498        cerr << endl;
    529499        #endif // __DEBUG_H__
    530500
    531501        if ( ! quiet ) {
    532502                cerr << "CFA " << "Version " << Version << heading << endl;
    533 
    534503                if ( help ) {
    535504                        cerr <<
     
    546515                if ( argc == 2 ) exit( EXIT_SUCCESS );                  // if only the -v flag is specified, do not invoke gcc
    547516
    548                 for ( int i = 0; args[i] != NULL; i += 1 ) {
     517                for ( int i = 0; args[i] != nullptr; i += 1 ) {
    549518                        cerr << args[i] << " ";
    550519                } // for
     
    560529
    561530        execvp( args[0], (char *const *)args );                         // should not return
    562         perror( "CFA Translator error: cfa level, execvp" );
     531        perror( "CFA Translator error: execvp" );
    563532        exit( EXIT_FAILURE );
    564533} // main
  • libcfa/Makefile.in

    r8e1467d r4a60488  
    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/configure

    r8e1467d r4a60488  
    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
     
    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

    r8e1467d r4a60488  
    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
  • libcfa/prelude/Makefile.am

    r8e1467d r4a60488  
    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@
     
    5454
    5555# create forward declarations for cfa builtins
    56 builtins.cf : builtins.c ${CC}
     56builtins.cf : builtins.c @LOCAL_CFACC@
    5757        ${AM_V_GEN}gcc ${AM_CFLAGS} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po -D__cforall
    5858        ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
     
    6868MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cfa
    6969MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
     70
     71if ENABLE_DISTCC
     72distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh
     73        ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
     74        @echo "Dummy file to track distribution to remote hosts" > ${@}
     75
     76all: all-am distribution
     77endif ENABLE_DISTCC
  • libcfa/prelude/Makefile.in

    r8e1467d r4a60488  
    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@
     
    555558
    556559# create forward declarations for cfa builtins
    557 builtins.cf : builtins.c ${CC}
     560builtins.cf : builtins.c @LOCAL_CFACC@
    558561        ${AM_V_GEN}gcc ${AM_CFLAGS} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po -D__cforall
    559562        ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
     
    566569maintainer-clean-local :
    567570        rm -rf $(DEPDIR)
     571
     572@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
     573@ENABLE_DISTCC_TRUE@    ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
     574@ENABLE_DISTCC_TRUE@    @echo "Dummy file to track distribution to remote hosts" > ${@}
     575
     576@ENABLE_DISTCC_TRUE@all: all-am distribution
    568577
    569578# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • libcfa/prelude/extras.regx

    r8e1467d r4a60488  
    1919typedef.* uint32_t;
    2020typedef.* uint64_t;
     21typedef.* __uint_least16_t;
     22typedef.* __uint_least32_t;
    2123typedef.* char16_t;
    2224typedef.* char32_t;
  • libcfa/src/Makefile.am

    r8e1467d r4a60488  
    2626VPATH += :../prelude
    2727
     28gdbwaittarget=""
     29
    2830# AM_CFLAGS for all cfa source
    2931# AM_CFAFLAGS for only cfa source
    3032# use -no-include-stdhdr to prevent rebuild cycles
    3133# The built sources must not depend on the installed headers
    32 AM_CFAFLAGS = -quiet -in-tree -I$(srcdir)/stdhdr @CONFIG_CFAFLAGS@
     34AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
    3335AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@
    3436AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@
     
    6264# add dependency of cfa files
    6365libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(libsrc))))
    64 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     66$(libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
    6567
    6668thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
    67 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     69$(thread_libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
    6870
    6971
     
    8486
    8587
    86 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
    87         ${AM_V_GEN}$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
     88if ENABLE_DISTCC
    8889
    89 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@
    90101        ${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
    91         $(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
    92 
     102        $(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@}
    93103
    94104#----------------------------------------------------------------------------------------------------------------
  • libcfa/src/Makefile.in

    r8e1467d r4a60488  
    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@
     
    435438am__v_UPP_1 =
    436439lib_LTLIBRARIES = libcfa.la libcfathread.la
     440gdbwaittarget = ""
    437441
    438442# AM_CFLAGS for all cfa source
     
    440444# use -no-include-stdhdr to prevent rebuild cycles
    441445# The built sources must not depend on the installed headers
    442 AM_CFAFLAGS = -quiet -in-tree -I$(srcdir)/stdhdr @CONFIG_CFAFLAGS@
     446AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
    443447AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@
    444448AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@
     
    936940        $(LTCFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
    937941        $(am__mv) $$depbase.Tpo $$depbase.Plo
    938 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    939 $(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     942$(libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
     943$(thread_libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa
    940944
    941945-include $(libdeps)
     
    943947-include $(thread_libdeps)
    944948
    945 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
    946         ${AM_V_GEN}$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
    947 
    948 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
     949@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
     950@ENABLE_DISTCC_TRUE@    @+make -C ../prelude distribution
     951
     952@ENABLE_DISTCC_TRUE@prelude.o prelude.lo $(libobjs) $(thread_libobjs) : ../prelude/distribution
     953
     954prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
     955        ${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@}
     956
     957prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
    949958        ${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
    950         $(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
     959        $(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@}
    951960
    952961#----------------------------------------------------------------------------------------------------------------
  • libcfa/src/fstream.cfa

    r8e1467d r4a60488  
    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 : Tue Sep 10 22:19:56 2019
     13// Update Count     : 354
    1414//
    1515
     
    164164} // fmt
    165165
    166 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_) };
     166static ofstream soutFile = { (FILE *)stdout };
    167167ofstream & sout = soutFile, & stdout = soutFile;
    168 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_) };
     168static ofstream serrFile = { (FILE *)stderr };
    169169ofstream & serr = serrFile, & stderr = serrFile;
    170170
    171 static ofstream exitFile = { (FILE *)(&_IO_2_1_stdout_) };
     171static ofstream exitFile = { (FILE *)stdout };
    172172ofstream & exit = exitFile;
    173 static ofstream abortFile = { (FILE *)(&_IO_2_1_stderr_) };
     173static ofstream abortFile = { (FILE *)stderr };
    174174ofstream & abort = abortFile;
    175175
     
    265265} // fmt
    266266
    267 
    268 static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) };
     267static ifstream sinFile = { (FILE *)stdin };
    269268ifstream & sin = sinFile, & stdin = sinFile;
    270269
  • libcfa/src/heap.cfa

    r8e1467d r4a60488  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 23 14:13:13 2019
    13 // Update Count     : 549
     12// Last Modified On : Wed Jul 24 13:12:45 2019
     13// Update Count     : 550
    1414//
    1515
     
    248248
    249249#ifdef FASTLOOKUP
    250 static_assert( 16 == sizeof(HeapManager.Storage), "size of HeapManager Storage wrong" ); // FIX ME
    251 enum { LookupSizes = 65_536 + 16 };                                             // number of fast lookup sizes
     250enum { LookupSizes = 65_536 + sizeof(HeapManager.Storage) }; // number of fast lookup sizes
    252251static unsigned char lookup[LookupSizes];                               // O(1) lookup for small sizes
    253252#endif // FASTLOOKUP
  • longrun_tests/Makefile.am

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

    r8e1467d r4a60488  
    348348CCDEPMODE = @CCDEPMODE@
    349349CFACC = @CFACC@
     350CFACC_INSTALL = @CFACC_INSTALL@
    350351CFACPP = @CFACPP@
    351352CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    365366CYGPATH_W = @CYGPATH_W@
    366367DEFS = @DEFS@
     368DEMANGLER = @DEMANGLER@
    367369DEPDIR = @DEPDIR@
    368370DLLTOOL = @DLLTOOL@
     
    377379FGREP = @FGREP@
    378380GREP = @GREP@
     381HAS_DISTCC = @HAS_DISTCC@
    379382HOST_FLAGS = @HOST_FLAGS@
    380383INSTALL = @INSTALL@
     
    390393LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    391394LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     395LIBDEMANGLE = @LIBDEMANGLE@
    392396LIBOBJS = @LIBOBJS@
    393397LIBS = @LIBS@
  • src/AST/Convert.cpp

    r8e1467d r4a60488  
    99// Author           : Thierry Delisle
    1010// Created On       : Thu May 09 15::37::05 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jun 17 16:44:00 2019
    13 // Update Count     : 12
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:21:46 2019
     13// Update Count     : 13
    1414//
    1515
     
    26882688                );
    26892689        }
    2690 
    2691         virtual void visit( const AttrExpr * ) override final {
    2692                 assertf( false, "AttrExpr deprecated in new AST." );
    2693         }
    26942690};
    26952691
  • src/AST/porting.md

    r8e1467d r4a60488  
    171171  * all existing uses assume `type` set if true and don't use `expr`
    172172
    173 `AttrExpr`
    174 * did not port due to feature deprecation (e.g. `expr@attribute`)
    175 
    176173`LogicalExpr`
    177174* un-defaulted constructor parameter determining `&&` or `||`
  • src/BasicTypes-gen.cc

    r8e1467d r4a60488  
    295295        // cout << code.str();
    296296
    297        
     297
     298        // 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 );
     303        start += sizeof( STARTMK );                                                     // includes newline
     304        code << str.substr( 0, start );
     305
     306        code << "\t" << BYMK << endl;
     307        code << "\tenum Kind {" << endl;
     308        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) {
     309                code << "\t\t" << graph[r].name << "," << endl;
     310        } // for       
     311        code << "\t\tNUMBER_OF_BASIC_TYPES" << endl;
     312        code << "\t} kind;" << endl;
     313        code << "\t";                                                                           // indentation for end marker
     314
     315        if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", TypeAST );
     316        code << str.substr( start );
     317
     318        output( file, TypeAST, code );
     319        // cout << code.str();
     320
     321
    298322        #define ConversionCost TOP_SRCDIR "src/ResolvExpr/ConversionCost.cc"
    299323        resetInput( file, ConversionCost, buffer, code, str );
     
    310334                        code << right << setw(30) << graph[c].type << left;
    311335                } else if ( graph[c].rank != graph[c + 2].rank ) {
    312                         code << string( 10, ' ' ) << setw(25) << graph[c].type << setw(25) << graph[c + 1].type;
     336                        code << string( 10, ' ' ) << setw(25) << graph[c].type << graph[c + 1].type;
    313337                        c += 1;
    314338                } else {
    315                         code << setw(20) << graph[c].type << setw(20) << graph[c + 1].type << setw(20) << graph[c + 2].type;
     339                        code << setw(20) << graph[c].type << setw(20) << graph[c + 1].type << graph[c + 2].type;
    316340                        c += 2;
    317341                } // if
     
    328352        code << "\t" << BYMK << endl;
    329353        code << "\tstatic const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node" << endl
    330                  << "\t\t/*         ";
     354                 << "\t\t/*           ";
    331355        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // titles
    332356                code << setw(5) << graph[r].abbrev;
     
    334358        code << " */" << endl;
    335359        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // costs
    336                 code << "\t\t/*" << setw(6) << graph[r].abbrev << "*/ {";
     360                code << "\t\t/* " << setw(6) << graph[r].abbrev << " */ {";
    337361                for ( int c = 0; c < NUMBER_OF_BASIC_TYPES; c += 1 ) {
    338362                        code << setw(4) << costMatrix[r][c] << ",";
     
    353377        code << "\t" << BYMK << endl;
    354378        code << "\tstatic const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion" << endl
    355                  << "\t\t/*         ";
     379                 << "\t\t/*           ";
    356380        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // titles
    357381                code << setw(5) << graph[r].abbrev;
     
    359383        code << " */" << endl;
    360384        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // costs
    361                 code << "\t\t/*" << setw(6) << graph[r].abbrev << "*/ {";
     385                code << "\t\t/* " << setw(6) << graph[r].abbrev << " */ {";
    362386                for ( int c = 0; c < NUMBER_OF_BASIC_TYPES; c += 1 ) {
    363387                        code << setw(4) << signMatrix[r][c] << ",";
     
    395419        code << "*/" << endl;
    396420        for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // costs
    397                 code << "\t\t\t\t  {\n\t\t/*" << setw(6) << graph[r].abbrev << "*/";
     421                code << "\t\t\t\t  {\n\t\t/* " << setw(6) << graph[r].abbrev << " */";
    398422                for ( int c = 0; c < NUMBER_OF_BASIC_TYPES; c += 1 ) {
    399423                        string s = string{"BT "} + graph[commonTypeMatrix[r][c]].name;
  • src/Common/Eval.cc

    r8e1467d r4a60488  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May  6 22:24:16 2018
    13 // Update Count     : 40
     12// Last Modified On : Wed Jul 24 15:09:06 2019
     13// Update Count     : 64
    1414//
    1515
     
    2727        bool valid = true;
    2828
    29         void previsit( BaseSyntaxNode * ) { visit_children = false; }
    30         void postvisit( BaseSyntaxNode * ) { valid = false; }
     29        void previsit( const BaseSyntaxNode * ) { visit_children = false; }
     30        void postvisit( const BaseSyntaxNode * ) { valid = false; }
    3131
    32         void postvisit( ConstantExpr * expr ) {
     32        void postvisit( const SizeofExpr * ) {
     33        }
     34
     35        void postvisit( const ConstantExpr * expr ) {
    3336                value = expr->intValue();
    3437        }
    3538
    36         void postvisit( CastExpr * expr ) {
     39        void postvisit( const CastExpr * expr ) {
    3740                auto arg = eval(expr->arg);
    3841                valid = arg.second;
     
    4144        }
    4245
    43         void postvisit( VariableExpr * expr ) {
     46        void postvisit( const VariableExpr * const expr ) {
    4447                if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
    4548                        if ( EnumDecl * decl = inst->baseEnum ) {
     
    5255        }
    5356
    54         void postvisit( ApplicationExpr * expr ) {
    55                 DeclarationWithType * function = InitTweak::getFunction(expr);
     57        void postvisit( const ApplicationExpr * expr ) {
     58                DeclarationWithType * function = InitTweak::getFunction(const_cast<ApplicationExpr *>(expr));
    5659                if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
    5760                const std::string & fname = function->name;
     
    9497        void postvisit( const ast::ConstantExpr * expr ) {
    9598                value = expr->intValue();
     99        }
     100
     101        void postvisit( const ast::SizeofExpr * expr ) {
     102                if ( expr->expr ) value = eval(expr->expr).first;
     103                else if ( expr->type ) value = eval(expr->expr).first;
     104                else SemanticError( expr->location, ::toString( "Internal error: SizeofExpr has no expression or type value" ) );
    96105        }
    97106
     
    145154};
    146155
    147 std::pair<long long int, bool> eval(Expression * expr) {
     156std::pair<long long int, bool> eval( const Expression * expr) {
    148157        PassVisitor<EvalOld> ev;
    149158        if (expr) {
  • src/Common/PassVisitor.h

    r8e1467d r4a60488  
    155155        virtual void visit( OffsetPackExpr * offsetPackExpr ) override final;
    156156        virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final;
    157         virtual void visit( AttrExpr * attrExpr ) override final;
    158         virtual void visit( const AttrExpr * attrExpr ) override final;
    159157        virtual void visit( LogicalExpr * logicalExpr ) override final;
    160158        virtual void visit( const LogicalExpr * logicalExpr ) override final;
     
    301299        virtual Expression * mutate( OffsetofExpr * offsetofExpr ) override final;
    302300        virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) override final;
    303         virtual Expression * mutate( AttrExpr * attrExpr ) override final;
    304301        virtual Expression * mutate( LogicalExpr * logicalExpr ) override final;
    305302        virtual Expression * mutate( ConditionalExpr * conditionalExpr ) override final;
  • src/Common/PassVisitor.impl.h

    r8e1467d r4a60488  
    23022302
    23032303//--------------------------------------------------------------------------
    2304 // AttrExpr
    2305 template< typename pass_type >
    2306 void PassVisitor< pass_type >::visit( AttrExpr * node ) {
    2307         VISIT_START( node );
    2308 
    2309         indexerScopedAccept( node->result, *this );
    2310         if ( node->get_isType() ) {
    2311                 maybeAccept_impl( node->type, *this );
    2312         } else {
    2313                 maybeAccept_impl( node->expr, *this );
    2314         }
    2315 
    2316         VISIT_END( node );
    2317 }
    2318 
    2319 template< typename pass_type >
    2320 void PassVisitor< pass_type >::visit( const AttrExpr * node ) {
    2321         VISIT_START( node );
    2322 
    2323         indexerScopedAccept( node->result, *this );
    2324         if ( node->get_isType() ) {
    2325                 maybeAccept_impl( node->type, *this );
    2326         } else {
    2327                 maybeAccept_impl( node->expr, *this );
    2328         }
    2329 
    2330         VISIT_END( node );
    2331 }
    2332 
    2333 template< typename pass_type >
    2334 Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
    2335         MUTATE_START( node );
    2336 
    2337         indexerScopedMutate( node->env   , *this );
    2338         indexerScopedMutate( node->result, *this );
    2339         if ( node->get_isType() ) {
    2340                 maybeMutate_impl( node->type, *this );
    2341         } else {
    2342                 maybeMutate_impl( node->expr, *this );
    2343         }
    2344 
    2345         MUTATE_END( Expression, node );
    2346 }
    2347 
    2348 //--------------------------------------------------------------------------
    23492304// LogicalExpr
    23502305template< typename pass_type >
  • src/Common/utility.h

    r8e1467d r4a60488  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May  6 22:24:16 2018
    13 // Update Count     : 40
     12// Last Modified On : Wed Jul 24 14:28:19 2019
     13// Update Count     : 41
    1414//
    1515
     
    483483// -----------------------------------------------------------------------------
    484484/// evaluates expr as a long long int. If second is false, expr could not be evaluated
    485 std::pair<long long int, bool> eval(Expression * expr);
     485std::pair<long long int, bool> eval(const Expression * expr);
    486486
    487487namespace ast {
  • src/GenPoly/Box.cc

    r8e1467d r4a60488  
    725725                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
    726726
    727                         if ( arg->result->get_lvalue() ) {
     727                        if ( arg->get_lvalue() ) {
    728728                                // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
    729729                                // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
  • src/GenPoly/Lvalue.cc

    r8e1467d r4a60488  
    363363                        int diff = depth1 - depth2;
    364364
    365                         if ( diff > 0 && ! srcType->get_lvalue() ) {
     365                        if ( diff > 0 && ! castExpr->arg->get_lvalue() ) {
    366366                                // rvalue to reference conversion -- introduce temporary
    367367                                // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g.
     
    407407                                        ret = new AddressExpr( ret );
    408408                                }
    409                                 if ( srcType->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {
     409                                if ( castExpr->arg->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {
    410410                                        // must keep cast if cast-to type is different from the actual type
    411411                                        castExpr->arg = ret;
  • src/InitTweak/InitTweak.cc

    r8e1467d r4a60488  
    99// Author           : Rob Schluntz
    1010// Created On       : Fri May 13 11:26:36 2016
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jun 19 14:34:00 2019
    13 // Update Count     : 6
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:21:48 2019
     13// Update Count     : 7
    1414//
    1515
     
    957957                void previsit( OffsetofExpr * ) {}
    958958                void previsit( OffsetPackExpr * ) {}
    959                 void previsit( AttrExpr * ) {}
    960959                void previsit( CommaExpr * ) {}
    961960                void previsit( LogicalExpr * ) {}
  • src/Makefile.am

    r8e1467d r4a60488  
    1111## Created On       : Sun May 31 08:51:46 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Fri Feb 15 09:44:09 2019
    14 ## Update Count     : 97
     13## Last Modified On : Mon Aug  5 12:57:46 2019
     14## Update Count     : 98
    1515###############################################################################
    1616
     
    5555$(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h
    5656
    57 $(srcdir)/SynTree/Type.h : BasicTypes-gen.cc
     57$(srcdir)/AST/Type.hpp : BasicTypes-gen.cc
    5858        ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra
    5959        @./BasicTypes-gen
     
    6262# put into lib for now
    6363cfa_cpplibdir = $(CFA_LIBDIR)
    64 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp demangler
     64cfa_cpplib_PROGRAMS = ../driver/cfa-cpp $(DEMANGLER)
     65EXTRA_PROGRAMS = demangler
    6566___driver_cfa_cpp_SOURCES = $(SRC)
    6667___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC)
     
    7475demangler_LDADD = libdemangle.a -ldl                    # yywrap
    7576
    76 noinst_LIBRARIES = libdemangle.a
     77noinst_LIBRARIES = $(LIBDEMANGLE)
     78EXTRA_LIBRARIES = libdemangle.a
    7779libdemangle_a_SOURCES = $(SRCDEMANGLE)
    7880
  • src/Makefile.in

    r8e1467d r4a60488  
    141141build_triplet = @build@
    142142host_triplet = @host@
    143 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp$(EXEEXT) demangler$(EXEEXT)
     143cfa_cpplib_PROGRAMS = ../driver/cfa-cpp$(EXEEXT) $(DEMANGLER)
     144EXTRA_PROGRAMS = demangler$(EXEEXT)
    144145subdir = src
    145146ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
     
    231232        SynTree/Initializer.$(OBJEXT) \
    232233        SynTree/TypeSubstitution.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \
    233         SynTree/DeclReplacer.$(OBJEXT)
     234        SynTree/DeclReplacer.$(OBJEXT) SynTree/TopLvalue.$(OBJEXT)
    234235am__objects_8 = CompilationState.$(OBJEXT) $(am__objects_1) \
    235236        $(am__objects_2) Concurrency/Keywords.$(OBJEXT) \
     
    411412CCDEPMODE = @CCDEPMODE@
    412413CFACC = @CFACC@
     414CFACC_INSTALL = @CFACC_INSTALL@
    413415CFACPP = @CFACPP@
    414416CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    428430CYGPATH_W = @CYGPATH_W@
    429431DEFS = @DEFS@
     432DEMANGLER = @DEMANGLER@
    430433DEPDIR = @DEPDIR@
    431434DLLTOOL = @DLLTOOL@
     
    440443FGREP = @FGREP@
    441444GREP = @GREP@
     445HAS_DISTCC = @HAS_DISTCC@
    442446HOST_FLAGS = @HOST_FLAGS@
    443447INSTALL = @INSTALL@
     
    453457LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    454458LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     459LIBDEMANGLE = @LIBDEMANGLE@
    455460LIBOBJS = @LIBOBJS@
    456461LIBS = @LIBS@
     
    693698      SynTree/TypeSubstitution.cc \
    694699      SynTree/Attribute.cc \
    695       SynTree/DeclReplacer.cc
     700      SynTree/DeclReplacer.cc \
     701      SynTree/TopLvalue.cc
    696702
    697703
     
    705711demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete
    706712demangler_LDADD = libdemangle.a -ldl                    # yywrap
    707 noinst_LIBRARIES = libdemangle.a
     713noinst_LIBRARIES = $(LIBDEMANGLE)
     714EXTRA_LIBRARIES = libdemangle.a
    708715libdemangle_a_SOURCES = $(SRCDEMANGLE)
    709716all: $(BUILT_SOURCES)
     
    10231030SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \
    10241031        SynTree/$(DEPDIR)/$(am__dirstamp)
     1032SynTree/TopLvalue.$(OBJEXT): SynTree/$(am__dirstamp) \
     1033        SynTree/$(DEPDIR)/$(am__dirstamp)
    10251034Tuples/$(am__dirstamp):
    10261035        @$(MKDIR_P) Tuples
     
    13341343@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ReferenceType.Po@am__quote@
    13351344@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Statement.Po@am__quote@
     1345@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TopLvalue.Po@am__quote@
    13361346@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleExpr.Po@am__quote@
    13371347@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleType.Po@am__quote@
     
    16671677$(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h
    16681678
    1669 $(srcdir)/SynTree/Type.h : BasicTypes-gen.cc
     1679$(srcdir)/AST/Type.hpp : BasicTypes-gen.cc
    16701680        ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra
    16711681        @./BasicTypes-gen
  • src/Parser/DeclarationNode.cc

    r8e1467d r4a60488  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  1 16:49:17 2019
    13 // Update Count     : 1113
     12// Last Modified On : Thu Jul 25 22:17:10 2019
     13// Update Count     : 1116
    1414//
    1515
     
    4949const char * DeclarationNode::aggregateNames[] = { "struct", "union", "trait", "coroutine", "monitor", "thread", "NoAggregateNames" };
    5050const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" };
    51 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "zero_t", "one_t", "NoBuiltinTypeNames" };
     51const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" };
    5252
    5353UniqueName DeclarationNode::anonymous( "__anonymous" );
     
    418418        return newnode;
    419419} // DeclarationNode::newBuiltinType
    420 
    421 DeclarationNode * DeclarationNode::newAttr( const string * name, ExpressionNode * expr ) {
    422         DeclarationNode * newnode = new DeclarationNode;
    423         newnode->type = nullptr;
    424 //      newnode->attr.name = name;
    425         newnode->name = name;
    426         newnode->attr.expr = expr;
    427         return newnode;
    428 }
    429 
    430 DeclarationNode * DeclarationNode::newAttr( const string * name, DeclarationNode * type ) {
    431         DeclarationNode * newnode = new DeclarationNode;
    432         newnode->type = nullptr;
    433 //      newnode->attr.name = name;
    434         newnode->name = name;
    435         newnode->attr.type = type;
    436         return newnode;
    437 }
    438420
    439421DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) {
  • src/Parser/ExpressionNode.cc

    r8e1467d r4a60488  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Mar 10 16:10:32 2019
    13 // Update Count     : 976
     12// Last Modified On : Sun Aug  4 20:57:55 2019
     13// Update Count     : 978
    1414//
    1515
     
    109109
    110110Expression * build_constantInteger( string & str ) {
    111         static const BasicType::Kind kind[2][7] = {
     111        static const BasicType::Kind kind[2][6] = {
    112112                // short (h) must be before char (hh) because shorter type has the longer suffix
    113113                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
  • src/Parser/ParseNode.h

    r8e1467d r4a60488  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr 15 14:22:39 2019
    13 // Update Count     : 874
     12// Last Modified On : Thu Jul 25 22:17:10 2019
     13// Update Count     : 876
    1414//
    1515
     
    221221        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
    222222        static const char * typeClassNames[];
    223         enum BuiltinType { Valist, Zero, One, NoBuiltinType };
     223        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
    224224        static const char * builtinTypeNames[];
    225225
     
    252252        static DeclarationNode * newTuple( DeclarationNode * members );
    253253        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
    254         static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
    255         static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
    256254        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
    257255        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
  • src/Parser/lex.ll

    r8e1467d r4a60488  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Wed May 15 21:25:27 2019
    13  * Update Count     : 708
     12 * Last Modified On : Sun Aug  4 20:53:47 2019
     13 * Update Count     : 719
    1414 */
    1515
     
    5959#define QKEYWORD_RETURN(x)      RETURN_VAL(x);                          // quasi-keyword
    6060#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    61 #define ATTRIBUTE_RETURN()      RETURN_VAL( ATTR_IDENTIFIER )
    6261
    6362#ifdef HAVE_KEYWORDS_FLOATXX                                                            // GCC >= 7 => keyword, otherwise typedef
     
    9291                                // identifier, GCC: $ in identifier
    9392identifier ([a-zA-Z_$]|{universal_char})([0-9a-zA-Z_$]|{universal_char})*
    94 
    95                                 // attribute identifier, GCC: $ in identifier
    96 attr_identifier "@"{identifier}
    9793
    9894                                // numeric constants, CFA: '_' in constant
     
    218214__attribute__   { KEYWORD_RETURN(ATTRIBUTE); }                  // GCC
    219215auto                    { KEYWORD_RETURN(AUTO); }
     216__auto_type             { KEYWORD_RETURN(AUTO_TYPE); }
    220217basetypeof              { KEYWORD_RETURN(BASETYPEOF); }                 // CFA
    221218_Bool                   { KEYWORD_RETURN(BOOL); }                               // C99
     
    276273__inline__              { KEYWORD_RETURN(INLINE); }                             // GCC
    277274int                             { KEYWORD_RETURN(INT); }
     275int128                  { KEYWORD_RETURN(INT128); }                             // CFA
    278276__int128                { KEYWORD_RETURN(INT128); }                             // GCC
    279 int128                  { KEYWORD_RETURN(INT128); }                             // GCC
     277__int128_t              { KEYWORD_RETURN(INT128); }                             // GCC
    280278__label__               { KEYWORD_RETURN(LABEL); }                              // GCC
    281279long                    { KEYWORD_RETURN(LONG); }
     
    292290__restrict__    { KEYWORD_RETURN(RESTRICT); }                   // GCC
    293291return                  { KEYWORD_RETURN(RETURN); }
     292        /* resume                       { KEYWORD_RETURN(RESUME); }                             // CFA */
    294293short                   { KEYWORD_RETURN(SHORT); }
    295294signed                  { KEYWORD_RETURN(SIGNED); }
     
    300299_Static_assert  { KEYWORD_RETURN(STATICASSERT); }               // C11
    301300struct                  { KEYWORD_RETURN(STRUCT); }
     301        /* suspend                      { KEYWORD_RETURN(SUSPEND); }                    // CFA */
    302302switch                  { KEYWORD_RETURN(SWITCH); }
    303303thread                  { KEYWORD_RETURN(THREAD); }                             // C11
     
    314314__typeof__              { KEYWORD_RETURN(TYPEOF); }                             // GCC
    315315union                   { KEYWORD_RETURN(UNION); }
     316__uint128_t             { KEYWORD_RETURN(UINT128); }                    // GCC
    316317unsigned                { KEYWORD_RETURN(UNSIGNED); }
    317318__builtin_va_list { KEYWORD_RETURN(VALIST); }                   // GCC
     
    333334        IDENTIFIER_RETURN();
    334335}
    335 {attr_identifier} { ATTRIBUTE_RETURN(); }
    336336
    337337                                /* numeric constants */
  • src/Parser/parser.yy

    r8e1467d r4a60488  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 14 07:54:30 2019
    13 // Update Count     : 4355
     12// Last Modified On : Sun Aug  4 21:48:23 2019
     13// Update Count     : 4364
    1414//
    1515
     
    268268%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    269269%token BOOL COMPLEX IMAGINARY                                                   // C99
    270 %token INT128 uuFLOAT80 uuFLOAT128                                              // GCC
     270%token INT128 UINT128 uuFLOAT80 uuFLOAT128                              // GCC
    271271%token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC
    272272%token ZERO_T ONE_T                                                                             // CFA
    273273%token VALIST                                                                                   // GCC
     274%token AUTO_TYPE                                                                                // GCC
    274275%token TYPEOF BASETYPEOF LABEL                                                  // GCC
    275276%token ENUM STRUCT UNION
     
    288289%token<tok> IDENTIFIER                  QUOTED_IDENTIFIER               TYPEDEFname                             TYPEGENname
    289290%token<tok> TIMEOUT                             WOR
    290 %token<tok> ATTR_IDENTIFIER             ATTR_TYPEDEFname                ATTR_TYPEGENname
    291291%token<tok> INTEGERconstant             CHARACTERconstant               STRINGliteral
    292292%token<tok> DIRECTIVE
     
    312312%token ATassign                                                                                 // @=
    313313
    314 %type<tok> identifier  no_attr_identifier
    315 %type<tok> identifier_or_type_name  no_attr_identifier_or_type_name  attr_name
     314%type<tok> identifier
     315%type<tok> identifier_or_type_name  attr_name
    316316%type<tok> quasi_keyword
    317317%type<constant> string_literal
     
    546546        ;
    547547
    548 no_attr_identifier:
     548identifier:
    549549        IDENTIFIER
    550550        | quasi_keyword
    551551        | '@'                                                                                           // CFA
    552552                { Token tok = { new string( DeclarationNode::anonymous.newName() ), yylval.tok.loc }; $$ = tok; }
    553         ;
    554 
    555 identifier:
    556         no_attr_identifier
    557         | ATTR_IDENTIFIER                                                                       // CFA
    558553        ;
    559554
     
    594589        | '(' comma_expression ')' '`' IDENTIFIER                       // CFA, postfix call
    595590                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
    596         | type_name '.' no_attr_identifier                                      // CFA, nested type
     591        | type_name '.' identifier                                                      // CFA, nested type
    597592                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    598593        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
     
    647642        | postfix_expression '(' argument_expression_list ')'
    648643                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
    649         | postfix_expression '.' no_attr_identifier
     644        | postfix_expression '.' identifier
    650645                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
    651646        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
     
    655650        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    656651                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    657         | postfix_expression ARROW no_attr_identifier
     652        | postfix_expression ARROW identifier
    658653                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
    659654        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
     
    718713        | FLOATINGconstant fraction_constants_opt
    719714                { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
    720         | no_attr_identifier fraction_constants_opt
     715        | identifier fraction_constants_opt
    721716                {
    722717                        $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     
    776771        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    777772                { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
    778         | OFFSETOF '(' type_no_function ',' no_attr_identifier ')'
     773        | OFFSETOF '(' type_no_function ',' identifier ')'
    779774                { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
    780         | ATTR_IDENTIFIER
    781                 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuild< Expression >( (ExpressionNode *)nullptr ) ) ); }
    782         | ATTR_IDENTIFIER '(' argument_expression ')'
    783                 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuild< Expression >( $3 ) ) ); }
    784         | ATTR_IDENTIFIER '(' type ')'
    785                 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuildType( $3 ) ) ); }
    786775        ;
    787776
     
    10181007
    10191008labeled_statement:
    1020                 // labels cannot be identifiers 0 or 1 or ATTR_IDENTIFIER
     1009                // labels cannot be identifiers 0 or 1
    10211010        identifier_or_type_name ':' attribute_list_opt statement
    10221011                { $$ = $4->add_label( $1, $3 ); }
     
    13861375        | type_specifier_nobody variable_abstract_declarator
    13871376                { $$ = $2->addType( $1 ); }
    1388         | cfa_abstract_declarator_tuple no_attr_identifier      // CFA
     1377        | cfa_abstract_declarator_tuple identifier                      // CFA
    13891378                { $$ = $1->addName( $2 ); }
    13901379        | cfa_abstract_declarator_tuple                                         // CFA
     
    14501439
    14511440label_list:
    1452         no_attr_identifier
     1441        identifier
    14531442                {
    14541443                        $$ = new LabelNode(); $$->labels.push_back( *$1 );
    14551444                        delete $1;                                                                      // allocated by lexer
    14561445                }
    1457         | label_list ',' no_attr_identifier
     1446        | label_list ',' identifier
    14581447                {
    14591448                        $$ = $1; $1->labels.push_back( *$3 );
     
    15001489
    15011490local_label_list:                                                                               // GCC, local label
    1502         no_attr_identifier_or_type_name
    1503         | local_label_list ',' no_attr_identifier_or_type_name
     1491        identifier_or_type_name
     1492        | local_label_list ',' identifier_or_type_name
    15041493        ;
    15051494
     
    16231612                        $$ = $2->addTypedef();
    16241613                }
    1625         | cfa_typedef_declaration pop ',' push no_attr_identifier
     1614        | cfa_typedef_declaration pop ',' push identifier
    16261615                {
    16271616                        typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "3" );
     
    16631652typedef_expression:
    16641653                // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression
    1665         TYPEDEF no_attr_identifier '=' assignment_expression
     1654        TYPEDEF identifier '=' assignment_expression
    16661655                {
    16671656                        // $$ = DeclarationNode::newName( 0 );                  // unimplemented
    16681657                        SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
    16691658                }
    1670         | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
     1659        | typedef_expression pop ',' push identifier '=' assignment_expression
    16711660                {
    16721661                        // $$ = DeclarationNode::newName( 0 );                  // unimplemented
     
    18371826        | INT128
    18381827                { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 ); }
     1828        | UINT128
     1829                { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ); }
    18391830        | FLOAT
    18401831                { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
     
    18711862        | VALIST                                                                                        // GCC, __builtin_va_list
    18721863                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
     1864        | AUTO_TYPE
     1865                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::AutoType ); }
    18731866        ;
    18741867
     
    19121905        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    19131906                { $$ = DeclarationNode::newTypeof( $3, true ); }
    1914         | ATTR_TYPEGENname '(' type ')'                                         // CFA: e.g., @type( x ) y;
    1915                 { $$ = DeclarationNode::newAttr( $1, $3 ); }
    1916         | ATTR_TYPEGENname '(' comma_expression ')'                     // CFA: e.g., @type( a+b ) y;
    1917                 { $$ = DeclarationNode::newAttr( $1, $3 ); }
    19181907        | ZERO_T                                                                                        // CFA
    19191908                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); }
     
    20242013          '{' field_declaration_list_opt '}' type_parameters_opt
    20252014                { $$ = DeclarationNode::newAggregate( $1, nullptr, $7, $5, true )->addQualifiers( $2 ); }
    2026         | aggregate_key attribute_list_opt no_attr_identifier fred
     2015        | aggregate_key attribute_list_opt identifier fred
    20272016                {
    20282017                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
     
    20502039
    20512040aggregate_type_nobody:                                                                  // struct, union - {...}
    2052         aggregate_key attribute_list_opt no_attr_identifier fred
     2041        aggregate_key attribute_list_opt identifier fred
    20532042                {
    20542043                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname );
     
    21512140cfa_field_declaring_list:                                                               // CFA, new style field declaration
    21522141        // bit-fields are handled by C declarations
    2153         cfa_abstract_declarator_tuple no_attr_identifier_or_type_name
     2142        cfa_abstract_declarator_tuple identifier_or_type_name
    21542143                { $$ = $1->addName( $2 ); }
    2155         | cfa_field_declaring_list ',' no_attr_identifier_or_type_name
     2144        | cfa_field_declaring_list ',' identifier_or_type_name
    21562145                { $$ = $1->appendList( $1->cloneType( $3 ) ); }
    21572146        ;
     
    21782167        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    21792168                { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
    2180         | ENUM attribute_list_opt no_attr_identifier
     2169        | ENUM attribute_list_opt identifier
    21812170                { typedefTable.makeTypedef( *$3 ); }
    21822171          '{' enumerator_list comma_opt '}'
     
    21892178
    21902179enum_type_nobody:                                                                               // enum - {...}
    2191         ENUM attribute_list_opt no_attr_identifier
     2180        ENUM attribute_list_opt identifier
    21922181                {
    21932182                        typedefTable.makeTypedef( *$3 );
     
    22022191
    22032192enumerator_list:
    2204         no_attr_identifier_or_type_name enumerator_value_opt
     2193        identifier_or_type_name enumerator_value_opt
    22052194                { $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
    2206         | enumerator_list ',' no_attr_identifier_or_type_name enumerator_value_opt
     2195        | enumerator_list ',' identifier_or_type_name enumerator_value_opt
    22072196                { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
    22082197        ;
     
    23122301
    23132302identifier_list:                                                                                // K&R-style parameter list => no types
    2314         no_attr_identifier
     2303        identifier
    23152304                { $$ = DeclarationNode::newName( $1 ); }
    2316         | identifier_list ',' no_attr_identifier
     2305        | identifier_list ',' identifier
    23172306                { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }
    23182307        ;
     
    23202309identifier_or_type_name:
    23212310        identifier
    2322         | TYPEDEFname
    2323         | TYPEGENname
    2324         ;
    2325 
    2326 no_attr_identifier_or_type_name:
    2327         no_attr_identifier
    23282311        | TYPEDEFname
    23292312        | TYPEGENname
     
    23802363designation:
    23812364        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    2382         | no_attr_identifier ':'                                                        // GCC, field name
     2365        | identifier ':'                                                                        // GCC, field name
    23832366                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    23842367        ;
     
    23922375
    23932376designator:
    2394         '.' no_attr_identifier                                                          // C99, field name
     2377        '.' identifier                                                                          // C99, field name
    23952378                { $$ = new ExpressionNode( build_varref( $2 ) ); }
    23962379        | '[' push assignment_expression pop ']'                        // C99, single array element
     
    24372420
    24382421type_parameter:                                                                                 // CFA
    2439         type_class no_attr_identifier_or_type_name
     2422        type_class identifier_or_type_name
    24402423                { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); }
    24412424          type_initializer_opt assertion_list_opt
     
    24702453
    24712454assertion:                                                                                              // CFA
    2472         '|' no_attr_identifier_or_type_name '(' type_list ')'
     2455        '|' identifier_or_type_name '(' type_list ')'
    24732456                { $$ = DeclarationNode::newTraitUse( $2, $4 ); }
    24742457        | '|' '{' push trait_declaration_list pop '}'
     
    25072490
    25082491type_declarator_name:                                                                   // CFA
    2509         no_attr_identifier_or_type_name
     2492        identifier_or_type_name
    25102493                {
    25112494                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    25122495                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
    25132496                }
    2514         | no_attr_identifier_or_type_name '(' type_parameter_list ')'
     2497        | identifier_or_type_name '(' type_parameter_list ')'
    25152498                {
    25162499                        typedefTable.addToEnclosingScope( *$1, TYPEGENname, "11" );
     
    25202503
    25212504trait_specifier:                                                                                // CFA
    2522         TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' '}'
     2505        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    25232506                { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
    2524         | TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
     2507        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    25252508                { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
    25262509        ;
  • src/ResolvExpr/AlternativeFinder.cc

    r8e1467d r4a60488  
    99