Changeset 4a60488


Ignore:
Timestamp:
Sep 27, 2019, 3:35:46 PM (6 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, arm-eh, ast-experimental, 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// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:52:08 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  1 21:00:56 2018
    13 // Update Count     : 35
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:35:00 2019
     13// Update Count     : 38
    1414//
    1515
     
    7979                void postvisit( OffsetofExpr * offsetofExpr );
    8080                void postvisit( OffsetPackExpr * offsetPackExpr );
    81                 void postvisit( AttrExpr * attrExpr );
    8281                void postvisit( LogicalExpr * logicalExpr );
    8382                void postvisit( ConditionalExpr * conditionalExpr );
     
    378377        }
    379378
    380         Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     379        Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
     380                        const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    381381                PRINT(
    382382                        std::cerr << std::endl << "converting ";
     
    388388                        std::cerr << std::endl;
    389389                )
    390                 Cost convCost = conversionCost( actualType, formalType, indexer, env );
     390                Cost convCost = conversionCost( actualType, formalType, actualIsLvalue, indexer, env );
    391391                PRINT(
    392392                        std::cerr << std::endl << "cost is " << convCost << std::endl;
     
    403403
    404404        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    405                 Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
     405                Cost convCost = computeConversionCost(
     406                        actualExpr->result, formalType, actualExpr->get_lvalue(), indexer, env );
    406407
    407408                // if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion.
     
    11361137        bool isLvalue( Expression *expr ) {
    11371138                // xxx - recurse into tuples?
    1138                 return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
     1139                return expr->result && ( expr->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
    11391140        }
    11401141
     
    11871188                assert( toType );
    11881189                toType = resolveTypeof( toType, indexer );
     1190                assert(!dynamic_cast<TypeofType *>(toType));
    11891191                SymTab::validateType( toType, &indexer );
    11901192                adjustExprType( toType, env, indexer );
     
    12131215                        unify( castExpr->result, alt.expr->result, alt.env, needAssertions,
    12141216                                haveAssertions, openVars, indexer );
    1215                         Cost thisCost = castCost( alt.expr->result, castExpr->result, indexer,
    1216                                 alt.env );
     1217                        Cost thisCost = castCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(),
     1218                                indexer, alt.env );
    12171219                        PRINT(
    12181220                                std::cerr << "working on cast with result: " << castExpr->result << std::endl;
     
    14021404        void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) {
    14031405                alternatives.push_back( Alternative{ offsetPackExpr->clone(), env } );
    1404         }
    1405 
    1406         namespace {
    1407                 void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type * argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
    1408                         // assume no polymorphism
    1409                         // assume no implicit conversions
    1410                         assert( function->parameters.size() == 1 );
    1411                         PRINT(
    1412                                 std::cerr << "resolvAttr: funcDecl is ";
    1413                                 data.id->print( std::cerr );
    1414                                 std::cerr << " argType is ";
    1415                                 argType->print( std::cerr );
    1416                                 std::cerr << std::endl;
    1417                         )
    1418                         const SymTab::Indexer & indexer = finder.get_indexer();
    1419                         AltList & alternatives = finder.get_alternatives();
    1420                         if ( typesCompatibleIgnoreQualifiers( argType, function->parameters.front()->get_type(), indexer, env ) ) {
    1421                                 Cost cost = Cost::zero;
    1422                                 Expression * newExpr = data.combine( cost );
    1423                                 alternatives.push_back( Alternative{
    1424                                         new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{},
    1425                                         AssertionList{}, Cost::zero, cost } );
    1426                                 for ( DeclarationWithType * retVal : function->returnVals ) {
    1427                                         alternatives.back().expr->result = retVal->get_type()->clone();
    1428                                 } // for
    1429                         } // if
    1430                 }
    1431         }
    1432 
    1433         void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {
    1434                 // assume no 'pointer-to-attribute'
    1435                 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    1436                 assert( nameExpr );
    1437                 std::list< SymTab::Indexer::IdData > attrList;
    1438                 indexer.lookupId( nameExpr->get_name(), attrList );
    1439                 if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
    1440                         for ( auto & data : attrList ) {
    1441                                 const DeclarationWithType * id = data.id;
    1442                                 // check if the type is function
    1443                                 if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) {
    1444                                         // assume exactly one parameter
    1445                                         if ( function->parameters.size() == 1 ) {
    1446                                                 if ( attrExpr->get_isType() ) {
    1447                                                         resolveAttr( data, function, attrExpr->get_type(), env, altFinder);
    1448                                                 } else {
    1449                                                         AlternativeFinder finder( indexer, env );
    1450                                                         finder.find( attrExpr->get_expr() );
    1451                                                         for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    1452                                                                 if ( choice->expr->get_result()->size() == 1 ) {
    1453                                                                         resolveAttr(data, function, choice->expr->get_result(), choice->env, altFinder );
    1454                                                                 } // fi
    1455                                                         } // for
    1456                                                 } // if
    1457                                         } // if
    1458                                 } // if
    1459                         } // for
    1460                 } else {
    1461                         for ( auto & data : attrList ) {
    1462                                 Cost cost = Cost::zero;
    1463                                 Expression * newExpr = data.combine( cost );
    1464                                 alternatives.push_back( Alternative{
    1465                                         newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } );
    1466                                 renameTypes( alternatives.back().expr );
    1467                         } // for
    1468                 } // if
    14691406        }
    14701407
     
    17061643                                // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?
    17071644
    1708                                 Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv );
     1645                                Cost thisCost = castCost( alt.expr->result, toType, alt.expr->get_lvalue(),
     1646                                        indexer, newEnv );
    17091647                                if ( thisCost != Cost::infinity ) {
    17101648                                        // count one safe conversion for each value that is thrown away
  • src/ResolvExpr/CastCost.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 06:57:43 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  2 15:34:36 2016
    13 // Update Count     : 7
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:12:00 2019
     13// Update Count     : 8
    1414//
    1515
     
    3737        struct CastCost_old : public ConversionCost {
    3838          public:
    39                 CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
     39                CastCost_old( const Type * dest, bool srcIsLvalue,
     40                        const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
    4041
    4142                using ConversionCost::previsit;
     
    4546        };
    4647
    47         Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     48        Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
     49                        const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    4850                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    4951                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
    5052                                if ( eqvClass->type ) {
    51                                         return castCost( src, eqvClass->type, indexer, env );
     53                                        return castCost( src, eqvClass->type, srcIsLvalue, indexer, env );
    5254                                } else {
    5355                                        return Cost::infinity;
     
    5759                                const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
    5860                                if ( type->base ) {
    59                                         return castCost( src, type->base, indexer, env ) + Cost::safe;
     61                                        return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe;
    6062                                } // if
    6163                        } // if
     
    7880                } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
    7981                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    80                         return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     82                        return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    8183                                return ptrsCastable( t1, t2, env, indexer );
    8284                        });
    8385                } else {
    8486                        PassVisitor<CastCost_old> converter(
    85                                 dest, indexer, env,
    86                                 (Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & ))
     87                                dest, srcIsLvalue, indexer, env,
     88                                (Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & ))
    8789                                        castCost );
    8890                        src->accept( converter );
     
    9698        }
    9799
    98         CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    99                 : ConversionCost( dest, indexer, env, costFunc ) {
     100        CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue,
     101                        const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     102                : ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) {
    100103        }
    101104
     
    106109                        cost = Cost::unsafe;
    107110                } else {
    108                         cost = conversionCost( basicType, dest, indexer, env );
     111                        cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env );
    109112                } // if
    110113        }
  • src/ResolvExpr/CommonType.cc

    r8e1467d r4a60488  
    190190                                 */
    191191                                  {
    192                 /*     B */                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     192                /*      B */                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    193193                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    194194                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    198198                                  },
    199199                                  {
    200                 /*     C */                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     200                /*      C */                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    201201                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    202202                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    206206                                  },
    207207                                  {
    208                 /*    SC */          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     208                /*     SC */          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    209209                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    210210                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    214214                                  },
    215215                                  {
    216                 /*    UC */        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     216                /*     UC */        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    217217                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    218218                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    222222                                  },
    223223                                  {
    224                 /*    SI */      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
     224                /*     SI */      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
    225225                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    226226                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    230230                                  },
    231231                                  {
    232                 /*   SUI */    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
     232                /*    SUI */    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
    233233                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    234234                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    238238                                  },
    239239                                  {
    240                 /*     I */           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
     240                /*      I */           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
    241241                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    242242                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    246246                                  },
    247247                                  {
    248                 /*    UI */         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
     248                /*     UI */         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
    249249                                           BT UnsignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    250250                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    254254                                  },
    255255                                  {
    256                 /*    LI */       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
     256                /*     LI */       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
    257257                                         BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    258258                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    262262                                  },
    263263                                  {
    264                 /*   LUI */     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
     264                /*    LUI */     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
    265265                                       BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    266266                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    270270                                  },
    271271                                  {
    272                 /*   LLI */   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
     272                /*    LLI */   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
    273273                                     BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    274274                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    278278                                  },
    279279                                  {
    280                 /*  LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
     280                /*   LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
    281281                                   BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
    282282                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    286286                                  },
    287287                                  {
    288                 /*    IB */        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
     288                /*     IB */        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
    289289                                          BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
    290290                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    294294                                  },
    295295                                  {
    296                 /*   UIB */      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
     296                /*    UIB */      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
    297297                                        BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
    298298                                        BT UnsignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    302302                                  },
    303303                                  {
    304                 /*   _FH */            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
     304                /*    _FH */            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
    305305                                              BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
    306306                                              BT uFloat16,            BT uFloat16,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    310310                                  },
    311311                                  {
    312                 /*   _FH */     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
     312                /*    _FH */     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
    313313                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
    314314                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     
    318318                                  },
    319319                                  {
    320                 /*    _F */            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
     320                /*     _F */            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
    321321                                              BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
    322322                                              BT uFloat32,            BT uFloat32,            BT uFloat32,     BT uFloat32Complex,            BT uFloat32,     BT uFloat32Complex,
     
    326326                                  },
    327327                                  {
    328                 /*   _FC */     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     328                /*    _FC */     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
    329329                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
    330330                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     
    334334                                  },
    335335                                  {
    336                 /*     F */               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
     336                /*      F */               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
    337337                                                 BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
    338338                                                 BT Float,               BT Float,               BT Float,        BT FloatComplex,               BT Float,        BT FloatComplex,
     
    342342                                  },
    343343                                  {
    344                 /*    FC */        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     344                /*     FC */        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
    345345                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
    346346                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     
    350350                                  },
    351351                                  {
    352                 /*   _FX */           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
     352                /*    _FX */           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
    353353                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
    354354                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,
     
    358358                                  },
    359359                                  {
    360                 /*  _FXC */    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     360                /*   _FXC */    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
    361361                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
    362362                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     
    366366                                  },
    367367                                  {
    368                 /*    FD */            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
     368                /*     FD */            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
    369369                                              BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
    370370                                              BT uFloat64,            BT uFloat64,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
     
    374374                                  },
    375375                                  {
    376                 /*  _FDC */     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     376                /*   _FDC */     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
    377377                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
    378378                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     
    382382                                  },
    383383                                  {
    384                 /*     D */              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
     384                /*      D */              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
    385385                                                BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
    386386                                                BT Double,              BT Double,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
     
    390390                                  },
    391391                                  {
    392                 /*    DC */       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     392                /*     DC */       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
    393393                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
    394394                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     
    398398                                  },
    399399                                  {
    400                 /*  F80X */           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
     400                /*   F80X */           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
    401401                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
    402402                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
     
    406406                                  },
    407407                                  {
    408                 /* _FDXC */    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     408                /*  _FDXC */    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
    409409                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
    410410                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     
    414414                                  },
    415415                                  {
    416                 /*   F80*/           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
     416                /*    F80 */           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
    417417                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
    418418                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,
     
    422422                                  },
    423423                                  {
    424                 /*   _FB */           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
     424                /*    _FB */           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
    425425                                             BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
    426426                                             BT uFloat128,           BT uFloat128,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
     
    430430                                  },
    431431                                  {
    432                 /* _FLDC */    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     432                /*  _FLDC */    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
    433433                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
    434434                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     
    438438                                  },
    439439                                  {
    440                 /*    FB */          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
     440                /*     FB */          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
    441441                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
    442442                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
     
    446446                                  },
    447447                                  {
    448                 /*    LD */          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
     448                /*     LD */          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
    449449                                            BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
    450450                                            BT LongDouble,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
     
    454454                                  },
    455455                                  {
    456                 /*   LDC */   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     456                /*    LDC */   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
    457457                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
    458458                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     
    462462                                  },
    463463                                  {
    464                 /*  _FBX */          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
     464                /*   _FBX */          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
    465465                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
    466466                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
  • src/ResolvExpr/ConversionCost.cc

    r8e1467d r4a60488  
    4646#endif
    4747
    48         Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     48        Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
     49                        const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    4950                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    5051                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
    5152                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
    5253                                if ( eqvClass->type ) {
    53                                         return conversionCost( src, eqvClass->type, indexer, env );
     54                                        return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env );
    5455                                } else {
    5556                                        return Cost::infinity;
     
    6162                                assert( type );
    6263                                if ( type->base ) {
    63                                         return conversionCost( src, type->base, indexer, env ) + Cost::safe;
     64                                        return conversionCost( src, type->base, srcIsLvalue, indexer, env )
     65                                                + Cost::safe;
    6466                                } // if
    6567                        } // if
     
    8183                } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
    8284                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    83                         return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
     85                        return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    8486                                return ptrsAssignable( t1, t2, env );
    8587                        });
    8688                } else {
    8789                        PassVisitor<ConversionCost> converter(
    88                                 dest, indexer, env,
    89                                 (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
     90                                dest, srcIsLvalue, indexer, env,
     91                                (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
    9092                                        conversionCost );
    9193                        src->accept( converter );
     
    98100        }
    99101
    100         Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     102        static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue,
     103                        int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    101104                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    102105                if ( diff > 0 ) {
    103106                        // TODO: document this
    104                         Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
     107                        Cost cost = convertToReferenceCost(
     108                                strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue,
     109                                diff-1, indexer, env, func );
    105110                        cost.incReference();
    106111                        return cost;
    107112                } else if ( diff < -1 ) {
    108113                        // TODO: document this
    109                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func );
     114                        Cost cost = convertToReferenceCost(
     115                                src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue,
     116                                diff+1, indexer, env, func );
    110117                        cost.incReference();
    111118                        return cost;
     
    138145                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    139146                                PassVisitor<ConversionCost> converter(
    140                                         dest, indexer, env,
    141                                         (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
     147                                        dest, srcIsLvalue, indexer, env,
     148                                        (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
    142149                                                conversionCost );
    143150                                src->accept( converter );
     
    150157                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    151158                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    152                                 if ( src->get_lvalue() ) {
     159                                if ( srcIsLvalue ) {
    153160                                        PRINT(
    154161                                                std::cerr << "lvalue to reference conversion" << std::endl;
     
    178185        }
    179186
    180         Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     187        Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
     188                        const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    181189                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    182                 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
     190                Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func );
    183191                PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
    184192                return cost;
    185193        }
    186194
    187         ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    188                 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
     195        ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     196                : dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
    189197        }
    190198
     
    217225        // GENERATED BY BasicTypes-gen.cc
    218226        static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
    219                 /*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    220                 /*     B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
    221                 /*     C */ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    222                 /*    SC */ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    223                 /*    UC */ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    224                 /*    SI */ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
    225                 /*   SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
    226                 /*     I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
    227                 /*    UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
    228                 /*    LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
    229                 /*   LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
    230                 /*   LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
    231                 /*  LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
    232                 /*    IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
    233                 /*   UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
    234                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
    235                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
    236                 /*    _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
    237                 /*   _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
    238                 /*     F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
    239                 /*    FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
    240                 /*   _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
    241                 /*  _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
    242                 /*    FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
    243                 /*  _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
    244                 /*     D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
    245                 /*    DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
    246                 /*  F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
    247                 /* _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
    248                 /*   F80*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3,   3,   4,   4, },
    249                 /*   _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3, },
    250                 /* _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,   2, },
    251                 /*    FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3, },
    252                 /*    LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2, },
    253                 /*   LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1, },
    254                 /*  _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1, },
     227                /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
     228                /*      B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
     229                /*      C */ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     230                /*     SC */ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     231                /*     UC */ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     232                /*     SI */ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
     233                /*    SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
     234                /*      I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
     235                /*     UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
     236                /*     LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
     237                /*    LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
     238                /*    LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
     239                /*   LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
     240                /*     IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
     241                /*    UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
     242                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
     243                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
     244                /*     _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
     245                /*    _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
     246                /*      F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
     247                /*     FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
     248                /*    _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
     249                /*   _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
     250                /*     FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
     251                /*   _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
     252                /*      D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
     253                /*     DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
     254                /*   F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
     255                /*  _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
     256                /*    F80 */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3,   3,   4,   4, },
     257                /*    _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3, },
     258                /*  _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,   2, },
     259                /*     FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3, },
     260                /*     LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2, },
     261                /*    LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1, },
     262                /*   _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1, },
    255263                /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
    256264        }; // costMatrix
     
    265273        // GENERATED BY BasicTypes-gen.cc
    266274        static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
    267                 /*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    268                 /*     B */ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    269                 /*     C */ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    270                 /*    SC */ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    271                 /*    UC */ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    272                 /*    SI */ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    273                 /*   SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    274                 /*     I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    275                 /*    UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    276                 /*    LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    277                 /*   LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    278                 /*   LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    279                 /*  LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    280                 /*    IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    281                 /*   UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    282                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    283                 /*   _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    284                 /*    _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    285                 /*   _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    286                 /*     F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    287                 /*    FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    288                 /*   _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    289                 /*  _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    290                 /*    FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    291                 /*  _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    292                 /*     D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    293                 /*    DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    294                 /*  F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    295                 /* _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    296                 /*   F80*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    297                 /*   _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, },
    298                 /* _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    299                 /*    FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0, },
    300                 /*    LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0, },
    301                 /*   LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0, },
    302                 /*  _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0, },
     275                /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
     276                /*      B */ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     277                /*      C */ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     278                /*     SC */ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     279                /*     UC */ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     280                /*     SI */ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     281                /*    SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     282                /*      I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     283                /*     UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     284                /*     LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     285                /*    LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     286                /*    LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     287                /*   LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     288                /*     IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     289                /*    UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     290                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     291                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     292                /*     _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     293                /*    _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     294                /*      F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     295                /*     FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     296                /*    _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     297                /*   _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     298                /*     FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     299                /*   _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     300                /*      D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     301                /*     DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     302                /*   F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     303                /*  _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     304                /*    F80 */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     305                /*    _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, },
     306                /*  _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     307                /*     FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0, },
     308                /*     LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0, },
     309                /*    LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0, },
     310                /*   _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0, },
    303311                /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
    304312        }; // signMatrix
     
    371379                // recursively compute conversion cost from T1 to T2.
    372380                // cv can be safely dropped because of 'implicit dereference' behavior.
    373                 cost = costFunc( refType->base, dest, indexer, env );
     381                cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env );
    374382                if ( refType->base->tq == dest->tq ) {
    375383                        cost.incReference();  // prefer exact qualifiers
     
    403411                static Type::Qualifiers q;
    404412                static BasicType integer( q, BasicType::SignedInt );
    405                 cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
     413                cost = costFunc( &integer, dest, srcIsLvalue, indexer, env );  // safe if dest >= int
    406414                if ( cost < Cost::unsafe ) {
    407415                        cost.incSafe();
     
    413421        void ConversionCost::postvisit( const TypeInstType * inst ) {
    414422                if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
    415                         cost = costFunc( eqvClass->type, dest, indexer, env );
     423                        cost = costFunc( eqvClass->type, dest, srcIsLvalue, indexer, env );
    416424                } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    417425                        if ( inst->name == destAsInst->name ) {
     
    423431                        assert( type );
    424432                        if ( type->base ) {
    425                                 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
     433                                cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe;
    426434                        } // if
    427435                } // if
     
    434442                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
    435443                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
    436                                 Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env );
     444                                Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );
    437445                                if ( newCost == Cost::infinity ) {
    438446                                        return;
     
    534542}
    535543
    536 Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, int diff,
    537                 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
     544static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst,
     545                int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
    538546                NumCostCalculation func ) {
    539547        if ( 0 < diff ) {
  • src/ResolvExpr/ConversionCost.h

    r8e1467d r4a60488  
    1010// Created On       : Sun May 17 09:37:28 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jun 24 10:00:00 2019
    13 // Update Count     : 5
     12// Last Modified On : Thu Aug  8 16:13:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    3333        class TypeEnvironment;
    3434
    35         typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
     35        typedef std::function<Cost(const Type *, const Type *, bool,
     36                const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
     37
    3638        struct ConversionCost : public WithShortCircuiting {
    3739          public:
    38                 ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
     40                ConversionCost( const Type * dest, bool srcIsLvalue,
     41                        const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
    3942
    4043                Cost get_cost() const { return cost; }
     
    5962          protected:
    6063                const Type * dest;
     64                bool srcIsLvalue;
    6165                const SymTab::Indexer &indexer;
    6266                Cost cost;
     
    6670
    6771        typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
    68         Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
     72        Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
     73                const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
    6974
    7075// Some function pointer types, differ in return type.
  • src/ResolvExpr/ResolveAssertions.cc

    r8e1467d r4a60488  
    99// Author           : Aaron B. Moss
    1010// Created On       : Fri Oct 05 13:46:00 2018
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 10 16:10:37 2019
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:47:00 2019
     13// Update Count     : 3
    1414//
    1515
     
    156156                        for ( const auto& assn : x.assns ) {
    157157                                // compute conversion cost from satisfying decl to assertion
     158                                assert( !assn.match.adjType->get_lvalue() );
    158159                                k += computeConversionCost(
    159                                         assn.match.adjType, assn.decl->get_type(), indexer, x.env );
     160                                        assn.match.adjType, assn.decl->get_type(), false, indexer, x.env );
    160161
    161162                                // mark vars+specialization cost on function-type assertions
  • src/ResolvExpr/Unify.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Mon Jun 18 11:58:00 2018
    13 // Update Count     : 43
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Sep  4 10:00:00 2019
     13// Update Count     : 44
    1414//
    1515
     
    274274#endif
    275275                        if ( ( common = commonType( type1, type2, widen.first, widen.second, indexer, env, openVars ) ) ) {
    276                                 common->get_qualifiers() = tq1 | tq2;
     276                                common->tq = tq1.unify( tq2 );
    277277#ifdef DEBUG
    278278                                std::cerr << "unifyInexact: common type is ";
     
    291291                                if ( ( tq1 > tq2 || widen.first ) && ( tq2 > tq1 || widen.second ) ) {
    292292                                        common = type1->clone();
    293                                         common->get_qualifiers() = tq1 | tq2;
     293                                        common->tq = tq1.unify( tq2 );
    294294                                        result = true;
    295295                                } else {
     
    298298                        } else {
    299299                                common = type1->clone();
    300                                 common->get_qualifiers() = tq1 | tq2;
     300                                common->tq = tq1.unify( tq2 );
    301301                                result = true;
    302302                        } // if
  • src/ResolvExpr/typeops.h

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 07:28:22 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  8 09:30:34 2019
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:36:00 2019
     13// Update Count     : 5
    1414//
    1515
     
    8080
    8181        // in CastCost.cc
    82         Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     82        Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
     83                const SymTab::Indexer & indexer, const TypeEnvironment & env );
    8384        Cost castCost(
    8485                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     
    8687
    8788        // in ConversionCost.cc
    88         Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     89        Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
     90                const SymTab::Indexer & indexer, const TypeEnvironment & env );
    8991        Cost conversionCost(
    9092                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     
    9294
    9395        // in AlternativeFinder.cc
    94         Cost computeConversionCost( Type * actualType, Type * formalType,
     96        Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
    9597                const SymTab::Indexer & indexer, const TypeEnvironment & env );
    9698
  • src/SymTab/Demangle.cc

    r8e1467d r4a60488  
    99// Author           : Rob Schluntz
    1010// Created On       : Thu Jul 19 12:52:41 2018
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Jul 19 12:54:35 2018
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Jul 30 13:46:33 2019
     13// Update Count     : 3
    1414//
    1515
     
    313313                        typeString = "_Atomic " + typeString;
    314314                } // if
    315                 if ( type->get_lvalue() ) {
    316                         // when not generating C code, print lvalue for debugging.
    317                         typeString = "lvalue " + typeString;
    318                 }
    319315        }
    320316}
  • src/SymTab/Mangler.cc

    r8e1467d r4a60488  
    1010// Created On       : Sun May 17 21:40:29 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:49:26 2017
    13 // Update Count     : 23
     12// Last Modified On : Tue Jul 30 13:46:10 2019
     13// Update Count     : 26
    1414//
    1515#include "Mangler.h"
     
    377377                                        mangleName << Encoding::qualifiers.at(Type::Mutex);
    378378                                } // if
    379                                 if ( type->get_lvalue() ) {
    380                                         // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    381                                         mangleName << Encoding::qualifiers.at(Type::Lvalue);
    382                                 }
    383 
    384379                                if ( inFunctionType ) {
    385380                                        // turn off inFunctionType so that types can be differentiated for nested qualifiers
     
    724719                                mangleName << Encoding::qualifiers.at(Type::Mutex);
    725720                        } // if
    726                         if ( type->is_lvalue() ) {
    727                                 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    728                                 mangleName << Encoding::qualifiers.at(Type::Lvalue);
    729                         }
    730 
    731721                        if ( inFunctionType ) {
    732722                                // turn off inFunctionType so that types can be differentiated for nested qualifiers
  • src/SymTab/Validate.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 28 13:47:23 2017
    13 // Update Count     : 359
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Aug  7 6:42:00 2019
     13// Update Count     : 360
    1414//
    1515
     
    8181#include "SynTree/Label.h"             // for operator==, Label
    8282#include "SynTree/Mutator.h"           // for Mutator
     83#include "SynTree/TopLvalue.h"         // for assertTopLvalue, clearInnerLvalue
    8384#include "SynTree/Type.h"              // for Type, TypeInstType, EnumInstType
    8485#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
     
    308309                PassVisitor<FixQualifiedTypes> fixQual;
    309310
     311                assertTopLvalue( translationUnit );
    310312                {
    311313                        Stats::Heap::newPass("validate-A");
     
    316318                        acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling
    317319                }
     320                assertTopLvalue( translationUnit );
    318321                {
    319322                        Stats::Heap::newPass("validate-B");
    320323                        Stats::Time::BlockGuard guard("validate-B");
     324                        assertTopLvalue( translationUnit );
    321325                        Stats::Time::TimeBlock("Link Reference To Types", [&]() {
    322326                                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
    323327                        });
     328                        clearInnerLvalue( translationUnit );
     329                        assertTopLvalue( translationUnit );
    324330                        Stats::Time::TimeBlock("Fix Qualified Types", [&]() {
    325331                                mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed
    326332                        });
     333                        assertTopLvalue( translationUnit );
    327334                        Stats::Time::TimeBlock("Hoist Structs", [&]() {
    328335                                HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
    329336                        });
     337                        assertTopLvalue( translationUnit );
    330338                        Stats::Time::TimeBlock("Eliminate Typedefs", [&]() {
    331339                                EliminateTypedef::eliminateTypedef( translationUnit ); //
    332340                        });
    333341                }
     342                assertTopLvalue( translationUnit );
    334343                {
    335344                        Stats::Heap::newPass("validate-C");
     
    340349                        InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
    341350                }
     351                assertTopLvalue( translationUnit );
    342352                {
    343353                        Stats::Heap::newPass("validate-D");
    344354                        Stats::Time::BlockGuard guard("validate-D");
     355                        assertTopLvalue( translationUnit );
    345356                        Stats::Time::TimeBlock("Apply Concurrent Keywords", [&]() {
    346357                                Concurrency::applyKeywords( translationUnit );
    347358                        });
     359                        clearInnerLvalue( translationUnit );
     360                        assertTopLvalue( translationUnit );
    348361                        Stats::Time::TimeBlock("Forall Pointer Decay", [&]() {
    349362                                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
    350363                        });
     364                        assertTopLvalue( translationUnit );
    351365                        Stats::Time::TimeBlock("Hoist Control Declarations", [&]() {
    352366                                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    353367                        });
     368                        assertTopLvalue( translationUnit );
    354369                        Stats::Time::TimeBlock("Generate Autogen routines", [&]() {
    355370                                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old
    356371                        });
    357                 }
     372                        clearInnerLvalue( translationUnit );
     373                }
     374                assertTopLvalue( translationUnit );
    358375                {
    359376                        Stats::Heap::newPass("validate-E");
    360377                        Stats::Time::BlockGuard guard("validate-E");
     378                        assertTopLvalue( translationUnit );
    361379                        Stats::Time::TimeBlock("Implement Mutex Func", [&]() {
    362380                                Concurrency::implementMutexFuncs( translationUnit );
    363381                        });
     382                        clearInnerLvalue( translationUnit );
     383                        assertTopLvalue( translationUnit );
    364384                        Stats::Time::TimeBlock("Implement Thread Start", [&]() {
    365385                                Concurrency::implementThreadStarter( translationUnit );
    366386                        });
     387                        assertTopLvalue( translationUnit );
    367388                        Stats::Time::TimeBlock("Compound Literal", [&]() {
    368389                                mutateAll( translationUnit, compoundliteral );
    369390                        });
     391                        assertTopLvalue( translationUnit );
    370392                        Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
    371393                                ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
    372394                        });
    373                 }
     395                        clearInnerLvalue( translationUnit );
     396                }
     397                assertTopLvalue( translationUnit );
    374398                {
    375399                        Stats::Heap::newPass("validate-F");
    376400                        Stats::Time::BlockGuard guard("validate-F");
     401                        assertTopLvalue( translationUnit );
    377402                        Stats::Time::TimeBlock("Fix Object Type", [&]() {
    378403                                FixObjectType::fix( translationUnit );
    379404                        });
     405                        assertTopLvalue( translationUnit );
    380406                        Stats::Time::TimeBlock("Array Length", [&]() {
    381407                                ArrayLength::computeLength( translationUnit );
    382408                        });
     409                        clearInnerLvalue( translationUnit );
     410                        assertTopLvalue( translationUnit );
    383411                        Stats::Time::TimeBlock("Find Special Declarations", [&]() {
    384412                                Validate::findSpecialDecls( translationUnit );
    385413                        });
     414                        assertTopLvalue( translationUnit );
    386415                        Stats::Time::TimeBlock("Fix Label Address", [&]() {
    387416                                mutateAll( translationUnit, labelAddrFixer );
    388417                        });
     418                        assertTopLvalue( translationUnit );
    389419                        Stats::Time::TimeBlock("Handle Attributes", [&]() {
    390420                                Validate::handleAttributes( translationUnit );
    391421                        });
    392422                }
     423                assertTopLvalue( translationUnit );
    393424        }
    394425
  • src/SynTree/AddressExpr.cc

    r8e1467d r4a60488  
    4242AddressExpr::AddressExpr( Expression *arg ) : Expression(), arg( arg ) {
    4343        if ( arg->result ) {
    44                 if ( arg->result->get_lvalue() ) {
     44                if ( arg->get_lvalue() ) {
    4545                        // lvalue, retains all layers of reference and gains a pointer inside the references
    4646                        set_result( addrType( arg->result ) );
  • src/SynTree/ApplicationExpr.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Apr 26 12:41:06 2016
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Aug 12 14:28:00 2019
     13// Update Count     : 5
    1414//
    1515
     
    2525#include "Declaration.h"         // for Declaration
    2626#include "Expression.h"          // for ParamEntry, ApplicationExpr, Expression
     27#include "InitTweak/InitTweak.h" // for getFunction
    2728#include "ResolvExpr/typeops.h"  // for extractResultType
    2829#include "Type.h"                // for Type, PointerType, FunctionType
     
    7677}
    7778
     79bool ApplicationExpr::get_lvalue() const {
     80        // from src/GenPoly/Lvalue.cc: isIntrinsicReference
     81        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
     82        if ( const DeclarationWithType * func = InitTweak::getFunction( this ) ) {
     83                return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name);
     84        }
     85        return false;
     86}
     87
    7888void ApplicationExpr::print( std::ostream &os, Indenter indent ) const {
    7989        os << "Application of" << std::endl << indent+1;
  • src/SynTree/BasicType.cc

    r8e1467d r4a60488  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jan 31 21:37:36 2019
    13 // Update Count     : 12
     12// Last Modified On : Sun Aug  4 21:07:44 2019
     13// Update Count     : 13
    1414//
    1515
     
    3131bool BasicType::isInteger() const {
    3232        return kind <= UnsignedInt128;
    33 #if 0
    34         switch ( kind ) {
    35           case Bool:
    36           case Char:
    37           case SignedChar:
    38           case UnsignedChar:
    39           case ShortSignedInt:
    40           case ShortUnsignedInt:
    41           case SignedInt:
    42           case UnsignedInt:
    43           case LongSignedInt:
    44           case LongUnsignedInt:
    45           case LongLongSignedInt:
    46           case LongLongUnsignedInt:
    47           case SignedInt128:
    48           case UnsignedInt128:
    49                 return true;
    50           case Float:
    51           case Double:
    52           case LongDouble:
    53           case FloatComplex:
    54           case DoubleComplex:
    55           case LongDoubleComplex:
    56           case FloatImaginary:
    57           case DoubleImaginary:
    58           case LongDoubleImaginary:
    59           case Float80:
    60           case Float128:
    61                 return false;
    62           case NUMBER_OF_BASIC_TYPES:
    63                 assert( false );
    64         } // switch
    65         assert( false );
    66         return false;
    67 #endif
    6833}
    6934
  • src/SynTree/CommaExpr.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 02 15:19:44 2016
    13 // Update Count     : 1
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Arg 12 16:11:00 2016
     13// Update Count     : 2
    1414//
    1515
     
    3939}
    4040
     41bool CommaExpr::get_lvalue() const {
     42        // This is wrong by C, but the current implementation uses it.
     43        return arg2->get_lvalue();
     44}
     45
    4146void CommaExpr::print( std::ostream &os, Indenter indent ) const {
    4247        os << "Comma Expression:" << std::endl;
  • src/SynTree/Expression.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb 19 18:10:55 2019
    13 // Update Count     : 60
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Aug 15 13:43:00 2019
     13// Update Count     : 64
    1414//
    1515
     
    1919#include <iostream>                  // for ostream, operator<<, basic_ostream
    2020#include <list>                      // for list, _List_iterator, list<>::co...
     21#include <set>                       // for set
    2122
    2223#include "Common/utility.h"          // for maybeClone, cloneAll, deleteAll
     
    6364}
    6465
     66bool Expression::get_lvalue() const {
     67        return false;
     68}
     69
    6570void Expression::print( std::ostream & os, Indenter indent ) const {
    6671        printInferParams( inferParams, os, indent+1, 0 );
     
    134139}
    135140
     141bool VariableExpr::get_lvalue() const {
     142        // It isn't always an lvalue, but it is never an rvalue.
     143        return true;
     144}
     145
    136146VariableExpr * VariableExpr::functionPointer( FunctionDecl * func ) {
    137147        VariableExpr * funcExpr = new VariableExpr( func );
     
    252262}
    253263
    254 AttrExpr::AttrExpr( Expression * attr, Expression * expr_ ) :
    255                 Expression(), attr( attr ), expr(expr_), type(0), isType(false) {
    256 }
    257 
    258 AttrExpr::AttrExpr( Expression * attr, Type * type_ ) :
    259                 Expression(), attr( attr ), expr(0), type(type_), isType(true) {
    260 }
    261 
    262 AttrExpr::AttrExpr( const AttrExpr & other ) :
    263                 Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
    264 }
    265 
    266 AttrExpr::~AttrExpr() {
    267         delete attr;
    268         delete expr;
    269         delete type;
    270 }
    271 
    272 void AttrExpr::print( std::ostream & os, Indenter indent) const {
    273         os << "Attr ";
    274         attr->print( os, indent+1);
    275         if ( isType || expr ) {
    276                 os << "applied to: ";
    277                 if (isType) type->print(os, indent+1);
    278                 else expr->print(os, indent+1);
    279         } // if
    280         Expression::print( os, indent );
    281 }
    282 
    283264CastExpr::CastExpr( Expression * arg, Type * toType, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) {
    284265        set_result(toType);
     
    294275CastExpr::~CastExpr() {
    295276        delete arg;
     277}
     278
     279bool CastExpr::get_lvalue() const {
     280        // This is actually wrong by C, but it works with our current set-up.
     281        return arg->get_lvalue();
    296282}
    297283
     
    376362}
    377363
     364bool UntypedMemberExpr::get_lvalue() const {
     365        return aggregate->get_lvalue();
     366}
     367
    378368void UntypedMemberExpr::print( std::ostream & os, Indenter indent ) const {
    379369        os << "Untyped Member Expression, with field: " << std::endl << indent+1;
     
    405395        // don't delete the member declaration, since it points somewhere else in the tree
    406396        delete aggregate;
     397}
     398
     399bool MemberExpr::get_lvalue() const {
     400        // This is actually wrong by C, but it works with our current set-up.
     401        return true;
    407402}
    408403
     
    457452}
    458453
     454bool UntypedExpr::get_lvalue() const {
     455        // from src/GenPoly/Lvalue.cc: isIntrinsicReference
     456        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
     457        std::string fname = InitTweak::getFunctionName( const_cast< UntypedExpr * >( this ) );
     458        return lvalueFunctions.count(fname);
     459}
    459460
    460461void UntypedExpr::print( std::ostream & os, Indenter indent ) const {
     
    515516        delete arg2;
    516517        delete arg3;
     518}
     519
     520bool ConditionalExpr::get_lvalue() const {
     521        return false;
    517522}
    518523
     
    573578}
    574579
     580bool ConstructorExpr::get_lvalue() const {
     581        return false;
     582}
     583
    575584void ConstructorExpr::print( std::ostream & os, Indenter indent ) const {
    576585        os <<  "Constructor Expression: " << std::endl << indent+1;
     
    590599CompoundLiteralExpr::~CompoundLiteralExpr() {
    591600        delete initializer;
     601}
     602
     603bool CompoundLiteralExpr::get_lvalue() const {
     604        return true;
    592605}
    593606
     
    641654                result = new VoidType( Type::Qualifiers() );
    642655        }
     656}
     657bool StmtExpr::get_lvalue() const {
     658        return false;
    643659}
    644660void StmtExpr::print( std::ostream & os, Indenter indent ) const {
  • src/SynTree/Expression.h

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Feb 18 18:29:51 2019
    13 // Update Count     : 49
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Aug 15 13:46:00 2019
     13// Update Count     : 54
    1414//
    1515
     
    7171        const Type * get_result() const { return result; }
    7272        void set_result( Type * newValue ) { result = newValue; }
     73        virtual bool get_lvalue() const;
    7374
    7475        TypeSubstitution * get_env() const { return env; }
     
    9899        virtual ~ApplicationExpr();
    99100
     101        bool get_lvalue() const final;
     102
    100103        Expression * get_function() const { return function; }
    101104        void set_function( Expression * newValue ) { function = newValue; }
     
    120123        UntypedExpr( const UntypedExpr & other );
    121124        virtual ~UntypedExpr();
     125
     126        bool get_lvalue() const final;
    122127
    123128        Expression * get_function() const { return function; }
     
    208213        virtual ~CastExpr();
    209214
     215        bool get_lvalue() const final;
     216
    210217        Expression * get_arg() const { return arg; }
    211218        void set_arg( Expression * newValue ) { arg = newValue; }
     
    268275        virtual ~UntypedMemberExpr();
    269276
     277        bool get_lvalue() const final;
     278
    270279        Expression * get_member() const { return member; }
    271280        void set_member( Expression * newValue ) { member = newValue; }
     
    291300        virtual ~MemberExpr();
    292301
     302        bool get_lvalue() const final;
     303
    293304        DeclarationWithType * get_member() const { return member; }
    294305        void set_member( DeclarationWithType * newValue ) { member = newValue; }
     
    313324        VariableExpr( const VariableExpr & other );
    314325        virtual ~VariableExpr();
     326
     327        bool get_lvalue() const final;
    315328
    316329        DeclarationWithType * get_var() const { return var; }
     
    463476};
    464477
    465 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    466 class AttrExpr : public Expression {
    467   public:
    468         Expression * attr;
    469         Expression * expr;
    470         Type * type;
    471         bool isType;
    472 
    473         AttrExpr(Expression * attr, Expression * expr );
    474         AttrExpr( const AttrExpr & other );
    475         AttrExpr( Expression * attr, Type * type );
    476         virtual ~AttrExpr();
    477 
    478         Expression * get_attr() const { return attr; }
    479         void set_attr( Expression * newValue ) { attr = newValue; }
    480         Expression * get_expr() const { return expr; }
    481         void set_expr( Expression * newValue ) { expr = newValue; }
    482         Type * get_type() const { return type; }
    483         void set_type( Type * newValue ) { type = newValue; }
    484         bool get_isType() const { return isType; }
    485         void set_isType( bool newValue ) { isType = newValue; }
    486 
    487         virtual AttrExpr * clone() const override { return new AttrExpr( * this ); }
    488         virtual void accept( Visitor & v ) override { v.visit( this ); }
    489         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    490         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    491         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    492 };
    493 
    494478/// LogicalExpr represents a short-circuit boolean expression (&& or ||)
    495479class LogicalExpr : public Expression {
     
    528512        ConditionalExpr( const ConditionalExpr & other );
    529513        virtual ~ConditionalExpr();
     514
     515        bool get_lvalue() const final;
    530516
    531517        Expression * get_arg1() const { return arg1; }
     
    553539        virtual ~CommaExpr();
    554540
     541        bool get_lvalue() const final;
     542
    555543        Expression * get_arg1() const { return arg1; }
    556544        void set_arg1( Expression * newValue ) { arg1 = newValue; }
     
    639627        ~ConstructorExpr();
    640628
     629        bool get_lvalue() const final;
     630
    641631        Expression * get_callExpr() const { return callExpr; }
    642632        void set_callExpr( Expression * newValue ) { callExpr = newValue; }
     
    657647        CompoundLiteralExpr( const CompoundLiteralExpr & other );
    658648        virtual ~CompoundLiteralExpr();
     649
     650        bool get_lvalue() const final;
    659651
    660652        Initializer * get_initializer() const { return initializer; }
     
    715707        virtual ~TupleExpr();
    716708
     709        bool get_lvalue() const final;
     710
    717711        std::list<Expression*>& get_exprs() { return exprs; }
    718712
     
    733727        TupleIndexExpr( const TupleIndexExpr & other );
    734728        virtual ~TupleIndexExpr();
     729
     730        bool get_lvalue() const final;
    735731
    736732        Expression * get_tuple() const { return tuple; }
     
    782778        StmtExpr( const StmtExpr & other );
    783779        virtual ~StmtExpr();
     780
     781        bool get_lvalue() const final;
    784782
    785783        CompoundStmt * get_statements() const { return statements; }
  • src/SynTree/Mutator.h

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jul 24 16:31:00 2017
    13 // Update Count     : 16
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:37:46 2019
     13// Update Count     : 17
    1414//
    1515#pragma once
     
    7474        virtual Expression * mutate( OffsetofExpr * offsetofExpr ) = 0;
    7575        virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) = 0;
    76         virtual Expression * mutate( AttrExpr * attrExpr ) = 0;
    7776        virtual Expression * mutate( LogicalExpr * logicalExpr ) = 0;
    7877        virtual Expression * mutate( ConditionalExpr * conditionalExpr ) = 0;
  • src/SynTree/SynTree.h

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jul 24 16:54:00 2017
    13 // Update Count     : 11
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:37:45 2019
     13// Update Count     : 12
    1414//
    1515
     
    7979class OffsetofExpr;
    8080class OffsetPackExpr;
    81 class AttrExpr;
    8281class LogicalExpr;
    8382class ConditionalExpr;
  • src/SynTree/TupleExpr.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:42:29 2017
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Aug 14 14:34:00 2019
     13// Update Count     : 5
    1414//
    1515
     
    5757}
    5858
     59bool TupleExpr::get_lvalue() const {
     60        return false;
     61}
     62
    5963void TupleExpr::print( std::ostream &os, Indenter indent ) const {
    6064        os << "Tuple:" << std::endl;
     
    7680TupleIndexExpr::~TupleIndexExpr() {
    7781        delete tuple;
     82}
     83
     84bool TupleIndexExpr::get_lvalue() const {
     85        return tuple->get_lvalue();
    7886}
    7987
  • src/SynTree/Type.cc

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 12 15:48:00 2019
    13 // Update Count     : 44
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Aug  4 21:05:07 2019
     13// Update Count     : 45
    1414//
    1515#include "Type.h"
     
    2424using namespace std;
    2525
    26 const char *BasicType::typeNames[] = {
    27 #if 0
    28         "_Bool",
    29         "char",
    30         "signed char",
    31         "unsigned char",
    32         "signed short int",
    33         "unsigned short int",
    34         "signed int",
    35         "unsigned int",
    36         "signed long int",
    37         "unsigned long int",
    38         "signed long long int",
    39         "unsigned long long int",
    40         "float",
    41         "double",
    42         "long double",
    43         "float _Complex",
    44         "double _Complex",
    45         "long double _Complex",
    46         "float _Imaginary",
    47         "double _Imaginary",
    48         "long double _Imaginary",
    49         "__int128",
    50         "unsigned __int128",
    51         "__float80",
    52         "__float128",
    53         "_Float16",
    54         "_Float32",
    55         "_Float32x",
    56         "_Float64",
    57         "_Float64x",
    58         "_Float128",
    59         "_Float128x",
    60         "_Float16 _Complex",
    61         "_Float32 _Complex",
    62         "_Float32x _Complex",
    63         "_Float64 _Complex",
    64         "_Float64x _Complex",
    65         "_Float128 _Complex",
    66         "_Float128x _Complex",
    67 #endif
     26const char * BasicType::typeNames[] = {
    6827        "_Bool",
    6928        "char",
     
    10766};
    10867static_assert(
    109         sizeof(BasicType::typeNames)/sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
     68        sizeof(BasicType::typeNames) / sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
    11069        "Each basic type name should have a corresponding kind enum value"
    11170);
     
    152111TypeSubstitution Type::genericSubstitution() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
    153112
    154 void Type::print( std::ostream &os, Indenter indent ) const {
     113void Type::print( std::ostream & os, Indenter indent ) const {
    155114        if ( ! forall.empty() ) {
    156115                os << "forall" << std::endl;
  • src/SynTree/Type.h

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 14 17:11:24 2019
    13 // Update Count     : 169
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Sep  4 09:58:00 2019
     13// Update Count     : 170
    1414//
    1515
     
    131131                bool operator>( Qualifiers other ) const { return *this != other && *this >= other; }
    132132                BFCommon( Qualifiers, NumTypeQualifier )
     133
     134                Qualifiers unify( Qualifiers const & other ) const {
     135                        int or_flags = Mask & (val | other.val);
     136                        int and_flags = val & other.val;
     137                        return Qualifiers( or_flags | and_flags );
     138                }
    133139        }; // Qualifiers
    134140
  • src/SynTree/Visitor.h

    r8e1467d r4a60488  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jul 24 16:28:00 2017
    13 // Update Count     : 13
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:21:49 2019
     13// Update Count     : 14
    1414//
    1515
     
    123123        virtual void visit( OffsetPackExpr * node ) { visit( const_cast<const OffsetPackExpr *>(node) ); }
    124124        virtual void visit( const OffsetPackExpr * offsetPackExpr ) = 0;
    125         virtual void visit( AttrExpr * node ) { visit( const_cast<const AttrExpr *>(node) ); }
    126         virtual void visit( const AttrExpr * attrExpr ) = 0;
    127125        virtual void visit( LogicalExpr * node ) { visit( const_cast<const LogicalExpr *>(node) ); }
    128126        virtual void visit( const LogicalExpr * logicalExpr ) = 0;
  • src/SynTree/module.mk

    r8e1467d r4a60488  
    4949      SynTree/TypeSubstitution.cc \
    5050      SynTree/Attribute.cc \
    51       SynTree/DeclReplacer.cc
     51      SynTree/DeclReplacer.cc \
     52      SynTree/TopLvalue.cc
    5253
    5354SRC += $(SRC_SYNTREE)
  • src/main.cc

    r8e1467d r4a60488  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun  5 20:35:13 2019
    13 // Update Count     : 601
     12// Last Modified On : Fri Aug 23 06:50:08 2019
     13// Update Count     : 607
    1414//
    1515
     
    1717#include <execinfo.h>                       // for backtrace, backtrace_symbols
    1818#include <getopt.h>                         // for no_argument, optind, geto...
    19 #include <signal.h>                         // for signal, SIGABRT, SIGSEGV
    2019#include <cassert>                          // for assertf
    2120#include <cstdio>                           // for fopen, FILE, fclose, stdin
    2221#include <cstdlib>                          // for exit, free, abort, EXIT_F...
     22#include <csignal>                         // for signal, SIGABRT, SIGSEGV
    2323#include <cstring>                          // for index
    2424#include <fstream>                          // for ofstream
     
    6060#include "ResolvExpr/Resolver.h"            // for resolve
    6161#include "SymTab/Validate.h"                // for validate
     62#include "SynTree/TopLvalue.h"              // for assertTopLvalue, clearInn...
    6263#include "SynTree/Declaration.h"            // for Declaration
    6364#include "SynTree/Visitor.h"                // for acceptAll
    6465#include "Tuples/Tuples.h"                  // for expandMemberTuples, expan...
    6566#include "Virtual/ExpandCasts.h"            // for expandCasts
     67
    6668
    6769using namespace std;
     
    9597DeclarationNode * parseTree = nullptr;                                  // program parse tree
    9698
     99static bool waiting_for_gdb = false;                                    // flag to set cfa-cpp to wait for gdb on start
     100
    97101static std::string PreludeDirector = "";
    98102
    99 static void parse_cmdline( int argc, char *argv[], const char *& filename );
     103static void parse_cmdline( int argc, char *argv[] );
    100104static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false );
    101105static void dump( list< Declaration * > & translationUnit, ostream & out = cout );
     
    166170} // sigAbortHandler
    167171
    168 
    169172int main( int argc, char * argv[] ) {
    170173        FILE * input;                                                                           // use FILE rather than istream because yyin is FILE
    171174        ostream * output = & cout;
    172         const char * filename = nullptr;
    173175        list< Declaration * > translationUnit;
    174176
     
    182184        // } // for
    183185
    184         parse_cmdline( argc, argv, filename );                          // process command-line arguments
     186        parse_cmdline( argc, argv );                                            // process command-line arguments
    185187        CodeGen::FixMain::setReplaceMain( !nomainp );
     188
     189        if ( waiting_for_gdb ) {
     190                std::cerr << "Waiting for gdb" << std::endl;
     191                std::cerr << "run :" << std::endl;
     192                std::cerr << "  gdb attach " << getpid() << std::endl;
     193                raise(SIGSTOP);
     194        } // if
    186195
    187196        try {
     
    189198                if ( optind < argc ) {                                                  // any commands after the flags ? => input file name
    190199                        input = fopen( argv[ optind ], "r" );
    191                         assertf( input, "cannot open %s\n", argv[ optind ] );
    192                         // if running cfa-cpp directly, might forget to pass -F option (and really shouldn't have to)
    193                         if ( filename == nullptr ) filename = argv[ optind ];
    194                         // prelude filename comes in differently
    195                         if ( libcfap ) filename = "prelude.cfa";
     200                        assertf( input, "cannot open %s because %s\n", argv[ optind ], strerror( errno ) );
    196201                        optind += 1;
    197202                } else {                                                                                // no input file name
    198203                        input = stdin;
    199                         // if running cfa-cpp directly, might forget to pass -F option. Since this takes from stdin, pass
    200                         // a fake name along
    201                         if ( filename == nullptr ) filename = "stdin";
    202204                } // if
    203205
     
    258260                Stats::Time::StopBlock();
    259261
     262                //std::cerr << "Post-Parse Check" << std::endl;
     263                clearInnerLvalue( translationUnit );
     264                assertTopLvalue( translationUnit );
     265
    260266                // add the assignment statement after the initialization of a type parameter
    261267                PASS( "Validate", SymTab::validate( translationUnit, symtabp ) );
     
    276282                } // if
    277283
     284                assertTopLvalue( translationUnit );
    278285                PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) );
     286                assertTopLvalue( translationUnit );
    279287                PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );
     288                assertTopLvalue( translationUnit );
    280289                PASS( "Gen Init", InitTweak::genInit( translationUnit ) );
     290                assertTopLvalue( translationUnit );
    281291                PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) );
     292                assertTopLvalue( translationUnit );
    282293                if ( libcfap ) {
    283294                        // generate the bodies of cfa library functions
     
    309320                        translationUnit = convert( move( transUnit ) );
    310321                }
     322
    311323                if ( exprp ) {
    312324                        dump( translationUnit );
    313325                        return EXIT_SUCCESS;
    314326                } // if
     327
     328                clearInnerLvalue( translationUnit );
     329                assertTopLvalue( translationUnit );
    315330
    316331                // fix ObjectDecl - replaces ConstructorInit nodes
    317332                PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) );
     333                clearInnerLvalue( translationUnit );
     334                assertTopLvalue( translationUnit );
    318335                if ( ctorinitp ) {
    319336                        dump ( translationUnit );
     
    322339
    323340                PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
     341                assertTopLvalue( translationUnit );
    324342
    325343                PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) );
     344                assertTopLvalue( translationUnit );
    326345
    327346                PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
     347                clearInnerLvalue( translationUnit );
     348                assertTopLvalue( translationUnit );
    328349
    329350                PASS( "Convert Specializations",  GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded
     351                clearInnerLvalue( translationUnit );
     352                assertTopLvalue( translationUnit );
    330353
    331354                PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?
     355                assertTopLvalue( translationUnit );
    332356
    333357                if ( tuplep ) {
     
    337361
    338362                PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
     363                assertTopLvalue( translationUnit );
    339364
    340365                PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) );
     
    343368                        return EXIT_SUCCESS;
    344369                } // if
     370                clearInnerLvalue( translationUnit );
     371                assertTopLvalue( translationUnit );
    345372                PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );
    346 
     373                clearInnerLvalue( translationUnit );
     374                assertTopLvalue( translationUnit );
    347375
    348376                if ( bboxp ) {
     
    351379                } // if
    352380                PASS( "Box", GenPoly::box( translationUnit ) );
     381                clearInnerLvalue( translationUnit );
     382                assertTopLvalue( translationUnit );
    353383
    354384                if ( bcodegenp ) {
     
    362392
    363393                CodeTools::fillLocations( translationUnit );
     394                assertTopLvalue( translationUnit );
    364395                PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) );
    365396
     
    412443
    413444
    414 static const char optstring[] = ":hlLmNnpP:S:twW:D:F:";
     445static const char optstring[] = ":hlLmNnpP:S:twW:D:";
    415446
    416447enum { PreludeDir = 128 };
     
    427458        { "statistics", required_argument, nullptr, 'S' },
    428459        { "tree", no_argument, nullptr, 't' },
     460        { "gdb", no_argument, nullptr, 'g' },
    429461        { "", no_argument, nullptr, 0 },                                        // -w
    430462        { "", no_argument, nullptr, 0 },                                        // -W
    431463        { "", no_argument, nullptr, 0 },                                        // -D
    432         { "", no_argument, nullptr, 0 },                                        // -F
    433464        { nullptr, 0, nullptr, 0 }
    434465}; // long_opts
     
    445476        "<directory> prelude directory for debug/nodebug",      // no flag
    446477        "<option-list> enable profiling information:\n          counters,heap,time,all,none", // -S
    447         "build in tree",                                                                        // -t
     478        "building cfa standard lib",                                                                    // -t
     479        "wait for gdb to attach",                                                                       // -g
    448480        "",                                                                                                     // -w
    449481        "",                                                                                                     // -W
    450482        "",                                                                                                     // -D
    451         "",                                                                                                     // -F
    452483}; // description
    453484
     
    484515
    485516static void usage( char *argv[] ) {
    486     cout << "Usage: " << argv[0] << " options are:" << endl;
     517    cout << "Usage: " << argv[0] << " [options] [input-file (default stdin)] [output-file (default stdout)], where options are:" << endl;
    487518        int i = 0, j = 1;                                                                       // j skips starting colon
    488519        for ( ; long_opts[i].name != 0 && optstring[j] != '\0'; i += 1, j += 1 ) {
     
    510541} // usage
    511542
    512 static void parse_cmdline( int argc, char * argv[], const char *& filename ) {
     543static void parse_cmdline( int argc, char * argv[] ) {
    513544        opterr = 0;                                                                                     // (global) prevent getopt from printing error messages
    514545
     
    556587                        Stats::parse_params( optarg );
    557588                        break;
    558                   case 't':                                                                             // build in tree
     589                  case 't':                                                                             // building cfa stdlib
    559590                        treep = true;
     591                        break;
     592                  case 'g':                                                                             // wait for gdb
     593                        waiting_for_gdb = true;
    560594                        break;
    561595                  case 'w':                                                                             // suppress all warnings, hidden
     
    581615                  case 'D':                                                                             // ignore -Dxxx, forwarded by cpp, hidden
    582616                        break;
    583                   case 'F':                                                                             // source file-name without suffix, hidden
    584                         filename = optarg;
    585                         break;
    586617                  case '?':                                                                             // unknown option
    587618                        if ( optopt ) {                                                         // short option ?
  • tests/.expect/gccExtensions.x64.txt

    r8e1467d r4a60488  
    291291    signed int _X2m2A0A0i_2[((unsigned long int )10)][((unsigned long int )10)];
    292292    signed int _X2m3A0A0i_2[((unsigned long int )10)][((unsigned long int )10)];
    293     {
    294         ((void)(_X12_retval_maini_1=0) /* ?{} */);
    295     }
    296 
    297     return _X12_retval_maini_1;
     293    void _X4f128Fv_n__2(__int128 _X1in_2);
     294    void _X4f128Fv_o__2(unsigned __int128 __anonymous_object0);
     295    __int128 _X6i128_0n_2;
     296    {
     297        ((void)_X4f128Fv_n__2(_X6i128_0n_2));
     298    }
     299
     300    unsigned __int128 _X6i128_1o_2;
     301    {
     302        ((void)_X4f128Fv_o__2(_X6i128_1o_2));
     303    }
     304
     305    __int128 _X6i128_2n_2;
     306    {
     307        ((void)_X4f128Fv_n__2(_X6i128_2n_2));
     308    }
     309
     310    unsigned __int128 _X6i128_3o_2;
     311    {
     312        ((void)_X4f128Fv_o__2(_X6i128_3o_2));
     313    }
     314
    298315    {
    299316        ((void)(_X12_retval_maini_1=0) /* ?{} */);
  • tests/.expect/gccExtensions.x86.txt

    r8e1467d r4a60488  
    296296
    297297    return _X12_retval_maini_1;
    298     {
    299         ((void)(_X12_retval_maini_1=0) /* ?{} */);
    300     }
    301 
    302     return _X12_retval_maini_1;
    303298}
    304299static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return _X4mainFi_iPPKc__1((signed int )argc, (const char **)argv); }
  • tests/Makefile.am

    r8e1467d r4a60488  
    2222debug=yes
    2323installed=no
     24archiveerrors=
    2425
    25 INSTALL_FLAGS=-in-tree
    2626DEBUG_FLAGS=-debug -O0
    2727
     
    3434
    3535# applies to both programs
     36# since automake doesn't have support for CFA we have to
    3637AM_CFLAGS = $(if $(test), 2> $(test), ) \
    3738        -g \
     
    4142        -DIN_DIR="${abs_srcdir}/.in/"
    4243
    43 AM_CFLAGS += ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
    44 CC = @CFACC@
     44# get the desired cfa to test
     45TARGET_CFA = $(if $(filter $(installed),yes), @CFACC_INSTALL@, @CFACC@)
     46
     47# adjust CC to current flags
     48CC = $(if $(ifeq $(DISTCC_CFA_PATH),yes),distcc $(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
     49CFACC = $(CC)
     50
     51# get local binary for depedencies
     52CFACCBIN = @CFACC@
     53
     54# adjusted CC but without the actual distcc call
     55CFACCLOCAL = $(if $(DISTCC_CFA_PATH),$(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
    4556
    4657PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
     
    5667#----------------------------------------------------------------------------------------------------------------
    5768all-local :
    58         @+${TEST_PY} --debug=${debug}  --install=${installed} ${concurrent} ${timeouts} ${quick_test}
     69        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} ${quick_test}
    5970
    6071all-tests :
    61         @+${TEST_PY} --debug=${debug}  --install=${installed} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
     72        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
    6273
    6374clean-local :
     
    8697
    8798# Use for all tests, make sure the path are correct and all flags are added
    88 CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g'))
    89 
    90 # Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail
    91 CFATEST_STDOUT=$(CFACOMPILETEST) -o $(abspath ${@})
    92 
    93 # Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr
    94 CFATEST_STDERR=$(CFACOMPILETEST) 2> $(abspath ${@})
     99CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g'))
    95100
    96101#----------------------------------------------------------------------------------------------------------------
    97102
    98103# implicit rule so not all test require a rule
    99 % : %.cfa $(CFACC)
    100         $(CFATEST_STDOUT)
     104# split into two steps to support compiling remotely using distcc
     105# don't use distcc to do the linking because distcc doesn't do linking
     106% : %.cfa $(CFACCBIN)
     107        $(CFACOMPILETEST) -c -o $(abspath ${@}).o
     108        $(CFACCLOCAL) $($(shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g')) $(abspath ${@}).o -o $(abspath ${@})
    101109
     110# implicit rule for c++ test
     111# convient for testing the testsuite itself but not actuall used
    102112% : %.cpp
    103113        $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
    104114
    105115#------------------------------------------------------------------------------
    106 # TARGET WITH STANDARD RULE BUT CUSTOM FLAGS
     116# TARGETS WITH CUSTOM FLAGS
    107117#------------------------------------------------------------------------------
    108 # Expected failures
    109 declarationSpecifier_FLAGS= -CFA -XCFA -p
    110 gccExtensions_FLAGS= -CFA -XCFA -p
    111 extension_FLAGS= -CFA -XCFA -p
    112 attributes_FLAGS= -CFA -XCFA -p
    113 functions_FLAGS= -CFA -XCFA -p
    114 KRfunctions_FLAGS= -CFA -XCFA -p
    115 gmp_FLAGS= -lgmp
     118# custom libs
     119gmp_FLAGSLD= -lgmp
    116120
    117121#------------------------------------------------------------------------------
    118 # Expected failures
    119 completeTypeError_FLAGS= -DERR1
     122# Generated code
     123GENERATED_CODE = declarationSpecifier gccExtensions extension attributes functions KRfunctions
     124$(GENERATED_CODE): % : %.cfa $(CFACCBIN)
     125        $(CFACOMPILETEST) -CFA -XCFA -p -c -fsyntax-only -o $(abspath ${@})
     126
     127# Use for tests where the make command is expected to succeed but the expected.txt should be compared to stderr
     128EXPECT_STDERR = builtins/sync warnings/self-assignment
     129$(EXPECT_STDERR): % : %.cfa $(CFACCBIN)
     130        $(CFACOMPILETEST) -c -fsyntax-only 2> $(abspath ${@})
    120131
    121132#------------------------------------------------------------------------------
    122133# CUSTOM TARGET
    123134#------------------------------------------------------------------------------
    124 typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
    125         $(CFATEST_STDOUT) -DERR1
     135# expected failures
     136# use custom target since they require a custom define and custom dependencies
     137alloc-ERROR : alloc.cfa $(CFACCBIN)
     138        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    126139
    127 alloc-ERROR: alloc.cfa $(CFACC)
    128         $(CFATEST_STDOUT) -DERR1
     140typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN)
     141        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    129142
    130 nested-types-ERR1: nested-types.cfa $(CFACC)
    131         $(CFATEST_STDOUT) -DERR1
     143nested-types-ERR1 : nested-types.cfa $(CFACCBIN)
     144        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    132145
    133 nested-types-ERR2: nested-types.cfa $(CFACC)
    134         $(CFATEST_STDOUT) -DERR2
     146nested-types-ERR2 : nested-types.cfa $(CFACCBIN)
     147        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
    135148
    136 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
    137         $(CFATEST_STDOUT) -DERR1
     149raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN)
     150        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    138151
    139 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
    140         $(CFATEST_STDOUT) -DERR2
     152raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN)
     153        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    141154
    142 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
    143         $(CFATEST_STDOUT) -DERR1
     155raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN)
     156        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
    144157
    145 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
    146         $(CFATEST_STDOUT) -DERR1
     158raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN)
     159        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
    147160
    148 #builtins
    149 builtins/sync: builtins/sync.cfa $(CFACC)
    150         $(CFATEST_STDERR) -fsyntax-only
    151 
    152 # Warnings
    153 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
    154         $(CFATEST_STDERR) -fsyntax-only
     161#------------------------------------------------------------------------------
     162# Other targets
  • tests/Makefile.in

    r8e1467d r4a60488  
    212212AWK = @AWK@
    213213BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@
    214 CC = @CFACC@
     214
     215# adjust CC to current flags
     216CC = $(if $(ifeq $(DISTCC_CFA_PATH),yes),distcc $(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
    215217CCAS = @CCAS@
    216218CCASDEPMODE = @CCASDEPMODE@
    217219CCASFLAGS = @CCASFLAGS@
    218220CCDEPMODE = @CCDEPMODE@
    219 CFACC = @CFACC@
     221CFACC = $(CC)
     222CFACC_INSTALL = @CFACC_INSTALL@
    220223CFACPP = @CFACPP@
    221224CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    235238CYGPATH_W = @CYGPATH_W@
    236239DEFS = @DEFS@
     240DEMANGLER = @DEMANGLER@
    237241DEPDIR = @DEPDIR@
    238242DLLTOOL = @DLLTOOL@
     
    247251FGREP = @FGREP@
    248252GREP = @GREP@
     253HAS_DISTCC = @HAS_DISTCC@
    249254HOST_FLAGS = @HOST_FLAGS@
    250255INSTALL = @INSTALL@
     
    260265LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    261266LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     267LIBDEMANGLE = @LIBDEMANGLE@
    262268LIBOBJS = @LIBOBJS@
    263269LIBS = @LIBS@
     
    375381debug = yes
    376382installed = no
    377 INSTALL_FLAGS = -in-tree
     383archiveerrors =
    378384DEBUG_FLAGS = -debug -O0
    379385quick_test = avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes
     
    383389
    384390# applies to both programs
    385 AM_CFLAGS = $(if $(test), 2> $(test), ) -g -Wall -Wno-unused-function \
    386         -quiet @CFA_FLAGS@ -DIN_DIR="${abs_srcdir}/.in/" \
    387         ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
     391# since automake doesn't have support for CFA we have to
     392AM_CFLAGS = $(if $(test), 2> $(test), ) \
     393        -g \
     394        -Wall \
     395        -Wno-unused-function \
     396        -quiet @CFA_FLAGS@ \
     397        -DIN_DIR="${abs_srcdir}/.in/"
     398
     399
     400# get the desired cfa to test
     401TARGET_CFA = $(if $(filter $(installed),yes), @CFACC_INSTALL@, @CFACC@)
     402
     403# get local binary for depedencies
     404CFACCBIN = @CFACC@
     405
     406# adjusted CC but without the actual distcc call
     407CFACCLOCAL = $(if $(DISTCC_CFA_PATH),$(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})
    388408PRETTY_PATH = mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
    389409avl_test_SOURCES = avltree/avl_test.cfa avltree/avl0.cfa avltree/avl1.cfa avltree/avl2.cfa avltree/avl3.cfa avltree/avl4.cfa avltree/avl-private.cfa
     
    394414
    395415# Use for all tests, make sure the path are correct and all flags are added
    396 CFACOMPILETEST = $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g'))
    397 
    398 # Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail
    399 CFATEST_STDOUT = $(CFACOMPILETEST) -o $(abspath ${@})
    400 
    401 # Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr
    402 CFATEST_STDERR = $(CFACOMPILETEST) 2> $(abspath ${@})
     416CFACOMPILETEST = $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g'))
    403417
    404418#------------------------------------------------------------------------------
    405 # TARGET WITH STANDARD RULE BUT CUSTOM FLAGS
     419# TARGETS WITH CUSTOM FLAGS
    406420#------------------------------------------------------------------------------
    407 # Expected failures
    408 declarationSpecifier_FLAGS = -CFA -XCFA -p
    409 gccExtensions_FLAGS = -CFA -XCFA -p
    410 extension_FLAGS = -CFA -XCFA -p
    411 attributes_FLAGS = -CFA -XCFA -p
    412 functions_FLAGS = -CFA -XCFA -p
    413 KRfunctions_FLAGS = -CFA -XCFA -p
    414 gmp_FLAGS = -lgmp
     421# custom libs
     422gmp_FLAGSLD = -lgmp
    415423
    416424#------------------------------------------------------------------------------
    417 # Expected failures
    418 completeTypeError_FLAGS = -DERR1
     425# Generated code
     426GENERATED_CODE = declarationSpecifier gccExtensions extension attributes functions KRfunctions
     427
     428# Use for tests where the make command is expected to succeed but the expected.txt should be compared to stderr
     429EXPECT_STDERR = builtins/sync warnings/self-assignment
    419430all: all-am
    420431
     
    768779#----------------------------------------------------------------------------------------------------------------
    769780all-local :
    770         @+${TEST_PY} --debug=${debug}  --install=${installed} ${concurrent} ${timeouts} ${quick_test}
     781        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} ${quick_test}
    771782
    772783all-tests :
    773         @+${TEST_PY} --debug=${debug}  --install=${installed} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
     784        @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
    774785
    775786clean-local :
     
    798809
    799810# implicit rule so not all test require a rule
    800 % : %.cfa $(CFACC)
    801         $(CFATEST_STDOUT)
    802 
     811# split into two steps to support compiling remotely using distcc
     812# don't use distcc to do the linking because distcc doesn't do linking
     813% : %.cfa $(CFACCBIN)
     814        $(CFACOMPILETEST) -c -o $(abspath ${@}).o
     815        $(CFACCLOCAL) $($(shell echo "${@}_FLAGSLD" | sed 's/-\|\//_/g')) $(abspath ${@}).o -o $(abspath ${@})
     816
     817# implicit rule for c++ test
     818# convient for testing the testsuite itself but not actuall used
    803819% : %.cpp
    804820        $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     821$(GENERATED_CODE): % : %.cfa $(CFACCBIN)
     822        $(CFACOMPILETEST) -CFA -XCFA -p -c -fsyntax-only -o $(abspath ${@})
     823$(EXPECT_STDERR): % : %.cfa $(CFACCBIN)
     824        $(CFACOMPILETEST) -c -fsyntax-only 2> $(abspath ${@})
    805825
    806826#------------------------------------------------------------------------------
    807827# CUSTOM TARGET
    808828#------------------------------------------------------------------------------
    809 typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
    810         $(CFATEST_STDOUT) -DERR1
    811 
    812 alloc-ERROR: alloc.cfa $(CFACC)
    813         $(CFATEST_STDOUT) -DERR1
    814 
    815 nested-types-ERR1: nested-types.cfa $(CFACC)
    816         $(CFATEST_STDOUT) -DERR1
    817 
    818 nested-types-ERR2: nested-types.cfa $(CFACC)
    819         $(CFATEST_STDOUT) -DERR2
    820 
    821 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
    822         $(CFATEST_STDOUT) -DERR1
    823 
    824 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
    825         $(CFATEST_STDOUT) -DERR2
    826 
    827 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
    828         $(CFATEST_STDOUT) -DERR1
    829 
    830 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
    831         $(CFATEST_STDOUT) -DERR1
    832 
    833 #builtins
    834 builtins/sync: builtins/sync.cfa $(CFACC)
    835         $(CFATEST_STDERR) -fsyntax-only
    836 
    837 # Warnings
    838 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
    839         $(CFATEST_STDERR) -fsyntax-only
     829# expected failures
     830# use custom target since they require a custom define and custom dependencies
     831alloc-ERROR : alloc.cfa $(CFACCBIN)
     832        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     833
     834typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN)
     835        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     836
     837nested-types-ERR1 : nested-types.cfa $(CFACCBIN)
     838        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     839
     840nested-types-ERR2 : nested-types.cfa $(CFACCBIN)
     841        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
     842
     843raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN)
     844        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     845
     846raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN)
     847        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     848
     849raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN)
     850        $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@})
     851
     852raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN)
     853        $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@})
     854
     855#------------------------------------------------------------------------------
     856# Other targets
    840857
    841858# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • tests/config.py.in

    r8e1467d r4a60488  
    88BUILDDIR = "@abs_builddir@"
    99HOSTARCH = "@host_cpu@"
     10DISTRIBUTE = @HAS_DISTCC@
  • tests/gccExtensions.cfa

    r8e1467d r4a60488  
    1010// Created On       : Sun Aug 14 17:28:17 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Nov  6 17:54:20 2018
    13 // Update Count     : 11
     12// Last Modified On : Mon Aug  5 18:04:37 2019
     13// Update Count     : 28
    1414//
    1515
     
    5050
    5151  L1: L2:
    52         asm goto ( "frob %%r5, %1; jc %l[L1]; mov (%2), %%r5"
    53                            : /* No outputs. */
    54                            : "r"(src), "r"(&dst)
    55                            : "r5", "memory"
    56                            : L1, L2 );
     52        asm goto ( "frob %%r5, %1; jc %l[L1]; mov (%2), %%r5"
     53                           : /* No outputs. */
     54                           : "r"(src), "r"(&dst)
     55                           : "r5", "memory"
     56                           : L1, L2 );
    5757
    5858        // alternative type/qualifer names
     
    110110        struct __attribute(()) s4 { int i; } x2, y2 __attribute(());
    111111
    112         int m1 [10] __attribute(());
    113         int m2 [10][10] __attribute(());
     112        int m1[10] __attribute(());
     113        int m2[10][10] __attribute(());
    114114        int __attribute(()) m3 [10][10];
    115115//      int ( __attribute(()) m4 [10] )[10];
    116116
    117         return 0;
     117        // int128
     118
     119#if defined( __SIZEOF_INT128__ )
     120        void f128( __int128 i );
     121        void f128( __uint128_t );
     122
     123        __int128 i128_0;
     124        f128( i128_0 );
     125        unsigned __int128 i128_1;
     126        f128( i128_1 );
     127        __int128_t i128_2;
     128        f128( i128_2 );
     129        __uint128_t i128_3;
     130        f128( i128_3 );
     131#endif
    118132}
    119133
  • tests/pybin/settings.py

    r8e1467d r4a60488  
    44from . import tools
    55
     6global original_path
     7
    68try :
     9        original_path = os.getcwd()
    710        testpath = os.path.dirname(os.path.abspath(os.path.join(os.getcwd(), sys.argv[0])))
    811        sys.path.append(testpath)
     
    1114        SRCDIR = os.path.abspath(config.SRCDIR)
    1215        BUILDDIR = os.path.abspath(config.BUILDDIR)
     16        distribute = config.DISTRIBUTE
    1317        os.chdir(testpath)
    1418
     
    1923class Architecture:
    2024        KnownArchitectures = {
    21                 'x64'                   : 'x64',
    22                 'x86-64'                : 'x64',
    23                 'x86_64'                : 'x64',
    24                 'x86'                   : 'x86',
     25                'x64'           : 'x64',
     26                'x86-64'        : 'x64',
     27                'x86_64'        : 'x64',
     28                'x86'           : 'x86',
     29                'aarch64'       : 'arm',
    2530                'i386'          : 'x86',
    2631                'i486'          : 'x86',
    2732                'i686'          : 'x86',
    2833                'Intel 80386'   : 'x86',
    29                 'arm'                   : 'arm',
    30                 'ARM'                   : 'arm',
     34                'arm'           : 'arm',
     35                'ARM'           : 'arm',
    3136        }
    3237
     
    4045                        canonical_host = Architecture.make_canonical( config.HOSTARCH )
    4146                except KeyError:
    42                         print("Unkown host architecture %s" % config.HOSTARCH, file=sys.stderr)
     47                        print("Unknown host architecture %s" % config.HOSTARCH, file=sys.stderr)
    4348                        sys.exit(1)
    4449
     
    4752                                arch = Architecture.make_canonical( arch )
    4853                        except KeyError:
    49                                 print("Unkown architecture %s" % arch, file=sys.stderr)
     54                                print("Unknown architecture %s" % arch, file=sys.stderr)
    5055                                sys.exit(1)
    5156
     
    8489                self.string = "debug" if value else "no debug"
    8590                self.flags  = """DEBUG_FLAGS=%s""" % ("-debug -O0" if value else "-nodebug -O2")
     91                self.path   = "debug" if value else "nodebug"
    8692
    8793class Install:
    8894        def __init__(self, value):
    89                 self.string = "installed" if value else "in-tree"
    90                 self.flags  = """INSTALL_FLAGS=%s""" % ("" if value else "-in-tree")
     95                if value:
     96                        distribute = False
     97
     98                self.string = "installed" if value else "in tree"
     99                self.flags  = """installed=%s""" % ("yes" if value else "no")
    91100
    92101class Timeouts:
     
    105114def init( options ):
    106115        global arch
     116        global archive
     117        global debug
     118        global distcc
    107119        global dry_run
    108120        global generating
     121        global install
    109122        global make
    110         global debug
    111         global install
     123        global output_width
    112124        global timeout
    113         global output_width
    114125
    115         dry_run      = options.dry_run
     126        arch         = Architecture(options.arch)
     127        archive      = os.path.abspath(os.path.join(original_path, options.archive_errors)) if options.archive_errors else None
     128        debug        = Debug(options.debug)
     129        dry_run      = options.dry_run # must be called before tools.config_hash()
     130        distcc       = "DISTCC_CFA_PATH=~/.cfadistcc/%s/cfa" % tools.config_hash()
    116131        generating   = options.regenerate_expected
     132        install      = Install(options.install)
    117133        make         = ['make']
    118         debug        = Debug(options.debug)
    119         install      = Install(options.install)
    120         arch         = Architecture(options.arch)
     134        output_width = 24
    121135        timeout      = Timeouts(options.timeout, options.global_timeout)
    122         output_width = 24
    123136
     137        # if we distribute, distcc errors will fail tests, use log file for distcc
     138        # don't use "'DISTCC_LOG' not in os.environ" because it can be set to ''
     139        if distribute and not os.environ.get('DISTCC_LOG'):
     140                os.putenv('DISTCC_LOG', os.path.join(BUILDDIR, 'distcc_error.log'))
    124141
    125142def update_make_cmd(force, jobs):
     
    130147def validate():
    131148        errf = os.path.join(BUILDDIR, ".validate.err")
    132         make_ret, out = tools.make( ".validate", error_file = errf, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
     149        make_ret, out = tools.make( ".validate", error_file = errf, output_file=subprocess.DEVNULL, error=subprocess.DEVNULL )
    133150        if make_ret != 0:
    134151                with open (errf, "r") as myfile:
  • tests/pybin/tools.py

    r8e1467d r4a60488  
    22import argparse
    33import contextlib
     4import datetime
    45import fileinput
    56import multiprocessing
     
    2223
    2324# helper functions to run terminal commands
    24 def sh(*cmd, timeout = False, output = None, input = None, error = subprocess.STDOUT):
     25def sh(*cmd, timeout = False, output_file = None, input_file = None, input_text = None, error = subprocess.STDOUT, ignore_dry_run = False):
    2526        cmd = list(cmd)
    2627
     28        if input_file and input_text:
     29                return 401, "Cannot use both text and file inputs"
     30
    2731        # if this is a dry_run, only print the commands that would be ran
    28         if settings.dry_run :
     32        if settings.dry_run and not ignore_dry_run:
    2933                cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd))
    30                 if output and not isinstance(output, int):
     34                if output_file and not isinstance(output_file, int):
    3135                        cmd += " > "
    32                         cmd += output
     36                        cmd += output_file
    3337
    3438                if error and not isinstance(error, int):
     
    3640                        cmd += error
    3741
    38                 if input and not isinstance(input, int) and os.path.isfile(input):
     42                if input_file and not isinstance(input_file, int) and os.path.isfile(input_file):
    3943                        cmd += " < "
    40                         cmd += input
     44                        cmd += input_file
    4145
    4246                print(cmd)
     
    4549        with contextlib.ExitStack() as onexit:
    4650                # add input redirection if needed
    47                 input = openfd(input, 'r', onexit, True)
     51                input_file = openfd(input_file, 'r', onexit, True)
    4852
    4953                # add output redirection if needed
    50                 output = openfd(output, 'w', onexit, False)
     54                output_file = openfd(output_file, 'w', onexit, False)
    5155
    5256                # add error redirection if needed
     
    5761                        proc = subprocess.run(
    5862                                cmd,
    59                                 stdin =input,
    60                                 stdout=output,
    61                                 stderr=error,
    62                                 timeout=settings.timeout.single if timeout else None
     63                                **({'input' : bytes(input_text, encoding='utf-8')} if input_text else {'stdin' : input_file}),
     64                                stdout  = output_file,
     65                                stderr  = error,
     66                                timeout = settings.timeout.single if timeout else None
    6367                        )
     68
    6469                        return proc.returncode, proc.stdout.decode("utf-8") if proc.stdout else None
    6570                except subprocess.TimeoutExpired:
     
    7479                return False
    7580
    76         code, out = sh("file %s" % fname, output=subprocess.PIPE)
     81        code, out = sh("file %s" % fname, output_file=subprocess.PIPE)
    7782        if code != 0:
    7883                return False
     
    106111        if isinstance(files, str ): files = [ files ]
    107112        for file in files:
    108                 sh( 'rm', '-f', file, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
     113                sh( 'rm', '-f', file, output_file=subprocess.DEVNULL, error=subprocess.DEVNULL )
    109114
    110115# Create 1 or more directory
     
    114119                p = os.path.normpath( file )
    115120                d = os.path.dirname ( p )
    116                 sh( 'mkdir', '-p', d, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
     121                sh( 'mkdir', '-p', d, output_file=subprocess.DEVNULL, error=subprocess.DEVNULL )
    117122
    118123
     
    137142                lhs,
    138143                rhs,
    139                 output=subprocess.PIPE
     144                output_file=subprocess.PIPE
    140145        )
    141146
    142147# call make
    143 def make(target, *, flags = '', output = None, error = None, error_file = None, silent = False):
     148def make(target, *, flags = '', output_file = None, error = None, error_file = None, silent = False):
    144149        test_param = """test="%s" """ % (error_file) if error_file else None
    145150        cmd = [
     
    150155                settings.debug.flags,
    151156                settings.install.flags,
     157                settings.distcc if settings.distribute else None,
    152158                flags,
    153159                target
    154160        ]
    155161        cmd = [s for s in cmd if s]
    156         return sh(*cmd, output=output, error=error)
     162        return sh(*cmd, output_file=output_file, error=error)
    157163
    158164def which(program):
     
    200206# cat one file into the other
    201207def cat(source, dest):
    202         ret, _ = sh("cat", source, output=dest)
     208        ret, _ = sh("cat", source, output_file=dest)
    203209        return ret
    204210
     
    255261                        os.write(int(make_jobs_fds.group(3)), tokens)
    256262                else :
    257                         options.jobs = multiprocessing.cpu_count()
     263                        if settings.distribute:
     264                                ret, jstr = sh("distcc", "-j", output_file=subprocess.PIPE, ignore_dry_run=True)
     265                                if ret == 0:
     266                                        options.jobs = int(jstr.strip())
     267                                else :
     268                                        options.jobs = multiprocessing.cpu_count()
     269                        else:
     270                                options.jobs = multiprocessing.cpu_count()
    258271        else :
    259272                force = True
     
    272285#               misc
    273286################################################################################
     287
     288# get hash for given configuration
     289def config_hash():
     290        path = os.path.normpath(os.path.join(
     291                settings.SRCDIR,
     292        ))
     293
     294        distcc_hash = os.path.join(settings.SRCDIR, '../tools/build/distcc_hash')
     295        config = "%s-%s" % (settings.arch.target, settings.debug.path)
     296        _, out = sh(distcc_hash, config, output_file=subprocess.PIPE, ignore_dry_run=True)
     297        return out.strip()
     298
     299# get pretty string for time of day
     300def pretty_now():
     301        ts = time.time()
     302        print(ts, file=sys.stderr)
     303        return datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H:%M:%S')
    274304
    275305# check if arguments is yes or no
     
    302332                return 1, "ERR No core dump"
    303333
    304         return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output=subprocess.PIPE)
     334        return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output_file=subprocess.PIPE)
     335
     336def core_archive(dst, name, exe):
     337        # Get the core dump
     338        core = os.path.join(os.getcwd(), "core" )
     339
     340        # update the path for this test
     341        dst  = os.path.join(dst, name)
     342
     343        # make a directory for this test
     344        # mkdir makes the parent directory only so add a dummy
     345        mkdir(os.path.join(dst, "dir"))
     346
     347        # moves the files
     348        mv( core, os.path.join(dst, "core" ) )
     349        mv( exe , os.path.join(dst, name   ) )
     350
     351        # return explanatory test
     352        return "Archiving %s (executable and core) to %s" % (os.path.relpath(exe, settings.BUILDDIR), os.path.relpath(dst, settings.original_path))
    305353
    306354class Timed:
  • tests/test.py

    r8e1467d r4a60488  
    9191        parser.add_argument('--all', help='Run all test available', action='store_true')
    9292        parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true')
     93        parser.add_argument('--archive-errors', help='If called with a valid path, on test crashes the test script will copy the core dump and the executable to the specified path.', type=str, default='')
    9394        parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int)
    9495        parser.add_argument('--list-comp', help='List all valide arguments', action='store_true')
     
    142143        # build, skipping to next test on error
    143144        with Timed() as comp_dur:
    144                 make_ret, _ = make( test.target(), output=subprocess.DEVNULL, error=out_file, error_file = err_file )
     145                make_ret, _ = make( test.target(), output_file=subprocess.DEVNULL, error=out_file, error_file = err_file )
    145146
    146147        run_dur = None
     
    152153                                if settings.dry_run or is_exe(exe_file):
    153154                                        # run test
    154                                         retcode, _ = sh(exe_file, output=out_file, input=in_file, timeout=True)
     155                                        retcode, _ = sh(exe_file, output_file=out_file, input_file=in_file, timeout=True)
    155156                                else :
    156157                                        # simply cat the result into the output
     
    179180                        error = error + info if error else info
    180181
     182                        if settings.archive:
     183                                error = error + '\n' + core_archive(settings.archive, test.target(), exe_file)
     184
    181185
    182186
     
    215219def run_tests(tests, jobs) :
    216220        # clean the sandbox from previous commands
    217         make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL)
     221        make('clean', output_file=subprocess.DEVNULL, error=subprocess.DEVNULL)
    218222
    219223        # create the executor for our jobs and handle the signal properly
     
    256260
    257261        # clean the workspace
    258         make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL)
     262        make('clean', output_file=subprocess.DEVNULL, error=subprocess.DEVNULL)
    259263
    260264        return 1 if failed else 0
     
    295299        # users may want to simply list the tests
    296300        if options.list_comp :
    297                 print("-h --help --debug --dry-run --list --arch --all --regenerate-expected --install --timeout --global-timeout -j --jobs ", end='')
     301                print("-h --help --debug --dry-run --list --arch --all --regenerate-expected --archive-errors --install --timeout --global-timeout -j --jobs ", end='')
    298302                print(" ".join(map(lambda t: "%s" % (t.target()), tests)))
    299303
  • tools/Makefile.in

    r8e1467d r4a60488  
    208208CCDEPMODE = @CCDEPMODE@
    209209CFACC = @CFACC@
     210CFACC_INSTALL = @CFACC_INSTALL@
    210211CFACPP = @CFACPP@
    211212CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    225226CYGPATH_W = @CYGPATH_W@
    226227DEFS = @DEFS@
     228DEMANGLER = @DEMANGLER@
    227229DEPDIR = @DEPDIR@
    228230DLLTOOL = @DLLTOOL@
     
    237239FGREP = @FGREP@
    238240GREP = @GREP@
     241HAS_DISTCC = @HAS_DISTCC@
    239242HOST_FLAGS = @HOST_FLAGS@
    240243INSTALL = @INSTALL@
     
    250253LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    251254LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     255LIBDEMANGLE = @LIBDEMANGLE@
    252256LIBOBJS = @LIBOBJS@
    253257LIBS = @LIBS@
  • tools/prettyprinter/Makefile.in

    r8e1467d r4a60488  
    237237CCDEPMODE = @CCDEPMODE@
    238238CFACC = @CFACC@
     239CFACC_INSTALL = @CFACC_INSTALL@
    239240CFACPP = @CFACPP@
    240241CFA_BACKEND_CC = @CFA_BACKEND_CC@
     
    254255CYGPATH_W = @CYGPATH_W@
    255256DEFS = @DEFS@
     257DEMANGLER = @DEMANGLER@
    256258DEPDIR = @DEPDIR@
    257259DLLTOOL = @DLLTOOL@
     
    266268FGREP = @FGREP@
    267269GREP = @GREP@
     270HAS_DISTCC = @HAS_DISTCC@
    268271HOST_FLAGS = @HOST_FLAGS@
    269272INSTALL = @INSTALL@
     
    279282LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
    280283LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     284LIBDEMANGLE = @LIBDEMANGLE@
    281285LIBOBJS = @LIBOBJS@
    282286LIBS = @LIBS@
Note: See TracChangeset for help on using the changeset viewer.