Index: driver/cfa.cc
===================================================================
--- driver/cfa.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ driver/cfa.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -405,8 +405,4 @@
 		args[nargs] = "--undefined=__cfaabi_appready_startup";
 		nargs += 1;
-		args[nargs] = "-Xlinker";
-		nargs += 1;
-		args[nargs] = "--undefined=__cfaabi_dbg_record";
-		nargs += 1;
 
 		// include the cfa library in case it's needed
@@ -414,4 +410,10 @@
 		nargs += 1;
 		args[nargs] = ( *new string( string("-Wl,-rpath," ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
+		nargs += 1;
+		args[nargs] = "-Wl,--push-state,--as-needed";
+		nargs += 1;
+		args[nargs] = "-lcfathread";
+		nargs += 1;
+		args[nargs] = "-Wl,--pop-state";
 		nargs += 1;
 		args[nargs] = "-lcfa";
Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/Makefile.am	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -22,5 +22,5 @@
 
 libdir = ${CFA_LIBDIR}
-lib_LTLIBRARIES = libcfa.la
+lib_LTLIBRARIES = libcfa.la libcfathread.la
 
 VPATH += :../prelude
@@ -41,15 +41,15 @@
 	  containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
 
-# not all platforms support concurrency, add option do disable it
-headers_nosrc += concurrency/invoke.h
-headers += concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
-
 libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
 
 # not all platforms support concurrency, add option do disable it
-libsrc += concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa
+thread_headers_nosrc = concurrency/invoke.h
+thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
+thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa ${thread_headers:.hfa=.cfa}
 else
 headers =
+thread_headers =
 headers_nosrc =
+thread_headers_nosrc =
 libsrc =
 endif
@@ -64,4 +64,7 @@
 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
 
+thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
+$(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
+
 
 # .deps inclusion is not done automatically by automake for new languages
@@ -72,4 +75,12 @@
 
 -include $(libdeps)
+
+thread_libdeps = $(join \
+	$(addsuffix $(DEPDIR)/ , $(dir $(thread_libobjs) ) ), \
+	$(notdir ${thread_libobjs:.lo=.Plo}) \
+)
+
+-include $(thread_libdeps)
+
 
 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
@@ -85,8 +96,11 @@
 libcfa_la_LDFLAGS = -version-info @CFA_VERSION@
 
+libcfathread_la_SOURCES = ${thread_libsrc}
+libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@
+
 stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ")
 
 cfa_includedir = $(CFA_INCDIR)
-nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc}
+nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}
 
 #----------------------------------------------------------------------------------------------------------------
Index: libcfa/src/Makefile.in
===================================================================
--- libcfa/src/Makefile.in	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/Makefile.in	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -142,9 +142,5 @@
 	time.cfa stdlib.cfa common.cfa containers/maybe.cfa \
 	containers/pair.cfa containers/result.cfa \
-	containers/vector.cfa concurrency/coroutine.cfa \
-	concurrency/thread.cfa concurrency/kernel.cfa \
-	concurrency/monitor.cfa concurrency/mutex.cfa \
-	concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
-	concurrency/invoke.c concurrency/preemption.cfa
+	containers/vector.cfa
 am__dirstamp = $(am__leading_dot)dirstamp
 @BUILDLIB_TRUE@am__objects_1 = fstream.lo iostream.lo iterator.lo \
@@ -152,13 +148,8 @@
 @BUILDLIB_TRUE@	common.lo containers/maybe.lo \
 @BUILDLIB_TRUE@	containers/pair.lo containers/result.lo \
-@BUILDLIB_TRUE@	containers/vector.lo concurrency/coroutine.lo \
-@BUILDLIB_TRUE@	concurrency/thread.lo concurrency/kernel.lo \
-@BUILDLIB_TRUE@	concurrency/monitor.lo concurrency/mutex.lo
+@BUILDLIB_TRUE@	containers/vector.lo
 @BUILDLIB_TRUE@am__objects_2 = startup.lo interpose.lo bits/debug.lo \
 @BUILDLIB_TRUE@	assert.lo exception.lo virtual.lo heap.lo \
-@BUILDLIB_TRUE@	$(am__objects_1) \
-@BUILDLIB_TRUE@	concurrency/CtxSwitch-@ARCHITECTURE@.lo \
-@BUILDLIB_TRUE@	concurrency/alarm.lo concurrency/invoke.lo \
-@BUILDLIB_TRUE@	concurrency/preemption.lo
+@BUILDLIB_TRUE@	$(am__objects_1)
 am_libcfa_la_OBJECTS = prelude.lo $(am__objects_2)
 libcfa_la_OBJECTS = $(am_libcfa_la_OBJECTS)
@@ -170,4 +161,24 @@
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(libcfa_la_LDFLAGS) $(LDFLAGS) -o $@
+libcfathread_la_LIBADD =
+am__libcfathread_la_SOURCES_DIST =  \
+	concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
+	concurrency/invoke.c concurrency/preemption.cfa \
+	concurrency/coroutine.cfa concurrency/thread.cfa \
+	concurrency/kernel.cfa concurrency/monitor.cfa \
+	concurrency/mutex.cfa
+@BUILDLIB_TRUE@am__objects_3 = concurrency/coroutine.lo \
+@BUILDLIB_TRUE@	concurrency/thread.lo concurrency/kernel.lo \
+@BUILDLIB_TRUE@	concurrency/monitor.lo concurrency/mutex.lo
+@BUILDLIB_TRUE@am__objects_4 =  \
+@BUILDLIB_TRUE@	concurrency/CtxSwitch-@ARCHITECTURE@.lo \
+@BUILDLIB_TRUE@	concurrency/alarm.lo concurrency/invoke.lo \
+@BUILDLIB_TRUE@	concurrency/preemption.lo $(am__objects_3)
+am_libcfathread_la_OBJECTS = $(am__objects_4)
+libcfathread_la_OBJECTS = $(am_libcfathread_la_OBJECTS)
+libcfathread_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libcfathread_la_LDFLAGS) $(LDFLAGS) \
+	-o $@
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -214,6 +225,7 @@
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libcfa_la_SOURCES)
-DIST_SOURCES = $(am__libcfa_la_SOURCES_DIST)
+SOURCES = $(libcfa_la_SOURCES) $(libcfathread_la_SOURCES)
+DIST_SOURCES = $(am__libcfa_la_SOURCES_DIST) \
+	$(am__libcfathread_la_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
@@ -225,9 +237,10 @@
 	limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
 	containers/maybe.hfa containers/pair.hfa containers/result.hfa \
-	containers/vector.hfa concurrency/coroutine.hfa \
+	containers/vector.hfa math.hfa gmp.hfa time_t.hfa \
+	bits/align.hfa bits/containers.hfa bits/defs.hfa \
+	bits/debug.hfa bits/locks.hfa concurrency/coroutine.hfa \
 	concurrency/thread.hfa concurrency/kernel.hfa \
-	concurrency/monitor.hfa concurrency/mutex.hfa math.hfa gmp.hfa \
-	time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa \
-	bits/debug.hfa bits/locks.hfa concurrency/invoke.h
+	concurrency/monitor.hfa concurrency/mutex.hfa \
+	concurrency/invoke.h
 HEADERS = $(nobase_cfa_include_HEADERS)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
@@ -421,5 +434,5 @@
 am__v_UPP_0 = @echo "  UPP     " $@;
 am__v_UPP_1 = 
-lib_LTLIBRARIES = libcfa.la
+lib_LTLIBRARIES = libcfa.la libcfathread.la
 
 # AM_CFLAGS for all cfa source
@@ -433,27 +446,18 @@
 
 #----------------------------------------------------------------------------------------------------------------
+@BUILDLIB_TRUE@headers_nosrc = math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa
+@BUILDLIB_FALSE@headers = 
+@BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
+@BUILDLIB_TRUE@	  containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
+
+@BUILDLIB_FALSE@libsrc = 
+@BUILDLIB_TRUE@libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
+@BUILDLIB_FALSE@thread_headers_nosrc = 
 
 # not all platforms support concurrency, add option do disable it
-@BUILDLIB_TRUE@headers_nosrc = math.hfa gmp.hfa time_t.hfa \
-@BUILDLIB_TRUE@	bits/align.hfa bits/containers.hfa \
-@BUILDLIB_TRUE@	bits/defs.hfa bits/debug.hfa bits/locks.hfa \
-@BUILDLIB_TRUE@	concurrency/invoke.h
-@BUILDLIB_FALSE@headers = 
-@BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa \
-@BUILDLIB_TRUE@	limits.hfa rational.hfa time.hfa stdlib.hfa \
-@BUILDLIB_TRUE@	common.hfa containers/maybe.hfa \
-@BUILDLIB_TRUE@	containers/pair.hfa containers/result.hfa \
-@BUILDLIB_TRUE@	containers/vector.hfa concurrency/coroutine.hfa \
-@BUILDLIB_TRUE@	concurrency/thread.hfa concurrency/kernel.hfa \
-@BUILDLIB_TRUE@	concurrency/monitor.hfa concurrency/mutex.hfa
-@BUILDLIB_FALSE@libsrc = 
-
-# not all platforms support concurrency, add option do disable it
-@BUILDLIB_TRUE@libsrc = startup.cfa interpose.cfa bits/debug.cfa \
-@BUILDLIB_TRUE@	assert.cfa exception.c virtual.c heap.cfa \
-@BUILDLIB_TRUE@	${headers:.hfa=.cfa} \
-@BUILDLIB_TRUE@	concurrency/CtxSwitch-@ARCHITECTURE@.S \
-@BUILDLIB_TRUE@	concurrency/alarm.cfa concurrency/invoke.c \
-@BUILDLIB_TRUE@	concurrency/preemption.cfa
+@BUILDLIB_TRUE@thread_headers_nosrc = concurrency/invoke.h
+@BUILDLIB_FALSE@thread_headers = 
+@BUILDLIB_TRUE@thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
+@BUILDLIB_TRUE@thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa ${thread_headers:.hfa=.cfa}
 
 #----------------------------------------------------------------------------------------------------------------
@@ -463,4 +467,5 @@
 # add dependency of cfa files
 libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(libsrc))))
+thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
 
 # .deps inclusion is not done automatically by automake for new languages
@@ -470,11 +475,18 @@
 )
 
+thread_libdeps = $(join \
+	$(addsuffix $(DEPDIR)/ , $(dir $(thread_libobjs) ) ), \
+	$(notdir ${thread_libobjs:.lo=.Plo}) \
+)
+
 
 #----------------------------------------------------------------------------------------------------------------
 libcfa_la_SOURCES = prelude.cfa ${libsrc}
 libcfa_la_LDFLAGS = -version-info @CFA_VERSION@
+libcfathread_la_SOURCES = ${thread_libsrc}
+libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@
 stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ")
 cfa_includedir = $(CFA_INCDIR)
-nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc}
+nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}
 all: all-am
 
@@ -567,4 +579,7 @@
 containers/vector.lo: containers/$(am__dirstamp) \
 	containers/$(DEPDIR)/$(am__dirstamp)
+
+libcfa.la: $(libcfa_la_OBJECTS) $(libcfa_la_DEPENDENCIES) $(EXTRA_libcfa_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libcfa_la_LINK) -rpath $(libdir) $(libcfa_la_OBJECTS) $(libcfa_la_LIBADD) $(LIBS)
 concurrency/$(am__dirstamp):
 	@$(MKDIR_P) concurrency
