Changeset 4a60488
- Timestamp:
- Sep 27, 2019, 3:35:46 PM (6 years ago)
- 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. - Files:
-
- 15 added
- 1 deleted
- 83 edited
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r8e1467d r4a60488 21 21 .deps 22 22 .dirstamp 23 bin24 lib25 include26 share27 build23 /bin 24 /lib 25 /include 26 /share 27 /build 28 28 *.class 29 29 -
Jenkins/FullBuild
r8e1467d r4a60488 132 132 133 133 <img src="https://cforall.uwaterloo.ca/jenkins/job/Cforall/job/master/plot/Compilation/getPlot?index=0" > 134 <img src="https://cforall.uwaterloo.ca/jenkins/job/Cforall/job/master/plot/Compilation/getPlot?index=1" > 134 135 135 136 <p>- Logs ----------------------------------------------------------------</p> -
Jenkinsfile_disabled
r8e1467d r4a60488 106 106 107 107 def build() { 108 // build_stage('Build', true) {109 // // Build outside of the src tree to ease cleaning110 // dir (BuildDir) {111 // //Configure the conpilation (Output is not relevant)112 // //Use the current directory as the installation target so nothing escapes the sandbox113 // //Also specify the compiler by hand114 // 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 project124 // sh 'make -j 8 --no-print-directory'125 // }126 // }127 128 108 debug = true 129 109 release = Settings.RunAllTests || Settings.RunBenchmark … … 175 155 176 156 def 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" 178 175 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 190 179 } 191 180 } … … 195 184 dir (BuildDir) { 196 185 //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}" 198 187 } 199 188 } … … 217 206 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' } 218 207 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) 221 210 222 211 //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)') 227 220 } 228 221 } … … 482 475 } 483 476 484 def do_plot(boolean new_data, String file, PlotGroup group, String title) {477 def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) { 485 478 486 479 if(new_data) { … … 505 498 exclZero: false, 506 499 keepRecords: false, 507 logarithmic: group.log,500 logarithmic: !relative && group.log, 508 501 numBuilds: '120', 509 502 useDescr: true, -
Makefile.in
r8e1467d r4a60488 264 264 CCDEPMODE = @CCDEPMODE@ 265 265 CFACC = @CFACC@ 266 CFACC_INSTALL = @CFACC_INSTALL@ 266 267 CFACPP = @CFACPP@ 267 268 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 281 282 CYGPATH_W = @CYGPATH_W@ 282 283 DEFS = @DEFS@ 284 DEMANGLER = @DEMANGLER@ 283 285 DEPDIR = @DEPDIR@ 284 286 DLLTOOL = @DLLTOOL@ … … 293 295 FGREP = @FGREP@ 294 296 GREP = @GREP@ 297 HAS_DISTCC = @HAS_DISTCC@ 295 298 HOST_FLAGS = @HOST_FLAGS@ 296 299 INSTALL = @INSTALL@ … … 306 309 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 307 310 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 311 LIBDEMANGLE = @LIBDEMANGLE@ 308 312 LIBOBJS = @LIBOBJS@ 309 313 LIBS = @LIBS@ -
automake/cfa.m4
r8e1467d r4a60488 66 66 "x86-64" ) cannon_arch_name="x64";; 67 67 "x86_64" ) cannon_arch_name="x64";; 68 "aarch64" ) cannon_arch_name="arm";; 68 69 "x86" ) cannon_arch_name="x86";; 69 70 "i386" ) cannon_arch_name="x86";; … … 75 76 "armv7l" ) cannon_arch_name="arm";; 76 77 *) 77 >&2 echo "Unk own architecture " $arch_name;78 >&2 echo "Unknown architecture " $arch_name; 78 79 exit 1 79 80 ;; -
benchmark/Makefile.am
r8e1467d r4a60488 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Ju n 24 16:45:42201914 ## Update Count : 5 313 ## Last Modified On : Mon Jul 29 18:02:19 2019 14 ## Update Count : 54 15 15 ############################################################################### 16 16 … … 22 22 23 23 AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror 24 AM_CFAFLAGS = -quiet -nodebug -in-tree24 AM_CFAFLAGS = -quiet -nodebug 25 25 AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14 26 26 … … 50 50 REPEAT = ${abs_top_builddir}/tools/repeat 51 51 STATS = ${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 53 repeats = 5 # 31 for benchmarks 54 arch = x64 53 55 skipcompile = no 54 56 TIME_FORMAT = "%E" … … 99 101 @DOifskipcompile@ 100 102 @+make compile.csv 103 @-+make compile.diff.csv 101 104 @DOendif@ 102 105 @+make ctxswitch.csv 106 @-+make ctxswitch.diff.csv 103 107 @+make mutex.csv 108 @-+make mutex.diff.csv 104 109 @+make signal.csv 110 @-+make signal.diff.csv 105 111 @DOifskipcompile@ 106 @cat compile.csv 112 cat compile.csv 113 -cat compile.diff.csv 107 114 @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 111 121 112 122 compile.csv: … … 142 152 @+make waitfor-cfa2.runquiet >> $@ 143 153 @$(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 144 159 145 160 ## ========================================================================================================= -
benchmark/Makefile.in
r8e1467d r4a60488 214 214 CCDEPMODE = @CCDEPMODE@ 215 215 CFACC = @CFACC@ 216 CFACC_INSTALL = @CFACC_INSTALL@ 216 217 CFACPP = @CFACPP@ 217 218 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 231 232 CYGPATH_W = @CYGPATH_W@ 232 233 DEFS = @DEFS@ 234 DEMANGLER = @DEMANGLER@ 233 235 DEPDIR = @DEPDIR@ 234 236 DLLTOOL = @DLLTOOL@ … … 243 245 FGREP = @FGREP@ 244 246 GREP = @GREP@ 247 HAS_DISTCC = @HAS_DISTCC@ 245 248 HOST_FLAGS = @HOST_FLAGS@ 246 249 INSTALL = @INSTALL@ … … 256 259 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 257 260 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 261 LIBDEMANGLE = @LIBDEMANGLE@ 258 262 LIBOBJS = @LIBOBJS@ 259 263 LIBS = @LIBS@ … … 372 376 # applies to both programs 373 377 AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror 374 AM_CFAFLAGS = -quiet -nodebug -in-tree378 AM_CFAFLAGS = -quiet -nodebug 375 379 AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14 376 380 BENCH_V_CC = $(__bench_v_CC_$(__quiet)) … … 396 400 REPEAT = ${abs_top_builddir}/tools/repeat 397 401 STATS = ${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 403 repeats = 5 # 31 for benchmarks 404 arch = x64 399 405 skipcompile = no 400 406 TIME_FORMAT = "%E" … … 761 767 @DOifskipcompile@ 762 768 @+make compile.csv 769 @-+make compile.diff.csv 763 770 @DOendif@ 764 771 @+make ctxswitch.csv 772 @-+make ctxswitch.diff.csv 765 773 @+make mutex.csv 774 @-+make mutex.diff.csv 766 775 @+make signal.csv 776 @-+make signal.diff.csv 767 777 @DOifskipcompile@ 768 @cat compile.csv 778 cat compile.csv 779 -cat compile.diff.csv 769 780 @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 773 787 774 788 compile.csv: … … 805 819 @$(srcdir)/fixcsv.sh $@ 806 820 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 807 825 loop$(EXEEXT): 808 826 $(BENCH_V_CC)$(COMPILE) -DBENCH_N=5000000000 $(srcdir)/loop.c -
benchmark/creation/JavaThread.java
r8e1467d r4a60488 1 1 public 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 2 30 public static class MyThread extends Thread { 3 31 @Override 4 32 public void run() {} 5 33 } 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 { 10 35 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(); 13 39 m.join(); 14 40 } 41 } 42 public static void InnerMain() throws InterruptedException { 43 long start = System.nanoTime(); 44 helper(); 15 45 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); 17 55 } 18 56 } -
benchmark/ctxswitch/JavaThread.java
r8e1467d r4a60488 1 1 public 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() { 5 31 for(int i = 1; i <= NoOfTimes; i += 1) { 6 32 Thread.yield(); 7 33 } 34 } 35 public static void InnerMain() { 36 long start = System.nanoTime(); 37 helper(); 8 38 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); 10 48 } 11 49 } -
benchmark/mutex/JavaThread.java
r8e1467d r4a60488 1 1 public 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 ; 3 8 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 { 6 34 JavaThread j = new JavaThread(); 7 long start = System.nanoTime(); 35 // Inhibit biased locking ... 36 x = (j.hashCode() ^ System.identityHashCode(j)) | 1 ; 8 37 for(int i = 1; i <= NoOfTimes; i += 1) { 38 x = nextRandom(x); 9 39 j.noop(); 10 40 } 41 } 42 public static void InnerMain() throws InterruptedException { 43 long start = System.nanoTime(); 44 helper(); 11 45 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); 13 55 } 14 56 } -
benchmark/schedint/JavaThread.java
r8e1467d r4a60488 1 1 class Monitor { 2 2 public static volatile Boolean go = false; 3 public static volatile Boolean next = false; 3 4 } 4 5 … … 13 14 while( Monitor.go ) { 14 15 synchronized(this.m) { 16 Monitor.next = false; 15 17 this.m.notify(); 16 18 } 19 while( ! Monitor.next && Monitor.go ); // spin until woken 17 20 } 18 21 } … … 20 23 21 24 public 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 { 24 60 Monitor m = new Monitor(); 25 61 long start, end; … … 31 67 } 32 68 start = System.nanoTime(); 33 for(int i = 1; i <= NoOfTimes; i += 1) { 34 m.wait(); 35 } 69 helper( m ); 36 70 end = System.nanoTime(); 37 71 } … … 40 74 System.out.println( (end - start) / NoOfTimes); 41 75 } 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 } 42 84 } -
configure
r8e1467d r4a60488 637 637 LIBOBJS 638 638 CFA_BACKEND_CC 639 DEMANGLER 640 LIBDEMANGLE 639 641 WITH_LIBTCMALLOC_FALSE 640 642 WITH_LIBTCMALLOC_TRUE … … 661 663 ac_ct_DUMPBIN 662 664 DUMPBIN 663 LD664 665 FGREP 665 666 EGREP … … 699 700 LDFLAGS 700 701 CXXFLAGS 701 CXX702 702 CFA_FLAGS 703 703 LIBCFA_TARGET_MAKEFILES … … 715 715 BUILD_IN_TREE_FLAGS 716 716 CFACPP 717 CFACC_INSTALL 717 718 CFACC 718 719 DRIVER_DIR … … 721 722 CFA_INCDIR 722 723 CFA_PREFIX 724 HAS_DISTCC 725 LD 726 CXX 727 ENABLE_DISTCC_FALSE 728 ENABLE_DISTCC_TRUE 723 729 DOendif 724 730 DOifskipcompile … … 795 801 enable_silent_rules 796 802 with_cfa_name 803 enable_distcc 797 804 with_target_hosts 798 805 enable_gprofiler 806 enable_demangler 799 807 enable_dependency_tracking 800 808 enable_shared … … 1456 1464 --enable-silent-rules less verbose build output (undo: "make V=1") 1457 1465 --disable-silent-rules verbose build output (undo: "make V=0") 1466 --enable-distcc whether or not to enable distributed compilation 1458 1467 --enable-gprofiler whether or not to enable gprofiler tools (if available) 1468 --enable-demangler whether or not to build the demangler (executable and library) 1459 1469 --enable-dependency-tracking 1460 1470 do not reject slow dependency extractors … … 3180 3190 3181 3191 #============================================================================== 3192 # distcc support 3193 3194 # Check whether --enable-distcc was given. 3195 if test "${enable_distcc+set}" = set; then : 3196 enableval=$enable_distcc; enable_distcc=$enableval 3197 else 3198 enable_distcc=no 3199 fi 3200 3201 3202 if test x$enable_distcc = xyes; then 3203 ENABLE_DISTCC_TRUE= 3204 ENABLE_DISTCC_FALSE='#' 3205 else 3206 ENABLE_DISTCC_TRUE='#' 3207 ENABLE_DISTCC_FALSE= 3208 fi 3209 3210 HAS_DISTCC="False" 3211 3212 if test x$enable_distcc = xyes; then 3213 CXX="distcc ${CXX}" 3214 LD="distcc ${LD} -lstdc++" 3215 HAS_DISTCC="True" 3216 echo "Enabling distributed builds" 3217 fi 3218 3219 3220 3221 3222 3223 #============================================================================== 3182 3224 # Installation paths 3183 3225 … … 3262 3304 DRIVER_DIR=${TOP_BUILDDIR}driver/ 3263 3305 CFACC=${DRIVER_DIR}cfa 3306 CFACC_INSTALL=${CFA_BINDIR}${CFA_NAME} 3264 3307 CFACPP=${DRIVER_DIR}cfa-cpp 3308 3265 3309 3266 3310 … … 3401 3445 3402 3446 3447 # Check whether --enable-demangler was given. 3448 if test "${enable_demangler+set}" = set; then : 3449 enableval=$enable_demangler; enable_demangler=$enableval 3450 else 3451 enable_demangler=yes 3452 fi 3453 3454 3403 3455 TARGET_HOSTS=${target_hosts} 3404 3456 … … 3433 3485 "x86-64" ) cannon_arch_name="x64";; 3434 3486 "x86_64" ) cannon_arch_name="x64";; 3487 "aarch64" ) cannon_arch_name="arm";; 3435 3488 "x86" ) cannon_arch_name="x86";; 3436 3489 "i386" ) cannon_arch_name="x86";; … … 3442 3495 "armv7l" ) cannon_arch_name="arm";; 3443 3496 *) 3444 >&2 echo "Unk own architecture " $arch_name;3497 >&2 echo "Unknown architecture " $arch_name; 3445 3498 exit 1 3446 3499 ;; … … 3474 3527 "x86-64" ) cannon_arch_name="x64";; 3475 3528 "x86_64" ) cannon_arch_name="x64";; 3529 "aarch64" ) cannon_arch_name="arm";; 3476 3530 "x86" ) cannon_arch_name="x86";; 3477 3531 "i386" ) cannon_arch_name="x86";; … … 3483 3537 "armv7l" ) cannon_arch_name="arm";; 3484 3538 *) 3485 >&2 echo "Unk own architecture " $arch_name;3539 >&2 echo "Unknown architecture " $arch_name; 3486 3540 exit 1 3487 3541 ;; … … 16778 16832 16779 16833 16834 # conditionnally build the demangler 16835 if test "x$enable_demangler" == xyes; then 16836 LIBDEMANGLE="libdemangle.a" 16837 DEMANGLER="demangler" 16838 else 16839 LIBDEMANGLE="" 16840 DEMANGLER="" 16841 fi 16842 16843 16844 16780 16845 # Checks for header files. 16781 16846 for ac_header in libintl.h malloc.h unistd.h … … 16992 17057 fi 16993 17058 17059 if test -z "${ENABLE_DISTCC_TRUE}" && test -z "${ENABLE_DISTCC_FALSE}"; then 17060 as_fn_error $? "conditional \"ENABLE_DISTCC\" was never defined. 17061 Usually this means the macro was only invoked conditionally." "$LINENO" 5 17062 fi 16994 17063 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then 16995 17064 as_fn_error $? "conditional \"AMDEP\" was never defined. -
configure.ac
r8e1467d r4a60488 58 58 59 59 #============================================================================== 60 # distcc support 61 62 AC_ARG_ENABLE(distcc, 63 [ --enable-distcc whether or not to enable distributed compilation], 64 enable_distcc=$enableval, enable_distcc=no) 65 66 AM_CONDITIONAL([ENABLE_DISTCC], [test x$enable_distcc = xyes]) 67 HAS_DISTCC="False" 68 69 if test x$enable_distcc = xyes; then 70 CXX="distcc ${CXX}" 71 LD="distcc ${LD} -lstdc++" 72 HAS_DISTCC="True" 73 echo "Enabling distributed builds" 74 fi 75 76 AC_SUBST(CXX) 77 AC_SUBST(LD) 78 AC_SUBST(HAS_DISTCC) 79 80 #============================================================================== 60 81 # Installation paths 61 82 M4CFA_PARSE_PREFIX … … 72 93 DRIVER_DIR=${TOP_BUILDDIR}driver/ 73 94 CFACC=${DRIVER_DIR}cfa 95 CFACC_INSTALL=${CFA_BINDIR}${CFA_NAME} 74 96 CFACPP=${DRIVER_DIR}cfa-cpp 75 97 AC_SUBST(DRIVER_DIR) 76 98 AC_SUBST(CFACC) 99 AC_SUBST(CFACC_INSTALL) 77 100 AC_SUBST(CFACPP) 78 101 … … 133 156 enable_gprofiler=$enableval, enable_gprofiler=yes) 134 157 158 AC_ARG_ENABLE(demangler, 159 [ --enable-demangler whether or not to build the demangler (executable and library)], 160 enable_demangler=$enableval, enable_demangler=yes) 161 135 162 AC_SUBST(TARGET_HOSTS, ${target_hosts}) 136 163 … … 205 232 AM_CONDITIONAL([WITH_LIBTCMALLOC], [test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBTCMALLOC" -eq 1]) 206 233 234 # conditionnally build the demangler 235 if test "x$enable_demangler" == xyes; then 236 LIBDEMANGLE="libdemangle.a" 237 DEMANGLER="demangler" 238 else 239 LIBDEMANGLE="" 240 DEMANGLER="" 241 fi 242 AC_SUBST([LIBDEMANGLE]) 243 AC_SUBST([DEMANGLER]) 244 207 245 # Checks for header files. 208 246 AC_CHECK_HEADERS([libintl.h malloc.h unistd.h], [], [echo "Error: Missing required header"; exit 1]) -
doc/bibliography/pl.bib
r8e1467d r4a60488 943 943 } 944 944 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 978 945 @article{Moss18, 979 946 keywords = {type systems, polymorphism, tuples, Cforall}, … … 988 955 pages = {2111-2146}, 989 956 note = {\href{http://dx.doi.org/10.1002/spe.2624}{http://\-dx.doi.org/\-10.1002/\-spe.2624}}, 957 } 958 959 @misc{CforallBenchMarks, 960 contributer = {pabuhr@plg}, 961 key = {Cforall Benchmarks}, 962 author = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}}, 963 howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmark.tar}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmark.tar}}, 964 } 965 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}}, 990 1000 } 991 1001 … … 1101 1111 1102 1112 @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} 1109 1119 } 1110 1120 … … 1158 1168 1159 1169 @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} 1164 1174 } 1165 1175 … … 1170 1180 title = {Checked C: Making C Safe by Extension}, 1171 1181 booktitle = {2018 IEEE Cybersecurity Development (SecDev)}, 1182 publisher = {IEEE}, 1172 1183 year = {2018}, 1173 month = {September},1184 month = sep, 1174 1185 pages = {53-60}, 1175 publisher = {IEEE},1176 1186 url = {https://www.microsoft.com/en-us/research/publication/checkedc-making-c-safe-by-extension/}, 1177 1187 } … … 1285 1295 1286 1296 @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}, 1303 1313 } 1304 1314 … … 1693 1703 1694 1704 @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} 1705 1715 } 1706 1716 … … 1729 1739 } 1730 1740 1731 @article{Delisle1 8b,1741 @article{Delisle19, 1732 1742 keywords = {concurrency, Cforall}, 1733 1743 contributer = {pabuhr@plg}, 1734 1744 author = {Thierry Delisle and Peter A. Buhr}, 1735 title = { Concurrency in \textsf{C}$\mathbf{\forall}$},1736 year = 201 8,1745 title = {Advanced Control-flow and Concurrency in \textsf{C}$\mathbf{\forall}$}, 1746 year = 2019, 1737 1747 journal = spe, 1738 pages = {1-3 2},1748 pages = {1-33}, 1739 1749 note = {submitted}, 1740 1750 } … … 2500 2510 2501 2511 @misc{Dotty-github, 2502 keywords 2503 contributer 2504 author 2505 title 2506 howpublished 2507 note 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} 2508 2518 } 2509 2519 … … 2656 2666 volume = 10, 2657 2667 number = 3, 2658 pages 2668 pages = {120-123}, 2659 2669 comment = { 2660 2670 The ``two-pass'' algorithm. An upward pass over a parse tree … … 3236 3246 3237 3247 @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}, 3256 3266 } 3257 3267 … … 4181 4191 4182 4192 @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} 4193 4203 } 4194 4204 … … 4389 4399 } 4390 4400 4391 4392 4401 @article{Liskov86, 4393 4402 keywords = {synchronous communication, concurrency}, … … 4448 4457 4449 4458 @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}, 4469 4478 } 4470 4479 … … 5449 5458 5450 5459 @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}, 5467 5476 } 5468 5477 … … 7531 7540 7532 7541 @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} 7540 7549 } 7541 7550 … … 7764 7773 7765 7774 @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} 7770 7779 } 7771 7780 -
doc/papers/concurrency/Paper.tex
r8e1467d r4a60488 307 307 In many ways, \CFA is to C as Scala~\cite{Scala} is to Java, providing a \emph{research vehicle} for new typing and control-flow capabilities on top of a highly popular programming language allowing immediate dissemination. 308 308 Within the \CFA framework, new control-flow features are created from scratch because ISO \Celeven defines only a subset of the \CFA extensions, where the overlapping features are concurrency~\cite[\S~7.26]{C11}. 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 fewlocks, which is low-level and error-prone;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 mutex/condition locks, which is low-level and error-prone; 310 310 no 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 .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 (possibly because the effort to add concurrency to \CC). 312 312 Finally, while the \Celeven standard does not state a threading model, the historical association with pthreads suggests implementations would adopt kernel-level threading (1:1)~\cite{ThreadModel}. 313 313 … … 333 333 334 334 Finally, it is important for a language to provide safety over performance \emph{as the default}, allowing careful reduction of safety for performance when necessary. 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. 335 Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging}\footnote{ 336 The notion of competitive succession instead of direct handoff, \ie a lock owner releases the lock and an arriving thread acquires it ahead of preexisting waiter threads. 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. 336 338 However, spurious wakeup is \emph{not} a foundational concurrency property~\cite[\S~8]{Buhr05a}, it is a performance design choice. 337 339 Similarly, signals-as-hints are often a performance decision. … … 351 353 We present comparative examples so the reader can judge if the \CFA control-flow extensions are better and safer than those in other concurrent, imperative programming languages, and perform experiments to show the \CFA runtime is competitive with other similar mechanisms. 352 354 The main contributions of this work are: 353 \begin{itemize} 355 \begin{itemize}[topsep=3pt,itemsep=1pt] 354 356 \item 355 357 language-level generators, coroutines and user-level threading, which respect the expectations of C programmers. … … 370 372 \end{itemize} 371 373 374 Section~\ref{s:StatefulFunction} begins advanced control by introducing sequential functions that retain data and execution state between calls, which produces constructs @generator@ and @coroutine@. 375 Section~\ref{s:Concurrency} begins concurrency, or how to create (fork) and destroy (join) a thread, which produces the @thread@ construct. 376 Section~\ref{s:MutualExclusionSynchronization} discusses the two mechanisms to restricted nondeterminism when controlling shared access to resources (mutual exclusion) and timing relationships among threads (synchronization). 377 Section~\ref{s:Monitor} shows how both mutual exclusion and synchronization are safely embedded in the @monitor@ and @thread@ constructs. 378 Section~\ref{s:CFARuntimeStructure} describes the large-scale mechanism to structure (cluster) threads and virtual processors (kernel threads). 379 Section~\ref{s:Performance} uses a series of microbenchmarks to compare \CFA threading with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0. 380 372 381 373 382 \section{Stateful Function} 383 \label{s:StatefulFunction} 374 384 375 385 The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg plugin, device driver, finite-state machine. … … 617 627 Figure~\ref{f:CFibonacciSim} shows the C implementation of the \CFA generator only needs one additional field, @next@, to handle retention of execution state. 618 628 The 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. 629 Finally, an explicit generator type provides both design and performance benefits, such as multiple type-safe interface functions taking and returning arbitrary types.\footnote{ 630 The \CFA operator syntax uses \lstinline|?| to denote operands, which allows precise definitions for pre, post, and infix operators, \eg \lstinline|++?|, \lstinline|?++|, and \lstinline|?+?|, in addition \lstinline|?\{\}| denotes a constructor, as in \lstinline|foo `f` = `\{`...`\}`|, \lstinline|^?\{\}| denotes a destructor, and \lstinline|?()| is \CC function call \lstinline|operator()|. 631 }% 620 632 \begin{cfa} 621 633 int ?()( Fib & fib ) { return `resume( fib )`.fn; } $\C[3.9in]{// function-call interface}$ … … 1511 1523 1512 1524 \section{Mutual Exclusion / Synchronization} 1525 \label{s:MutualExclusionSynchronization} 1513 1526 1514 1527 Unrestricted nondeterminism is meaningless as there is no way to know when the result is completed without synchronization. … … 1551 1564 higher-level mechanisms often simplify usage by adding better coupling between synchronization and data, \eg receive-specific versus receive-any thread in message passing or offering specialized solutions, \eg barrier lock. 1552 1565 Often synchronization is used to order access to a critical section, \eg ensuring a waiting writer thread enters the critical section before a calling reader thread. 1553 If the calling reader is scheduled before the waiting writer, the reader has \newterm{barged}.1566 If the calling reader is scheduled before the waiting writer, the reader has barged. 1554 1567 Barging can result in staleness/freshness problems, where a reader barges ahead of a writer and reads temporally stale data, or a writer barges ahead of another writer overwriting data with a fresh value preventing the previous value from ever being read (lost computation). 1555 1568 Preventing or detecting barging is an involved challenge with low-level locks, which is made easier through higher-level constructs. … … 2120 2133 2121 2134 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 2137 Figure~\ref{f:ExtendedWaitfor} shows the extended form of the @waitfor@ statement to conditionally accept one of a group of mutex functions, with an optional statement to be performed \emph{after} the mutex function finishes. 2125 2138 For a @waitfor@ clause to be executed, its @when@ must be true and an outstanding call to its corresponding member(s) must exist. 2126 2139 The \emph{conditional-expression} of a @when@ may call a function, but the function must not block or context switch. … … 2131 2144 Hence, the terminating @else@ clause allows a conditional attempt to accept a call without blocking. 2132 2145 If both @timeout@ and @else@ clause are present, the @else@ must be conditional, or the @timeout@ is never triggered. 2146 There is also a traditional future wait queue (not shown) (\eg Microsoft (@WaitForMultipleObjects@)), to wait for a specified number of future elements in the queue. 2133 2147 2134 2148 \begin{figure} … … 2355 2369 2356 2370 2357 \subsection{\ protect\lstinline@mutex@ Threads}2371 \subsection{\texorpdfstring{\protect\lstinline@mutex@ Threads}{mutex Threads}} 2358 2372 2359 2373 Threads in \CFA can also be monitors to allow \emph{direct communication} among threads, \ie threads can have mutex functions that are called by other threads. … … 2499 2513 \renewcommand{\arraystretch}{1.25} 2500 2514 %\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} \\ 2503 2517 \hline 2504 2518 thread & stateful & \multicolumn{1}{c|}{No} & \multicolumn{1}{c}{Yes} \\ … … 2605 2619 2606 2620 2607 \section{ \protect\CFARuntime Structure}2621 \section{Runtime Structure} 2608 2622 \label{s:CFARuntimeStructure} 2609 2623 … … 2709 2723 2710 2724 \section{Performance} 2711 \label{ results}2725 \label{s:Performance} 2712 2726 2713 2727 To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0. … … 2715 2729 The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \CFA/\uC are compiled with gcc 6.5. 2716 2730 2717 All benchmarks are run using the following harness. 2731 All benchmarks are run using the following harness. (The Java harness is augmented to circumvent JIT issues.) 2718 2732 \begin{cfa} 2719 2733 unsigned int N = 10_000_000; … … 2754 2768 \begin{tabular}[t]{@{}r*{3}{D{.}{.}{5.2}}@{}} 2755 2769 \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 \\ 2775 Goroutine & 4068.0 & 4113.1 & 414.55 \\ 2776 Java Thread & 103848.5 & 104295.4 & 2637.57 \\ 2777 Pthreads & 33112.6 & 33127.1 & 165.90 2778 \end{tabular} 2779 \end{multicols} 2780 2781 2782 \paragraph{Context-Switching} 2783 2784 In 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.) 2786 Similarly, when modularization extends to coroutines/tasks, the time for a context switch becomes a relevant factor. 2787 The coroutine test is from resumer to suspender and from suspender to resumer, which is two context switches. 2788 The thread test is using yield to enter and return from the runtime kernel, which is two context switches. 2789 The difference in performance between coroutine and thread context-switch is the cost of scheduling for threads, whereas coroutines are self-scheduling. 2790 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}. 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; 2796 void main( C & ) { for ( ;; ) { @suspend;@ } } 2797 int main() { // coroutine test 2798 BENCH( for ( N ) { @resume( c );@ } ) 2799 sout | result`ns; 2800 } 2801 int 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} \\ 2816 C 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 \\ 2822 Goroutine & 141.0 & 141.3 & 3.39 \\ 2823 Java Thread & 374.0 & 375.8 & 10.38 \\ 2824 Pthreads Thread & 361.0 & 365.3 & 13.19 2825 \end{tabular} 2826 \end{multicols} 2827 2828 2829 \paragraph{Mutual-Exclusion} 2830 2831 Uncontented mutual exclusion, which frequently occurs, is measured by entering/leaving a critical section. 2832 For monitors, entering and leaving a monitor function is measured. 2833 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. 2834 Figure~\ref{f:mutex} shows the code for \CFA with all results in Table~\ref{tab:mutex}. 2835 Note, 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*/; 2841 void __attribute__((noinline)) 2842 do_call( M & @mutex m/*, m2, m3, m4*/@ ) {} 2843 int 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} \\ 2860 test 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 \\ 2865 Java synchronized method & 31.0 & 31.1 & 0.50 \\ 2866 Pthreads Mutex Lock & 33.6 & 32.6 & 1.14 2867 \end{tabular} 2868 \end{multicols} 2869 2870 2871 \paragraph{External Scheduling} 2872 2873 External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement. 2874 Figure~\ref{f:ext-sched} shows the code for \CFA, with results in Table~\ref{tab:ext-sched}. 2875 Note, 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} 2881 volatile int go = 0; 2882 @monitor@ M {} m; 2883 thread T {}; 2884 void __attribute__((noinline)) 2885 do_call( M & @mutex@ ) {} 2886 void main( T & ) { 2887 while ( go == 0 ) { yield(); } 2888 while ( go == 1 ) { do_call( m ); } 2889 } 2890 int __attribute__((noinline)) 2891 do_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 } 2897 int 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 2765 2916 \end{tabular} 2766 2917 \end{multicols} … … 2810 2961 \begin{tabular}{@{}r*{3}{D{.}{.}{5.2}}@{}} 2811 2962 \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 \\ 2967 Java @notify@ & 10160.5 & 10169.4 & 267.71 \\ 2968 Pthreads Cond. Variable & 4949.6 & 5065.2 & 363 2957 2969 \end{tabular} 2958 2970 \end{multicols} -
driver/Makefile.in
r8e1467d r4a60488 201 201 CCDEPMODE = @CCDEPMODE@ 202 202 CFACC = @CFACC@ 203 CFACC_INSTALL = @CFACC_INSTALL@ 203 204 CFACPP = @CFACPP@ 204 205 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 218 219 CYGPATH_W = @CYGPATH_W@ 219 220 DEFS = @DEFS@ 221 DEMANGLER = @DEMANGLER@ 220 222 DEPDIR = @DEPDIR@ 221 223 DLLTOOL = @DLLTOOL@ … … 230 232 FGREP = @FGREP@ 231 233 GREP = @GREP@ 234 HAS_DISTCC = @HAS_DISTCC@ 232 235 HOST_FLAGS = @HOST_FLAGS@ 233 236 INSTALL = @INSTALL@ … … 243 246 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 244 247 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 248 LIBDEMANGLE = @LIBDEMANGLE@ 245 249 LIBOBJS = @LIBOBJS@ 246 250 LIBS = @LIBS@ -
driver/cc1.cc
r8e1467d r4a60488 10 10 // Created On : Fri Aug 26 14:23:51 2005 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 3 16:57:05 201813 // Update Count : 12512 // Last Modified On : Mon Sep 9 17:50:53 2019 13 // Update Count : 384 14 14 // 15 15 … … 19 19 #include <string> 20 20 using std::string; 21 #include <algorithm> // find 21 22 #include <cstdio> // stderr, stdout, perror, fprintf 22 23 #include <cstdlib> // getenv, exit, mkstemp 23 24 #include <unistd.h> // execvp, fork, unlink 24 25 #include <sys/wait.h> // wait 26 #include <fcntl.h> 27 25 28 26 29 #include "config.h" // configure info … … 30 33 31 34 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 ) { 35 static string compiler_path( CFA_BACKEND_CC ); // C compiler path/name 36 static bool CFA_flag = false; // -CFA flag 37 static bool save_temps = false; // -save-temps flag 38 static string o_file; 39 static string bprefix; 40 41 42 static bool prefix( const string & arg, const string & pre ) { 42 43 return arg.substr( 0, pre.size() ) == pre; 43 44 } // prefix 44 45 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; 46 static void suffix( const string & arg, const char * args[], int & nargs ) { 47 enum { NumSuffixes = 3 }; 48 static const string suffixes[NumSuffixes] = { "cfa", "hfa", "ifa" }; 49 50 50 size_t dot = arg.find_last_of( "." ); 51 //std::cerr << dot << " " << (dot != string::npos ? arg.substr( dot + 1 ) : "fred" ) << std::endl;52 51 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 63 57 } // suffix 64 58 65 59 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() { 60 static string __CFA_FLAGPREFIX__( "__CFA_FLAG" ); // "N__=" suffix 61 62 static 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 81 static 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 110 static char tmpname[] = P_tmpdir "/CFAXXXXXX.ifa"; 111 static int tmpfilefd = -1; 112 static bool startrm = false; 113 114 static void rmtmpfile() { 115 if ( tmpfilefd == -1 ) return; // RACE, file created ? 116 117 startrm = true; // RACE with C-c C-c 98 118 if ( unlink( tmpname ) == -1 ) { // remove tmpname 99 perror ( "C FA Translator error: cpp failed" );100 exit( EXIT_FAILURE ); 101 } // if 102 tmpfilefd = -1; // mark closed119 perror ( "CC1 Translator error: failed, unlink" ); 120 exit( EXIT_FAILURE ); 121 } // if 122 tmpfilefd = -1; // mark removed 103 123 } // rmtmpfile 104 124 105 125 106 void sigTermHandler( __attribute__((unused)) int signal ) { 126 static void sigTermHandler( int ) { // C-c C-c 127 if ( startrm ) return; // return and let rmtmpfile finish, and then program finishes 128 107 129 if ( tmpfilefd != -1 ) { // RACE, file created ? 108 rmtmpfile(); // remove 109 exit( EXIT_FAILURE ); // terminate110 } // if130 rmtmpfile(); // remove tmpname 131 } // if 132 exit( EXIT_FAILURE ); // terminate 111 133 } // sigTermHandler 112 134 113 135 114 void Stage1( const int argc, const char * const argv[] ) {136 static void Stage1( const int argc, const char * const argv[] ) { 115 137 int code; 116 117 138 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 124 143 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 values144 bool o_flag = false; 145 146 const char * args[argc + 100]; // leave space for 100 additional cpp command line values 128 147 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 values130 int ncargs = 1; // 0 => command name131 132 signal( SIGINT, sigTermHandler );133 signal( SIGTERM, sigTermHandler );134 148 135 149 #ifdef __DEBUG_H__ 136 150 cerr << "Stage1" << endl; 137 151 #endif // __DEBUG_H__ 138 checkEnv ( args, nargs ); // arguments passed via environment variables152 checkEnv1( args, nargs ); // arguments passed via environment variables 139 153 #ifdef __DEBUG_H__ 140 154 for ( int i = 1; i < argc; i += 1 ) { … … 168 182 i += 1; // and the argument 169 183 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 189 186 190 187 } else if ( arg == "-o" ) { 191 188 i += 1; 192 o_name = argv[i]; 189 o_flag = true; 190 cpp_out = argv[i]; 193 191 } else { 194 args[nargs] = argv[i]; // pass the flag along 195 nargs += 1; 192 args[nargs++] = argv[i]; // pass the flag along 196 193 // CPP flags with an argument 197 194 if ( arg == "-D" || arg == "-U" || arg == "-I" || arg == "-MF" || arg == "-MT" || arg == "-MQ" || … … 199 196 arg == "-iwithprefix" || arg == "-iwithprefixbefore" || arg == "-isystem" || arg == "-isysroot" ) { 200 197 i += 1; 201 args[nargs] = argv[i]; // pass the argument along 202 nargs += 1; 198 args[nargs++] = argv[i]; // pass the argument along 203 199 #ifdef __DEBUG_H__ 204 200 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl; 205 201 #endif // __DEBUG_H__ 206 202 } else if ( arg == "-MD" || arg == "-MMD" ) { 207 args[nargs] = "-MF"; // insert before file 208 nargs += 1; 203 args[nargs++] = "-MF"; // insert before file 209 204 i += 1; 210 args[nargs] = argv[i]; // pass the argument along 211 nargs += 1; 205 args[nargs++] = argv[i]; // pass the argument along 212 206 #ifdef __DEBUG_H__ 213 207 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl; … … 216 210 } // if 217 211 } else { // obtain input and possibly output files 218 if ( cpp_in == NULL) {212 if ( cpp_in == nullptr ) { 219 213 cpp_in = argv[i]; 220 214 #ifdef __DEBUG_H__ 221 215 cerr << "cpp_in:\"" << cpp_in << "\"" << endl; 222 216 #endif // __DEBUG_H__ 223 } else if ( cpp_out == NULL) {217 } else if ( cpp_out == nullptr ) { 224 218 cpp_out = argv[i]; 225 219 #ifdef __DEBUG_H__ … … 238 232 cerr << " " << args[i]; 239 233 } // 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; 242 236 cerr << endl; 243 237 #endif // __DEBUG_H__ 244 238 245 if ( cpp_in == NULL) {239 if ( cpp_in == nullptr ) { 246 240 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl; 247 241 exit( EXIT_FAILURE ); … … 252 246 // output or -o. The call to cfa has a -E so it does not have to be added to the argument list. 253 247 254 args[0] = compiler_ name.c_str();248 args[0] = compiler_path.c_str(); 255 249 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 265 256 266 257 #ifdef __DEBUG_H__ 267 258 cerr << "nargs: " << nargs << endl; 268 for ( int i = 0; args[i] != NULL; i += 1 ) {259 for ( int i = 0; args[i] != nullptr; i += 1 ) { 269 260 cerr << args[i] << " "; 270 261 } // for … … 272 263 #endif // __DEBUG_H__ 273 264 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. 292 271 293 272 if ( fork() == 0 ) { // child process ? … … 295 274 // an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error, 296 275 // when cpp writes to stdout. Hence, stdout is redirected into the temporary file. 297 if ( freopen( tmpname, "w", stdout ) == NULL ) { // redirect stdout to tmpname298 perror( "C FA 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" ); 299 278 exit( EXIT_FAILURE ); 300 279 } // if 301 280 302 args[0] = compiler_ name.c_str();281 args[0] = compiler_path.c_str(); 303 282 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 307 285 308 286 #ifdef __DEBUG_H__ 309 287 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 ) { 311 289 cerr << args[i] << " "; 312 290 } // for … … 314 292 #endif // __DEBUG_H__ 315 293 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; 318 297 exit( EXIT_FAILURE ); 319 298 } // if … … 325 304 #endif // __DEBUG_H__ 326 305 327 if ( WIFSIGNALED(code) != 0 ) { // child failed ?328 rmtmpfile(); // remove tmpname329 cerr << "CFA Translator error: cpp failed with signal " << WTERMSIG(code) << endl;330 exit( EXIT_FAILURE );331 } // if332 333 if ( WEXITSTATUS(code) != 0 ) { // child error ?334 rmtmpfile(); // remove tmpname335 exit( WEXITSTATUS( code ) ); // do not continue336 } // if337 338 // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard339 // 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 CFA342 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 } // if359 cargs[ncargs] = NULL; // terminate argument list360 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 } // for366 cerr << endl;367 #endif // __DEBUG_H__368 369 execvp( cargs[0], (char * const *)cargs ); // should not return370 perror( "CFA Translator error: cpp level, execvp" );371 exit( EXIT_FAILURE );372 } // if373 374 wait( &code ); // wait for child to finish375 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 tmpname382 383 306 if ( WIFSIGNALED(code) ) { // child failed ? 384 cerr << "C FA 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 389 312 } // Stage1 390 313 391 314 392 void Stage2( const int argc, const char * const * argv ) { 315 static void Stage2( const int argc, const char * const * argv ) { 316 int code; 393 317 string arg; 394 318 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 398 323 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 399 326 400 327 #ifdef __DEBUG_H__ 401 328 cerr << "Stage2" << endl; 402 329 #endif // __DEBUG_H__ 403 checkEnv ( args, nargs ); // arguments passed via environment variables330 checkEnv2( cargs, ncargs ); // arguments passed via environment variables 404 331 #ifdef __DEBUG_H__ 405 332 for ( int i = 1; i < argc; i += 1 ) { … … 430 357 431 358 } else { 432 args[nargs] = argv[i]; // pass the flag along 433 nargs += 1; 359 args[nargs++] = argv[i]; // pass the flag along 434 360 if ( arg == "-o" ) { 435 361 i += 1; 436 args[nargs] = argv[i]; // pass the argument along437 nargs += 1;362 cpp_out = argv[i]; 363 args[nargs++] = argv[i]; // pass the argument along 438 364 #ifdef __DEBUG_H__ 439 365 cerr << "arg:\"" << argv[i] << "\"" << endl; … … 442 368 } // if 443 369 } else { // obtain input and possibly output files 444 if ( cpp_in == NULL) {370 if ( cpp_in == nullptr ) { 445 371 cpp_in = argv[i]; 446 372 #ifdef __DEBUG_H__ 447 373 cerr << "cpp_in:\"" << cpp_in << "\"" << endl; 448 374 #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__ 449 380 } else { 450 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;381 cerr << "Usage: " << argv[0] << " more than two files specified" << endl; 451 382 exit( EXIT_FAILURE ); 452 383 } // if 453 384 } // if 454 385 } // 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 455 477 456 478 #ifdef __DEBUG_H__ … … 459 481 cerr << " " << args[i]; 460 482 } // 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 483 522 } // Stage2 484 523 485 524 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 486 530 int main( const int argc, const char * const argv[], __attribute__((unused)) const char * const env[] ) { 487 531 #ifdef __DEBUG_H__ 488 for ( int i = 0; env[i] != NULL; i += 1 ) {532 for ( int i = 0; env[i] != nullptr; i += 1 ) { 489 533 cerr << env[i] << endl; 490 534 } // for 491 535 #endif // __DEBUG_H__ 492 536 493 string arg = argv[1]; 537 signal( SIGINT, sigTermHandler ); 538 signal( SIGTERM, sigTermHandler ); 539 540 string arg( argv[1] ); 494 541 495 542 // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed. -
driver/cfa.cc
r8e1467d r4a60488 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Feb 10 08:28:09201913 // Update Count : 28112 // Last Modified On : Tue Sep 10 17:00:15 2019 13 // Update Count : 420 14 14 // 15 15 16 16 #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 22 24 23 25 #include <sys/types.h> … … 32 34 using std::to_string; 33 35 34 35 //#define __DEBUG_H__ 36 37 38 bool prefix( string arg, string pre ) { 36 // #define __DEBUG_H__ 37 38 // "N__=" suffix 39 static string __CFA_FLAGPREFIX__( "__CFA_FLAG" ); 40 41 void 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 52 bool prefix( const string & arg, const string & pre ) { 39 53 return arg.substr( 0, pre.size() ) == pre; 40 54 } // prefix 41 55 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; 56 inline 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 62 bool suffix( const string & arg ) { 63 enum { NumSuffixes = 3 }; 64 static const string suffixes[NumSuffixes] = { "cfa", "hfa", "ifa" }; 65 47 66 size_t dot = arg.find_last_of( "." ); 48 //std::cerr << dot << " " << (dot != string::npos ? arg.substr( dot + 1 ) : "fred" ) << std::endl;49 67 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; 61 70 } // suffix 62 71 63 72 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) { 73 static inline bool dirExists( const string & path ) { // check if directory exists 78 74 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 79 static inline string dir(const string & path) { 80 return path.substr(0, path.find_last_of('/')); 81 } 82 83 // Different path modes 84 enum 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 91 PathMode 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) 88 122 #define str(s) #s 89 123 90 int main( int argc, char * argv[] ) {124 int main( int argc, char * argv[] ) { 91 125 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 ) ); 93 127 94 128 string installincdir( CFA_INCDIR ); // fixed location of include files … … 98 132 string heading; // banner printed at start of cfa compilation 99 133 string arg; // current command-line argument during command-line parsing 100 string Bprefix; // path where gcc looks for compiler commandsteps134 string bprefix; // path where gcc looks for compiler steps 101 135 string langstd; // language standard 102 136 … … 104 138 string compiler_name; // name of C compiler 105 139 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 108 143 bool verbose = false; // -v flag 109 bool quiet = false; // -quiet flag110 bool debug = true; // -debug flag111 bool nolib = false; // -nolib flag112 bool help = false; // -help flag144 bool quiet = false; // -quiet flag 145 bool debug = true; // -debug flag 146 bool nolib = false; // -nolib flag 147 bool help = false; // -help flag 113 148 bool CFA_flag = false; // -CFA flag 114 149 bool cpp_flag = false; // -E or -M flag, preprocessor only … … 116 151 bool noincstd_flag = false; // -no-include-stdhdr= flag 117 152 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(); 121 159 122 160 const char *args[argc + 100]; // cfa command line values, plus some space for additional flags … … 142 180 143 181 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 146 183 i += 1; 147 184 if ( i == argc ) continue; // next argument available ? 148 args[nargs ] = argv[i]; // pass theargument along149 nargs += 1;185 args[nargs++] = argv[i]; // pass argument along 186 if ( arg == "-o" ) o_file = i; // remember file 150 187 } else if ( arg == "-XCFA" ) { // CFA pass through 151 188 i += 1; 152 args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + argv[i] ) ).c_str(); 153 nargs += 1; 189 Putenv( argv, argv[i] ); 154 190 155 191 // CFA specific arguments … … 158 194 CFA_flag = true; // strip the -CFA flag 159 195 link = false; 160 args[nargs] = "-E"; // replace the argument with -E 161 nargs += 1; 196 args[nargs++] = "-fsyntax-only"; // stop after stage 2 162 197 } else if ( arg == "-debug" ) { 163 198 debug = true; // strip the debug flag 164 199 } else if ( arg == "-nodebug" ) { 165 debug = false; // strip the debug flag200 debug = false; // strip the nodebug flag 166 201 } else if ( arg == "-nolib" ) { 167 202 nolib = true; // strip the nodebug flag … … 176 211 } else if ( arg == "-no-include-stdhdr" ) { 177 212 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; 180 215 } else if ( arg == "-compiler" ) { 181 216 // use the user specified compiler … … 183 218 if ( i == argc ) continue; // next argument available ? 184 219 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] ); 189 221 190 222 // C specific arguments … … 192 224 } else if ( arg == "-v" ) { 193 225 verbose = true; // verbosity required 194 args[nargs] = argv[i]; // pass the argument along 195 nargs += 1; 226 args[nargs++] = argv[i]; // pass argument along 196 227 } else if ( arg == "-g" ) { 197 228 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"; 200 245 } else if ( prefix( arg, "-std=" ) || prefix( arg, "--std=" ) ) { 201 246 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 204 248 } 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 ); 209 251 } else if ( prefix( arg, "-W" ) ) { // check before next tests 210 252 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] ); 215 255 } else { 216 256 unsigned int adv = prefix( arg, "-Wno-" ) ? 5 : 2; 217 args[nargs] = argv[i]; // conditionally pass theargument along218 const char * warning = argv[i] + adv; 257 args[nargs] = argv[i]; // conditionally pass argument along 258 const char * warning = argv[i] + adv; // extract warning 219 259 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 ); 221 261 } // if 222 262 nargs += 1; 223 263 } // if 224 264 } 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 258 266 } 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 261 268 if ( arg == "-E" || arg == "-M" || arg == "-MM" ) { 262 269 cpp_flag = true; // cpp only … … 265 272 } else if ( arg[1] == 'l' ) { 266 273 // if the user specifies a library, load it after user code 267 libs[nlibs] = argv[i]; 268 nlibs += 1; 274 libs[nlibs++] = argv[i]; 269 275 } else if ( arg == "-m32" ) { 270 276 m32 = true; 271 277 m64 = false; 272 args[nargs] = argv[i]; 273 nargs += 1; 278 args[nargs++] = argv[i]; 274 279 } else if ( arg == "-m64" ) { 275 280 m64 = true; 276 281 m32 = false; 277 args[nargs] = argv[i]; 278 nargs += 1; 282 args[nargs++] = argv[i]; 279 283 } else { 280 284 // concatenate any other arguments 281 args[nargs] = argv[i]; 282 nargs += 1; 285 args[nargs++] = argv[i]; 283 286 } // if 284 287 } 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"; 293 297 } // if 294 298 nonoptarg = true; … … 296 300 } // for 297 301 298 args[nargs] = "-x"; // turn off language299 nargs += 1;300 args[nargs] = "none";301 nargs += 1;302 303 302 #ifdef __x86_64__ 304 args[nargs] = "-mcx16"; // allow double-wide CAA 305 nargs += 1; 303 args[nargs++] = "-mcx16"; // allow double-wide CAA 306 304 #endif // __x86_64__ 307 305 … … 314 312 #endif // __DEBUG_H__ 315 313 314 // -E flag stops at cc1 stage 1, so cfa-cpp in cc1 stage 2 is never executed. 316 315 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; 319 318 } // if 320 319 321 320 // 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 345 347 346 348 // 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) ); 362 357 if ( ! m32 && ! m64 ) { 363 358 if ( arch == "x86" ) { 364 args[nargs] = "-m32"; 365 nargs += 1; 359 args[nargs++] = "-m32"; 366 360 } else if ( arch == "x64" ) { 367 args[nargs] = "-m64"; 368 nargs += 1; 361 args[nargs++] = "-m64"; 369 362 } // if 370 363 } // if 364 371 365 const char * config = nolib ? "nolib" : (debug ? "debug": "nodebug"); 372 366 string libdir = libbase + arch + "-" + config; 373 367 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 } 388 391 389 392 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]; 392 394 } // for 393 395 394 396 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"; 449 427 450 428 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 457 432 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] ); 461 438 } else { 462 args[sargs] = "-D__CFA_FLAG__=-L"; 463 } // if 464 sargs += 1; 439 Putenv( argv, "-L" ); 440 } // if 465 441 466 442 if ( debug ) { 467 443 heading += " (debug)"; 468 args[nargs] = "-D__CFA_DEBUG__"; 469 nargs += 1; 444 args[nargs++] = "-D__CFA_DEBUG__"; 470 445 } else { 471 446 heading += " (no debug)"; 472 447 } // if 473 448 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"; 485 461 486 462 // execute the compilation command … … 496 472 497 473 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 506 479 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(); 516 485 } else { 517 486 cerr << argv[0] << " error, compiler \"" << compiler_name << "\" unsupported." << endl; … … 519 488 } // if 520 489 521 args[nargs] = NULL; // terminate with NULL490 args[nargs] = nullptr; // terminate 522 491 523 492 #ifdef __DEBUG_H__ 524 493 cerr << "nargs: " << nargs << endl; 525 494 cerr << "args:" << endl; 526 for ( int i = 0; args[i] != NULL; i += 1 ) {495 for ( int i = 0; args[i] != nullptr; i += 1 ) { 527 496 cerr << " \"" << args[i] << "\"" << endl; 528 497 } // for 498 cerr << endl; 529 499 #endif // __DEBUG_H__ 530 500 531 501 if ( ! quiet ) { 532 502 cerr << "CFA " << "Version " << Version << heading << endl; 533 534 503 if ( help ) { 535 504 cerr << … … 546 515 if ( argc == 2 ) exit( EXIT_SUCCESS ); // if only the -v flag is specified, do not invoke gcc 547 516 548 for ( int i = 0; args[i] != NULL; i += 1 ) {517 for ( int i = 0; args[i] != nullptr; i += 1 ) { 549 518 cerr << args[i] << " "; 550 519 } // for … … 560 529 561 530 execvp( args[0], (char *const *)args ); // should not return 562 perror( "CFA Translator error: cfa level,execvp" );531 perror( "CFA Translator error: execvp" ); 563 532 exit( EXIT_FAILURE ); 564 533 } // main -
libcfa/Makefile.in
r8e1467d r4a60488 231 231 CFACC = @CFACC@ 232 232 CFACPP = @CFACPP@ 233 CFADIR_HASH = @CFADIR_HASH@ 233 234 CFA_BINDIR = @CFA_BINDIR@ 234 235 CFA_INCDIR = @CFA_INCDIR@ … … 274 275 LIPO = @LIPO@ 275 276 LN_S = @LN_S@ 277 LOCAL_CC1 = @LOCAL_CC1@ 278 LOCAL_CFACC = @LOCAL_CFACC@ 276 279 LTLIBOBJS = @LTLIBOBJS@ 277 280 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -
libcfa/configure
r8e1467d r4a60488 707 707 CONFIG_CFLAGS 708 708 ARCH_FLAGS 709 CFADIR_HASH 710 LOCAL_CC1 711 LOCAL_CFACC 709 712 CFACPP 710 713 CFACC 714 ENABLE_DISTCC_FALSE 715 ENABLE_DISTCC_TRUE 711 716 CFA_VERSION 712 717 DRIVER_DIR … … 783 788 enable_option_checking 784 789 enable_silent_rules 790 enable_distcc 785 791 with_cfa_name 786 792 enable_shared … … 1445 1451 --enable-silent-rules less verbose build output (undo: "make V=1") 1446 1452 --disable-silent-rules verbose build output (undo: "make V=0") 1453 --enable-distcc whether or not to enable distributed compilation 1447 1454 --enable-shared[=PKGS] build shared libraries [default=yes] 1448 1455 --enable-static[=PKGS] build static libraries [default=yes] … … 2941 2948 2942 2949 2943 CFACC=${DRIVER_DIR}cfa 2950 # Check whether --enable-distcc was given. 2951 if test "${enable_distcc+set}" = set; then : 2952 enableval=$enable_distcc; enable_distcc=$enableval 2953 else 2954 enable_distcc=no 2955 fi 2956 2957 2958 echo -n "checking for distributated build... " 2959 if test x$enable_distcc = xno; then 2960 CFACC=${DRIVER_DIR}cfa 2961 echo "no" 2962 else 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})" 2969 fi 2944 2970 CFACPP=${DRIVER_DIR}cfa-cpp 2971 LOCAL_CFACC=${DRIVER_DIR}cfa 2972 LOCAL_CC1=${DRIVER_DIR}cc1 2973 2974 if test x$enable_distcc = xyes; then 2975 ENABLE_DISTCC_TRUE= 2976 ENABLE_DISTCC_FALSE='#' 2977 else 2978 ENABLE_DISTCC_TRUE='#' 2979 ENABLE_DISTCC_FALSE= 2980 fi 2981 2982 2983 2984 2985 2945 2986 2946 2987 … … 16982 17023 fi 16983 17024 17025 if test -z "${ENABLE_DISTCC_TRUE}" && test -z "${ENABLE_DISTCC_FALSE}"; then 17026 as_fn_error $? "conditional \"ENABLE_DISTCC\" was never defined. 17027 Usually this means the macro was only invoked conditionally." "$LINENO" 5 17028 fi 16984 17029 if test -z "${BUILDLIB_TRUE}" && test -z "${BUILDLIB_FALSE}"; then 16985 17030 as_fn_error $? "conditional \"BUILDLIB\" was never defined. -
libcfa/configure.ac
r8e1467d r4a60488 27 27 AC_ARG_VAR(CFA_VERSION, [The long version of cfa]) 28 28 29 CFACC=${DRIVER_DIR}cfa 29 AC_ARG_ENABLE(distcc, 30 [ --enable-distcc whether or not to enable distributed compilation], 31 enable_distcc=$enableval, enable_distcc=no) 32 33 echo -n "checking for distributated build... " 34 if test x$enable_distcc = xno; then 35 CFACC=${DRIVER_DIR}cfa 36 echo "no" 37 else 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})" 44 fi 30 45 CFACPP=${DRIVER_DIR}cfa-cpp 46 LOCAL_CFACC=${DRIVER_DIR}cfa 47 LOCAL_CC1=${DRIVER_DIR}cc1 48 49 AM_CONDITIONAL([ENABLE_DISTCC], [test x$enable_distcc = xyes]) 50 31 51 AC_SUBST(CFACC) 32 52 AC_SUBST(CFACPP) 53 AC_SUBST(LOCAL_CFACC) 54 AC_SUBST(LOCAL_CC1) 55 AC_SUBST(CFADIR_HASH) 33 56 AC_SUBST(CFA_VERSION) 34 57 -
libcfa/prelude/Makefile.am
r8e1467d r4a60488 23 23 cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c 24 24 25 CC = @ CFACC@25 CC = @LOCAL_CFACC@ 26 26 AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@ 27 27 AM_CFAFLAGS = @CONFIG_CFAFLAGS@ … … 54 54 55 55 # create forward declarations for cfa builtins 56 builtins.cf : builtins.c ${CC}56 builtins.cf : builtins.c @LOCAL_CFACC@ 57 57 ${AM_V_GEN}gcc ${AM_CFLAGS} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po -D__cforall 58 58 ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po … … 68 68 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cfa 69 69 MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}} 70 71 if ENABLE_DISTCC 72 distribution: @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 76 all: all-am distribution 77 endif ENABLE_DISTCC -
libcfa/prelude/Makefile.in
r8e1467d r4a60488 167 167 AUTOMAKE = @AUTOMAKE@ 168 168 AWK = @AWK@ 169 CC = @ CFACC@169 CC = @LOCAL_CFACC@ 170 170 CCAS = @CCAS@ 171 171 CCASDEPMODE = @CCASDEPMODE@ … … 174 174 CFACC = @CFACC@ 175 175 CFACPP = @CFACPP@ 176 CFADIR_HASH = @CFADIR_HASH@ 176 177 CFA_BINDIR = @CFA_BINDIR@ 177 178 CFA_INCDIR = @CFA_INCDIR@ … … 217 218 LIPO = @LIPO@ 218 219 LN_S = @LN_S@ 220 LOCAL_CC1 = @LOCAL_CC1@ 221 LOCAL_CFACC = @LOCAL_CFACC@ 219 222 LTLIBOBJS = @LTLIBOBJS@ 220 223 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ … … 555 558 556 559 # create forward declarations for cfa builtins 557 builtins.cf : builtins.c ${CC}560 builtins.cf : builtins.c @LOCAL_CFACC@ 558 561 ${AM_V_GEN}gcc ${AM_CFLAGS} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po -D__cforall 559 562 ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po … … 566 569 maintainer-clean-local : 567 570 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 568 577 569 578 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
libcfa/prelude/extras.regx
r8e1467d r4a60488 19 19 typedef.* uint32_t; 20 20 typedef.* uint64_t; 21 typedef.* __uint_least16_t; 22 typedef.* __uint_least32_t; 21 23 typedef.* char16_t; 22 24 typedef.* char32_t; -
libcfa/src/Makefile.am
r8e1467d r4a60488 26 26 VPATH += :../prelude 27 27 28 gdbwaittarget="" 29 28 30 # AM_CFLAGS for all cfa source 29 31 # AM_CFAFLAGS for only cfa source 30 32 # use -no-include-stdhdr to prevent rebuild cycles 31 33 # The built sources must not depend on the installed headers 32 AM_CFAFLAGS = -quiet - in-tree -I$(srcdir)/stdhdr@CONFIG_CFAFLAGS@34 AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@ 33 35 AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@ 34 36 AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@ … … 62 64 # add dependency of cfa files 63 65 libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(libsrc)))) 64 $(libobjs) : @ CFACC@ @CFACPP@ prelude.cfa66 $(libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa 65 67 66 68 thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc)))) 67 $(thread_libobjs) : @ CFACC@ @CFACPP@ prelude.cfa69 $(thread_libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa 68 70 69 71 … … 84 86 85 87 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 ${@} 88 if ENABLE_DISTCC 88 89 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 93 prelude.o prelude.lo $(libobjs) $(thread_libobjs) : ../prelude/distribution 94 95 endif ENABLE_DISTCC 96 97 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@ 98 ${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@} 99 100 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@ 90 101 ${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 ${@} 93 103 94 104 #---------------------------------------------------------------------------------------------------------------- -
libcfa/src/Makefile.in
r8e1467d r4a60488 284 284 CFACC = @CFACC@ 285 285 CFACPP = @CFACPP@ 286 CFADIR_HASH = @CFADIR_HASH@ 286 287 CFA_BINDIR = @CFA_BINDIR@ 287 288 CFA_INCDIR = @CFA_INCDIR@ … … 327 328 LIPO = @LIPO@ 328 329 LN_S = @LN_S@ 330 LOCAL_CC1 = @LOCAL_CC1@ 331 LOCAL_CFACC = @LOCAL_CFACC@ 329 332 LTLIBOBJS = @LTLIBOBJS@ 330 333 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ … … 435 438 am__v_UPP_1 = 436 439 lib_LTLIBRARIES = libcfa.la libcfathread.la 440 gdbwaittarget = "" 437 441 438 442 # AM_CFLAGS for all cfa source … … 440 444 # use -no-include-stdhdr to prevent rebuild cycles 441 445 # The built sources must not depend on the installed headers 442 AM_CFAFLAGS = -quiet - in-tree -I$(srcdir)/stdhdr@CONFIG_CFAFLAGS@446 AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@ 443 447 AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC @ARCH_FLAGS@ @CONFIG_CFLAGS@ 444 448 AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@ … … 936 940 $(LTCFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 937 941 $(am__mv) $$depbase.Tpo $$depbase.Plo 938 $(libobjs) : @ CFACC@ @CFACPP@ prelude.cfa939 $(thread_libobjs) : @ CFACC@ @CFACPP@ prelude.cfa942 $(libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa 943 $(thread_libobjs) : @LOCAL_CFACC@ @CFACPP@ prelude.cfa 940 944 941 945 -include $(libdeps) … … 943 947 -include $(thread_libdeps) 944 948 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 954 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@ 955 ${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA -l ${<} -c -o ${@} 956 957 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@ 949 958 ${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 ${@} 951 960 952 961 #---------------------------------------------------------------------------------------------------------------- -
libcfa/src/fstream.cfa
r8e1467d r4a60488 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jul 15 18:11:26 201913 // Update Count : 3 4912 // Last Modified On : Tue Sep 10 22:19:56 2019 13 // Update Count : 354 14 14 // 15 15 … … 164 164 } // fmt 165 165 166 static ofstream soutFile = { (FILE *) (&_IO_2_1_stdout_)};166 static ofstream soutFile = { (FILE *)stdout }; 167 167 ofstream & sout = soutFile, & stdout = soutFile; 168 static ofstream serrFile = { (FILE *) (&_IO_2_1_stderr_)};168 static ofstream serrFile = { (FILE *)stderr }; 169 169 ofstream & serr = serrFile, & stderr = serrFile; 170 170 171 static ofstream exitFile = { (FILE *) (&_IO_2_1_stdout_)};171 static ofstream exitFile = { (FILE *)stdout }; 172 172 ofstream & exit = exitFile; 173 static ofstream abortFile = { (FILE *) (&_IO_2_1_stderr_)};173 static ofstream abortFile = { (FILE *)stderr }; 174 174 ofstream & abort = abortFile; 175 175 … … 265 265 } // fmt 266 266 267 268 static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) }; 267 static ifstream sinFile = { (FILE *)stdin }; 269 268 ifstream & sin = sinFile, & stdin = sinFile; 270 269 -
libcfa/src/heap.cfa
r8e1467d r4a60488 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 23 14:13:13201913 // Update Count : 5 4912 // Last Modified On : Wed Jul 24 13:12:45 2019 13 // Update Count : 550 14 14 // 15 15 … … 248 248 249 249 #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 250 enum { LookupSizes = 65_536 + sizeof(HeapManager.Storage) }; // number of fast lookup sizes 252 251 static unsigned char lookup[LookupSizes]; // O(1) lookup for small sizes 253 252 #endif // FASTLOOKUP -
longrun_tests/Makefile.am
r8e1467d r4a60488 43 43 -I$(srcdir) \ 44 44 -DTEST_$(shell cat .type | tr a-z A-Z) \ 45 -in-tree46 45 47 46 TESTS = block coroutine create disjoint enter enter3 processor stack wait yield -
longrun_tests/Makefile.in
r8e1467d r4a60488 348 348 CCDEPMODE = @CCDEPMODE@ 349 349 CFACC = @CFACC@ 350 CFACC_INSTALL = @CFACC_INSTALL@ 350 351 CFACPP = @CFACPP@ 351 352 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 365 366 CYGPATH_W = @CYGPATH_W@ 366 367 DEFS = @DEFS@ 368 DEMANGLER = @DEMANGLER@ 367 369 DEPDIR = @DEPDIR@ 368 370 DLLTOOL = @DLLTOOL@ … … 377 379 FGREP = @FGREP@ 378 380 GREP = @GREP@ 381 HAS_DISTCC = @HAS_DISTCC@ 379 382 HOST_FLAGS = @HOST_FLAGS@ 380 383 INSTALL = @INSTALL@ … … 390 393 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 391 394 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 395 LIBDEMANGLE = @LIBDEMANGLE@ 392 396 LIBOBJS = @LIBOBJS@ 393 397 LIBS = @LIBS@ -
src/AST/Convert.cpp
r8e1467d r4a60488 9 9 // Author : Thierry Delisle 10 10 // Created On : Thu May 09 15::37::05 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Jun 17 16:44:00201913 // Update Count : 1 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:21:46 2019 13 // Update Count : 13 14 14 // 15 15 … … 2688 2688 ); 2689 2689 } 2690 2691 virtual void visit( const AttrExpr * ) override final {2692 assertf( false, "AttrExpr deprecated in new AST." );2693 }2694 2690 }; 2695 2691 -
src/AST/porting.md
r8e1467d r4a60488 171 171 * all existing uses assume `type` set if true and don't use `expr` 172 172 173 `AttrExpr`174 * did not port due to feature deprecation (e.g. `expr@attribute`)175 176 173 `LogicalExpr` 177 174 * un-defaulted constructor parameter determining `&&` or `||` -
src/BasicTypes-gen.cc
r8e1467d r4a60488 295 295 // cout << code.str(); 296 296 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 298 322 #define ConversionCost TOP_SRCDIR "src/ResolvExpr/ConversionCost.cc" 299 323 resetInput( file, ConversionCost, buffer, code, str ); … … 310 334 code << right << setw(30) << graph[c].type << left; 311 335 } 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; 313 337 c += 1; 314 338 } 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; 316 340 c += 2; 317 341 } // if … … 328 352 code << "\t" << BYMK << endl; 329 353 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/* "; 331 355 for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // titles 332 356 code << setw(5) << graph[r].abbrev; … … 334 358 code << " */" << endl; 335 359 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 << " */ {"; 337 361 for ( int c = 0; c < NUMBER_OF_BASIC_TYPES; c += 1 ) { 338 362 code << setw(4) << costMatrix[r][c] << ","; … … 353 377 code << "\t" << BYMK << endl; 354 378 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/* "; 356 380 for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // titles 357 381 code << setw(5) << graph[r].abbrev; … … 359 383 code << " */" << endl; 360 384 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 << " */ {"; 362 386 for ( int c = 0; c < NUMBER_OF_BASIC_TYPES; c += 1 ) { 363 387 code << setw(4) << signMatrix[r][c] << ","; … … 395 419 code << "*/" << endl; 396 420 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 << " */"; 398 422 for ( int c = 0; c < NUMBER_OF_BASIC_TYPES; c += 1 ) { 399 423 string s = string{"BT "} + graph[commonTypeMatrix[r][c]].name; -
src/Common/Eval.cc
r8e1467d r4a60488 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 6 22:24:16 201813 // Update Count : 4012 // Last Modified On : Wed Jul 24 15:09:06 2019 13 // Update Count : 64 14 14 // 15 15 … … 27 27 bool valid = true; 28 28 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; } 31 31 32 void postvisit( ConstantExpr * expr ) { 32 void postvisit( const SizeofExpr * ) { 33 } 34 35 void postvisit( const ConstantExpr * expr ) { 33 36 value = expr->intValue(); 34 37 } 35 38 36 void postvisit( CastExpr * expr ) {39 void postvisit( const CastExpr * expr ) { 37 40 auto arg = eval(expr->arg); 38 41 valid = arg.second; … … 41 44 } 42 45 43 void postvisit( VariableExpr *expr ) {46 void postvisit( const VariableExpr * const expr ) { 44 47 if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) { 45 48 if ( EnumDecl * decl = inst->baseEnum ) { … … 52 55 } 53 56 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)); 56 59 if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; } 57 60 const std::string & fname = function->name; … … 94 97 void postvisit( const ast::ConstantExpr * expr ) { 95 98 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" ) ); 96 105 } 97 106 … … 145 154 }; 146 155 147 std::pair<long long int, bool> eval( Expression * expr) {156 std::pair<long long int, bool> eval( const Expression * expr) { 148 157 PassVisitor<EvalOld> ev; 149 158 if (expr) { -
src/Common/PassVisitor.h
r8e1467d r4a60488 155 155 virtual void visit( OffsetPackExpr * offsetPackExpr ) override final; 156 156 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;159 157 virtual void visit( LogicalExpr * logicalExpr ) override final; 160 158 virtual void visit( const LogicalExpr * logicalExpr ) override final; … … 301 299 virtual Expression * mutate( OffsetofExpr * offsetofExpr ) override final; 302 300 virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) override final; 303 virtual Expression * mutate( AttrExpr * attrExpr ) override final;304 301 virtual Expression * mutate( LogicalExpr * logicalExpr ) override final; 305 302 virtual Expression * mutate( ConditionalExpr * conditionalExpr ) override final; -
src/Common/PassVisitor.impl.h
r8e1467d r4a60488 2302 2302 2303 2303 //-------------------------------------------------------------------------- 2304 // AttrExpr2305 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 //--------------------------------------------------------------------------2349 2304 // LogicalExpr 2350 2305 template< typename pass_type > -
src/Common/utility.h
r8e1467d r4a60488 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 6 22:24:16 201813 // Update Count : 4 012 // Last Modified On : Wed Jul 24 14:28:19 2019 13 // Update Count : 41 14 14 // 15 15 … … 483 483 // ----------------------------------------------------------------------------- 484 484 /// evaluates expr as a long long int. If second is false, expr could not be evaluated 485 std::pair<long long int, bool> eval( Expression * expr);485 std::pair<long long int, bool> eval(const Expression * expr); 486 486 487 487 namespace ast { -
src/GenPoly/Box.cc
r8e1467d r4a60488 725 725 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 726 726 727 if ( arg-> result->get_lvalue() ) {727 if ( arg->get_lvalue() ) { 728 728 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 729 729 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { -
src/GenPoly/Lvalue.cc
r8e1467d r4a60488 363 363 int diff = depth1 - depth2; 364 364 365 if ( diff > 0 && ! srcType->get_lvalue() ) {365 if ( diff > 0 && ! castExpr->arg->get_lvalue() ) { 366 366 // rvalue to reference conversion -- introduce temporary 367 367 // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g. … … 407 407 ret = new AddressExpr( ret ); 408 408 } 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() ) ) { 410 410 // must keep cast if cast-to type is different from the actual type 411 411 castExpr->arg = ret; -
src/InitTweak/InitTweak.cc
r8e1467d r4a60488 9 9 // Author : Rob Schluntz 10 10 // Created On : Fri May 13 11:26:36 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Jun 19 14:34:00201913 // Update Count : 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:21:48 2019 13 // Update Count : 7 14 14 // 15 15 … … 957 957 void previsit( OffsetofExpr * ) {} 958 958 void previsit( OffsetPackExpr * ) {} 959 void previsit( AttrExpr * ) {}960 959 void previsit( CommaExpr * ) {} 961 960 void previsit( LogicalExpr * ) {} -
src/Makefile.am
r8e1467d r4a60488 11 11 ## Created On : Sun May 31 08:51:46 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Fri Feb 15 09:44:09201914 ## Update Count : 9 713 ## Last Modified On : Mon Aug 5 12:57:46 2019 14 ## Update Count : 98 15 15 ############################################################################### 16 16 … … 55 55 $(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h 56 56 57 $(srcdir)/ SynTree/Type.h: BasicTypes-gen.cc57 $(srcdir)/AST/Type.hpp : BasicTypes-gen.cc 58 58 ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra 59 59 @./BasicTypes-gen … … 62 62 # put into lib for now 63 63 cfa_cpplibdir = $(CFA_LIBDIR) 64 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp demangler 64 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp $(DEMANGLER) 65 EXTRA_PROGRAMS = demangler 65 66 ___driver_cfa_cpp_SOURCES = $(SRC) 66 67 ___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC) … … 74 75 demangler_LDADD = libdemangle.a -ldl # yywrap 75 76 76 noinst_LIBRARIES = libdemangle.a 77 noinst_LIBRARIES = $(LIBDEMANGLE) 78 EXTRA_LIBRARIES = libdemangle.a 77 79 libdemangle_a_SOURCES = $(SRCDEMANGLE) 78 80 -
src/Makefile.in
r8e1467d r4a60488 141 141 build_triplet = @build@ 142 142 host_triplet = @host@ 143 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp$(EXEEXT) demangler$(EXEEXT) 143 cfa_cpplib_PROGRAMS = ../driver/cfa-cpp$(EXEEXT) $(DEMANGLER) 144 EXTRA_PROGRAMS = demangler$(EXEEXT) 144 145 subdir = src 145 146 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 … … 231 232 SynTree/Initializer.$(OBJEXT) \ 232 233 SynTree/TypeSubstitution.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \ 233 SynTree/DeclReplacer.$(OBJEXT) 234 SynTree/DeclReplacer.$(OBJEXT) SynTree/TopLvalue.$(OBJEXT) 234 235 am__objects_8 = CompilationState.$(OBJEXT) $(am__objects_1) \ 235 236 $(am__objects_2) Concurrency/Keywords.$(OBJEXT) \ … … 411 412 CCDEPMODE = @CCDEPMODE@ 412 413 CFACC = @CFACC@ 414 CFACC_INSTALL = @CFACC_INSTALL@ 413 415 CFACPP = @CFACPP@ 414 416 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 428 430 CYGPATH_W = @CYGPATH_W@ 429 431 DEFS = @DEFS@ 432 DEMANGLER = @DEMANGLER@ 430 433 DEPDIR = @DEPDIR@ 431 434 DLLTOOL = @DLLTOOL@ … … 440 443 FGREP = @FGREP@ 441 444 GREP = @GREP@ 445 HAS_DISTCC = @HAS_DISTCC@ 442 446 HOST_FLAGS = @HOST_FLAGS@ 443 447 INSTALL = @INSTALL@ … … 453 457 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 454 458 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 459 LIBDEMANGLE = @LIBDEMANGLE@ 455 460 LIBOBJS = @LIBOBJS@ 456 461 LIBS = @LIBS@ … … 693 698 SynTree/TypeSubstitution.cc \ 694 699 SynTree/Attribute.cc \ 695 SynTree/DeclReplacer.cc 700 SynTree/DeclReplacer.cc \ 701 SynTree/TopLvalue.cc 696 702 697 703 … … 705 711 demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete 706 712 demangler_LDADD = libdemangle.a -ldl # yywrap 707 noinst_LIBRARIES = libdemangle.a 713 noinst_LIBRARIES = $(LIBDEMANGLE) 714 EXTRA_LIBRARIES = libdemangle.a 708 715 libdemangle_a_SOURCES = $(SRCDEMANGLE) 709 716 all: $(BUILT_SOURCES) … … 1023 1030 SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \ 1024 1031 SynTree/$(DEPDIR)/$(am__dirstamp) 1032 SynTree/TopLvalue.$(OBJEXT): SynTree/$(am__dirstamp) \ 1033 SynTree/$(DEPDIR)/$(am__dirstamp) 1025 1034 Tuples/$(am__dirstamp): 1026 1035 @$(MKDIR_P) Tuples … … 1334 1343 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ReferenceType.Po@am__quote@ 1335 1344 @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@ 1336 1346 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleExpr.Po@am__quote@ 1337 1347 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleType.Po@am__quote@ … … 1667 1677 $(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h 1668 1678 1669 $(srcdir)/ SynTree/Type.h: BasicTypes-gen.cc1679 $(srcdir)/AST/Type.hpp : BasicTypes-gen.cc 1670 1680 ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra 1671 1681 @./BasicTypes-gen -
src/Parser/DeclarationNode.cc
r8e1467d r4a60488 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 1 16:49:17201913 // Update Count : 111 312 // Last Modified On : Thu Jul 25 22:17:10 2019 13 // Update Count : 1116 14 14 // 15 15 … … 49 49 const char * DeclarationNode::aggregateNames[] = { "struct", "union", "trait", "coroutine", "monitor", "thread", "NoAggregateNames" }; 50 50 const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" }; 51 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", " zero_t", "one_t", "NoBuiltinTypeNames" };51 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" }; 52 52 53 53 UniqueName DeclarationNode::anonymous( "__anonymous" ); … … 418 418 return newnode; 419 419 } // 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 }438 420 439 421 DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) { -
src/Parser/ExpressionNode.cc
r8e1467d r4a60488 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Mar 10 16:10:32201913 // Update Count : 97 612 // Last Modified On : Sun Aug 4 20:57:55 2019 13 // Update Count : 978 14 14 // 15 15 … … 109 109 110 110 Expression * build_constantInteger( string & str ) { 111 static const BasicType::Kind kind[2][ 7] = {111 static const BasicType::Kind kind[2][6] = { 112 112 // short (h) must be before char (hh) because shorter type has the longer suffix 113 113 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, }, -
src/Parser/ParseNode.h
r8e1467d r4a60488 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 15 14:22:39201913 // Update Count : 87 412 // Last Modified On : Thu Jul 25 22:17:10 2019 13 // Update Count : 876 14 14 // 15 15 … … 221 221 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass }; 222 222 static const char * typeClassNames[]; 223 enum BuiltinType { Valist, Zero, One, NoBuiltinType };223 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType }; 224 224 static const char * builtinTypeNames[]; 225 225 … … 252 252 static DeclarationNode * newTuple( DeclarationNode * members ); 253 253 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false ); 254 static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes255 static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes256 254 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes 257 255 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement -
src/Parser/lex.ll
r8e1467d r4a60488 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Wed May 15 21:25:27 201913 * Update Count : 7 0812 * Last Modified On : Sun Aug 4 20:53:47 2019 13 * Update Count : 719 14 14 */ 15 15 … … 59 59 #define QKEYWORD_RETURN(x) RETURN_VAL(x); // quasi-keyword 60 60 #define IDENTIFIER_RETURN() RETURN_VAL( typedefTable.isKind( yytext ) ) 61 #define ATTRIBUTE_RETURN() RETURN_VAL( ATTR_IDENTIFIER )62 61 63 62 #ifdef HAVE_KEYWORDS_FLOATXX // GCC >= 7 => keyword, otherwise typedef … … 92 91 // identifier, GCC: $ in identifier 93 92 identifier ([a-zA-Z_$]|{universal_char})([0-9a-zA-Z_$]|{universal_char})* 94 95 // attribute identifier, GCC: $ in identifier96 attr_identifier "@"{identifier}97 93 98 94 // numeric constants, CFA: '_' in constant … … 218 214 __attribute__ { KEYWORD_RETURN(ATTRIBUTE); } // GCC 219 215 auto { KEYWORD_RETURN(AUTO); } 216 __auto_type { KEYWORD_RETURN(AUTO_TYPE); } 220 217 basetypeof { KEYWORD_RETURN(BASETYPEOF); } // CFA 221 218 _Bool { KEYWORD_RETURN(BOOL); } // C99 … … 276 273 __inline__ { KEYWORD_RETURN(INLINE); } // GCC 277 274 int { KEYWORD_RETURN(INT); } 275 int128 { KEYWORD_RETURN(INT128); } // CFA 278 276 __int128 { KEYWORD_RETURN(INT128); } // GCC 279 int128{ KEYWORD_RETURN(INT128); } // GCC277 __int128_t { KEYWORD_RETURN(INT128); } // GCC 280 278 __label__ { KEYWORD_RETURN(LABEL); } // GCC 281 279 long { KEYWORD_RETURN(LONG); } … … 292 290 __restrict__ { KEYWORD_RETURN(RESTRICT); } // GCC 293 291 return { KEYWORD_RETURN(RETURN); } 292 /* resume { KEYWORD_RETURN(RESUME); } // CFA */ 294 293 short { KEYWORD_RETURN(SHORT); } 295 294 signed { KEYWORD_RETURN(SIGNED); } … … 300 299 _Static_assert { KEYWORD_RETURN(STATICASSERT); } // C11 301 300 struct { KEYWORD_RETURN(STRUCT); } 301 /* suspend { KEYWORD_RETURN(SUSPEND); } // CFA */ 302 302 switch { KEYWORD_RETURN(SWITCH); } 303 303 thread { KEYWORD_RETURN(THREAD); } // C11 … … 314 314 __typeof__ { KEYWORD_RETURN(TYPEOF); } // GCC 315 315 union { KEYWORD_RETURN(UNION); } 316 __uint128_t { KEYWORD_RETURN(UINT128); } // GCC 316 317 unsigned { KEYWORD_RETURN(UNSIGNED); } 317 318 __builtin_va_list { KEYWORD_RETURN(VALIST); } // GCC … … 333 334 IDENTIFIER_RETURN(); 334 335 } 335 {attr_identifier} { ATTRIBUTE_RETURN(); }336 336 337 337 /* numeric constants */ -
src/Parser/parser.yy
r8e1467d r4a60488 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 14 07:54:30201913 // Update Count : 43 5512 // Last Modified On : Sun Aug 4 21:48:23 2019 13 // Update Count : 4364 14 14 // 15 15 … … 268 268 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 269 269 %token BOOL COMPLEX IMAGINARY // C99 270 %token INT128 uuFLOAT80 uuFLOAT128// GCC270 %token INT128 UINT128 uuFLOAT80 uuFLOAT128 // GCC 271 271 %token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC 272 272 %token ZERO_T ONE_T // CFA 273 273 %token VALIST // GCC 274 %token AUTO_TYPE // GCC 274 275 %token TYPEOF BASETYPEOF LABEL // GCC 275 276 %token ENUM STRUCT UNION … … 288 289 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDEFname TYPEGENname 289 290 %token<tok> TIMEOUT WOR 290 %token<tok> ATTR_IDENTIFIER ATTR_TYPEDEFname ATTR_TYPEGENname291 291 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral 292 292 %token<tok> DIRECTIVE … … 312 312 %token ATassign // @= 313 313 314 %type<tok> identifier no_attr_identifier315 %type<tok> identifier_or_type_name no_attr_identifier_or_type_nameattr_name314 %type<tok> identifier 315 %type<tok> identifier_or_type_name attr_name 316 316 %type<tok> quasi_keyword 317 317 %type<constant> string_literal … … 546 546 ; 547 547 548 no_attr_identifier:548 identifier: 549 549 IDENTIFIER 550 550 | quasi_keyword 551 551 | '@' // CFA 552 552 { Token tok = { new string( DeclarationNode::anonymous.newName() ), yylval.tok.loc }; $$ = tok; } 553 ;554 555 identifier:556 no_attr_identifier557 | ATTR_IDENTIFIER // CFA558 553 ; 559 554 … … 594 589 | '(' comma_expression ')' '`' IDENTIFIER // CFA, postfix call 595 590 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); } 596 | type_name '.' no_attr_identifier// CFA, nested type591 | type_name '.' identifier // CFA, nested type 597 592 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 598 593 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector … … 647 642 | postfix_expression '(' argument_expression_list ')' 648 643 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 649 | postfix_expression '.' no_attr_identifier644 | postfix_expression '.' identifier 650 645 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 651 646 | postfix_expression '.' INTEGERconstant // CFA, tuple index … … 655 650 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 656 651 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 657 | postfix_expression ARROW no_attr_identifier652 | postfix_expression ARROW identifier 658 653 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 659 654 | postfix_expression ARROW INTEGERconstant // CFA, tuple index … … 718 713 | FLOATINGconstant fraction_constants_opt 719 714 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); } 720 | no_attr_identifier fraction_constants_opt715 | identifier fraction_constants_opt 721 716 { 722 717 $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); … … 776 771 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 777 772 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); } 778 | OFFSETOF '(' type_no_function ',' no_attr_identifier ')'773 | OFFSETOF '(' type_no_function ',' identifier ')' 779 774 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); } 780 | ATTR_IDENTIFIER781 { $$ = 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 ) ) ); }786 775 ; 787 776 … … 1018 1007 1019 1008 labeled_statement: 1020 // labels cannot be identifiers 0 or 1 or ATTR_IDENTIFIER1009 // labels cannot be identifiers 0 or 1 1021 1010 identifier_or_type_name ':' attribute_list_opt statement 1022 1011 { $$ = $4->add_label( $1, $3 ); } … … 1386 1375 | type_specifier_nobody variable_abstract_declarator 1387 1376 { $$ = $2->addType( $1 ); } 1388 | cfa_abstract_declarator_tuple no_attr_identifier// CFA1377 | cfa_abstract_declarator_tuple identifier // CFA 1389 1378 { $$ = $1->addName( $2 ); } 1390 1379 | cfa_abstract_declarator_tuple // CFA … … 1450 1439 1451 1440 label_list: 1452 no_attr_identifier1441 identifier 1453 1442 { 1454 1443 $$ = new LabelNode(); $$->labels.push_back( *$1 ); 1455 1444 delete $1; // allocated by lexer 1456 1445 } 1457 | label_list ',' no_attr_identifier1446 | label_list ',' identifier 1458 1447 { 1459 1448 $$ = $1; $1->labels.push_back( *$3 ); … … 1500 1489 1501 1490 local_label_list: // GCC, local label 1502 no_attr_identifier_or_type_name1503 | local_label_list ',' no_attr_identifier_or_type_name1491 identifier_or_type_name 1492 | local_label_list ',' identifier_or_type_name 1504 1493 ; 1505 1494 … … 1623 1612 $$ = $2->addTypedef(); 1624 1613 } 1625 | cfa_typedef_declaration pop ',' push no_attr_identifier1614 | cfa_typedef_declaration pop ',' push identifier 1626 1615 { 1627 1616 typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "3" ); … … 1663 1652 typedef_expression: 1664 1653 // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression 1665 TYPEDEF no_attr_identifier '=' assignment_expression1654 TYPEDEF identifier '=' assignment_expression 1666 1655 { 1667 1656 // $$ = DeclarationNode::newName( 0 ); // unimplemented 1668 1657 SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr; 1669 1658 } 1670 | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression1659 | typedef_expression pop ',' push identifier '=' assignment_expression 1671 1660 { 1672 1661 // $$ = DeclarationNode::newName( 0 ); // unimplemented … … 1837 1826 | INT128 1838 1827 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 ); } 1828 | UINT128 1829 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ); } 1839 1830 | FLOAT 1840 1831 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); } … … 1871 1862 | VALIST // GCC, __builtin_va_list 1872 1863 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); } 1864 | AUTO_TYPE 1865 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::AutoType ); } 1873 1866 ; 1874 1867 … … 1912 1905 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 1913 1906 { $$ = 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 ); }1918 1907 | ZERO_T // CFA 1919 1908 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); } … … 2024 2013 '{' field_declaration_list_opt '}' type_parameters_opt 2025 2014 { $$ = DeclarationNode::newAggregate( $1, nullptr, $7, $5, true )->addQualifiers( $2 ); } 2026 | aggregate_key attribute_list_opt no_attr_identifier fred2015 | aggregate_key attribute_list_opt identifier fred 2027 2016 { 2028 2017 typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef … … 2050 2039 2051 2040 aggregate_type_nobody: // struct, union - {...} 2052 aggregate_key attribute_list_opt no_attr_identifier fred2041 aggregate_key attribute_list_opt identifier fred 2053 2042 { 2054 2043 typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); … … 2151 2140 cfa_field_declaring_list: // CFA, new style field declaration 2152 2141 // bit-fields are handled by C declarations 2153 cfa_abstract_declarator_tuple no_attr_identifier_or_type_name2142 cfa_abstract_declarator_tuple identifier_or_type_name 2154 2143 { $$ = $1->addName( $2 ); } 2155 | cfa_field_declaring_list ',' no_attr_identifier_or_type_name2144 | cfa_field_declaring_list ',' identifier_or_type_name 2156 2145 { $$ = $1->appendList( $1->cloneType( $3 ) ); } 2157 2146 ; … … 2178 2167 ENUM attribute_list_opt '{' enumerator_list comma_opt '}' 2179 2168 { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); } 2180 | ENUM attribute_list_opt no_attr_identifier2169 | ENUM attribute_list_opt identifier 2181 2170 { typedefTable.makeTypedef( *$3 ); } 2182 2171 '{' enumerator_list comma_opt '}' … … 2189 2178 2190 2179 enum_type_nobody: // enum - {...} 2191 ENUM attribute_list_opt no_attr_identifier2180 ENUM attribute_list_opt identifier 2192 2181 { 2193 2182 typedefTable.makeTypedef( *$3 ); … … 2202 2191 2203 2192 enumerator_list: 2204 no_attr_identifier_or_type_name enumerator_value_opt2193 identifier_or_type_name enumerator_value_opt 2205 2194 { $$ = DeclarationNode::newEnumConstant( $1, $2 ); } 2206 | enumerator_list ',' no_attr_identifier_or_type_name enumerator_value_opt2195 | enumerator_list ',' identifier_or_type_name enumerator_value_opt 2207 2196 { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); } 2208 2197 ; … … 2312 2301 2313 2302 identifier_list: // K&R-style parameter list => no types 2314 no_attr_identifier2303 identifier 2315 2304 { $$ = DeclarationNode::newName( $1 ); } 2316 | identifier_list ',' no_attr_identifier2305 | identifier_list ',' identifier 2317 2306 { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); } 2318 2307 ; … … 2320 2309 identifier_or_type_name: 2321 2310 identifier 2322 | TYPEDEFname2323 | TYPEGENname2324 ;2325 2326 no_attr_identifier_or_type_name:2327 no_attr_identifier2328 2311 | TYPEDEFname 2329 2312 | TYPEGENname … … 2380 2363 designation: 2381 2364 designator_list ':' // C99, CFA uses ":" instead of "=" 2382 | no_attr_identifier ':'// GCC, field name2365 | identifier ':' // GCC, field name 2383 2366 { $$ = new ExpressionNode( build_varref( $1 ) ); } 2384 2367 ; … … 2392 2375 2393 2376 designator: 2394 '.' no_attr_identifier// C99, field name2377 '.' identifier // C99, field name 2395 2378 { $$ = new ExpressionNode( build_varref( $2 ) ); } 2396 2379 | '[' push assignment_expression pop ']' // C99, single array element … … 2437 2420 2438 2421 type_parameter: // CFA 2439 type_class no_attr_identifier_or_type_name2422 type_class identifier_or_type_name 2440 2423 { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); } 2441 2424 type_initializer_opt assertion_list_opt … … 2470 2453 2471 2454 assertion: // CFA 2472 '|' no_attr_identifier_or_type_name '(' type_list ')'2455 '|' identifier_or_type_name '(' type_list ')' 2473 2456 { $$ = DeclarationNode::newTraitUse( $2, $4 ); } 2474 2457 | '|' '{' push trait_declaration_list pop '}' … … 2507 2490 2508 2491 type_declarator_name: // CFA 2509 no_attr_identifier_or_type_name2492 identifier_or_type_name 2510 2493 { 2511 2494 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 2512 2495 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 2513 2496 } 2514 | no_attr_identifier_or_type_name '(' type_parameter_list ')'2497 | identifier_or_type_name '(' type_parameter_list ')' 2515 2498 { 2516 2499 typedefTable.addToEnclosingScope( *$1, TYPEGENname, "11" ); … … 2520 2503 2521 2504 trait_specifier: // CFA 2522 TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' '}'2505 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 2523 2506 { $$ = 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 '}' 2525 2508 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 2526 2509 ; -
src/ResolvExpr/AlternativeFinder.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:52:08 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Nov 1 21:00:56 201813 // Update Count : 3 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:35:00 2019 13 // Update Count : 38 14 14 // 15 15 … … 79 79 void postvisit( OffsetofExpr * offsetofExpr ); 80 80 void postvisit( OffsetPackExpr * offsetPackExpr ); 81 void postvisit( AttrExpr * attrExpr );82 81 void postvisit( LogicalExpr * logicalExpr ); 83 82 void postvisit( ConditionalExpr * conditionalExpr ); … … 378 377 } 379 378 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 ) { 381 381 PRINT( 382 382 std::cerr << std::endl << "converting "; … … 388 388 std::cerr << std::endl; 389 389 ) 390 Cost convCost = conversionCost( actualType, formalType, indexer, env );390 Cost convCost = conversionCost( actualType, formalType, actualIsLvalue, indexer, env ); 391 391 PRINT( 392 392 std::cerr << std::endl << "cost is " << convCost << std::endl; … … 403 403 404 404 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 ); 406 407 407 408 // if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion. … … 1136 1137 bool isLvalue( Expression *expr ) { 1137 1138 // 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 ) ); 1139 1140 } 1140 1141 … … 1187 1188 assert( toType ); 1188 1189 toType = resolveTypeof( toType, indexer ); 1190 assert(!dynamic_cast<TypeofType *>(toType)); 1189 1191 SymTab::validateType( toType, &indexer ); 1190 1192 adjustExprType( toType, env, indexer ); … … 1213 1215 unify( castExpr->result, alt.expr->result, alt.env, needAssertions, 1214 1216 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 ); 1217 1219 PRINT( 1218 1220 std::cerr << "working on cast with result: " << castExpr->result << std::endl; … … 1402 1404 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1403 1405 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 polymorphism1409 // assume no implicit conversions1410 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 } // for1429 } // if1430 }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 function1443 if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) {1444 // assume exactly one parameter1445 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 } // fi1455 } // for1456 } // if1457 } // if1458 } // if1459 } // for1460 } 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 } // for1468 } // if1469 1406 } 1470 1407 … … 1706 1643 // xxx - do some inspecting on this line... why isn't result bound to initAlt.type? 1707 1644 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 ); 1709 1647 if ( thisCost != Cost::infinity ) { 1710 1648 // count one safe conversion for each value that is thrown away -
src/ResolvExpr/CastCost.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 06:57:43 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Feb 2 15:34:36 201613 // Update Count : 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:12:00 2019 13 // Update Count : 8 14 14 // 15 15 … … 37 37 struct CastCost_old : public ConversionCost { 38 38 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 ); 40 41 41 42 using ConversionCost::previsit; … … 45 46 }; 46 47 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 ) { 48 50 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 49 51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 50 52 if ( eqvClass->type ) { 51 return castCost( src, eqvClass->type, indexer, env );53 return castCost( src, eqvClass->type, srcIsLvalue, indexer, env ); 52 54 } else { 53 55 return Cost::infinity; … … 57 59 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType ); 58 60 if ( type->base ) { 59 return castCost( src, type->base, indexer, env ) + Cost::safe;61 return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe; 60 62 } // if 61 63 } // if … … 78 80 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 79 81 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 ) { 81 83 return ptrsCastable( t1, t2, env, indexer ); 82 84 }); 83 85 } else { 84 86 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 & )) 87 89 castCost ); 88 90 src->accept( converter ); … … 96 98 } 97 99 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 ) { 100 103 } 101 104 … … 106 109 cost = Cost::unsafe; 107 110 } else { 108 cost = conversionCost( basicType, dest, indexer, env );111 cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env ); 109 112 } // if 110 113 } -
src/ResolvExpr/CommonType.cc
r8e1467d r4a60488 190 190 */ 191 191 { 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, 193 193 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 194 194 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 198 198 }, 199 199 { 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, 201 201 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 202 202 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 206 206 }, 207 207 { 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, 209 209 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 210 210 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 214 214 }, 215 215 { 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, 217 217 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 218 218 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 222 222 }, 223 223 { 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, 225 225 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 226 226 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 230 230 }, 231 231 { 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, 233 233 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 234 234 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 238 238 }, 239 239 { 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, 241 241 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 242 242 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 246 246 }, 247 247 { 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, 249 249 BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 250 250 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 254 254 }, 255 255 { 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, 257 257 BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 258 258 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 262 262 }, 263 263 { 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, 265 265 BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 266 266 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 270 270 }, 271 271 { 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, 273 273 BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 274 274 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 278 278 }, 279 279 { 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, 281 281 BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 282 282 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 286 286 }, 287 287 { 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, 289 289 BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 290 290 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 294 294 }, 295 295 { 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, 297 297 BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 298 298 BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 302 302 }, 303 303 { 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, 305 305 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 306 306 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 310 310 }, 311 311 { 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, 313 313 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 314 314 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex, … … 318 318 }, 319 319 { 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, 321 321 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 322 322 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex, … … 326 326 }, 327 327 { 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, 329 329 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 330 330 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, … … 334 334 }, 335 335 { 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, 337 337 BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 338 338 BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex, … … 342 342 }, 343 343 { 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, 345 345 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 346 346 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, … … 350 350 }, 351 351 { 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, 353 353 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 354 354 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, … … 358 358 }, 359 359 { 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, 361 361 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 362 362 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, … … 366 366 }, 367 367 { 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, 369 369 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 370 370 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, … … 374 374 }, 375 375 { 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, 377 377 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 378 378 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, … … 382 382 }, 383 383 { 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, 385 385 BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 386 386 BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, … … 390 390 }, 391 391 { 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, 393 393 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 394 394 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, … … 398 398 }, 399 399 { 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, 401 401 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 402 402 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, … … 406 406 }, 407 407 { 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, 409 409 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 410 410 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, … … 414 414 }, 415 415 { 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, 417 417 BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, 418 418 BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, … … 422 422 }, 423 423 { 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, 425 425 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 426 426 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, … … 430 430 }, 431 431 { 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, 433 433 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 434 434 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, … … 438 438 }, 439 439 { 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, 441 441 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 442 442 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, … … 446 446 }, 447 447 { 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, 449 449 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 450 450 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, … … 454 454 }, 455 455 { 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, 457 457 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 458 458 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, … … 462 462 }, 463 463 { 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, 465 465 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 466 466 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, -
src/ResolvExpr/ConversionCost.cc
r8e1467d r4a60488 46 46 #endif 47 47 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 ) { 49 50 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 50 51 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 51 52 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 52 53 if ( eqvClass->type ) { 53 return conversionCost( src, eqvClass->type, indexer, env );54 return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env ); 54 55 } else { 55 56 return Cost::infinity; … … 61 62 assert( type ); 62 63 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; 64 66 } // if 65 67 } // if … … 81 83 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 82 84 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 ){ 84 86 return ptrsAssignable( t1, t2, env ); 85 87 }); 86 88 } else { 87 89 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&)) 90 92 conversionCost ); 91 93 src->accept( converter ); … … 98 100 } 99 101 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 ) { 101 104 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 102 105 if ( diff > 0 ) { 103 106 // 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 ); 105 110 cost.incReference(); 106 111 return cost; 107 112 } else if ( diff < -1 ) { 108 113 // 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 ); 110 117 cost.incReference(); 111 118 return cost; … … 138 145 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 139 146 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&)) 142 149 conversionCost ); 143 150 src->accept( converter ); … … 150 157 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) { 151 158 PRINT( std::cerr << "converting compatible base type" << std::endl; ) 152 if ( src ->get_lvalue()) {159 if ( srcIsLvalue ) { 153 160 PRINT( 154 161 std::cerr << "lvalue to reference conversion" << std::endl; … … 178 185 } 179 186 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 ) { 181 189 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 182 Cost cost = convertToReferenceCost( src, dest, s depth-ddepth, indexer, env, func );190 Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func ); 183 191 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; ) 184 192 return cost; 185 193 } 186 194 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 ) { 189 197 } 190 198 … … 217 225 // GENERATED BY BasicTypes-gen.cc 218 226 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, }, 255 263 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 256 264 }; // costMatrix … … 265 273 // GENERATED BY BasicTypes-gen.cc 266 274 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, }, 303 311 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 304 312 }; // signMatrix … … 371 379 // recursively compute conversion cost from T1 to T2. 372 380 // 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 ); 374 382 if ( refType->base->tq == dest->tq ) { 375 383 cost.incReference(); // prefer exact qualifiers … … 403 411 static Type::Qualifiers q; 404 412 static BasicType integer( q, BasicType::SignedInt ); 405 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int413 cost = costFunc( &integer, dest, srcIsLvalue, indexer, env ); // safe if dest >= int 406 414 if ( cost < Cost::unsafe ) { 407 415 cost.incSafe(); … … 413 421 void ConversionCost::postvisit( const TypeInstType * inst ) { 414 422 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 ); 416 424 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) { 417 425 if ( inst->name == destAsInst->name ) { … … 423 431 assert( type ); 424 432 if ( type->base ) { 425 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;433 cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe; 426 434 } // if 427 435 } // if … … 434 442 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 435 443 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 ); 437 445 if ( newCost == Cost::infinity ) { 438 446 return; … … 534 542 } 535 543 536 Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, int diff,537 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,544 static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, 545 int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env, 538 546 NumCostCalculation func ) { 539 547 if ( 0 < diff ) { -
src/ResolvExpr/ConversionCost.h
r8e1467d r4a60488 10 10 // Created On : Sun May 17 09:37:28 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 24 10:00:00 201913 // Update Count : 512 // Last Modified On : Thu Aug 8 16:13:00 2019 13 // Update Count : 6 14 14 // 15 15 … … 33 33 class TypeEnvironment; 34 34 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 36 38 struct ConversionCost : public WithShortCircuiting { 37 39 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 ); 39 42 40 43 Cost get_cost() const { return cost; } … … 59 62 protected: 60 63 const Type * dest; 64 bool srcIsLvalue; 61 65 const SymTab::Indexer &indexer; 62 66 Cost cost; … … 66 70 67 71 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 ); 69 74 70 75 // Some function pointer types, differ in return type. -
src/ResolvExpr/ResolveAssertions.cc
r8e1467d r4a60488 9 9 // Author : Aaron B. Moss 10 10 // Created On : Fri Oct 05 13:46:00 2018 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jul 10 16:10:37201913 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:47:00 2019 13 // Update Count : 3 14 14 // 15 15 … … 156 156 for ( const auto& assn : x.assns ) { 157 157 // compute conversion cost from satisfying decl to assertion 158 assert( !assn.match.adjType->get_lvalue() ); 158 159 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 ); 160 161 161 162 // mark vars+specialization cost on function-type assertions -
src/ResolvExpr/Unify.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:27:10 2015 11 // Last Modified By : A aron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 4 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 4 10:00:00 2019 13 // Update Count : 44 14 14 // 15 15 … … 274 274 #endif 275 275 if ( ( common = commonType( type1, type2, widen.first, widen.second, indexer, env, openVars ) ) ) { 276 common-> get_qualifiers() = tq1 | tq2;276 common->tq = tq1.unify( tq2 ); 277 277 #ifdef DEBUG 278 278 std::cerr << "unifyInexact: common type is "; … … 291 291 if ( ( tq1 > tq2 || widen.first ) && ( tq2 > tq1 || widen.second ) ) { 292 292 common = type1->clone(); 293 common-> get_qualifiers() = tq1 | tq2;293 common->tq = tq1.unify( tq2 ); 294 294 result = true; 295 295 } else { … … 298 298 } else { 299 299 common = type1->clone(); 300 common-> get_qualifiers() = tq1 | tq2;300 common->tq = tq1.unify( tq2 ); 301 301 result = true; 302 302 } // if -
src/ResolvExpr/typeops.h
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 07:28:22 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Feb 8 09:30:34201913 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Aug 8 16:36:00 2019 13 // Update Count : 5 14 14 // 15 15 … … 80 80 81 81 // 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 ); 83 84 Cost castCost( 84 85 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, … … 86 87 87 88 // 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 ); 89 91 Cost conversionCost( 90 92 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, … … 92 94 93 95 // in AlternativeFinder.cc 94 Cost computeConversionCost( Type * actualType, Type * formalType, 96 Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue, 95 97 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 96 98 -
src/SymTab/Demangle.cc
r8e1467d r4a60488 9 9 // Author : Rob Schluntz 10 10 // Created On : Thu Jul 19 12:52:41 2018 11 // Last Modified By : Rob Schluntz12 // Last Modified On : T hu Jul 19 12:54:35 201813 // Update Count : 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 30 13:46:33 2019 13 // Update Count : 3 14 14 // 15 15 … … 313 313 typeString = "_Atomic " + typeString; 314 314 } // if 315 if ( type->get_lvalue() ) {316 // when not generating C code, print lvalue for debugging.317 typeString = "lvalue " + typeString;318 }319 315 } 320 316 } -
src/SymTab/Mangler.cc
r8e1467d r4a60488 10 10 // Created On : Sun May 17 21:40:29 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 15:49:26 201713 // Update Count : 2 312 // Last Modified On : Tue Jul 30 13:46:10 2019 13 // Update Count : 26 14 14 // 15 15 #include "Mangler.h" … … 377 377 mangleName << Encoding::qualifiers.at(Type::Mutex); 378 378 } // if 379 if ( type->get_lvalue() ) {380 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues381 mangleName << Encoding::qualifiers.at(Type::Lvalue);382 }383 384 379 if ( inFunctionType ) { 385 380 // turn off inFunctionType so that types can be differentiated for nested qualifiers … … 724 719 mangleName << Encoding::qualifiers.at(Type::Mutex); 725 720 } // if 726 if ( type->is_lvalue() ) {727 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues728 mangleName << Encoding::qualifiers.at(Type::Lvalue);729 }730 731 721 if ( inFunctionType ) { 732 722 // turn off inFunctionType so that types can be differentiated for nested qualifiers -
src/SymTab/Validate.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:50:04 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Aug 28 13:47:23 201713 // Update Count : 3 5911 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Aug 7 6:42:00 2019 13 // Update Count : 360 14 14 // 15 15 … … 81 81 #include "SynTree/Label.h" // for operator==, Label 82 82 #include "SynTree/Mutator.h" // for Mutator 83 #include "SynTree/TopLvalue.h" // for assertTopLvalue, clearInnerLvalue 83 84 #include "SynTree/Type.h" // for Type, TypeInstType, EnumInstType 84 85 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution … … 308 309 PassVisitor<FixQualifiedTypes> fixQual; 309 310 311 assertTopLvalue( translationUnit ); 310 312 { 311 313 Stats::Heap::newPass("validate-A"); … … 316 318 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling 317 319 } 320 assertTopLvalue( translationUnit ); 318 321 { 319 322 Stats::Heap::newPass("validate-B"); 320 323 Stats::Time::BlockGuard guard("validate-B"); 324 assertTopLvalue( translationUnit ); 321 325 Stats::Time::TimeBlock("Link Reference To Types", [&]() { 322 326 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 323 327 }); 328 clearInnerLvalue( translationUnit ); 329 assertTopLvalue( translationUnit ); 324 330 Stats::Time::TimeBlock("Fix Qualified Types", [&]() { 325 331 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed 326 332 }); 333 assertTopLvalue( translationUnit ); 327 334 Stats::Time::TimeBlock("Hoist Structs", [&]() { 328 335 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 329 336 }); 337 assertTopLvalue( translationUnit ); 330 338 Stats::Time::TimeBlock("Eliminate Typedefs", [&]() { 331 339 EliminateTypedef::eliminateTypedef( translationUnit ); // 332 340 }); 333 341 } 342 assertTopLvalue( translationUnit ); 334 343 { 335 344 Stats::Heap::newPass("validate-C"); … … 340 349 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen 341 350 } 351 assertTopLvalue( translationUnit ); 342 352 { 343 353 Stats::Heap::newPass("validate-D"); 344 354 Stats::Time::BlockGuard guard("validate-D"); 355 assertTopLvalue( translationUnit ); 345 356 Stats::Time::TimeBlock("Apply Concurrent Keywords", [&]() { 346 357 Concurrency::applyKeywords( translationUnit ); 347 358 }); 359 clearInnerLvalue( translationUnit ); 360 assertTopLvalue( translationUnit ); 348 361 Stats::Time::TimeBlock("Forall Pointer Decay", [&]() { 349 362 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution 350 363 }); 364 assertTopLvalue( translationUnit ); 351 365 Stats::Time::TimeBlock("Hoist Control Declarations", [&]() { 352 366 ControlStruct::hoistControlDecls( translationUnit ); // hoist initialization out of for statements; must happen before autogenerateRoutines 353 367 }); 368 assertTopLvalue( translationUnit ); 354 369 Stats::Time::TimeBlock("Generate Autogen routines", [&]() { 355 370 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old 356 371 }); 357 } 372 clearInnerLvalue( translationUnit ); 373 } 374 assertTopLvalue( translationUnit ); 358 375 { 359 376 Stats::Heap::newPass("validate-E"); 360 377 Stats::Time::BlockGuard guard("validate-E"); 378 assertTopLvalue( translationUnit ); 361 379 Stats::Time::TimeBlock("Implement Mutex Func", [&]() { 362 380 Concurrency::implementMutexFuncs( translationUnit ); 363 381 }); 382 clearInnerLvalue( translationUnit ); 383 assertTopLvalue( translationUnit ); 364 384 Stats::Time::TimeBlock("Implement Thread Start", [&]() { 365 385 Concurrency::implementThreadStarter( translationUnit ); 366 386 }); 387 assertTopLvalue( translationUnit ); 367 388 Stats::Time::TimeBlock("Compound Literal", [&]() { 368 389 mutateAll( translationUnit, compoundliteral ); 369 390 }); 391 assertTopLvalue( translationUnit ); 370 392 Stats::Time::TimeBlock("Resolve With Expressions", [&]() { 371 393 ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables 372 394 }); 373 } 395 clearInnerLvalue( translationUnit ); 396 } 397 assertTopLvalue( translationUnit ); 374 398 { 375 399 Stats::Heap::newPass("validate-F"); 376 400 Stats::Time::BlockGuard guard("validate-F"); 401 assertTopLvalue( translationUnit ); 377 402 Stats::Time::TimeBlock("Fix Object Type", [&]() { 378 403 FixObjectType::fix( translationUnit ); 379 404 }); 405 assertTopLvalue( translationUnit ); 380 406 Stats::Time::TimeBlock("Array Length", [&]() { 381 407 ArrayLength::computeLength( translationUnit ); 382 408 }); 409 clearInnerLvalue( translationUnit ); 410 assertTopLvalue( translationUnit ); 383 411 Stats::Time::TimeBlock("Find Special Declarations", [&]() { 384 412 Validate::findSpecialDecls( translationUnit ); 385 413 }); 414 assertTopLvalue( translationUnit ); 386 415 Stats::Time::TimeBlock("Fix Label Address", [&]() { 387 416 mutateAll( translationUnit, labelAddrFixer ); 388 417 }); 418 assertTopLvalue( translationUnit ); 389 419 Stats::Time::TimeBlock("Handle Attributes", [&]() { 390 420 Validate::handleAttributes( translationUnit ); 391 421 }); 392 422 } 423 assertTopLvalue( translationUnit ); 393 424 } 394 425 -
src/SynTree/AddressExpr.cc
r8e1467d r4a60488 42 42 AddressExpr::AddressExpr( Expression *arg ) : Expression(), arg( arg ) { 43 43 if ( arg->result ) { 44 if ( arg-> result->get_lvalue() ) {44 if ( arg->get_lvalue() ) { 45 45 // lvalue, retains all layers of reference and gains a pointer inside the references 46 46 set_result( addrType( arg->result ) ); -
src/SynTree/ApplicationExpr.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Tue Apr 26 12:41:06 201613 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Aug 12 14:28:00 2019 13 // Update Count : 5 14 14 // 15 15 … … 25 25 #include "Declaration.h" // for Declaration 26 26 #include "Expression.h" // for ParamEntry, ApplicationExpr, Expression 27 #include "InitTweak/InitTweak.h" // for getFunction 27 28 #include "ResolvExpr/typeops.h" // for extractResultType 28 29 #include "Type.h" // for Type, PointerType, FunctionType … … 76 77 } 77 78 79 bool ApplicationExpr::get_lvalue() const { 80 // from src/GenPoly/Lvalue.cc: isIntrinsicReference 81 static std::set<std::string> lvalueFunctions = { "*?", "?[?]" }; 82 if ( const DeclarationWithType * func = InitTweak::getFunction( this ) ) { 83 return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name); 84 } 85 return false; 86 } 87 78 88 void ApplicationExpr::print( std::ostream &os, Indenter indent ) const { 79 89 os << "Application of" << std::endl << indent+1; -
src/SynTree/BasicType.cc
r8e1467d r4a60488 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jan 31 21:37:36201913 // Update Count : 1 212 // Last Modified On : Sun Aug 4 21:07:44 2019 13 // Update Count : 13 14 14 // 15 15 … … 31 31 bool BasicType::isInteger() const { 32 32 return kind <= UnsignedInt128; 33 #if 034 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 } // switch65 assert( false );66 return false;67 #endif68 33 } 69 34 -
src/SynTree/CommaExpr.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Mon May 02 15:19:44201613 // Update Count : 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Arg 12 16:11:00 2016 13 // Update Count : 2 14 14 // 15 15 … … 39 39 } 40 40 41 bool CommaExpr::get_lvalue() const { 42 // This is wrong by C, but the current implementation uses it. 43 return arg2->get_lvalue(); 44 } 45 41 46 void CommaExpr::print( std::ostream &os, Indenter indent ) const { 42 47 os << "Comma Expression:" << std::endl; -
src/SynTree/Expression.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Feb 19 18:10:55201913 // Update Count : 6 011 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 15 13:43:00 2019 13 // Update Count : 64 14 14 // 15 15 … … 19 19 #include <iostream> // for ostream, operator<<, basic_ostream 20 20 #include <list> // for list, _List_iterator, list<>::co... 21 #include <set> // for set 21 22 22 23 #include "Common/utility.h" // for maybeClone, cloneAll, deleteAll … … 63 64 } 64 65 66 bool Expression::get_lvalue() const { 67 return false; 68 } 69 65 70 void Expression::print( std::ostream & os, Indenter indent ) const { 66 71 printInferParams( inferParams, os, indent+1, 0 ); … … 134 139 } 135 140 141 bool VariableExpr::get_lvalue() const { 142 // It isn't always an lvalue, but it is never an rvalue. 143 return true; 144 } 145 136 146 VariableExpr * VariableExpr::functionPointer( FunctionDecl * func ) { 137 147 VariableExpr * funcExpr = new VariableExpr( func ); … … 252 262 } 253 263 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 } // if280 Expression::print( os, indent );281 }282 283 264 CastExpr::CastExpr( Expression * arg, Type * toType, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) { 284 265 set_result(toType); … … 294 275 CastExpr::~CastExpr() { 295 276 delete arg; 277 } 278 279 bool CastExpr::get_lvalue() const { 280 // This is actually wrong by C, but it works with our current set-up. 281 return arg->get_lvalue(); 296 282 } 297 283 … … 376 362 } 377 363 364 bool UntypedMemberExpr::get_lvalue() const { 365 return aggregate->get_lvalue(); 366 } 367 378 368 void UntypedMemberExpr::print( std::ostream & os, Indenter indent ) const { 379 369 os << "Untyped Member Expression, with field: " << std::endl << indent+1; … … 405 395 // don't delete the member declaration, since it points somewhere else in the tree 406 396 delete aggregate; 397 } 398 399 bool MemberExpr::get_lvalue() const { 400 // This is actually wrong by C, but it works with our current set-up. 401 return true; 407 402 } 408 403 … … 457 452 } 458 453 454 bool 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 } 459 460 460 461 void UntypedExpr::print( std::ostream & os, Indenter indent ) const { … … 515 516 delete arg2; 516 517 delete arg3; 518 } 519 520 bool ConditionalExpr::get_lvalue() const { 521 return false; 517 522 } 518 523 … … 573 578 } 574 579 580 bool ConstructorExpr::get_lvalue() const { 581 return false; 582 } 583 575 584 void ConstructorExpr::print( std::ostream & os, Indenter indent ) const { 576 585 os << "Constructor Expression: " << std::endl << indent+1; … … 590 599 CompoundLiteralExpr::~CompoundLiteralExpr() { 591 600 delete initializer; 601 } 602 603 bool CompoundLiteralExpr::get_lvalue() const { 604 return true; 592 605 } 593 606 … … 641 654 result = new VoidType( Type::Qualifiers() ); 642 655 } 656 } 657 bool StmtExpr::get_lvalue() const { 658 return false; 643 659 } 644 660 void StmtExpr::print( std::ostream & os, Indenter indent ) const { -
src/SynTree/Expression.h
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Feb 18 18:29:51201913 // Update Count : 4911 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 15 13:46:00 2019 13 // Update Count : 54 14 14 // 15 15 … … 71 71 const Type * get_result() const { return result; } 72 72 void set_result( Type * newValue ) { result = newValue; } 73 virtual bool get_lvalue() const; 73 74 74 75 TypeSubstitution * get_env() const { return env; } … … 98 99 virtual ~ApplicationExpr(); 99 100 101 bool get_lvalue() const final; 102 100 103 Expression * get_function() const { return function; } 101 104 void set_function( Expression * newValue ) { function = newValue; } … … 120 123 UntypedExpr( const UntypedExpr & other ); 121 124 virtual ~UntypedExpr(); 125 126 bool get_lvalue() const final; 122 127 123 128 Expression * get_function() const { return function; } … … 208 213 virtual ~CastExpr(); 209 214 215 bool get_lvalue() const final; 216 210 217 Expression * get_arg() const { return arg; } 211 218 void set_arg( Expression * newValue ) { arg = newValue; } … … 268 275 virtual ~UntypedMemberExpr(); 269 276 277 bool get_lvalue() const final; 278 270 279 Expression * get_member() const { return member; } 271 280 void set_member( Expression * newValue ) { member = newValue; } … … 291 300 virtual ~MemberExpr(); 292 301 302 bool get_lvalue() const final; 303 293 304 DeclarationWithType * get_member() const { return member; } 294 305 void set_member( DeclarationWithType * newValue ) { member = newValue; } … … 313 324 VariableExpr( const VariableExpr & other ); 314 325 virtual ~VariableExpr(); 326 327 bool get_lvalue() const final; 315 328 316 329 DeclarationWithType * get_var() const { return var; } … … 463 476 }; 464 477 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 494 478 /// LogicalExpr represents a short-circuit boolean expression (&& or ||) 495 479 class LogicalExpr : public Expression { … … 528 512 ConditionalExpr( const ConditionalExpr & other ); 529 513 virtual ~ConditionalExpr(); 514 515 bool get_lvalue() const final; 530 516 531 517 Expression * get_arg1() const { return arg1; } … … 553 539 virtual ~CommaExpr(); 554 540 541 bool get_lvalue() const final; 542 555 543 Expression * get_arg1() const { return arg1; } 556 544 void set_arg1( Expression * newValue ) { arg1 = newValue; } … … 639 627 ~ConstructorExpr(); 640 628 629 bool get_lvalue() const final; 630 641 631 Expression * get_callExpr() const { return callExpr; } 642 632 void set_callExpr( Expression * newValue ) { callExpr = newValue; } … … 657 647 CompoundLiteralExpr( const CompoundLiteralExpr & other ); 658 648 virtual ~CompoundLiteralExpr(); 649 650 bool get_lvalue() const final; 659 651 660 652 Initializer * get_initializer() const { return initializer; } … … 715 707 virtual ~TupleExpr(); 716 708 709 bool get_lvalue() const final; 710 717 711 std::list<Expression*>& get_exprs() { return exprs; } 718 712 … … 733 727 TupleIndexExpr( const TupleIndexExpr & other ); 734 728 virtual ~TupleIndexExpr(); 729 730 bool get_lvalue() const final; 735 731 736 732 Expression * get_tuple() const { return tuple; } … … 782 778 StmtExpr( const StmtExpr & other ); 783 779 virtual ~StmtExpr(); 780 781 bool get_lvalue() const final; 784 782 785 783 CompoundStmt * get_statements() const { return statements; } -
src/SynTree/Mutator.h
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Jul 24 16:31:00 201713 // Update Count : 1 611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:37:46 2019 13 // Update Count : 17 14 14 // 15 15 #pragma once … … 74 74 virtual Expression * mutate( OffsetofExpr * offsetofExpr ) = 0; 75 75 virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) = 0; 76 virtual Expression * mutate( AttrExpr * attrExpr ) = 0;77 76 virtual Expression * mutate( LogicalExpr * logicalExpr ) = 0; 78 77 virtual Expression * mutate( ConditionalExpr * conditionalExpr ) = 0; -
src/SynTree/SynTree.h
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Jul 24 16:54:00 201713 // Update Count : 1 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:37:45 2019 13 // Update Count : 12 14 14 // 15 15 … … 79 79 class OffsetofExpr; 80 80 class OffsetPackExpr; 81 class AttrExpr;82 81 class LogicalExpr; 83 82 class ConditionalExpr; -
src/SynTree/TupleExpr.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Mar 17 09:42:29 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Aug 14 14:34:00 2019 13 // Update Count : 5 14 14 // 15 15 … … 57 57 } 58 58 59 bool TupleExpr::get_lvalue() const { 60 return false; 61 } 62 59 63 void TupleExpr::print( std::ostream &os, Indenter indent ) const { 60 64 os << "Tuple:" << std::endl; … … 76 80 TupleIndexExpr::~TupleIndexExpr() { 77 81 delete tuple; 82 } 83 84 bool TupleIndexExpr::get_lvalue() const { 85 return tuple->get_lvalue(); 78 86 } 79 87 -
src/SynTree/Type.cc
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Jul 12 15:48:00201913 // Update Count : 4 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Aug 4 21:05:07 2019 13 // Update Count : 45 14 14 // 15 15 #include "Type.h" … … 24 24 using namespace std; 25 25 26 const char *BasicType::typeNames[] = { 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 26 const char * BasicType::typeNames[] = { 68 27 "_Bool", 69 28 "char", … … 107 66 }; 108 67 static_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, 110 69 "Each basic type name should have a corresponding kind enum value" 111 70 ); … … 152 111 TypeSubstitution Type::genericSubstitution() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); } 153 112 154 void Type::print( std::ostream & os, Indenter indent ) const {113 void Type::print( std::ostream & os, Indenter indent ) const { 155 114 if ( ! forall.empty() ) { 156 115 os << "forall" << std::endl; -
src/SynTree/Type.h
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Feb 14 17:11:24201913 // Update Count : 1 6911 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 4 09:58:00 2019 13 // Update Count : 170 14 14 // 15 15 … … 131 131 bool operator>( Qualifiers other ) const { return *this != other && *this >= other; } 132 132 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 } 133 139 }; // Qualifiers 134 140 -
src/SynTree/Visitor.h
r8e1467d r4a60488 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Jul 24 16:28:00 201713 // Update Count : 1 311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:21:49 2019 13 // Update Count : 14 14 14 // 15 15 … … 123 123 virtual void visit( OffsetPackExpr * node ) { visit( const_cast<const OffsetPackExpr *>(node) ); } 124 124 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;127 125 virtual void visit( LogicalExpr * node ) { visit( const_cast<const LogicalExpr *>(node) ); } 128 126 virtual void visit( const LogicalExpr * logicalExpr ) = 0; -
src/SynTree/module.mk
r8e1467d r4a60488 49 49 SynTree/TypeSubstitution.cc \ 50 50 SynTree/Attribute.cc \ 51 SynTree/DeclReplacer.cc 51 SynTree/DeclReplacer.cc \ 52 SynTree/TopLvalue.cc 52 53 53 54 SRC += $(SRC_SYNTREE) -
src/main.cc
r8e1467d r4a60488 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 5 20:35:13201913 // Update Count : 60 112 // Last Modified On : Fri Aug 23 06:50:08 2019 13 // Update Count : 607 14 14 // 15 15 … … 17 17 #include <execinfo.h> // for backtrace, backtrace_symbols 18 18 #include <getopt.h> // for no_argument, optind, geto... 19 #include <signal.h> // for signal, SIGABRT, SIGSEGV20 19 #include <cassert> // for assertf 21 20 #include <cstdio> // for fopen, FILE, fclose, stdin 22 21 #include <cstdlib> // for exit, free, abort, EXIT_F... 22 #include <csignal> // for signal, SIGABRT, SIGSEGV 23 23 #include <cstring> // for index 24 24 #include <fstream> // for ofstream … … 60 60 #include "ResolvExpr/Resolver.h" // for resolve 61 61 #include "SymTab/Validate.h" // for validate 62 #include "SynTree/TopLvalue.h" // for assertTopLvalue, clearInn... 62 63 #include "SynTree/Declaration.h" // for Declaration 63 64 #include "SynTree/Visitor.h" // for acceptAll 64 65 #include "Tuples/Tuples.h" // for expandMemberTuples, expan... 65 66 #include "Virtual/ExpandCasts.h" // for expandCasts 67 66 68 67 69 using namespace std; … … 95 97 DeclarationNode * parseTree = nullptr; // program parse tree 96 98 99 static bool waiting_for_gdb = false; // flag to set cfa-cpp to wait for gdb on start 100 97 101 static std::string PreludeDirector = ""; 98 102 99 static void parse_cmdline( int argc, char *argv[] , const char *& filename);103 static void parse_cmdline( int argc, char *argv[] ); 100 104 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false ); 101 105 static void dump( list< Declaration * > & translationUnit, ostream & out = cout ); … … 166 170 } // sigAbortHandler 167 171 168 169 172 int main( int argc, char * argv[] ) { 170 173 FILE * input; // use FILE rather than istream because yyin is FILE 171 174 ostream * output = & cout; 172 const char * filename = nullptr;173 175 list< Declaration * > translationUnit; 174 176 … … 182 184 // } // for 183 185 184 parse_cmdline( argc, argv , filename );// process command-line arguments186 parse_cmdline( argc, argv ); // process command-line arguments 185 187 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 186 195 187 196 try { … … 189 198 if ( optind < argc ) { // any commands after the flags ? => input file name 190 199 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 ) ); 196 201 optind += 1; 197 202 } else { // no input file name 198 203 input = stdin; 199 // if running cfa-cpp directly, might forget to pass -F option. Since this takes from stdin, pass200 // a fake name along201 if ( filename == nullptr ) filename = "stdin";202 204 } // if 203 205 … … 258 260 Stats::Time::StopBlock(); 259 261 262 //std::cerr << "Post-Parse Check" << std::endl; 263 clearInnerLvalue( translationUnit ); 264 assertTopLvalue( translationUnit ); 265 260 266 // add the assignment statement after the initialization of a type parameter 261 267 PASS( "Validate", SymTab::validate( translationUnit, symtabp ) ); … … 276 282 } // if 277 283 284 assertTopLvalue( translationUnit ); 278 285 PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) ); 286 assertTopLvalue( translationUnit ); 279 287 PASS( "Fix Names", CodeGen::fixNames( translationUnit ) ); 288 assertTopLvalue( translationUnit ); 280 289 PASS( "Gen Init", InitTweak::genInit( translationUnit ) ); 290 assertTopLvalue( translationUnit ); 281 291 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) ); 292 assertTopLvalue( translationUnit ); 282 293 if ( libcfap ) { 283 294 // generate the bodies of cfa library functions … … 309 320 translationUnit = convert( move( transUnit ) ); 310 321 } 322 311 323 if ( exprp ) { 312 324 dump( translationUnit ); 313 325 return EXIT_SUCCESS; 314 326 } // if 327 328 clearInnerLvalue( translationUnit ); 329 assertTopLvalue( translationUnit ); 315 330 316 331 // fix ObjectDecl - replaces ConstructorInit nodes 317 332 PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) ); 333 clearInnerLvalue( translationUnit ); 334 assertTopLvalue( translationUnit ); 318 335 if ( ctorinitp ) { 319 336 dump ( translationUnit ); … … 322 339 323 340 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 ); 324 342 325 343 PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) ); 344 assertTopLvalue( translationUnit ); 326 345 327 346 PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) ); 347 clearInnerLvalue( translationUnit ); 348 assertTopLvalue( translationUnit ); 328 349 329 350 PASS( "Convert Specializations", GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded 351 clearInnerLvalue( translationUnit ); 352 assertTopLvalue( translationUnit ); 330 353 331 354 PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this? 355 assertTopLvalue( translationUnit ); 332 356 333 357 if ( tuplep ) { … … 337 361 338 362 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM 363 assertTopLvalue( translationUnit ); 339 364 340 365 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) ); … … 343 368 return EXIT_SUCCESS; 344 369 } // if 370 clearInnerLvalue( translationUnit ); 371 assertTopLvalue( translationUnit ); 345 372 PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) ); 346 373 clearInnerLvalue( translationUnit ); 374 assertTopLvalue( translationUnit ); 347 375 348 376 if ( bboxp ) { … … 351 379 } // if 352 380 PASS( "Box", GenPoly::box( translationUnit ) ); 381 clearInnerLvalue( translationUnit ); 382 assertTopLvalue( translationUnit ); 353 383 354 384 if ( bcodegenp ) { … … 362 392 363 393 CodeTools::fillLocations( translationUnit ); 394 assertTopLvalue( translationUnit ); 364 395 PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) ); 365 396 … … 412 443 413 444 414 static const char optstring[] = ":hlLmNnpP:S:twW:D: F:";445 static const char optstring[] = ":hlLmNnpP:S:twW:D:"; 415 446 416 447 enum { PreludeDir = 128 }; … … 427 458 { "statistics", required_argument, nullptr, 'S' }, 428 459 { "tree", no_argument, nullptr, 't' }, 460 { "gdb", no_argument, nullptr, 'g' }, 429 461 { "", no_argument, nullptr, 0 }, // -w 430 462 { "", no_argument, nullptr, 0 }, // -W 431 463 { "", no_argument, nullptr, 0 }, // -D 432 { "", no_argument, nullptr, 0 }, // -F433 464 { nullptr, 0, nullptr, 0 } 434 465 }; // long_opts … … 445 476 "<directory> prelude directory for debug/nodebug", // no flag 446 477 "<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 448 480 "", // -w 449 481 "", // -W 450 482 "", // -D 451 "", // -F452 483 }; // description 453 484 … … 484 515 485 516 static 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; 487 518 int i = 0, j = 1; // j skips starting colon 488 519 for ( ; long_opts[i].name != 0 && optstring[j] != '\0'; i += 1, j += 1 ) { … … 510 541 } // usage 511 542 512 static void parse_cmdline( int argc, char * argv[] , const char *& filename) {543 static void parse_cmdline( int argc, char * argv[] ) { 513 544 opterr = 0; // (global) prevent getopt from printing error messages 514 545 … … 556 587 Stats::parse_params( optarg ); 557 588 break; 558 case 't': // build in tree589 case 't': // building cfa stdlib 559 590 treep = true; 591 break; 592 case 'g': // wait for gdb 593 waiting_for_gdb = true; 560 594 break; 561 595 case 'w': // suppress all warnings, hidden … … 581 615 case 'D': // ignore -Dxxx, forwarded by cpp, hidden 582 616 break; 583 case 'F': // source file-name without suffix, hidden584 filename = optarg;585 break;586 617 case '?': // unknown option 587 618 if ( optopt ) { // short option ? -
tests/.expect/gccExtensions.x64.txt
r8e1467d r4a60488 291 291 signed int _X2m2A0A0i_2[((unsigned long int )10)][((unsigned long int )10)]; 292 292 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 298 315 { 299 316 ((void)(_X12_retval_maini_1=0) /* ?{} */); -
tests/.expect/gccExtensions.x86.txt
r8e1467d r4a60488 296 296 297 297 return _X12_retval_maini_1; 298 {299 ((void)(_X12_retval_maini_1=0) /* ?{} */);300 }301 302 return _X12_retval_maini_1;303 298 } 304 299 static 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 22 22 debug=yes 23 23 installed=no 24 archiveerrors= 24 25 25 INSTALL_FLAGS=-in-tree26 26 DEBUG_FLAGS=-debug -O0 27 27 … … 34 34 35 35 # applies to both programs 36 # since automake doesn't have support for CFA we have to 36 37 AM_CFLAGS = $(if $(test), 2> $(test), ) \ 37 38 -g \ … … 41 42 -DIN_DIR="${abs_srcdir}/.in/" 42 43 43 AM_CFLAGS += ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS} 44 CC = @CFACC@ 44 # get the desired cfa to test 45 TARGET_CFA = $(if $(filter $(installed),yes), @CFACC_INSTALL@, @CFACC@) 46 47 # adjust CC to current flags 48 CC = $(if $(ifeq $(DISTCC_CFA_PATH),yes),distcc $(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS}) 49 CFACC = $(CC) 50 51 # get local binary for depedencies 52 CFACCBIN = @CFACC@ 53 54 # adjusted CC but without the actual distcc call 55 CFACCLOCAL = $(if $(DISTCC_CFA_PATH),$(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS}) 45 56 46 57 PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} && … … 56 67 #---------------------------------------------------------------------------------------------------------------- 57 68 all-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} 59 70 60 71 all-tests : 61 @+${TEST_PY} --debug=${debug} --install=${installed} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program72 @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 62 73 63 74 clean-local : … … 86 97 87 98 # 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 ${@}) 99 CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g')) 95 100 96 101 #---------------------------------------------------------------------------------------------------------------- 97 102 98 103 # 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 ${@}) 101 109 110 # implicit rule for c++ test 111 # convient for testing the testsuite itself but not actuall used 102 112 % : %.cpp 103 113 $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 104 114 105 115 #------------------------------------------------------------------------------ 106 # TARGET WITH STANDARD RULE BUTCUSTOM FLAGS116 # TARGETS WITH CUSTOM FLAGS 107 117 #------------------------------------------------------------------------------ 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 119 gmp_FLAGSLD= -lgmp 116 120 117 121 #------------------------------------------------------------------------------ 118 # Expected failures 119 completeTypeError_FLAGS= -DERR1 122 # Generated code 123 GENERATED_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 128 EXPECT_STDERR = builtins/sync warnings/self-assignment 129 $(EXPECT_STDERR): % : %.cfa $(CFACCBIN) 130 $(CFACOMPILETEST) -c -fsyntax-only 2> $(abspath ${@}) 120 131 121 132 #------------------------------------------------------------------------------ 122 133 # CUSTOM TARGET 123 134 #------------------------------------------------------------------------------ 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 137 alloc-ERROR : alloc.cfa $(CFACCBIN) 138 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 126 139 127 alloc-ERROR: alloc.cfa $(CFACC)128 $(CFA TEST_STDOUT) -DERR1140 typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN) 141 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 129 142 130 nested-types-ERR1 : nested-types.cfa $(CFACC)131 $(CFA TEST_STDOUT) -DERR1143 nested-types-ERR1 : nested-types.cfa $(CFACCBIN) 144 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 132 145 133 nested-types-ERR2 : nested-types.cfa $(CFACC)134 $(CFA TEST_STDOUT) -DERR2146 nested-types-ERR2 : nested-types.cfa $(CFACCBIN) 147 $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@}) 135 148 136 raii/ dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)137 $(CFA TEST_STDOUT) -DERR1149 raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN) 150 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 138 151 139 raii/ dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)140 $(CFA TEST_STDOUT) -DERR2152 raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN) 153 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 141 154 142 raii/ memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)143 $(CFA TEST_STDOUT) -DERR1155 raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN) 156 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 144 157 145 raii/ ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)146 $(CFA TEST_STDOUT) -DERR1158 raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN) 159 $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@}) 147 160 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 212 212 AWK = @AWK@ 213 213 BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@ 214 CC = @CFACC@ 214 215 # adjust CC to current flags 216 CC = $(if $(ifeq $(DISTCC_CFA_PATH),yes),distcc $(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS}) 215 217 CCAS = @CCAS@ 216 218 CCASDEPMODE = @CCASDEPMODE@ 217 219 CCASFLAGS = @CCASFLAGS@ 218 220 CCDEPMODE = @CCDEPMODE@ 219 CFACC = @CFACC@ 221 CFACC = $(CC) 222 CFACC_INSTALL = @CFACC_INSTALL@ 220 223 CFACPP = @CFACPP@ 221 224 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 235 238 CYGPATH_W = @CYGPATH_W@ 236 239 DEFS = @DEFS@ 240 DEMANGLER = @DEMANGLER@ 237 241 DEPDIR = @DEPDIR@ 238 242 DLLTOOL = @DLLTOOL@ … … 247 251 FGREP = @FGREP@ 248 252 GREP = @GREP@ 253 HAS_DISTCC = @HAS_DISTCC@ 249 254 HOST_FLAGS = @HOST_FLAGS@ 250 255 INSTALL = @INSTALL@ … … 260 265 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 261 266 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 267 LIBDEMANGLE = @LIBDEMANGLE@ 262 268 LIBOBJS = @LIBOBJS@ 263 269 LIBS = @LIBS@ … … 375 381 debug = yes 376 382 installed = no 377 INSTALL_FLAGS = -in-tree 383 archiveerrors = 378 384 DEBUG_FLAGS = -debug -O0 379 385 quick_test = avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes … … 383 389 384 390 # 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 392 AM_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 401 TARGET_CFA = $(if $(filter $(installed),yes), @CFACC_INSTALL@, @CFACC@) 402 403 # get local binary for depedencies 404 CFACCBIN = @CFACC@ 405 406 # adjusted CC but without the actual distcc call 407 CFACCLOCAL = $(if $(DISTCC_CFA_PATH),$(DISTCC_CFA_PATH),$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS}) 388 408 PRETTY_PATH = mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} && 389 409 avl_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 … … 394 414 395 415 # 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 ${@}) 416 CFACOMPILETEST = $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGSCFA" | sed 's/-\|\//_/g')) 403 417 404 418 #------------------------------------------------------------------------------ 405 # TARGET WITH STANDARD RULE BUTCUSTOM FLAGS419 # TARGETS WITH CUSTOM FLAGS 406 420 #------------------------------------------------------------------------------ 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 422 gmp_FLAGSLD = -lgmp 415 423 416 424 #------------------------------------------------------------------------------ 417 # Expected failures 418 completeTypeError_FLAGS = -DERR1 425 # Generated code 426 GENERATED_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 429 EXPECT_STDERR = builtins/sync warnings/self-assignment 419 430 all: all-am 420 431 … … 768 779 #---------------------------------------------------------------------------------------------------------------- 769 780 all-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} 771 782 772 783 all-tests : 773 @+${TEST_PY} --debug=${debug} --install=${installed} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program784 @+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 774 785 775 786 clean-local : … … 798 809 799 810 # 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 803 819 % : %.cpp 804 820 $(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 ${@}) 805 825 806 826 #------------------------------------------------------------------------------ 807 827 # CUSTOM TARGET 808 828 #------------------------------------------------------------------------------ 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 831 alloc-ERROR : alloc.cfa $(CFACCBIN) 832 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 833 834 typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN) 835 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 836 837 nested-types-ERR1 : nested-types.cfa $(CFACCBIN) 838 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 839 840 nested-types-ERR2 : nested-types.cfa $(CFACCBIN) 841 $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@}) 842 843 raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN) 844 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 845 846 raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN) 847 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 848 849 raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN) 850 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 851 852 raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN) 853 $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@}) 854 855 #------------------------------------------------------------------------------ 856 # Other targets 840 857 841 858 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
tests/config.py.in
r8e1467d r4a60488 8 8 BUILDDIR = "@abs_builddir@" 9 9 HOSTARCH = "@host_cpu@" 10 DISTRIBUTE = @HAS_DISTCC@ -
tests/gccExtensions.cfa
r8e1467d r4a60488 10 10 // Created On : Sun Aug 14 17:28:17 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Nov 6 17:54:20 201813 // Update Count : 1112 // Last Modified On : Mon Aug 5 18:04:37 2019 13 // Update Count : 28 14 14 // 15 15 … … 50 50 51 51 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 ); 57 57 58 58 // alternative type/qualifer names … … 110 110 struct __attribute(()) s4 { int i; } x2, y2 __attribute(()); 111 111 112 int m1 113 int m2 112 int m1[10] __attribute(()); 113 int m2[10][10] __attribute(()); 114 114 int __attribute(()) m3 [10][10]; 115 115 // int ( __attribute(()) m4 [10] )[10]; 116 116 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 118 132 } 119 133 -
tests/pybin/settings.py
r8e1467d r4a60488 4 4 from . import tools 5 5 6 global original_path 7 6 8 try : 9 original_path = os.getcwd() 7 10 testpath = os.path.dirname(os.path.abspath(os.path.join(os.getcwd(), sys.argv[0]))) 8 11 sys.path.append(testpath) … … 11 14 SRCDIR = os.path.abspath(config.SRCDIR) 12 15 BUILDDIR = os.path.abspath(config.BUILDDIR) 16 distribute = config.DISTRIBUTE 13 17 os.chdir(testpath) 14 18 … … 19 23 class Architecture: 20 24 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', 25 30 'i386' : 'x86', 26 31 'i486' : 'x86', 27 32 'i686' : 'x86', 28 33 'Intel 80386' : 'x86', 29 'arm' 30 'ARM' 34 'arm' : 'arm', 35 'ARM' : 'arm', 31 36 } 32 37 … … 40 45 canonical_host = Architecture.make_canonical( config.HOSTARCH ) 41 46 except KeyError: 42 print("Unk own host architecture %s" % config.HOSTARCH, file=sys.stderr)47 print("Unknown host architecture %s" % config.HOSTARCH, file=sys.stderr) 43 48 sys.exit(1) 44 49 … … 47 52 arch = Architecture.make_canonical( arch ) 48 53 except KeyError: 49 print("Unk own architecture %s" % arch, file=sys.stderr)54 print("Unknown architecture %s" % arch, file=sys.stderr) 50 55 sys.exit(1) 51 56 … … 84 89 self.string = "debug" if value else "no debug" 85 90 self.flags = """DEBUG_FLAGS=%s""" % ("-debug -O0" if value else "-nodebug -O2") 91 self.path = "debug" if value else "nodebug" 86 92 87 93 class Install: 88 94 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") 91 100 92 101 class Timeouts: … … 105 114 def init( options ): 106 115 global arch 116 global archive 117 global debug 118 global distcc 107 119 global dry_run 108 120 global generating 121 global install 109 122 global make 110 global debug 111 global install 123 global output_width 112 124 global timeout 113 global output_width114 125 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() 116 131 generating = options.regenerate_expected 132 install = Install(options.install) 117 133 make = ['make'] 118 debug = Debug(options.debug) 119 install = Install(options.install) 120 arch = Architecture(options.arch) 134 output_width = 24 121 135 timeout = Timeouts(options.timeout, options.global_timeout) 122 output_width = 24123 136 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')) 124 141 125 142 def update_make_cmd(force, jobs): … … 130 147 def validate(): 131 148 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 ) 133 150 if make_ret != 0: 134 151 with open (errf, "r") as myfile: -
tests/pybin/tools.py
r8e1467d r4a60488 2 2 import argparse 3 3 import contextlib 4 import datetime 4 5 import fileinput 5 6 import multiprocessing … … 22 23 23 24 # helper functions to run terminal commands 24 def sh(*cmd, timeout = False, output = None, input = None, error = subprocess.STDOUT):25 def sh(*cmd, timeout = False, output_file = None, input_file = None, input_text = None, error = subprocess.STDOUT, ignore_dry_run = False): 25 26 cmd = list(cmd) 26 27 28 if input_file and input_text: 29 return 401, "Cannot use both text and file inputs" 30 27 31 # 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: 29 33 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): 31 35 cmd += " > " 32 cmd += output 36 cmd += output_file 33 37 34 38 if error and not isinstance(error, int): … … 36 40 cmd += error 37 41 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): 39 43 cmd += " < " 40 cmd += input 44 cmd += input_file 41 45 42 46 print(cmd) … … 45 49 with contextlib.ExitStack() as onexit: 46 50 # add input redirection if needed 47 input = openfd(input, 'r', onexit, True)51 input_file = openfd(input_file, 'r', onexit, True) 48 52 49 53 # add output redirection if needed 50 output = openfd(output, 'w', onexit, False)54 output_file = openfd(output_file, 'w', onexit, False) 51 55 52 56 # add error redirection if needed … … 57 61 proc = subprocess.run( 58 62 cmd, 59 stdin =input,60 stdout =output,61 stderr =error,62 timeout =settings.timeout.single if timeout else None63 **({'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 63 67 ) 68 64 69 return proc.returncode, proc.stdout.decode("utf-8") if proc.stdout else None 65 70 except subprocess.TimeoutExpired: … … 74 79 return False 75 80 76 code, out = sh("file %s" % fname, output =subprocess.PIPE)81 code, out = sh("file %s" % fname, output_file=subprocess.PIPE) 77 82 if code != 0: 78 83 return False … … 106 111 if isinstance(files, str ): files = [ files ] 107 112 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 ) 109 114 110 115 # Create 1 or more directory … … 114 119 p = os.path.normpath( file ) 115 120 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 ) 117 122 118 123 … … 137 142 lhs, 138 143 rhs, 139 output =subprocess.PIPE144 output_file=subprocess.PIPE 140 145 ) 141 146 142 147 # call make 143 def make(target, *, flags = '', output = None, error = None, error_file = None, silent = False):148 def make(target, *, flags = '', output_file = None, error = None, error_file = None, silent = False): 144 149 test_param = """test="%s" """ % (error_file) if error_file else None 145 150 cmd = [ … … 150 155 settings.debug.flags, 151 156 settings.install.flags, 157 settings.distcc if settings.distribute else None, 152 158 flags, 153 159 target 154 160 ] 155 161 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) 157 163 158 164 def which(program): … … 200 206 # cat one file into the other 201 207 def cat(source, dest): 202 ret, _ = sh("cat", source, output =dest)208 ret, _ = sh("cat", source, output_file=dest) 203 209 return ret 204 210 … … 255 261 os.write(int(make_jobs_fds.group(3)), tokens) 256 262 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() 258 271 else : 259 272 force = True … … 272 285 # misc 273 286 ################################################################################ 287 288 # get hash for given configuration 289 def 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 300 def 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') 274 304 275 305 # check if arguments is yes or no … … 302 332 return 1, "ERR No core dump" 303 333 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 336 def 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)) 305 353 306 354 class Timed: -
tests/test.py
r8e1467d r4a60488 91 91 parser.add_argument('--all', help='Run all test available', action='store_true') 92 92 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='') 93 94 parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int) 94 95 parser.add_argument('--list-comp', help='List all valide arguments', action='store_true') … … 142 143 # build, skipping to next test on error 143 144 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 ) 145 146 146 147 run_dur = None … … 152 153 if settings.dry_run or is_exe(exe_file): 153 154 # 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) 155 156 else : 156 157 # simply cat the result into the output … … 179 180 error = error + info if error else info 180 181 182 if settings.archive: 183 error = error + '\n' + core_archive(settings.archive, test.target(), exe_file) 184 181 185 182 186 … … 215 219 def run_tests(tests, jobs) : 216 220 # 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) 218 222 219 223 # create the executor for our jobs and handle the signal properly … … 256 260 257 261 # clean the workspace 258 make('clean', output =subprocess.DEVNULL, error=subprocess.DEVNULL)262 make('clean', output_file=subprocess.DEVNULL, error=subprocess.DEVNULL) 259 263 260 264 return 1 if failed else 0 … … 295 299 # users may want to simply list the tests 296 300 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='') 298 302 print(" ".join(map(lambda t: "%s" % (t.target()), tests))) 299 303 -
tools/Makefile.in
r8e1467d r4a60488 208 208 CCDEPMODE = @CCDEPMODE@ 209 209 CFACC = @CFACC@ 210 CFACC_INSTALL = @CFACC_INSTALL@ 210 211 CFACPP = @CFACPP@ 211 212 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 225 226 CYGPATH_W = @CYGPATH_W@ 226 227 DEFS = @DEFS@ 228 DEMANGLER = @DEMANGLER@ 227 229 DEPDIR = @DEPDIR@ 228 230 DLLTOOL = @DLLTOOL@ … … 237 239 FGREP = @FGREP@ 238 240 GREP = @GREP@ 241 HAS_DISTCC = @HAS_DISTCC@ 239 242 HOST_FLAGS = @HOST_FLAGS@ 240 243 INSTALL = @INSTALL@ … … 250 253 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 251 254 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 255 LIBDEMANGLE = @LIBDEMANGLE@ 252 256 LIBOBJS = @LIBOBJS@ 253 257 LIBS = @LIBS@ -
tools/prettyprinter/Makefile.in
r8e1467d r4a60488 237 237 CCDEPMODE = @CCDEPMODE@ 238 238 CFACC = @CFACC@ 239 CFACC_INSTALL = @CFACC_INSTALL@ 239 240 CFACPP = @CFACPP@ 240 241 CFA_BACKEND_CC = @CFA_BACKEND_CC@ … … 254 255 CYGPATH_W = @CYGPATH_W@ 255 256 DEFS = @DEFS@ 257 DEMANGLER = @DEMANGLER@ 256 258 DEPDIR = @DEPDIR@ 257 259 DLLTOOL = @DLLTOOL@ … … 266 268 FGREP = @FGREP@ 267 269 GREP = @GREP@ 270 HAS_DISTCC = @HAS_DISTCC@ 268 271 HOST_FLAGS = @HOST_FLAGS@ 269 272 INSTALL = @INSTALL@ … … 279 282 LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@ 280 283 LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@ 284 LIBDEMANGLE = @LIBDEMANGLE@ 281 285 LIBOBJS = @LIBOBJS@ 282 286 LIBS = @LIBS@
Note:
See TracChangeset
for help on using the changeset viewer.