Changeset 4a60488
- Timestamp:
- Sep 27, 2019, 3:35:46 PM (3 years ago)
- Branches:
- arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 90ce35aa
- Parents:
- 8e1467d (diff), 849720f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - 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