@@ -573,4 +588,12 @@
 	@$(MKDIR_P) concurrency/$(DEPDIR)
 	@: > concurrency/$(DEPDIR)/$(am__dirstamp)
+concurrency/CtxSwitch-@ARCHITECTURE@.lo: concurrency/$(am__dirstamp) \
+	concurrency/$(DEPDIR)/$(am__dirstamp)
+concurrency/alarm.lo: concurrency/$(am__dirstamp) \
+	concurrency/$(DEPDIR)/$(am__dirstamp)
+concurrency/invoke.lo: concurrency/$(am__dirstamp) \
+	concurrency/$(DEPDIR)/$(am__dirstamp)
+concurrency/preemption.lo: concurrency/$(am__dirstamp) \
+	concurrency/$(DEPDIR)/$(am__dirstamp)
 concurrency/coroutine.lo: concurrency/$(am__dirstamp) \
 	concurrency/$(DEPDIR)/$(am__dirstamp)
@@ -583,15 +606,7 @@
 concurrency/mutex.lo: concurrency/$(am__dirstamp) \
 	concurrency/$(DEPDIR)/$(am__dirstamp)
-concurrency/CtxSwitch-@ARCHITECTURE@.lo: concurrency/$(am__dirstamp) \
-	concurrency/$(DEPDIR)/$(am__dirstamp)
-concurrency/alarm.lo: concurrency/$(am__dirstamp) \
-	concurrency/$(DEPDIR)/$(am__dirstamp)
-concurrency/invoke.lo: concurrency/$(am__dirstamp) \
-	concurrency/$(DEPDIR)/$(am__dirstamp)
-concurrency/preemption.lo: concurrency/$(am__dirstamp) \
-	concurrency/$(DEPDIR)/$(am__dirstamp)
-
-libcfa.la: $(libcfa_la_OBJECTS) $(libcfa_la_DEPENDENCIES) $(EXTRA_libcfa_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libcfa_la_LINK) -rpath $(libdir) $(libcfa_la_OBJECTS) $(libcfa_la_LIBADD) $(LIBS)
+
+libcfathread.la: $(libcfathread_la_OBJECTS) $(libcfathread_la_DEPENDENCIES) $(EXTRA_libcfathread_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libcfathread_la_LINK) -rpath $(libdir) $(libcfathread_la_OBJECTS) $(libcfathread_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
@@ -922,6 +937,9 @@
 	$(am__mv) $$depbase.Tpo $$depbase.Plo
 $(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
+$(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
 
 -include $(libdeps)
+
+-include $(thread_libdeps)
 
 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
Index: libcfa/src/bits/defs.hfa
===================================================================
--- libcfa/src/bits/defs.hfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/bits/defs.hfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -41,2 +41,8 @@
 }
 #endif
+
+#if defined(__cforall_thread__)
+#define OPTIONAL_THREAD
+#else
+#define OPTIONAL_THREAD __attribute__((weak))
+#endif
Index: libcfa/src/bits/locks.hfa
===================================================================
--- libcfa/src/bits/locks.hfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/bits/locks.hfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -50,6 +50,6 @@
 #ifdef __cforall
 	extern "C" {
-		extern void disable_interrupts();
-		extern void enable_interrupts_noPoll();
+		extern void disable_interrupts() OPTIONAL_THREAD;
+		extern void enable_interrupts_noPoll() OPTIONAL_THREAD;
 
 		#ifdef __CFA_DEBUG__
Index: libcfa/src/concurrency/alarm.cfa
===================================================================
--- libcfa/src/concurrency/alarm.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/alarm.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -13,4 +13,6 @@
 // Update Count     : 67
 //
+
+#define __cforall_thread__
 
 extern "C" {
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -13,4 +13,6 @@
 // Update Count     : 9
 //
+
+#define __cforall_thread__
 
 #include "coroutine.hfa"
Index: libcfa/src/concurrency/invoke.c
===================================================================
--- libcfa/src/concurrency/invoke.c	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/invoke.c	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -13,4 +13,6 @@
 // Update Count     : 5
 //
+
+#define __cforall_thread__
 
 #include <stdbool.h>
@@ -31,5 +33,5 @@
 extern void __finish_creation( struct thread_desc * );
 extern void __leave_thread_monitor( struct thread_desc * this );
-extern void disable_interrupts();
+extern void disable_interrupts() OPTIONAL_THREAD;
 extern void enable_interrupts( __cfaabi_dbg_ctx_param );
 
Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/kernel.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -13,4 +13,6 @@
 // Update Count     : 25
 //
+
+#define __cforall_thread__
 
 //C Includes
@@ -943,4 +945,10 @@
 	}
 )
+
+//-----------------------------------------------------------------------------
+// Debug
+bool threading_enabled(void) {
+	return true;
+}
 // Local Variables: //
 // mode: c //
Index: libcfa/src/concurrency/kernel_private.hfa
===================================================================
--- libcfa/src/concurrency/kernel_private.hfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/kernel_private.hfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -26,5 +26,5 @@
 
 extern "C" {
-	void disable_interrupts();
+	void disable_interrupts() OPTIONAL_THREAD;
 	void enable_interrupts_noPoll();
 	void enable_interrupts( __cfaabi_dbg_ctx_param );
Index: libcfa/src/concurrency/monitor.cfa
===================================================================
--- libcfa/src/concurrency/monitor.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/monitor.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -13,4 +13,6 @@
 // Update Count     : 9
 //
+
+#define __cforall_thread__
 
 #include "monitor.hfa"
Index: libcfa/src/concurrency/mutex.cfa
===================================================================
--- libcfa/src/concurrency/mutex.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/mutex.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -15,4 +15,6 @@
 // Update Count     : 0
 //
+
+#define __cforall_thread__
 
 #include "mutex.hfa"
Index: libcfa/src/concurrency/preemption.cfa
===================================================================
--- libcfa/src/concurrency/preemption.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/preemption.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -13,4 +13,6 @@
 // Update Count     : 37
 //
+
+#define __cforall_thread__
 
 #include "preemption.hfa"
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/concurrency/thread.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -13,4 +13,6 @@
 // Update Count     : 8
 //
+
+#define __cforall_thread__
 
 #include "thread.hfa"
Index: libcfa/src/stdlib.cfa
===================================================================
--- libcfa/src/stdlib.cfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/stdlib.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -252,4 +252,9 @@
 long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); }
 
+//---------------------------------------
+
+bool threading_enabled(void) __attribute__((weak)) {
+	return false;
+}
 
 // Local Variables: //
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ libcfa/src/stdlib.hfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -15,4 +15,6 @@
 
 #pragma once
+
+#include "bits/defs.hfa"
 
 #include <stdlib.h>										// *alloc, strto*, ato*
@@ -246,4 +248,8 @@
 #include "common.hfa"
 
+//---------------------------------------
+
+extern bool threading_enabled(void) OPTIONAL_THREAD;
+
 // Local Variables: //
 // mode: c //
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/InitTweak/InitTweak.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -9,7 +9,7 @@
 // Author           : Rob Schluntz
 // Created On       : Fri May 13 11:26:36 2016
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Mon Jun 10 13:30:00 2019
-// Update Count     : 5
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Jun 19 14:34:00 2019
+// Update Count     : 6
 //
 
@@ -633,13 +633,21 @@
 			return nullptr;
 		}
