Changes in / [34a6b2e:461eed2]
- Files:
-
- 5 deleted
- 28 edited
-
.gitignore (modified) (1 diff)
-
Jenkinsfile (modified) (1 diff)
-
benchmark/Makefile.am (modified) (4 diffs)
-
benchmark/Makefile.in (modified) (5 diffs)
-
configure (modified) (3 diffs)
-
configure.ac (modified) (1 diff)
-
doc/proposals/virtual.txt (modified) (4 diffs)
-
doc/theses/aaron_moss_PhD/phd/.gitignore (modified) (1 diff)
-
doc/theses/aaron_moss_PhD/phd/Makefile (modified) (1 diff)
-
doc/theses/aaron_moss_PhD/phd/cfa-macros.tex (modified) (1 diff)
-
doc/theses/aaron_moss_PhD/phd/code/bespoke-generic.c (deleted)
-
doc/theses/aaron_moss_PhD/phd/code/cfa-generic.cfa (deleted)
-
doc/theses/aaron_moss_PhD/phd/code/macro-generic.c (deleted)
-
doc/theses/aaron_moss_PhD/phd/code/void-generic.c (deleted)
-
doc/theses/aaron_moss_PhD/phd/frontpgs.tex (modified) (1 diff)
-
doc/theses/aaron_moss_PhD/phd/generic-types.tex (modified) (1 diff)
-
doc/theses/aaron_moss_PhD/phd/timeline.md (deleted)
-
driver/cfa.cc (modified) (1 diff)
-
libcfa/Makefile.in (modified) (1 diff)
-
libcfa/configure (modified) (3 diffs)
-
libcfa/configure.ac (modified) (2 diffs)
-
libcfa/prelude/Makefile.am (modified) (4 diffs)
-
libcfa/prelude/Makefile.in (modified) (5 diffs)
-
libcfa/prelude/prelude-gen.cc (modified) (1 diff)
-
libcfa/src/Makefile.am (modified) (3 diffs)
-
libcfa/src/Makefile.in (modified) (13 diffs)
-
src/Makefile.am (modified) (1 diff)
-
src/Makefile.in (modified) (2 diffs)
-
src/SymTab/Demangle.cc (modified) (1 diff)
-
src/cfa.make (modified) (1 diff)
-
src/main.cc (modified) (2 diffs)
-
tests/Makefile.am (modified) (2 diffs)
-
tests/Makefile.in (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r34a6b2e r461eed2 38 38 libcfa/prelude/gcc-builtins.cf 39 39 libcfa/prelude/gcc-builtins.c 40 libcfa/prelude/prelude.cf a40 libcfa/prelude/prelude.cf 41 41 libcfa/x64-debug/ 42 42 libcfa/x64-nodebug/ -
Jenkinsfile
r34a6b2e r461eed2 128 128 //Run the tests from the tests directory 129 129 if ( Settings.RunAllTests ) { 130 sh 'make --no-print-directory -C tests timeouts="--timeout=600"all-tests debug=yes'131 sh 'make --no-print-directory -C tests timeouts="--timeout=600"all-tests debug=no '130 sh 'make --no-print-directory -C tests all-tests debug=yes' 131 sh 'make --no-print-directory -C tests all-tests debug=no ' 132 132 } 133 133 else { -
benchmark/Makefile.am
r34a6b2e r461eed2 33 33 TIME_FORMAT = "%E" 34 34 PRINT_FORMAT = %20s: #Comments needed for spacing 35 36 LIBFIBRE_DIR ?= /home/tdelisle/software/KOS/src/ 35 37 36 38 .NOTPARALLEL: … … 109 111 110 112 ## ========================================================================================================= 111 CTXSWITCH_DEPEND =\113 ctxswitch$(EXEEXT): \ 112 114 loop.run \ 113 115 function.run \ … … 119 121 ctxswitch-upp_coroutine.run \ 120 122 ctxswitch-upp_thread.run \ 123 -ctxswitch-kos_fibre.run \ 124 -ctxswitch-kos_fibre2.run \ 121 125 ctxswitch-goroutine.run \ 122 126 ctxswitch-java_thread.run 123 127 124 if WITH_LIBFIBRE 125 CTXSWITCH_DEPEND += \ 126 ctxswitch-kos_fibre.run \ 127 ctxswitch-kos_fibre2.run 128 128 ctxswitch-pthread$(EXEEXT): 129 @$(COMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c 130 131 ctxswitch-cfa_coroutine$(EXEEXT): 132 @$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_cor.c 133 134 ctxswitch-cfa_thread$(EXEEXT): 135 @$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd.c 136 137 ctxswitch-cfa_thread2$(EXEEXT): 138 @$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd2.c 139 140 ctxswitch-upp_coroutine$(EXEEXT): 141 @$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_cor.cc 142 143 ctxswitch-upp_thread$(EXEEXT): 144 @$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_thrd.cc 129 145 130 146 ctxswitch-kos_fibre$(EXEEXT): … … 133 149 ctxswitch-kos_fibre2$(EXEEXT): 134 150 @$(CXXCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/kos_fibre2.cpp -I$(LIBFIBRE_DIR) -lfibre 135 endif136 137 ctxswitch$(EXEEXT): $(CTXSWITCH_DEPEND)138 139 ctxswitch-pthread$(EXEEXT):140 @$(COMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c141 142 ctxswitch-cfa_coroutine$(EXEEXT):143 @$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_cor.c144 145 ctxswitch-cfa_thread$(EXEEXT):146 @$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd.c147 148 ctxswitch-cfa_thread2$(EXEEXT):149 @$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_thrd2.c150 151 ctxswitch-upp_coroutine$(EXEEXT):152 @$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_cor.cc153 154 ctxswitch-upp_thread$(EXEEXT):155 @$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_thrd.cc156 151 157 152 ctxswitch-goroutine$(EXEEXT): -
benchmark/Makefile.in
r34a6b2e r461eed2 93 93 host_triplet = @host@ 94 94 noinst_PROGRAMS = 95 @WITH_LIBFIBRE_TRUE@am__append_1 = \96 @WITH_LIBFIBRE_TRUE@ ctxswitch-kos_fibre.run \97 @WITH_LIBFIBRE_TRUE@ ctxswitch-kos_fibre2.run98 99 95 subdir = benchmark 100 96 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 … … 277 273 TIME_FORMAT = "%E" 278 274 PRINT_FORMAT = %20s: #Comments needed for spacing 279 CTXSWITCH_DEPEND = loop.run function.run fetch_add.run \280 ctxswitch-pthread.run ctxswitch-cfa_coroutine.run \281 ctxswitch-cfa_thread.run ctxswitch-cfa_thread2.run \282 ctxswitch-upp_coroutine.run ctxswitch-upp_thread.run \283 ctxswitch-goroutine.run ctxswitch-java_thread.run \284 $(am__append_1)285 275 testdir = $(top_srcdir)/tests 286 276 all: all-am … … 475 465 476 466 477 .cfa.o: 467 .cfa.o: $(CFACC) $(CFACPP) 478 468 $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ 479 469 $(CFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 480 470 $(am__mv) $$depbase.Tpo $$depbase.Po 471 472 LIBFIBRE_DIR ?= /home/tdelisle/software/KOS/src/ 481 473 482 474 .NOTPARALLEL: … … 549 541 $(COMPILE) -DBENCH_N=500000000 fetch_add.c 550 542 551 @WITH_LIBFIBRE_TRUE@ctxswitch-kos_fibre$(EXEEXT): 552 @WITH_LIBFIBRE_TRUE@ @$(CXXCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/kos_fibre.cpp -I$(LIBFIBRE_DIR) -lfibre 553 554 @WITH_LIBFIBRE_TRUE@ctxswitch-kos_fibre2$(EXEEXT): 555 @WITH_LIBFIBRE_TRUE@ @$(CXXCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/kos_fibre2.cpp -I$(LIBFIBRE_DIR) -lfibre 556 557 ctxswitch$(EXEEXT): $(CTXSWITCH_DEPEND) 543 ctxswitch$(EXEEXT): \ 544 loop.run \ 545 function.run \ 546 fetch_add.run \ 547 ctxswitch-pthread.run \ 548 ctxswitch-cfa_coroutine.run \ 549 ctxswitch-cfa_thread.run \ 550 ctxswitch-cfa_thread2.run \ 551 ctxswitch-upp_coroutine.run \ 552 ctxswitch-upp_thread.run \ 553 -ctxswitch-kos_fibre.run \ 554 -ctxswitch-kos_fibre2.run \ 555 ctxswitch-goroutine.run \ 556 ctxswitch-java_thread.run 558 557 559 558 ctxswitch-pthread$(EXEEXT): … … 574 573 ctxswitch-upp_thread$(EXEEXT): 575 574 @$(UPPCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/upp_thrd.cc 575 576 ctxswitch-kos_fibre$(EXEEXT): 577 @$(CXXCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/kos_fibre.cpp -I$(LIBFIBRE_DIR) -lfibre 578 579 ctxswitch-kos_fibre2$(EXEEXT): 580 @$(CXXCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/kos_fibre2.cpp -I$(LIBFIBRE_DIR) -lfibre 576 581 577 582 ctxswitch-goroutine$(EXEEXT): -
configure
r34a6b2e r461eed2 630 630 GREP 631 631 CPP 632 WITH_LIBFIBRE_FALSE633 WITH_LIBFIBRE_TRUE634 632 RANLIB 635 633 LEXLIB … … 5441 5439 5442 5440 # Checks for libraries. 5443 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fibre::yield in -lfibre" >&55444 $as_echo_n "checking for Fibre::yield in -lfibre... " >&6; }5445 if ${ac_cv_lib_fibre_Fibre__yield+:} false; then :5446 $as_echo_n "(cached) " >&65447 else5448 ac_check_lib_save_LIBS=$LIBS5449 LIBS="-lfibre $LIBS"5450 cat confdefs.h - <<_ACEOF >conftest.$ac_ext5451 /* end confdefs.h. */5452 5453 /* Override any GCC internal prototype to avoid an error.5454 Use char because int might match the return type of a GCC5455 builtin and then its argument prototype would still apply. */5456 #ifdef __cplusplus5457 extern "C"5458 #endif5459 char Fibre::yield ();5460 int5461 main ()5462 {5463 return Fibre::yield ();5464 ;5465 return 0;5466 }5467 _ACEOF5468 if ac_fn_c_try_link "$LINENO"; then :5469 ac_cv_lib_fibre_Fibre__yield=yes5470 else5471 ac_cv_lib_fibre_Fibre__yield=no5472 fi5473 rm -f core conftest.err conftest.$ac_objext \5474 conftest$ac_exeext conftest.$ac_ext5475 LIBS=$ac_check_lib_save_LIBS5476 fi5477 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fibre_Fibre__yield" >&55478 $as_echo "$ac_cv_lib_fibre_Fibre__yield" >&6; }5479 if test "x$ac_cv_lib_fibre_Fibre__yield" = xyes; then :5480 HAVE_LIBFIBRE=15481 else5482 HAVE_LIBFIBRE=05483 fi5484 5485 if test "$HAVE_LIBFIBRE" -eq 1; then5486 WITH_LIBFIBRE_TRUE=5487 WITH_LIBFIBRE_FALSE='#'5488 else5489 WITH_LIBFIBRE_TRUE='#'5490 WITH_LIBFIBRE_FALSE=5491 fi5492 5493 5441 5494 5442 # Checks for header files. … … 6530 6478 if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then 6531 6479 as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. 6532 Usually this means the macro was only invoked conditionally." "$LINENO" 56533 fi6534 if test -z "${WITH_LIBFIBRE_TRUE}" && test -z "${WITH_LIBFIBRE_FALSE}"; then6535 as_fn_error $? "conditional \"WITH_LIBFIBRE\" was never defined.6536 6480 Usually this means the macro was only invoked conditionally." "$LINENO" 5 6537 6481 fi -
configure.ac
r34a6b2e r461eed2 204 204 205 205 # Checks for libraries. 206 AC_CHECK_LIB([fibre], [Fibre::yield], [HAVE_LIBFIBRE=1], [HAVE_LIBFIBRE=0])207 AM_CONDITIONAL([WITH_LIBFIBRE], [test "$HAVE_LIBFIBRE" -eq 1])208 206 209 207 # Checks for header files. -
doc/proposals/virtual.txt
r34a6b2e r461eed2 87 87 first polymorphic parameter). 88 88 89 Instances of a trait are created by wrapping an existing instance of a type 90 that implements that trait. This wrapper includes all the function pointers 91 and other values required to preform the dynamic look-up. These are chosen by 92 the normal look-up rules at the point of abstraction.89 Once a function in a trait has been marked as virtual it defines a new 90 function that takes in that trait's reference and then dynamically calls the 91 underlying type implementation. Hence a trait reference becomes a kind of 92 abstract type, cannot be directly instantiated but can still be used. 93 93 94 94 One of the limitations of this design is that it does not support double … … 98 98 is also restricted, initially forbidden, see extension. 99 99 100 Ownership of the underlying structure is also a bit of a trick. Considering101 the use cases for trait object, it is probably best to have the underlying102 object be heap allocated and owned by the trait object.103 104 100 Extension: Multi-parameter Virtual Traits: 105 101 … … 161 157 context, for instance if the cast occurs on the right hand side of an 162 158 assignment. 163 164 Function look-up follows the same rules as relaxed (behavioural) inheritance.165 Traits can be upcast and down cast without losing information unless the166 trait is cast down to a structure. Here there are two options.167 168 Abstraction Time Binding: The more efficient and consistant with other parts169 of CFA. Only the trait types use dynamic look-up, if converveted back into a170 structure the normal static look-up rules find the function at compile time.171 Casting down to a structure type can then result in the loss of a set of172 bindings.173 Construction Time Binding: For more consistant handling of the virtual174 structs, they are always considered wrapped. Functions are bound to the175 instance the moment it is constructed and remain unchanged throughout its176 lifetime, so down casting does not lose information.177 178 (We will have to decide between one of these two.)179 159 180 160 Extension: Multiple Parents … … 225 205 226 206 We have so far been silent on how the vtable is created, stored and accessed. 227 The vtables for the two types might be handled slightly differently and then 228 there is also the hierarchy data for virtual casts. 229 230 The hierarchy data is simple conceptually. A single (exactly one copy) pointer 231 for each type can act as the identity for it. The value of the pointer is 232 its parent type, with the root pointer being NULL. Additional meta-data 233 can accompany the parent pointer, such as a string name or the vtable fields. 234 235 They types of each vtable can be constructed from the definitions of the 236 traits (or internal nodes). The stand alone/base vtable is the same for both 237 kinds of inheritance. It may be argumented differently however (include parent 238 /this pointer in hierachal inheritance). 239 240 Creation of the actual vtable is tricky. For classical single implementation 241 semantics we would assemble the functions and create one vtable at compile 242 time. However, not only does this not give CFA-like behaviour, it is 243 impossible generally because types can satify assertions in different ways at 244 different times and stop satifying them. A special set of harder rules could 245 be used, instead we have decided to try creating multiple vtables for each 246 type. The different vtables will all implement the same type but not always 247 in the same way. 248 249 Storage has some issues from creation. If the contents of every vtable could 250 be determained at compile time they could all be created and stored 251 statically. However since thunks can be constructed on the stack and become 252 the best match, that isn't always possible. Those will have to be stored in 253 dynamic memory. Which means that all vtables must be stored dynamically or 254 there must be a way to determain which ones to free when the trait object is 255 destroyed. 207 208 Creation happens at compile time. Function pointers are found by using the 209 same best match rules as elsewhere (additional rules for defaults from the 210 parent may or may not be required). For strict virtual this must happen at the 211 global scope and forbidding static functions, to ensure that a single unique 212 vtable is created. Similarly, there may have to be stricter matching rules 213 for the functions that go into the vtable, possibly requiring an exact match. 214 Relaxed virtual could relax both restrictions, if we allow different vtable 215 at different conversion (struct to trait reference) sites. If it is allowed 216 local functions being bound to a vtable could cause issues when they go out 217 of scope, however this should follow the lifetime rules most C programs 218 already follow implicitly. 219 220 Most vtables should be stored statically, the only exception being some of 221 the relaxed vtables that could have local function pointers. These may be able 222 to be stack allocated. All vtables should be immutable and require no manual 223 cleanup. 256 224 257 225 Access has two main options: -
doc/theses/aaron_moss_PhD/phd/.gitignore
r34a6b2e r461eed2 1 1 templates/ 2 code/a.out3 2 thesis.pdf 4 3 thesis.aux -
doc/theses/aaron_moss_PhD/phd/Makefile
r34a6b2e r461eed2 17 17 introduction \ 18 18 background \ 19 generic-types \20 19 type-environment \ 21 20 resolution-heuristics \ -
doc/theses/aaron_moss_PhD/phd/cfa-macros.tex
r34a6b2e r461eed2 43 43 tabsize=5, % N space tabbing 44 44 xleftmargin=\parindentlnth, % indent code to paragraph indentation 45 %mathescape=true, % LaTeX math escape in CFA code $...$ 45 46 escapechar=\$, % LaTeX escape in CFA code 46 47 keepspaces=true, % -
doc/theses/aaron_moss_PhD/phd/frontpgs.tex
r34a6b2e r461eed2 160 160 % L I S T O F F I G U R E S 161 161 % ----------------------------- 162 \addcontentsline{toc}{chapter}{List of Figures}163 \listoffigures164 \cleardoublepage165 \phantomsection % allows hyperref to link to the correct page162 % \addcontentsline{toc}{chapter}{List of Figures} 163 % \listoffigures 164 % \cleardoublepage 165 % \phantomsection % allows hyperref to link to the correct page 166 166 167 167 % GLOSSARIES (Lists of definitions, abbreviations, symbols, etc. provided by the glossaries-extra package) -
doc/theses/aaron_moss_PhD/phd/generic-types.tex
r34a6b2e r461eed2 2 2 \label{generic-chap} 3 3 4 A significant shortcoming in standard C is the lack of reusable type-safe abstractions for generic data structures and algorithms. 5 Broadly speaking, there are three approaches to implement abstract data structures in C. 6 One approach is to write bespoke data structures for each context in which they are needed. 7 While this approach is flexible and supports integration with the C type checker and tooling, it is also tedious and error prone, especially for more complex data structures. 8 A second approach is to use !void*!-based polymorphism, \eg{} the C standard library functions !bsearch! and !qsort!, which allow for the reuse of common functionality. 9 However, basing all polymorphism on !void*! eliminates the type checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that is otherwise not needed. 10 A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type checked, but errors in such code may be difficult to locate and debug. 11 Furthermore, writing and using preprocessor macros is unnatural and inflexible. 12 Figure~\ref{bespoke-generic-fig} demonstrates the bespoke approach for a simple linked list with !insert! and !head! operations, while Figure~\ref{void-generic-fig} and Figure~\ref{macro-generic-fig} show the same example using !void*!- and !#define!-based polymorphism, respectively. 13 14 \begin{figure} 15 \begin{cfa} 16 struct int_list { int value; struct int_list* next; }; 17 18 void int_list_insert( struct int_list** ls, int x ) { 19 struct int_list* node = malloc(sizeof(struct int_list)); 20 node->value = x; node->next = *ls; 21 *ls = node; 22 } 23 24 int int_list_head( const struct int_list* ls ) { return ls->value; } 25 26 $\C[\textwidth]{// all code must be duplicated for every generic instantiation}$ 27 28 struct string_list { const char* value; struct string_list* next; }; 29 30 void string_list_insert( struct string_list** ls, const char* x ) { 31 struct string_list* node = malloc(sizeof(struct string_list)); 32 node->value = x; node->next = *ls; 33 *ls = node; 34 } 35 36 const char* string_list_head( const struct string_list* ls ) 37 { return ls->value; } 38 39 $\C[\textwidth]{// use is efficient and idiomatic}$ 40 41 int main() { 42 struct int_list* il = NULL; 43 int_list_insert( &il, 42 ); 44 printf("%d\n", int_list_head(il)); 45 46 struct string_list* sl = NULL; 47 string_list_insert( &sl, "hello" ); 48 printf("%s\n", string_list_head(sl)); 49 } 50 \end{cfa} 51 52 \caption{Bespoke code for linked list implementation.} \label{bespoke-generic-fig} 53 \end{figure} 54 55 \begin{figure} 56 \begin{cfa} 57 // single code implementation 58 59 struct list { void* value; struct list* next; }; 60 61 $\C[\textwidth]{// internal memory management requires helper functions}$ 62 63 void list_insert( struct list** ls, void* x, void* (*copy)(void*) ) { 64 struct list* node = malloc(sizeof(struct list)); 65 node->value = copy(x); node->next = *ls; 66 *ls = node; 67 } 68 69 void* list_head( const struct list* ls ) { return ls->value; } 70 71 $\C[\textwidth]{// helpers duplicated per type}$ 72 73 void* int_copy(void* x) { 74 int* n = malloc(sizeof(int)); 75 *n = *(int*)x; 76 return n; 77 } 78 79 void* string_copy(void* x) { return strdup((const char*)x); } 80 81 int main() { 82 struct list* il = NULL; 83 int i = 42; 84 list_insert( &il, &i, int_copy ); 85 printf("%d\n", *(int*)list_head(il)); $\C[2in]{// unsafe type cast}$ 86 87 struct list* sl = NULL; 88 list_insert( &sl, "hello", string_copy ); 89 printf("%s\n", (char*)list_head(sl)); $\C[2in]{// unsafe type cast}$ 90 } 91 \end{cfa} 92 93 \caption{\lstinline{void*}-polymorphic code for linked list implementation.} \label{void-generic-fig} 94 \end{figure} 95 96 \begin{figure} 97 \begin{cfa} 98 $\C[\textwidth]{// code is nested in macros}$ 99 100 #define list(N) N ## _list 101 102 #define list_insert(N) N ## _list_insert 103 104 #define list_head(N) N ## _list_head 105 106 #define define_list(N, T) $\C[0.25in]{ \textbackslash }$ 107 struct list(N) { T value; struct list(N)* next; }; $\C[0.25in]{ \textbackslash }$ 108 $\C[0.25in]{ \textbackslash }$ 109 void list_insert(N)( struct list(N)** ls, T x ) { $\C[0.25in]{ \textbackslash }$ 110 struct list(N)* node = malloc(sizeof(struct list(N))); $\C[0.25in]{ \textbackslash }$ 111 node->value = x; node->next = *ls; $\C[0.25in]{ \textbackslash }$ 112 *ls = node; $\C[0.25in]{ \textbackslash }$ 113 } $\C[0.25in]{ \textbackslash }$ 114 $\C[0.25in]{ \textbackslash }$ 115 T list_head(N)( const struct list(N)* ls ) { return ls->value; } 116 117 define_list(int, int); $\C[3in]{// defines int\_list}$ 118 define_list(string, const char*); $\C[3in]{// defines string\_list}$ 119 120 $\C[\textwidth]{// use is efficient, but syntactically idiosyncratic}$ 121 122 int main() { 123 struct list(int)* il = NULL; $\C[3in]{// does not match compiler-visible name}$ 124 list_insert(int)( &il, 42 ); 125 printf("%d\n", list_head(int)(il)); 126 127 struct list(string)* sl = NULL; 128 list_insert(string)( &sl, "hello" ); 129 printf("%s\n", list_head(string)(sl)); 130 } 131 \end{cfa} 132 133 \caption{Macros for generic linked list implementation.} \label{macro-generic-fig} 134 \end{figure} 135 136 \CC{}, Java, and other languages use \emph{generic types} to produce type-safe abstract data types. 137 Design and implementation of generic types for \CFA{} is the first major contribution of this thesis, a summary of which is published in \cite{Moss18}. 138 \CFA{} generic types integrate efficiently and naturally with the existing polymorphic functions in \CFA{}, while retaining backward compatibility with C in layout and support for separate compilation. 139 A generic type can be declared in \CFA{} by placing a !forall! specifier on a !struct! or !union! declaration, and instantiated using a parenthesized list of types after the generic name. 140 An example comparable to the C polymorphism examples in Figures~\ref{bespoke-generic-fig}, \ref{void-generic-fig}, and \ref{macro-generic-fig} can be seen in Figure~\ref{cfa-generic-fig} \TODO{test this code}. 141 142 \begin{figure} 143 \begin{cfa} 144 forall(otype T) struct list { T value; list(T)* next; }; 145 146 $\C[\textwidth]{// single polymorphic implementation of each function}$ 147 $\C[\textwidth]{// overloading reduces need for namespace prefixes}$ 148 149 forall(otype T) void insert( list(T)** ls, T x ) { 150 list(T)* node = alloc(); $\C{// type-inferring alloc}$ 151 (*node){ x, *ls }; $\C{// concise constructor syntax}$ 152 *ls = node; 153 } 154 155 forall(otype T) T head( const list(T)* ls ) { return ls->value; } 156 157 $\C[\textwidth]{// use is clear and efficient}$ 158 159 int main() { 160 list(int)* il = 0; 161 insert( &il, 42 ); $\C{// inferred polymorphic T}$ 162 printf("%d\n", head(il)); 163 164 list(const char*)* sl = 0; 165 insert( &sl, "hello" ); 166 printf("%s\n", head(sl)); 167 } 168 \end{cfa} 169 170 \caption{\CFA{} generic linked list implementation.} \label{cfa-generic-fig} 171 \end{figure} 172 173 \section{Design} 174 175 Though a number of languages have some implementation of generic types, backward compatibility with both C and existing \CFA{} polymorphism presented some unique design constraints for this project. 176 The guiding principle was to maintain an unsurprising language model for C programmers without compromising runtime efficiency. 177 A key insight for this design was that C already possesses a handful of built-in generic types (\emph{compound types} in the language of the standard\cit{}), notably pointer (!T*!) and array (!T[]!), and that user-definable generics should act similarly. 178 179 \subsection{Related Work} 180 181 One approach to the design of generic types is that taken by \CC{} templates\cit{}. 182 The template approach is closely related to the macro-expansion approach to C polymorphism demonstrated in Figure~\ref{macro-generic-fig}, but where the macro-expansion syntax has been given first-class language support. 183 Template expansion has the benefit of generating code with near-optimal runtime efficiency, as distinct optimizations can be applied for each instantiation of the template. 184 On the other hand, template expansion can also lead to significant code bloat, exponential in the worst case\cit{}, and the costs of increased instruction cache pressure at runtime and wasted developer time when compiling cannot be discounted. 185 The most significant restriction of the \CC{} template model is that it breaks separate compilation and C's translation-unit-based encapsulation mechanisms. 186 Because a \CC{} template is not actually code, but rather a sort of ``recipe'' to generate code, template code must be visible at its call site to be used. 187 C code, by contrast, only needs a !struct! or function declaration to call that function or use (by-pointer) values of that type, a desirable property to maintain for \CFA{}. 188 189 Java\cit{} has another prominent implementation for generic types, based on a significantly different approach than \CC{}. 190 The Java approach has much more in common with the !void*!-polymorphism shown in Figure~\ref{void-generic-fig}; since in Java nearly all data is stored by reference, the Java approach to polymorphic data is to store pointers to arbitrary data and insert type-checked implicit casts at compile-time. 191 This process of \emph{type erasure} has the benefit of allowing a single instantiation of polymorphic code, but relies heavily on Java's object model and garbage collector. 192 To use this model, a more C-like language such as \CFA{} would be required to dynamically allocate internal storage for variables, track their lifetime, and properly clean them up afterward. 193 194 \TODO{Talk about Go, maybe Rust, Swift, etc. as well; specifically mention ``fat pointer'' polymorphism} 195 196 \TODO{Talk about Cyclone as well, and why my generics are more powerful} 197 198 \subsection{\CFA{} Generics} 199 200 The generic types design in \CFA{} draws inspiration from both \CC{} and Java generics, capturing the better aspects of each. 201 Like \CC{} template types, generic !struct!s and !union!s in \CFA{} have macro-expanded storage layouts, but, like Java generics, \CFA{} generic types can be used with separately-compiled polymorphic functions without requiring either the type or function definition to be visible to the other. 202 The fact that the storage layout of any instantiation of a \CFA{} generic type is identical to that of the monomorphic type produced by simple macro replacement of the generic type parameters is important to provide consistent and predictable runtime performance, and to not impose any undue abstraction penalty on generic code. 203 As an example, consider the following generic type and function \TODO{test this}: 204 205 \begin{cfa} 206 forall( otype R, otype S ) struct pair { R first; S second; }; 207 208 pair(const char*, int) with_len( const char* s ) { 209 return (pair(const char*), int){ s, strlen(s) }; 210 } 211 \end{cfa} 212 213 In this example, !with_len! is defined at the same scope as !pair!, but it could be called from any context that can see the definition of !pair! and a declaration of !with_len!. 214 If its return type was !pair(const char*, int)*!, callers of !with_len! would only need the declaration !forall(otype R, otype S) struct pair;! to call it, in accordance with the usual C rules for opaque types. 215 216 !with_len! is itself a monomorphic function, returning a type that is structurally identical to !struct { const char* first; int second; }!, and as such could be called from C given an appropriate redeclaration and demangling flags. 217 However, the definition of !with_len! depends on a polymorphic function call to the !pair! constructor, which only needs to be written once (in this case, implicitly by the compiler according to the usual \CFA{} constructor generation\cite{Moss18}) and can be re-used for a wide variety of !pair! instantiations. 218 Since the parameters to this polymorphic constructor call are all statically known, compiler inlining can eliminate any runtime overhead of this polymorphic call. 219 220 \CFA{} deliberately does not support \CC{}-style partial specializations of generic types. 221 A particularly infamous example in the \CC{} standard library is !vector<bool>!, which is represented as a bitstring rather than the array representation of the other !vector! instantiations. 222 Complications from this inconsistency (chiefly the fact that a single bit is not addressable, unlike an array element) make the \CC{} !vector! unpleasant to use in generic contexts due to the break in its public interface. 223 Rather than attempting to plug leaks in the template specialization abstraction with a detailed method interface, \CFA{} takes the more principled position that two types with an unrelated data layout are in fact unrelated types, and should be handled with different code. 224 Of course, to the degree that distinct types are similar enough to share an interface, the \CFA{} !trait! system allows one to be defined, and objects of types implementing that !trait! to be operated on in the same polymorphic functions. 225 226 Since \CFA{} polymorphic functions can operate over polymorphic generic types, functions over such types can be partially or completely specialized using the usual overload selection rules. 227 As an example, the !with_len! function above could be an optimization of the following more general function: 228 229 \begin{cfa} 230 forall(otype T, otype I | { I len(T); }) 231 pair(T, I) with_len( T s ) { 232 return (pair(T,I)){ s, len(s) }; 233 } 234 \end{cfa} 235 236 \section{Implementation} 237 238 % forall constraints on struct/union constrain default constructor (TODO check with Rob) 4 Talk about generic types. Pull from Moss~\etal\cite{Moss18}. 239 5 240 6 % TODO discuss layout function algorithm, application to separate compilation 241 % TODO put a static const field in for _n_fields for each generic, describe utility for separate compilation (actually no, you need to be able to see the type for it to be sized)7 % TODO put a static const field in for _n_fields for each generic, describe utility for separate compilation 242 8 243 % mention that tuples are implemented on top of a per-arity generic type9 % TODO mention impetus for zero_t design 244 10 245 \section{Performance Experiments} 11 % TODO mention use in tuple-type implementation 246 12 247 13 % TODO pull benchmarks from Moss et al. 248 249 \section{Future Work}250 251 % mention future work adding non-type generic parameters, like ints252 253 % taking advantage of generic layout functions to provide field assertions in forall qualifiers254 255 % mention packed generic layouts (significantly more complex layout function, but possible) -
driver/cfa.cc
r34a6b2e r461eed2 357 357 358 358 string arch = m32 ? CFA_32_CPU : (m64 ? CFA_64_CPU : CFA_DEFAULT_CPU); 359 if ( ! m32 && ! m64 ) { 360 if ( arch == "x86" ) { 361 args[nargs] = "-m32"; 362 nargs += 1; 363 } else if ( arch == "x64" ) { 364 args[nargs] = "-m64"; 365 nargs += 1; 366 } // if 359 if ( ! m32 && ! m64 && arch == "x86" ) { // no override and 32-bit architecture 360 args[nargs] = "-m32"; 361 nargs += 1; 367 362 } // if 368 363 const char * config = debug ? "debug": "nodebug"; -
libcfa/Makefile.in
r34a6b2e r461eed2 229 229 CFLAGS = @CFLAGS@ 230 230 CONFIGURATION = @CONFIGURATION@ 231 CONFIG_BUILDLIB = @CONFIG_BUILDLIB@232 231 CONFIG_CFAFLAGS = @CONFIG_CFAFLAGS@ 233 232 CONFIG_CFLAGS = @CONFIG_CFLAGS@ -
libcfa/configure
r34a6b2e r461eed2 623 623 CFA_PREFIX 624 624 CFA_NAME 625 BUILDLIB_FALSE626 BUILDLIB_TRUE627 CONFIG_BUILDLIB628 625 CONFIG_CFAFLAGS 629 626 CONFIG_CFLAGS … … 2534 2531 CONFIG_CFLAGS="-O0 -g" 2535 2532 CONFIG_CFAFLAGS="-debug" 2536 CONFIG_BUILDLIB="yes"2537 2533 ;; 2538 2534 "nodebug" ) 2539 2535 CONFIG_CFLAGS="-O2 -s" 2540 2536 CONFIG_CFAFLAGS="-nodebug" 2541 CONFIG_BUILDLIB="yes"2542 2537 ;; 2543 2538 "nolib" ) 2544 CONFIG_CFLAGS="-O2 -s" 2545 CONFIG_CFAFLAGS="-nodebug" 2546 CONFIG_BUILDLIB="no" 2539 CONFIG_CFLAGS="" 2540 CONFIG_CFAFLAGS="" 2547 2541 ;; 2548 2542 esac 2549 2543 2550 2544 2551 2552 2553 2554 if test "x${CONFIG_BUILDLIB}" = "xyes"; then2555 BUILDLIB_TRUE=2556 BUILDLIB_FALSE='#'2557 else2558 BUILDLIB_TRUE='#'2559 BUILDLIB_FALSE=2560 fi2561 2545 2562 2546 … … 4494 4478 fi 4495 4479 4496 if test -z "${BUILDLIB_TRUE}" && test -z "${BUILDLIB_FALSE}"; then4497 as_fn_error $? "conditional \"BUILDLIB\" was never defined.4498 Usually this means the macro was only invoked conditionally." "$LINENO" 54499 fi4500 4480 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then 4501 4481 as_fn_error $? "conditional \"AMDEP\" was never defined. -
libcfa/configure.ac
r34a6b2e r461eed2 41 41 CONFIG_CFLAGS="-O0 -g" 42 42 CONFIG_CFAFLAGS="-debug" 43 CONFIG_BUILDLIB="yes"44 43 ;; 45 44 "nodebug" ) 46 45 CONFIG_CFLAGS="-O2 -s" 47 46 CONFIG_CFAFLAGS="-nodebug" 48 CONFIG_BUILDLIB="yes"49 47 ;; 50 48 "nolib" ) 51 CONFIG_CFLAGS="-O2 -s" 52 CONFIG_CFAFLAGS="-nodebug" 53 CONFIG_BUILDLIB="no" 49 CONFIG_CFLAGS="" 50 CONFIG_CFAFLAGS="" 54 51 ;; 55 52 esac … … 57 54 AC_SUBST(CONFIG_CFLAGS) 58 55 AC_SUBST(CONFIG_CFAFLAGS) 59 AC_SUBST(CONFIG_BUILDLIB)60 61 AM_CONDITIONAL([BUILDLIB], [test "x${CONFIG_BUILDLIB}" = "xyes"])62 56 63 57 #============================================================================== -
libcfa/prelude/Makefile.am
r34a6b2e r461eed2 20 20 # put into lib for now 21 21 cfalibdir = ${CFA_LIBDIR} 22 cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c 22 cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cf bootloader.c 23 noinst_DATA = ../src/prelude.c 23 24 24 25 CC = @CFACC@ … … 43 44 ${AM_V_GEN}gcc -I${srcdir} -E ${srcdir}/prototypes.c | awk -f ${srcdir}/prototypes.awk > $@ 44 45 45 prelude.cf a: prelude-gen.cc46 prelude.cf : prelude-gen.cc 46 47 ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${AM_CFLAGS} ${<} -o prelude-gen -Wall -Wextra -O2 -g -std=c++14 47 48 @./prelude-gen > $@ … … 59 60 include $(DEPDIR)/builtins.Po 60 61 61 bootloader.c : ${srcdir}/bootloader.cf prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACPP@ 62 ../src/prelude.c : prelude.cf extras.cf gcc-builtins.cf builtins.cf @CFACPP@ 63 ${AM_V_GEN}@CFACPP@ --prelude-dir=${builddir} -l prelude.cf $@ # use src/cfa-cpp as not in lib until after install 64 65 bootloader.c : ${srcdir}/bootloader.cf prelude.cf extras.cf gcc-builtins.cf builtins.cf @CFACPP@ 62 66 ${AM_V_GEN}@CFACPP@ --prelude-dir=${builddir} -tpm ${srcdir}/bootloader.cf $@ # use src/cfa-cpp as not in lib until after install 63 67 … … 65 69 rm -rf $(DEPDIR) 66 70 67 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cf a71 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cf 68 72 MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}} -
libcfa/prelude/Makefile.in
r34a6b2e r461eed2 147 147 } 148 148 am__installdirs = "$(DESTDIR)$(cfalibdir)" 149 DATA = $(cfalib_DATA) 149 DATA = $(cfalib_DATA) $(noinst_DATA) 150 150 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 151 151 am__DIST_COMMON = $(srcdir)/Makefile.in … … 174 174 CFLAGS = @CFLAGS@ 175 175 CONFIGURATION = @CONFIGURATION@ 176 CONFIG_BUILDLIB = @CONFIG_BUILDLIB@177 176 CONFIG_CFAFLAGS = @CONFIG_CFAFLAGS@ 178 177 CONFIG_CFLAGS = @CONFIG_CFLAGS@ … … 264 263 # put into lib for now 265 264 cfalibdir = ${CFA_LIBDIR} 266 cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c 265 cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cf bootloader.c 266 noinst_DATA = ../src/prelude.c 267 267 AM_CFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@ 268 268 AM_CFAFLAGS = @CONFIG_CFAFLAGS@ 269 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cf a269 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cf 270 270 MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}} 271 271 all: all-am … … 499 499 ${AM_V_GEN}gcc -I${srcdir} -E ${srcdir}/prototypes.c | awk -f ${srcdir}/prototypes.awk > $@ 500 500 501 prelude.cf a: prelude-gen.cc501 prelude.cf : prelude-gen.cc 502 502 ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${AM_CFLAGS} ${<} -o prelude-gen -Wall -Wextra -O2 -g -std=c++14 503 503 @./prelude-gen > $@ … … 515 515 include $(DEPDIR)/builtins.Po 516 516 517 bootloader.c : ${srcdir}/bootloader.cf prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACPP@ 517 ../src/prelude.c : prelude.cf extras.cf gcc-builtins.cf builtins.cf @CFACPP@ 518 ${AM_V_GEN}@CFACPP@ --prelude-dir=${builddir} -l prelude.cf $@ # use src/cfa-cpp as not in lib until after install 519 520 bootloader.c : ${srcdir}/bootloader.cf prelude.cf extras.cf gcc-builtins.cf builtins.cf @CFACPP@ 518 521 ${AM_V_GEN}@CFACPP@ --prelude-dir=${builddir} -tpm ${srcdir}/bootloader.cf $@ # use src/cfa-cpp as not in lib until after install 519 522 -
libcfa/prelude/prelude-gen.cc
r34a6b2e r461eed2 142 142 143 143 int main() { 144 cout << "# 2 \"prelude.cf a\" // needed for error messages from this file" << endl;144 cout << "# 2 \"prelude.cf\" // needed for error messages from this file" << endl; 145 145 cout << "trait sized(dtype T) {};" << endl; 146 146 -
libcfa/src/Makefile.am
r34a6b2e r461eed2 16 16 17 17 # create object files in directory with source files 18 AUTOMAKE_OPTIONS = foreignsubdir-objects18 AUTOMAKE_OPTIONS = subdir-objects 19 19 ARFLAGS = cr 20 20 … … 24 24 lib_LIBRARIES = libcfa.a 25 25 26 VPATH += :../prelude27 28 26 # AM_CFLAGS for all cfa source 29 27 # AM_CFAFLAGS for only cfa source 30 28 # use -no-include-stdhdr to prevent rebuild cycles 31 29 # The built sources must not depend on the installed headers 32 AM_CFAFLAGS = -quiet -in-tree - I$(srcdir)/stdhdr @CONFIG_CFAFLAGS@30 AM_CFAFLAGS = -quiet -in-tree -imacros prelude.c -I$(srcdir)/stdhdr @CONFIG_CFAFLAGS@ 33 31 AM_CFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@ 34 32 AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@ … … 36 34 37 35 #---------------------------------------------------------------------------------------------------------------- 38 if BUILDLIB39 36 headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \ 40 37 containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa 41 42 headers_nosrc = math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa43 38 44 39 # not all platforms support concurrency, add option do disable it 45 40 headers += concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa 46 41 47 headers_nosrc += concurrency/invoke.h 48 49 libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa${headers:.hfa=.cfa}42 libobjs = ${headers:.hfa=.o} 43 libsrc = prelude.c startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa \ 44 ${headers:.hfa=.cfa} 50 45 51 46 # not all platforms support concurrency, add option do disable it 52 47 libsrc += concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa 53 else54 headers =55 headers_nosrc =56 libsrc =57 endif58 59 48 60 49 #---------------------------------------------------------------------------------------------------------------- 61 50 # add dependency to cfa-cpp so all libraries are rebuilt with new translator 62 #@CFACC@ @CFACPP@ prelude.cfa 51 ${libobjs} : ${cfalib_DATA} 63 52 64 # add dependency of cfa files 65 libobjs = $(addsuffix .o, $(basename $(filter %.cfa,$(libsrc)))) 66 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa 67 68 69 # .deps inclusion is not done automatically by automake for new languages 70 libdeps = $(join \ 71 $(addsuffix $(DEPDIR)/ , $(dir $(libobjs) ) ), \ 72 $(notdir ${libobjs:.o=.Po}) \ 73 ) 74 75 -include $(libdeps) 76 77 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@ 78 ${AM_V_GEN}@CFACC@ ${AM_CFLAGS} ${CFLAGS} -quiet -in-tree -XCFA -l ${<} -c -o ${@} 79 80 81 82 #---------------------------------------------------------------------------------------------------------------- 83 libcfa_a_SOURCES = prelude.cfa ${libsrc} 53 libcfa_a_SOURCES = ${libsrc} 84 54 85 55 stdhdr = ${shell find ${srcdir}/stdhdr -type f -printf "%p "} 86 56 87 57 cfa_includedir = $(CFA_INCDIR) 88 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} 58 nobase_cfa_include_HEADERS = \ 59 ${headers} \ 60 ${stdhdr} \ 61 math.hfa \ 62 gmp.hfa \ 63 time_t.hfa \ 64 bits/align.hfa \ 65 bits/containers.hfa \ 66 bits/defs.hfa \ 67 bits/debug.hfa \ 68 bits/locks.hfa \ 69 concurrency/invoke.h 70 71 MOSTLYCLEANFILES = prelude.c 89 72 90 73 #---------------------------------------------------------------------------------------------------------------- 91 74 maintainer-clean-local: 92 75 -rm -rf ${CFA_INCDIR} ${CFA_LIBDIR} 93 94 95 # $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\96 # $(CFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\97 # $(am__mv) $$depbase.Tpo $$depbase.Po -
libcfa/src/Makefile.in
r34a6b2e r461eed2 19 19 20 20 21 VPATH = @srcdir@ 21 22 am__is_gnu_make = { \ 22 23 if test -z '$(MAKELEVEL)'; then \ … … 96 97 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 97 98 $(ACLOCAL_M4) 98 DIST_COMMON = $(srcdir)/Makefile.am \99 $(am__ nobase_cfa_include_HEADERS_DIST) $(am__DIST_COMMON)99 DIST_COMMON = $(srcdir)/Makefile.am $(nobase_cfa_include_HEADERS) \ 100 $(am__DIST_COMMON) 100 101 mkinstalldirs = $(install_sh) -d 101 102 CONFIG_CLEAN_FILES = … … 137 138 libcfa_a_AR = $(AR) $(ARFLAGS) 138 139 libcfa_a_LIBADD = 139 am__libcfa_a_SOURCES_DIST = prelude.cfa startup.cfa interpose.cfa \140 bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa \141 fstream.cfa iostream.cfa iterator.cfa limits.cfa rational.cfa \142 time.cfa stdlib.cfa common.cfa containers/maybe.cfa \143 containers/pair.cfa containers/result.cfa \144 containers/vector.cfa concurrency/coroutine.cfa \145 concurrency/thread.cfa concurrency/kernel.cfa \146 concurrency/monitor.cfa concurrency/mutex.cfa \147 concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \148 concurrency/invoke.c concurrency/preemption.cfa149 140 am__dirstamp = $(am__leading_dot)dirstamp 150 @BUILDLIB_TRUE@am__objects_1 = fstream.$(OBJEXT) iostream.$(OBJEXT) \ 151 @BUILDLIB_TRUE@ iterator.$(OBJEXT) limits.$(OBJEXT) \ 152 @BUILDLIB_TRUE@ rational.$(OBJEXT) time.$(OBJEXT) \ 153 @BUILDLIB_TRUE@ stdlib.$(OBJEXT) common.$(OBJEXT) \ 154 @BUILDLIB_TRUE@ containers/maybe.$(OBJEXT) \ 155 @BUILDLIB_TRUE@ containers/pair.$(OBJEXT) \ 156 @BUILDLIB_TRUE@ containers/result.$(OBJEXT) \ 157 @BUILDLIB_TRUE@ containers/vector.$(OBJEXT) \ 158 @BUILDLIB_TRUE@ concurrency/coroutine.$(OBJEXT) \ 159 @BUILDLIB_TRUE@ concurrency/thread.$(OBJEXT) \ 160 @BUILDLIB_TRUE@ concurrency/kernel.$(OBJEXT) \ 161 @BUILDLIB_TRUE@ concurrency/monitor.$(OBJEXT) \ 162 @BUILDLIB_TRUE@ concurrency/mutex.$(OBJEXT) 163 @BUILDLIB_TRUE@am__objects_2 = startup.$(OBJEXT) interpose.$(OBJEXT) \ 164 @BUILDLIB_TRUE@ bits/debug.$(OBJEXT) assert.$(OBJEXT) \ 165 @BUILDLIB_TRUE@ exception.$(OBJEXT) virtual.$(OBJEXT) \ 166 @BUILDLIB_TRUE@ heap.$(OBJEXT) $(am__objects_1) \ 167 @BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.$(OBJEXT) \ 168 @BUILDLIB_TRUE@ concurrency/alarm.$(OBJEXT) \ 169 @BUILDLIB_TRUE@ concurrency/invoke.$(OBJEXT) \ 170 @BUILDLIB_TRUE@ concurrency/preemption.$(OBJEXT) 171 am_libcfa_a_OBJECTS = prelude.$(OBJEXT) $(am__objects_2) 141 am__objects_1 = fstream.$(OBJEXT) iostream.$(OBJEXT) \ 142 iterator.$(OBJEXT) limits.$(OBJEXT) rational.$(OBJEXT) \ 143 time.$(OBJEXT) stdlib.$(OBJEXT) common.$(OBJEXT) \ 144 containers/maybe.$(OBJEXT) containers/pair.$(OBJEXT) \ 145 containers/result.$(OBJEXT) containers/vector.$(OBJEXT) \ 146 concurrency/coroutine.$(OBJEXT) concurrency/thread.$(OBJEXT) \ 147 concurrency/kernel.$(OBJEXT) concurrency/monitor.$(OBJEXT) \ 148 concurrency/mutex.$(OBJEXT) 149 am__objects_2 = prelude.$(OBJEXT) startup.$(OBJEXT) \ 150 interpose.$(OBJEXT) bits/debug.$(OBJEXT) assert.$(OBJEXT) \ 151 exception.$(OBJEXT) virtual.$(OBJEXT) heap.$(OBJEXT) \ 152 $(am__objects_1) \ 153 concurrency/CtxSwitch-@ARCHITECTURE@.$(OBJEXT) \ 154 concurrency/alarm.$(OBJEXT) concurrency/invoke.$(OBJEXT) \ 155 concurrency/preemption.$(OBJEXT) 156 am_libcfa_a_OBJECTS = $(am__objects_2) 172 157 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS) 173 158 AM_V_P = $(am__v_P_@AM_V@) … … 206 191 am__v_CCLD_1 = 207 192 SOURCES = $(libcfa_a_SOURCES) 208 DIST_SOURCES = $( am__libcfa_a_SOURCES_DIST)193 DIST_SOURCES = $(libcfa_a_SOURCES) 209 194 am__can_run_installinfo = \ 210 195 case $$AM_UPDATE_INFO_DIR in \ … … 212 197 *) (install-info --version) >/dev/null 2>&1;; \ 213 198 esac 214 am__nobase_cfa_include_HEADERS_DIST = ${shell find ${srcdir}/stdhdr \215 -type f -printf "%p "} fstream.hfa iostream.hfa iterator.hfa \216 limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \217 containers/maybe.hfa containers/pair.hfa containers/result.hfa \218 containers/vector.hfa concurrency/coroutine.hfa \219 concurrency/thread.hfa concurrency/kernel.hfa \220 concurrency/monitor.hfa concurrency/mutex.hfa math.hfa gmp.hfa \221 time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa \222 bits/debug.hfa bits/locks.hfa concurrency/invoke.h223 199 HEADERS = $(nobase_cfa_include_HEADERS) 224 200 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 244 220 $(top_srcdir)/./automake/depcomp 245 221 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 246 VPATH = @srcdir@ :../prelude247 222 ACLOCAL = @ACLOCAL@ 248 223 AMTAR = @AMTAR@ … … 268 243 CFLAGS = @CFLAGS@ 269 244 CONFIGURATION = @CONFIGURATION@ 270 CONFIG_BUILDLIB = @CONFIG_BUILDLIB@271 245 CONFIG_CFAFLAGS = @CONFIG_CFAFLAGS@ 272 246 CONFIG_CFLAGS = @CONFIG_CFLAGS@ … … 354 328 355 329 # create object files in directory with source files 356 AUTOMAKE_OPTIONS = foreignsubdir-objects330 AUTOMAKE_OPTIONS = subdir-objects 357 331 ARFLAGS = cr 358 332 CFACOMPILE = $(CFACC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) $(AM_CFLAGS) $(CFLAGS) … … 367 341 # use -no-include-stdhdr to prevent rebuild cycles 368 342 # The built sources must not depend on the installed headers 369 AM_CFAFLAGS = -quiet -in-tree - I$(srcdir)/stdhdr @CONFIG_CFAFLAGS@343 AM_CFAFLAGS = -quiet -in-tree -imacros prelude.c -I$(srcdir)/stdhdr @CONFIG_CFAFLAGS@ 370 344 AM_CFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@ 371 345 AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@ 372 @BUILDLIB_FALSE@headers =373 346 374 347 #---------------------------------------------------------------------------------------------------------------- 375 348 376 349 # not all platforms support concurrency, add option do disable it 377 @BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa \ 378 @BUILDLIB_TRUE@ limits.hfa rational.hfa time.hfa stdlib.hfa \ 379 @BUILDLIB_TRUE@ common.hfa containers/maybe.hfa \ 380 @BUILDLIB_TRUE@ containers/pair.hfa containers/result.hfa \ 381 @BUILDLIB_TRUE@ containers/vector.hfa concurrency/coroutine.hfa \ 382 @BUILDLIB_TRUE@ concurrency/thread.hfa concurrency/kernel.hfa \ 383 @BUILDLIB_TRUE@ concurrency/monitor.hfa concurrency/mutex.hfa 384 @BUILDLIB_FALSE@headers_nosrc = 385 @BUILDLIB_TRUE@headers_nosrc = math.hfa gmp.hfa time_t.hfa \ 386 @BUILDLIB_TRUE@ bits/align.hfa bits/containers.hfa \ 387 @BUILDLIB_TRUE@ bits/defs.hfa bits/debug.hfa bits/locks.hfa \ 388 @BUILDLIB_TRUE@ concurrency/invoke.h 389 @BUILDLIB_FALSE@libsrc = 350 headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa \ 351 rational.hfa time.hfa stdlib.hfa common.hfa \ 352 containers/maybe.hfa containers/pair.hfa containers/result.hfa \ 353 containers/vector.hfa concurrency/coroutine.hfa \ 354 concurrency/thread.hfa concurrency/kernel.hfa \ 355 concurrency/monitor.hfa concurrency/mutex.hfa 356 libobjs = ${headers:.hfa=.o} 390 357 391 358 # not all platforms support concurrency, add option do disable it 392 @BUILDLIB_TRUE@libsrc = startup.cfa interpose.cfa bits/debug.cfa \ 393 @BUILDLIB_TRUE@ assert.cfa exception.c virtual.c heap.cfa \ 394 @BUILDLIB_TRUE@ ${headers:.hfa=.cfa} \ 395 @BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.S \ 396 @BUILDLIB_TRUE@ concurrency/alarm.cfa concurrency/invoke.c \ 397 @BUILDLIB_TRUE@ concurrency/preemption.cfa 398 399 #---------------------------------------------------------------------------------------------------------------- 400 # add dependency to cfa-cpp so all libraries are rebuilt with new translator 401 #@CFACC@ @CFACPP@ prelude.cfa 402 403 # add dependency of cfa files 404 libobjs = $(addsuffix .o, $(basename $(filter %.cfa,$(libsrc)))) 405 406 # .deps inclusion is not done automatically by automake for new languages 407 libdeps = $(join \ 408 $(addsuffix $(DEPDIR)/ , $(dir $(libobjs) ) ), \ 409 $(notdir ${libobjs:.o=.Po}) \ 410 ) 411 412 413 #---------------------------------------------------------------------------------------------------------------- 414 libcfa_a_SOURCES = prelude.cfa ${libsrc} 359 libsrc = prelude.c startup.cfa interpose.cfa bits/debug.cfa assert.cfa \ 360 exception.c virtual.c heap.cfa ${headers:.hfa=.cfa} \ 361 concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \ 362 concurrency/invoke.c concurrency/preemption.cfa 363 libcfa_a_SOURCES = ${libsrc} 415 364 stdhdr = ${shell find ${srcdir}/stdhdr -type f -printf "%p "} 416 365 cfa_includedir = $(CFA_INCDIR) 417 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} 366 nobase_cfa_include_HEADERS = \ 367 ${headers} \ 368 ${stdhdr} \ 369 math.hfa \ 370 gmp.hfa \ 371 time_t.hfa \ 372 bits/align.hfa \ 373 bits/containers.hfa \ 374 bits/defs.hfa \ 375 bits/debug.hfa \ 376 bits/locks.hfa \ 377 concurrency/invoke.h 378 379 MOSTLYCLEANFILES = prelude.c 418 380 all: all-am 419 381 … … 544 506 545 507 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception.Po@am__quote@ 508 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prelude.Po@am__quote@ 546 509 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virtual.Po@am__quote@ 547 510 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/CtxSwitch-@ARCHITECTURE@.Po@am__quote@ … … 713 676 fi 714 677 mostlyclean-generic: 678 -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) 715 679 716 680 clean-generic: … … 820 784 821 785 822 .cfa.o: 786 .cfa.o: $(CFACC) $(CFACPP) 823 787 $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ 824 788 $(CFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 825 789 $(am__mv) $$depbase.Tpo $$depbase.Po 826 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa 827 828 -include $(libdeps) 829 830 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@ 831 ${AM_V_GEN}@CFACC@ ${AM_CFLAGS} ${CFLAGS} -quiet -in-tree -XCFA -l ${<} -c -o ${@} 790 791 #---------------------------------------------------------------------------------------------------------------- 792 # add dependency to cfa-cpp so all libraries are rebuilt with new translator 793 ${libobjs} : ${cfalib_DATA} 832 794 833 795 #---------------------------------------------------------------------------------------------------------------- … … 835 797 -rm -rf ${CFA_INCDIR} ${CFA_LIBDIR} 836 798 837 # $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\838 # $(CFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\839 # $(am__mv) $$depbase.Tpo $$depbase.Po840 841 799 # Tell versions [3.59,3.63) of GNU make to not export all variables. 842 800 # Otherwise a system limit (for SysV at least) may be exceeded. -
src/Makefile.am
r34a6b2e r461eed2 50 50 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O2 -g -std=c++14 51 51 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 52 ARFLAGS = cr53 52 54 53 demangler_SOURCES = SymTab/demangler.cc -
src/Makefile.in
r34a6b2e r461eed2 152 152 LIBRARIES = $(noinst_LIBRARIES) 153 153 AR = ar 154 ARFLAGS = cru 154 155 AM_V_AR = $(am__v_AR_@AM_V@) 155 156 am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) … … 581 582 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O2 -g -std=c++14 582 583 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 583 ARFLAGS = cr584 584 demangler_SOURCES = SymTab/demangler.cc 585 585 demangler_LDADD = libdemangle.a # yywrap -
src/SymTab/Demangle.cc
r34a6b2e r461eed2 392 392 parsers.emplace_back(Encoding::enum_t, [this](Type::Qualifiers tq) { return parseEnum(tq); }); 393 393 parsers.emplace_back(Encoding::type, [this](Type::Qualifiers tq) { return parseType(tq); }); 394 parsers.emplace_back(Encoding::zero, [ ](Type::Qualifiers tq) { return new ZeroType(tq); });395 parsers.emplace_back(Encoding::one, [ ](Type::Qualifiers tq) { return new OneType(tq); });394 parsers.emplace_back(Encoding::zero, [this](Type::Qualifiers tq) { return new ZeroType(tq); }); 395 parsers.emplace_back(Encoding::one, [this](Type::Qualifiers tq) { return new OneType(tq); }); 396 396 } 397 397 -
src/cfa.make
r34a6b2e r461eed2 6 6 am__v_CFA_1 = 7 7 8 .cfa.o: 8 .cfa.o: $(CFACC) $(CFACPP) 9 9 $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ 10 10 $(CFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -
src/main.cc
r34a6b2e r461eed2 172 172 if ( filename == nullptr ) filename = argv[ optind ]; 173 173 // prelude filename comes in differently 174 if ( libcfap ) filename = "prelude.cf a";174 if ( libcfap ) filename = "prelude.cf"; 175 175 optind += 1; 176 176 } else { // no input file name … … 199 199 if ( ! libcfap ) { 200 200 // read the prelude in, if not generating the cfa library 201 FILE * prelude = fopen( (PreludeDirector + "/prelude.cf a").c_str(), "r" );202 assertf( prelude, "cannot open prelude.cf a\n" );201 FILE * prelude = fopen( (PreludeDirector + "/prelude.cf").c_str(), "r" ); 202 assertf( prelude, "cannot open prelude.cf\n" ); 203 203 parse( prelude, LinkageSpec::Intrinsic ); 204 204 -
tests/Makefile.am
r34a6b2e r461eed2 23 23 24 24 concurrent= 25 timeouts=26 25 27 26 TEST_PY = python ${builddir}/test.py … … 51 50 #---------------------------------------------------------------------------------------------------------------- 52 51 all-local : 53 @+${TEST_PY} --debug=${debug} --install=${installed} ${concurrent} ${ timeouts} ${quick_test}52 @+${TEST_PY} --debug=${debug} --install=${installed} ${concurrent} ${quick_test} 54 53 55 54 all-tests : 56 @+${TEST_PY} -- debug=${debug} --install=${installed} ${concurrent} ${timeouts} --all# '@' => do not echo command (SILENT), '+' => allows recursive make from within python program55 @+${TEST_PY} --all --debug=${debug} --install=${installed} ${concurrent} # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 57 56 58 57 clean-local : -
tests/Makefile.in
r34a6b2e r461eed2 301 301 quick_test = avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes 302 302 concurrent = 303 timeouts =304 303 TEST_PY = python ${builddir}/test.py 305 304 … … 617 616 #---------------------------------------------------------------------------------------------------------------- 618 617 all-local : 619 @+${TEST_PY} --debug=${debug} --install=${installed} ${concurrent} ${ timeouts} ${quick_test}618 @+${TEST_PY} --debug=${debug} --install=${installed} ${concurrent} ${quick_test} 620 619 621 620 all-tests : 622 @+${TEST_PY} -- debug=${debug} --install=${installed} ${concurrent} ${timeouts} --all# '@' => do not echo command (SILENT), '+' => allows recursive make from within python program621 @+${TEST_PY} --all --debug=${debug} --install=${installed} ${concurrent} # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 623 622 624 623 clean-local :
Note:
See TracChangeset
for help on using the changeset viewer.