+
+		DeclarationWithType * getFunctionCore( const Expression * expr ) {
+			if ( const auto * appExpr = dynamic_cast< const ApplicationExpr * >( expr ) ) {
+				return getCalledFunction( appExpr->function );
+			} else if ( const auto * untyped = dynamic_cast< const UntypedExpr * >( expr ) ) {
+				return getCalledFunction( untyped->function );
+			}
+			assertf( false, "getFunction with unknown expression: %s", toString( expr ).c_str() );
+		}
 	}
 
 	DeclarationWithType * getFunction( Expression * expr ) {
-		if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) {
-			return getCalledFunction( appExpr->get_function() );
-		} else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) {
-			return getCalledFunction( untyped->get_function() );
-		}
-		assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );
+		return getFunctionCore( expr );
+	}
+
+	const DeclarationWithType * getFunction( const Expression * expr ) {
+		return getFunctionCore( expr );
 	}
 
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/InitTweak/InitTweak.h	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -9,7 +9,7 @@
 // Author           : Rob Schluntz
 // Created On       : Fri May 13 11:26:36 2016
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Mon Jun 10 13:30:00 2019
-// Update Count     : 5
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Jul 19 14:18:00 2019
+// Update Count     : 6
 //
 
@@ -61,4 +61,5 @@
 	/// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr)
 	DeclarationWithType * getFunction( Expression * expr );
+	const DeclarationWithType * getFunction( const Expression * expr );
 	const ast::DeclWithType * getFunction( const ast::Expr * expr );
 
Index: src/ResolvExpr/FindOpenVars.cc
===================================================================
--- src/ResolvExpr/FindOpenVars.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/ResolvExpr/FindOpenVars.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 09:42:48 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 17 09:45:25 2015
-// Update Count     : 3
+// Last Modified By : Andrew
+// Last Modified On : Fri Jul 12 14:18:00 2019
+// Update Count     : 4
 //
 
@@ -29,10 +29,10 @@
 		FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
 
-		void previsit( PointerType * pointerType );
-		void previsit( ArrayType * arrayType );
-		void previsit( FunctionType * functionType );
-		void previsit( TupleType * tupleType );
+		void previsit( const PointerType * pointerType );
+		void previsit( const ArrayType * arrayType );
+		void previsit( const FunctionType * functionType );
+		void previsit( const TupleType * tupleType );
 
-		void common_action( Type *type );
+		void common_action( const Type *type );
 
 		OpenVarSet &openVars, &closedVars;
@@ -41,5 +41,5 @@
 	};
 
-	void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
+	void findOpenVars( const Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
 		PassVisitor<FindOpenVars_old> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
 		type->accept( finder );
@@ -50,7 +50,7 @@
 	}
 
-	void FindOpenVars_old::common_action( Type *type ) {
+	void FindOpenVars_old::common_action( const Type * type ) {
 		if ( nextIsOpen ) {
-			for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+			for ( Type::ForallList::const_iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
 				openVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
 				for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
@@ -61,5 +61,5 @@
 			}
 		} else {
-			for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+			for ( Type::ForallList::const_iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
 				closedVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
 				for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
@@ -78,13 +78,13 @@
 	}
 
-	void FindOpenVars_old::previsit(PointerType *pointerType) {
+	void FindOpenVars_old::previsit(const PointerType * pointerType) {
 		common_action( pointerType );
 	}
 
-	void FindOpenVars_old::previsit(ArrayType *arrayType) {
+	void FindOpenVars_old::previsit(const ArrayType * arrayType) {
 		common_action( arrayType );
 	}
 
-	void FindOpenVars_old::previsit(FunctionType *functionType) {
+	void FindOpenVars_old::previsit(const FunctionType * functionType) {
 		common_action( functionType );
 		nextIsOpen = ! nextIsOpen;
@@ -92,5 +92,5 @@
 	}
 
-	void FindOpenVars_old::previsit(TupleType *tupleType) {
+	void FindOpenVars_old::previsit(const TupleType * tupleType) {
 		common_action( tupleType );
 	}
@@ -104,6 +104,6 @@
 			bool nextIsOpen;
 
-			FindOpenVars_new( 
-				ast::OpenVarSet & o, ast::OpenVarSet & c, ast::AssertionSet & n, 
+			FindOpenVars_new(
+				ast::OpenVarSet & o, ast::OpenVarSet & c, ast::AssertionSet & n,
 				ast::AssertionSet & h, FirstMode firstIsOpen )
 			: open( o ), closed( c ), need( n ), have( h ), nextIsOpen( firstIsOpen ) {}
@@ -135,6 +135,6 @@
 	}
 
-	void findOpenVars( 
-			const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed, 
+	void findOpenVars(
+			const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed,
 			ast::AssertionSet & need, ast::AssertionSet & have, FirstMode firstIsOpen ) {
 		ast::Pass< FindOpenVars_new > finder{ open, closed, need, have, firstIsOpen };
Index: src/ResolvExpr/FindOpenVars.h
===================================================================
--- src/ResolvExpr/FindOpenVars.h	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/ResolvExpr/FindOpenVars.h	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -26,5 +26,5 @@
 namespace ResolvExpr {
 	// Updates open and closed variables and their associated assertions
-	void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
+	void findOpenVars( const Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
 
 	enum FirstMode { FirstClosed, FirstOpen };
Index: src/ResolvExpr/Occurs.cc
===================================================================
--- src/ResolvExpr/Occurs.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/ResolvExpr/Occurs.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -24,5 +24,5 @@
 	struct Occurs : public WithVisitorRef<Occurs> {
 		Occurs( std::string varName, const TypeEnvironment &env );
-		void previsit( TypeInstType * typeInst );
+		void previsit( const TypeInstType * typeInst );
 
 		bool result;
@@ -31,5 +31,5 @@
 	};
 
-	bool occurs( Type *type, std::string varName, const TypeEnvironment &env ) {
+	bool occurs( const Type *type, const std::string & varName, const TypeEnvironment &env ) {
 		PassVisitor<Occurs> occur( varName, env );
 		type->accept( occur );
@@ -45,5 +45,5 @@
 	}
 
-	void Occurs::previsit( TypeInstType * typeInst ) {
+	void Occurs::previsit( const TypeInstType * typeInst ) {
 		///   std::cerr << "searching for vars: ";
 ///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cerr, " " ) );
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -73,5 +73,5 @@
 		CandidateList matches;
 
-		DeferItem( DeclarationWithType* decl, const AssertionSetValue& info, CandidateList&& matches )
+		DeferItem( const DeclarationWithType* decl, const AssertionSetValue& info, CandidateList&& matches )
 		: decl(decl), info(info), matches(std::move(matches)) {}
 
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -315,8 +315,8 @@
 	}
 
-	bool isFtype( Type *type ) {
-		if ( dynamic_cast< FunctionType* >( type ) ) {
+	bool isFtype( const Type *type ) {
+		if ( dynamic_cast< const FunctionType * >( type ) ) {
 			return true;
-		} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+		} else if ( const TypeInstType *typeInst = dynamic_cast< const TypeInstType * >( type ) ) {
 			return typeInst->get_isFtype();
 		} // if
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/ResolvExpr/typeops.h	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -149,5 +149,5 @@
 
 	// in Occurs.cc
-	bool occurs( Type * type, std::string varName, const TypeEnvironment & env );
+	bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env );
 	// new AST version in TypeEnvironment.cpp (only place it was used in old AST)
 
@@ -200,5 +200,5 @@
 
 	// in TypeEnvironment.cc
-	bool isFtype( Type * type );
+	bool isFtype( const Type * type );
 } // namespace ResolvExpr
 
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/SynTree/Type.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jan 31 21:54:16 2019
-// Update Count     : 43
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Jul 12 15:48:00 2019
+// Update Count     : 44
 //
 #include "Type.h"
@@ -141,4 +141,11 @@
 }
 
+const Type * Type::stripReferences() const {
+	const Type * type;
+	const ReferenceType * ref;
+	for ( type = this; (ref = dynamic_cast<const ReferenceType *>( type )); type = ref->base );
+	return type;
+}
+
 int Type::referenceDepth() const { return 0; }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/SynTree/Type.h	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -172,4 +172,5 @@
 	/// return type without outer references
 	Type * stripReferences();
+	const Type * stripReferences() const;
 
 	/// return the number of references occuring consecutively on the outermost layer of this type (i.e. do not count references nested within other types)
@@ -256,5 +257,5 @@
 	BasicType( const Type::Qualifiers & tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 
-	Kind get_kind() { return kind; }
+	Kind get_kind() const { return kind; }
 	void set_kind( Kind newValue ) { kind = newValue; }
 
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/SynTree/module.mk	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/Tuples/TupleExpansion.cc	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 13 18:14:12 2019
-// Update Count     : 21
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Jul 19 14:39:00 2019
+// Update Count     : 22
 //
 
@@ -364,9 +364,9 @@
 			ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {}
 
-			void previsit( ApplicationExpr * appExpr ) {
+			void previsit( const ApplicationExpr * appExpr ) {
 				visit_children = false;
-				if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {
-					if ( function->get_linkage() == LinkageSpec::Intrinsic ) {
-						if ( function->get_name() == "*?" || function->get_name() == "?[?]" ) {
+				if ( const DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {
+					if ( function->linkage == LinkageSpec::Intrinsic ) {
+						if ( function->name == "*?" || function->name == "?[?]" ) {
 							// intrinsic dereference, subscript are pure, but need to recursively look for impurity
 							visit_children = true;
@@ -377,6 +377,6 @@
 				maybeImpure = true;
 			}
-			void previsit( UntypedExpr * ) { maybeImpure = true; visit_children = false; }
-			void previsit( UniqueExpr * ) {
+			void previsit( const UntypedExpr * ) { maybeImpure = true; visit_children = false; }
+			void previsit( const UniqueExpr * ) {
 				if ( ignoreUnique ) {
 					// bottom out at unique expression.
@@ -393,5 +393,5 @@
 	} // namespace
 
-	bool maybeImpure( Expression * expr ) {
+	bool maybeImpure( const Expression * expr ) {
 		PassVisitor<ImpurityDetector> detector( false );
 		expr->accept( detector );
@@ -399,5 +399,5 @@
 	}
 
-	bool maybeImpureIgnoreUnique( Expression * expr ) {
+	bool maybeImpureIgnoreUnique( const Expression * expr ) {
 		PassVisitor<ImpurityDetector> detector( true );
 		expr->accept( detector );
Index: src/Tuples/Tuples.h
===================================================================
--- src/Tuples/Tuples.h	(revision e7231002bcdfdd0362118b8f0aa1cdc1d9a7e312)
+++ src/Tuples/Tuples.h	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -55,10 +55,10 @@
 
 	/// returns true if the expression may contain side-effects.
-	bool maybeImpure( Expression * expr );
+	bool maybeImpure( const Expression * expr );
 	bool maybeImpure( const ast::Expr * expr );
 
 	/// Returns true if the expression may contain side-effect,
 	/// ignoring the presence of unique expressions.
-	bool maybeImpureIgnoreUnique( Expression * expr );
+	bool maybeImpureIgnoreUnique( const Expression * expr );
 	bool maybeImpureIgnoreUnique( const ast::Expr * expr );
 } // namespace Tuples
Index: tests/linking/.expect/nothreads.txt
===================================================================
--- tests/linking/.expect/nothreads.txt	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
+++ tests/linking/.expect/nothreads.txt	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -0,0 +1,1 @@
+NO
Index: tests/linking/.expect/withthreads.txt
===================================================================
--- tests/linking/.expect/withthreads.txt	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
+++ tests/linking/.expect/withthreads.txt	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -0,0 +1,1 @@
+YES
Index: tests/linking/nothreads.cfa
===================================================================
--- tests/linking/nothreads.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
+++ tests/linking/nothreads.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -0,0 +1,31 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// nothreads.cfa --
+//
+// Author           : Thierry Delisle
+// Created On       : Tue Jul 16 12:14:39 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include <fstream.hfa>
+#include <stdlib.hfa>
+
+int main() {
+	if(threading_enabled()) {
+		stdout | "YES";
+	} else {
+		stdout | "NO";
+	}
+	return 0;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa nothreads.cfa" //
+// End: //
Index: tests/linking/withthreads.cfa
===================================================================
--- tests/linking/withthreads.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
+++ tests/linking/withthreads.cfa	(revision 884f14097e02f66e09356b478c49b4c0cd96149a)
@@ -0,0 +1,37 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// nothreads.cfa --
+//
+// Author           : Thierry Delisle
+// Created On       : Tue Jul 16 12:14:39 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include <fstream.hfa>
+#include <stdlib.hfa>
+
+#include <thread.hfa>
+
+thread Dummy {};
+void main( Dummy & ) {}
+
+int main() {
+	if(threading_enabled()) {
+		stdout | "YES";
+	} else {
+		stdout | "NO";
+	}
+	Dummy d;
+	return 0;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa nothreads.cfa" //
+// End: //
