Index: doc/proposals/concurrency/text/basics.tex
===================================================================
--- doc/proposals/concurrency/text/basics.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/basics.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -4,5 +4,5 @@
 % ======================================================================
 % ======================================================================
-Before any detailed discussion of the concurrency and parallelism in \CFA, it is important to describe the basics of concurrency and how they are expressed in \CFA user-code.
+Before any detailed discussion of the concurrency and parallelism in \CFA, it is important to describe the basics of concurrency and how they are expressed in \CFA user code.
 
 \section{Basics of concurrency}
@@ -11,13 +11,13 @@
 Execution with a single thread and multiple stacks where the thread is self-scheduling deterministically across the stacks is called coroutining. Execution with a single and multiple stacks but where the thread is scheduled by an oracle (non-deterministic from the thread perspective) across the stacks is called concurrency.
 
-Therefore, a minimal concurrency system can be achieved by creating coroutines, which instead of context switching among each other, always ask an oracle where to context switch next. While coroutines can execute on the caller's stack-frame, stack-full coroutines allow full generality and are sufficient as the basis for concurrency. The aforementioned oracle is a scheduler and the whole system now follows a cooperative threading-model (a.k.a non-preemptive scheduling). The oracle/scheduler can either be a stack-less or stack-full entity and correspondingly require one or two context switches to run a different coroutine. In any case, a subset of concurrency related challenges start to appear. For the complete set of concurrency challenges to occur, the only feature missing is preemption.
-
-A scheduler introduces order of execution uncertainty, while preemption introduces uncertainty about where context-switches occur. Mutual-exclusion and synchronization are ways of limiting non-determinism in a concurrent system. Now it is important to understand that uncertainty is desirable; uncertainty can be used by runtime systems to significantly increase performance and is often the basis of giving a user the illusion that tasks are running in parallel. Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows.
-
-\section{\protect\CFA 's Thread Building Blocks}
-One of the important features that is missing in C is threading. On modern architectures, a lack of threading is unacceptable~\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write performant concurrent programs to take advantage of parallelism. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay.
-
-\section{Coroutines: A stepping stone}\label{coroutine}
-While the main focus of this proposal is concurrency and parallelism, it is important to address coroutines, which are actually a significant building block of a concurrency system. Coroutines need to deal with context-switches and other context-management operations. Therefore, this proposal includes coroutines both as an intermediate step for the implementation of threads, and a first class feature of \CFA. Furthermore, many design challenges of threads are at least partially present in designing coroutines, which makes the design effort that much more relevant. The core \acrshort{api} of coroutines revolve around two features: independent call stacks and \code{suspend}/\code{resume}.
+Therefore, a minimal concurrency system can be achieved by creating coroutines, which instead of context-switching among each other, always ask an oracle where to context-switch next. While coroutines can execute on the caller?s stack-frame, stack-full coroutines allow full generality and are sufficient as the basis for concurrency. The aforementioned oracle is a scheduler and the whole system now follows a cooperative threading-model (aka non-preemptive scheduling). The oracle/scheduler can either be a stack-less or stack-full entity and correspondingly require one or two context-switches to run a different coroutine. In any case, a subset of concurrency related challenges start to appear. For the complete set of concurrency challenges to occur, the only feature missing is preemption.
+
+A scheduler introduces order of execution uncertainty, while preemption introduces uncertainty about where context switches occur. Mutual exclusion and synchronization are ways of limiting non-determinism in a concurrent system. Now it is important to understand that uncertainty is desirable; uncertainty can be used by runtime systems to significantly increase performance and is often the basis of giving a user the illusion that tasks are running in parallel. Optimal performance in concurrent applications is often obtained by having as much non-determinism as correctness allows.
+
+\section{\protect\CFA's Thread Building Blocks}
+One of the important features that are missing in C is threading. On modern architectures, a lack of threading is unacceptable~\cite{Sutter05, Sutter05b}, and therefore modern programming languages must have the proper tools to allow users to write efficient concurrent programs to take advantage of parallelism. As an extension of C, \CFA needs to express these concepts in a way that is as natural as possible to programmers familiar with imperative languages. And being a system-level language means programmers expect to choose precisely which features they need and which cost they are willing to pay.
+
+\section{Coroutines: A Stepping Stone}\label{coroutine}
+While the main focus of this proposal is concurrency and parallelism, it is important to address coroutines, which are actually a significant building block of a concurrency system. Coroutines need to deal with context switches and other context-management operations. Therefore, this proposal includes coroutines both as an intermediate step for the implementation of threads, and a first-class feature of \CFA. Furthermore, many design challenges of threads are at least partially present in designing coroutines, which makes the design effort that much more relevant. The core \acrshort{api} of coroutines revolves around two features: independent call-stacks and \code{suspend}/\code{resume}.
 
 \begin{table}
@@ -133,5 +133,5 @@
 \end{table}
 
-A good example of a problem made easier with coroutines is generators, like the Fibonacci sequence. This problem comes with the challenge of decoupling how a sequence is generated and how it is used. Table \ref{lst:fibonacci-c} shows conventional approaches to writing generators in C. All three of these approach suffer from strong coupling. The left and center approaches require that the generator have knowledge of how the sequence is used, while the rightmost approach requires holding internal state between calls on behalf of the generator and makes it much harder to handle corner cases like the Fibonacci seed.
+A good example of a problem made easier with coroutines is generators, like the Fibonacci sequence. This problem comes with the challenge of decoupling how a sequence is generated and how it is used. Table \ref{lst:fibonacci-c} shows conventional approaches to writing generators in C. All three of these approach suffer from strong coupling. The left and centre approaches require that the generator have knowledge of how the sequence is used, while the rightmost approach requires holding internal state between calls on behalf of the generator and makes it much harder to handle corner cases like the Fibonacci seed.
 
 Listing \ref{lst:fibonacci-cfa} is an example of a solution to the Fibonacci problem using \CFA coroutines, where the coroutine stack holds sufficient state for the next generation. This solution has the advantage of having very strong decoupling between how the sequence is generated and how it is used. Indeed, this version is as easy to use as the \code{fibonacci_state} solution, while the implementation is very similar to the \code{fibonacci_func} example.
@@ -233,7 +233,7 @@
 One important design challenge for implementing coroutines and threads (shown in section \ref{threads}) is that the runtime system needs to run code after the user-constructor runs to connect the fully constructed object into the system. In the case of coroutines, this challenge is simpler since there is no non-determinism from preemption or scheduling. However, the underlying challenge remains the same for coroutines and threads.
 
-The runtime system needs to create the coroutine's stack and more importantly prepare it for the first resumption. The timing of the creation is non-trivial since users both expect to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor. There are several solutions to this problem but the chosen options effectively forces the design of the coroutine.
-
-Furthermore, \CFA faces an extra challenge as polymorphic routines create invisible thunks when casted to non-polymorphic routines and these thunks have function scope. For example, the following code, while looking benign, can run into undefined behaviour because of thunks:
+The runtime system needs to create the coroutine?s stack and more importantly prepare it for the first resumption. The timing of the creation is non-trivial since users both expect to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor. There are several solutions to this problem but the chosen option effectively forces the design of the coroutine.
+
+Furthermore, \CFA faces an extra challenge as polymorphic routines create invisible thunks when cast to non-polymorphic routines and these thunks have function scope. For example, the following code, while looking benign, can run into undefined behaviour because of thunks:
 
 \begin{cfacode}
@@ -268,5 +268,5 @@
 }
 \end{ccode}
-The problem in this example is a storage management issue, the function pointer \code{_thunk0} is only valid until the end of the block, which limits the viable solutions because storing the function pointer for too long causes Undefined Behavior; i.e., the stack-based thunk being destroyed before it can be used. This challenge is an extension of challenges that come with second-class routines. Indeed, GCC nested routines also have the limitation that nested routine cannot be passed outside of the declaration scope. The case of coroutines and threads is simply an extension of this problem to multiple call-stacks.
+The problem in this example is a storage management issue, the function pointer \code{_thunk0} is only valid until the end of the block, which limits the viable solutions because storing the function pointer for too long causes Undefined Behaviour; i.e., the stack-based thunk being destroyed before it can be used. This challenge is an extension of challenges that come with second-class routines. Indeed, GCC nested routines also have the limitation that nested routine cannot be passed outside of the declaration scope. The case of coroutines and threads is simply an extension of this problem to multiple call stacks.
 
 \subsection{Alternative: Composition}
@@ -310,5 +310,5 @@
 symmetric_coroutine<>::yield_type
 \end{cfacode}
-Often, the canonical threading paradigm in languages is based on function pointers, pthread being one of the most well known examples. The main problem of this approach is that the thread usage is limited to a generic handle that must otherwise be wrapped in a custom type. Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda based coroutines adds very little.
+Often, the canonical threading paradigm in languages is based on function pointers, pthread being one of the most well-known examples. The main problem of this approach is that the thread usage is limited to a generic handle that must otherwise be wrapped in a custom type. Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda based coroutines adds very little.
 
 A variation of this would be to use a simple function pointer in the same way pthread does for threads :
@@ -327,7 +327,7 @@
 This semantics is more common for thread interfaces but coroutines work equally well. As discussed in section \ref{threads}, this approach is superseded by static approaches in terms of expressivity.
 
-\subsection{Alternative: Trait-based coroutines}
-
-Finally the underlying approach, which is the one closest to \CFA idioms, is to use trait-based lazy coroutines. This approach defines a coroutine as anything that satisfies the trait \code{is_coroutine} and is used as a coroutine.
+\subsection{Alternative: Trait-Based Coroutines}
+
+Finally, the underlying approach, which is the one closest to \CFA idioms, is to use trait-based lazy coroutines. This approach defines a coroutine as anything that satisfies the trait \code{is_coroutine} and is used as a coroutine.
 
 \begin{cfacode}
@@ -369,5 +369,5 @@
 
 \section{Thread Interface}\label{threads}
-The basic building blocks of multi-threading in \CFA are \glspl{cfathread}. Both user and kernel threads are supported, where user threads are the concurrency mechanism and kernel threads are the parallel mechanism. User threads offer a flexible and lightweight interface. A thread can be declared using a struct declaration \code{thread} as follows:
+The basic building blocks of multithreading in \CFA are \glspl{cfathread}. Both user and kernel threads are supported, where user threads are the concurrency mechanism and kernel threads are the parallel mechanism. User threads offer a flexible and lightweight interface. A thread can be declared using a struct declaration \code{thread} as follows:
 
 \begin{cfacode}
@@ -394,5 +394,5 @@
 \end{cfacode}
 
-In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!"}. While this thesis encourages this approach to enforce strongly-typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity. With the static semantics it is trivial to write a thread type that takes a function pointer as a parameter and executes it on its stack asynchronously.
+In this example, threads of type \code{foo} start execution in the \code{void main(foo &)} routine, which prints \code{"Hello World!".} While this thesis encourages this approach to enforce strongly typed programming, users may prefer to use the routine-based thread semantics for the sake of simplicity. With the static semantics it is trivial to write a thread type that takes a function pointer as a parameter and executes it on its stack asynchronously.
 \begin{cfacode}
 typedef void (*voidFunc)(int);
@@ -419,9 +419,9 @@
 int main() {
 	FuncRunner f = {hello, 42};
-	return 0'
-}
-\end{cfacode}
-
-A consequence of the strongly-typed approach to main is that memory layout of parameters and return values to/from a thread are now explicitly specified in the \acrshort{api}.
+	return 0?
+}
+\end{cfacode}
+
+A consequence of the strongly typed approach to main is that memory layout of parameters and return values to/from a thread are now explicitly specified in the \acrshort{api}.
 
 Of course for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution. While using an \acrshort{api} such as \code{fork} and \code{join} is relatively common in the literature, such an interface is unnecessary. Indeed, the simplest approach is to use \acrshort{raii} principles and have threads \code{fork} after the constructor has completed and \code{join} before the destructor runs.
Index: doc/proposals/concurrency/text/cforall.tex
===================================================================
--- doc/proposals/concurrency/text/cforall.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/cforall.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -7,6 +7,6 @@
 The following is a quick introduction to the \CFA language, specifically tailored to the features needed to support concurrency.
 
-\CFA is an extension of ISO-C and therefore supports all of the same paradigms as C. It is a non-object-oriented system-language, meaning most of the major abstractions have either no runtime overhead or can be opt-out easily. Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over machine code. The vast majority of the code produced by the \CFA translator respects memory-layouts and calling-conventions laid out by C. Interestingly, while \CFA is not an object-oriented language, lacking the concept of a receiver (e.g., {\tt this}), it does have some notion of objects\footnote{C defines the term objects as : ``region of data storage in the execution environment, the contents of which can represent
-values''~\cite[3.15]{C11}}, most importantly construction and destruction of objects. Most of the following code examples can be found on the \CFA website~\cite{www-cfa}
+\CFA is an extension of ISO-C and therefore supports all of the same paradigms as C. It is a non-object-oriented system-language, meaning most of the major abstractions have either no runtime overhead or can be opted out easily. Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over machine code. The vast majority of the code produced by the \CFA translator respects memory layouts and calling conventions laid out by C. Interestingly, while \CFA is not an object-oriented language, lacking the concept of a receiver (e.g., {\tt this}), it does have some notion of objects\footnote{C defines the term objects as : ``region of data storage in the execution environment, the contents of which can represent
+values''~\cite[3.15]{C11}}, most importantly construction and destruction of objects. Most of the following code examples can be found on the \CFA website~\cite{www-cfa}.
 
 % ======================================================================
@@ -72,5 +72,5 @@
 % ======================================================================
 \section{Constructors/Destructors}
-Object life-time is often a challenge in concurrency. \CFA uses the approach of giving concurrent meaning to object life-time as a mean of synchronization and/or mutual exclusion. Since \CFA relies heavily on the life time of objects, constructors and destructors are a core feature required for concurrency and parallelism. \CFA uses the following syntax for constructors and destructors :
+Object lifetime is often a challenge in concurrency. \CFA uses the approach of giving concurrent meaning to object lifetime as a means of synchronization and/or mutual exclusion. Since \CFA relies heavily on the lifetime of objects, constructors and destructors is a core feature required for concurrency and parallelism. \CFA uses the following syntax for constructors and destructors :
 \begin{cfacode}
 struct S {
@@ -135,5 +135,5 @@
 \end{cfacode}
 
-Note that the type use for assertions can be either an \code{otype} or a \code{dtype}. Types declares as \code{otype} refer to ``complete'' objects, i.e., objects with a size, a default constructor, a copy constructor, a destructor and an assignment operator. Using \code{dtype} on the other hand has none of these assumptions but is extremely restrictive, it only guarantees the object is addressable.
+Note that the type use for assertions can be either an \code{otype} or a \code{dtype}. Types declared as \code{otype} refer to ``complete'' objects, i.e., objects with a size, a default constructor, a copy constructor, a destructor and an assignment operator. Using \code{dtype,} on the other hand, has none of these assumptions but is extremely restrictive, it only guarantees the object is addressable.
 
 % ======================================================================
Index: doc/proposals/concurrency/text/concurrency.tex
===================================================================
--- doc/proposals/concurrency/text/concurrency.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/concurrency.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -4,11 +4,11 @@
 % ======================================================================
 % ======================================================================
-Several tool can be used to solve concurrency challenges. Since many of these challenges appear with the use of mutable shared-state, some languages and libraries simply disallow mutable shared-state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}). In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (channels~\cite{CSP,Go} for example). However, in languages that use routine calls as their core abstraction-mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (i.e., message passing versus routine call). This distinction in turn means that, in order to be effective, programmers need to learn two sets of designs patterns. While this distinction can be hidden away in library code, effective use of the library still has to take both paradigms into account.
+Several tools can be used to solve concurrency challenges. Since many of these challenges appear with the use of mutable shared-state, some languages and libraries simply disallow mutable shared-state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}). In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (channels~\cite{CSP,Go} for example). However, in languages that use routine calls as their core abstraction mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (i.e., message passing versus routine calls). This distinction in turn means that, in order to be effective, programmers need to learn two sets of design patterns. While this distinction can be hidden away in library code, effective use of the library still has to take both paradigms into account.
 
 Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on basic constructs like routine calls and shared objects. At the lowest level, concurrent paradigms are implemented as atomic operations and locks. Many such mechanisms have been proposed, including semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}. However, for productivity reasons it is desirable to have a higher-level construct be the core concurrency paradigm~\cite{HPP:Study}.
 
-An approach that is worth mentioning because it is gaining in popularity is transactional memory~\cite{Herlihy93}. While this approach is even pursued by system languages like \CC~\cite{Cpp-Transactions}, the performance and feature set is currently too restrictive to be the main concurrency paradigm for systems language, which is why it was rejected as the core paradigm for concurrency in \CFA.
-
-One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared-memory systems, is the \emph{monitor}. Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}. Many programming languages---e.g., Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs. In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors. For these reasons, this project proposes monitors as the core concurrency-construct.
+An approach that is worth mentioning because it is gaining in popularity is transactional memory~\cite{Herlihy93}. While this approach is even pursued by system languages like \CC~\cite{Cpp-Transactions}, the performance and feature set is currently too restrictive to be the main concurrency paradigm for system languages, which is why it was rejected as the core paradigm for concurrency in \CFA.
+
+One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared-memory systems, is the \emph{monitor}. Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}. Many programming languages---e.g., Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs. In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors. For these reasons, this project proposes monitors as the core concurrency construct.
 
 \section{Basics}
@@ -19,5 +19,5 @@
 
 \subsection{Synchronization}
-As for mutual-exclusion, low-level synchronization primitives often offer good performance and good flexibility at the cost of ease of use. Again, higher-level mechanism often simplify usage by adding better coupling between synchronization and data, e.g.: message passing, or offering a simpler solution to otherwise involved challenges. As mentioned above, synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}. Most of the time, synchronization happens within a critical section, where threads must acquire mutual-exclusion in a certain order. However, it may also be desirable to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}. Not satisfying this property is called barging. For example, where event \textit{X} tries to effect event \textit{Y} but another thread acquires the critical section and emits \textit{Z} before \textit{Y}. The classic example is the thread that finishes using a resource and unblocks a thread waiting to use the resource, but the unblocked thread must compete again to acquire the resource. Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs. This challenge is often split into two different methods, barging avoidance and barging prevention. Algorithms that use flag variables to detect barging threads are said to be using barging avoidance, while algorithms that baton-pass locks~\cite{Andrews89} between threads instead of releasing the locks are said to be using barging prevention.
+As for mutual-exclusion, low-level synchronization primitives often offer good performance and good flexibility at the cost of ease of use. Again, higher-level mechanisms often simplify usage by adding better coupling between synchronization and data, e.g.: message passing, or offering a simpler solution to otherwise involved challenges. As mentioned above, synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}. Most of the time, synchronization happens within a critical section, where threads must acquire mutual-exclusion in a certain order. However, it may also be desirable to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}. Not satisfying this property is called barging. For example, where event \textit{X} tries to effect event \textit{Y} but another thread acquires the critical section and emits \textit{Z} before \textit{Y}. The classic example is the thread that finishes using a resource and unblocks a thread waiting to use the resource, but the unblocked thread must compete again to acquire the resource. Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs. This challenge is often split into two different methods, barging avoidance and barging prevention. Algorithms that use flag variables to detect barging threads are said to be using barging avoidance, while algorithms that baton-pass locks~\cite{Andrews89} between threads instead of releasing the locks are said to be using barging prevention.
 
 % ======================================================================
@@ -26,5 +26,5 @@
 % ======================================================================
 % ======================================================================
-A monitor is a set of routines that ensure mutual exclusion when accessing shared state. This concept is generally associated with Object-Oriented Languages like Java~\cite{Java} or \uC~\cite{uC++book} but does not strictly require OO semantics. The only requirements is the ability to declare a handle to a shared object and a set of routines that act on it :
+A monitor is a set of routines that ensure mutual exclusion when accessing shared state. This concept is generally associated with Object-Oriented Languages like Java~\cite{Java} or \uC~\cite{uC++book} but does not strictly require OO semantics. The only requirement is the ability to declare a handle to a shared object and a set of routines that act on it :
 \begin{cfacode}
 typedef /*some monitor type*/ monitor;
@@ -39,5 +39,5 @@
 % ======================================================================
 % ======================================================================
-\subsection{Call semantics} \label{call}
+\subsection{Call Semantics} \label{call}
 % ======================================================================
 % ======================================================================
@@ -103,5 +103,5 @@
 int f5(graph(monitor*) & mutex m);
 \end{cfacode}
-The problem is to identify which object(s) should be acquired. Furthermore, each object needs to be acquired only once. In the case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entry. Adding indirections (\code{f3}) still allows the compiler and programmer to identify which object is acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths are not necessarily known in C, and even then, making sure objects are only acquired once becomes none-trivial. This problem can be extended to absurd limits like \code{f5}, which uses a graph of monitors. To make the issue tractable, this project imposes the requirement that a routine may only acquire one monitor per parameter and it must be the type of the parameter with at most one level of indirection (ignoring potential qualifiers). Also note that while routine \code{f3} can be supported, meaning that monitor \code{**m} is be acquired, passing an array to this routine would be type safe and yet result in undefined behaviour because only the first element of the array is acquired. However, this ambiguity is part of the C type-system with respects to arrays. For this reason, \code{mutex} is disallowed in the context where arrays may be passed:
+The problem is to identify which object(s) should be acquired. Furthermore, each object needs to be acquired only once. In the case of simple routines like \code{f1} and \code{f2} it is easy to identify an exhaustive list of objects to acquire on entry. Adding indirections (\code{f3}) still allows the compiler and programmer to identify which object is acquired. However, adding in arrays (\code{f4}) makes it much harder. Array lengths are not necessarily known in C, and even then, making sure objects are only acquired once becomes none-trivial. This problem can be extended to absurd limits like \code{f5}, which uses a graph of monitors. To make the issue tractable, this project imposes the requirement that a routine may only acquire one monitor per parameter and it must be the type of the parameter with at most one level of indirection (ignoring potential qualifiers). Also note that while routine \code{f3} can be supported, meaning that monitor \code{**m} is acquired, passing an array to this routine would be type-safe and yet result in undefined behaviour because only the first element of the array is acquired. However, this ambiguity is part of the C type-system with respects to arrays. For this reason, \code{mutex} is disallowed in the context where arrays may be passed:
 \begin{cfacode}
 int f1(monitor& mutex m);   //Okay : recommended case
@@ -137,5 +137,5 @@
 The \gls{multi-acq} monitor lock allows a monitor lock to be acquired by both \code{bar} or \code{baz} and acquired again in \code{foo}. In the calls to \code{bar} and \code{baz} the monitors are acquired in opposite order.
 
-However, such use leads to the lock acquiring order problem. In the example above, the user uses implicit ordering in the case of function \code{foo} but explicit ordering in the case of \code{bar} and \code{baz}. This subtle difference means that calling these routines concurrently may lead to deadlock and is therefore Undefined Behavior. As shown~\cite{Lister77}, solving this problem requires:
+However, such use leads to the lock acquiring order problems. In the example above, the user uses implicit ordering in the case of function \code{foo} but explicit ordering in the case of \code{bar} and \code{baz}. This subtle difference means that calling these routines concurrently may lead to deadlock and is therefore Undefined Behaviour. As shown~\cite{Lister77}, solving this problem requires:
 \begin{enumerate}
 	\item Dynamically tracking of the monitor-call order.
@@ -155,9 +155,9 @@
 }
 \end{cfacode}
-This example shows a trivial solution to the bank-account transfer-problem~\cite{BankTransfer}. Without \gls{multi-acq} and \gls{bulk-acq}, the solution to this problem is much more involved and requires careful engineering.
+This example shows a trivial solution to the bank-account transfer problem~\cite{BankTransfer}. Without \gls{multi-acq} and \gls{bulk-acq}, the solution to this problem is much more involved and requires careful engineering.
 
 \subsection{\code{mutex} statement} \label{mutex-stmt}
 
-The call semantics discussed above have one software engineering issue, only a named routine can acquire the mutual-exclusion of a set of monitor. \CFA offers the \code{mutex} statement to workaround the need for unnecessary names, avoiding a major software engineering problem~\cite{2FTwoHardThings}. Table \ref{lst:mutex-stmt} shows an example of the \code{mutex} statement, which introduces a new scope in which the mutual-exclusion of a set of monitor is acquired. Beyond naming, the \code{mutex} statement has no semantic difference from a routine call with \code{mutex} parameters.
+The call semantics discussed above have one software engineering issue, only a named routine can acquire the mutual-exclusion of a set of monitor. \CFA offers the \code{mutex} statement to work around the need for unnecessary names, avoiding a major software engineering problem~\cite{2FTwoHardThings}. Table \ref{lst:mutex-stmt} shows an example of the \code{mutex} statement, which introduces a new scope in which the mutual-exclusion of a set of monitor is acquired. Beyond naming, the \code{mutex} statement has no semantic difference from a routine call with \code{mutex} parameters.
 
 \begin{table}
@@ -196,5 +196,5 @@
 % ======================================================================
 % ======================================================================
-Once the call semantics are established, the next step is to establish data semantics. Indeed, until now a monitor is used simply as a generic handle but in most cases monitors contain shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appropriate protection. For example, here is a complete version of the counter showed in section \ref{call}:
+Once the call semantics are established, the next step is to establish data semantics. Indeed, until now a monitor is used simply as a generic handle but in most cases monitors contain shared data. This data should be intrinsic to the monitor declaration to prevent any accidental use of data without its appropriate protection. For example, here is a complete version of the counter shown in section \ref{call}:
 \begin{cfacode}
 monitor counter_t {
@@ -227,10 +227,10 @@
 % ======================================================================
 % ======================================================================
-\section{Internal scheduling} \label{intsched}
+\section{Internal Scheduling} \label{intsched}
 % ======================================================================
 % ======================================================================
 In addition to mutual exclusion, the monitors at the core of \CFA's concurrency can also be used to achieve synchronization. With monitors, this capability is generally achieved with internal or external scheduling as in~\cite{Hoare74}. Since internal scheduling within a single monitor is mostly a solved problem, this thesis concentrates on extending internal scheduling to multiple monitors. Indeed, like the \gls{bulk-acq} semantics, internal scheduling extends to multiple monitors in a way that is natural to the user but requires additional complexity on the implementation side.
 
-First, here is a simple example of internal-scheduling :
+First, here is a simple example of internal scheduling :
 
 \begin{cfacode}
@@ -253,14 +253,14 @@
 }
 \end{cfacode}
-There are two details to note here. First, the \code{signal} is a delayed operation, it only unblocks the waiting thread when it reaches the end of the critical section. This semantic is needed to respect mutual-exclusion, i.e., the signaller and signalled thread cannot be in the monitor simultaneously. The alternative is to return immediately after the call to \code{signal}, which is significantly more restrictive. Second, in \CFA, while it is common to store a \code{condition} as a field of the monitor, a \code{condition} variable can be stored/created independently of a monitor. Here routine \code{foo} waits for the \code{signal} from \code{bar} before making further progress, effectively ensuring a basic ordering.
-
-An important aspect of the implementation is that \CFA does not allow barging, which means that once function \code{bar} releases the monitor, \code{foo} is guaranteed to resume immediately after (unless some other thread waited on the same condition). This guarantee offers the benefit of not having to loop around waits to recheck that a condition is met. The main reason \CFA offers this guarantee is that users can easily introduce barging if it becomes a necessity but adding barging prevention or barging avoidance is more involved without language support. Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design of \CFA concurrency.
-
-% ======================================================================
-% ======================================================================
-\subsection{Internal Scheduling - multi monitor}
-% ======================================================================
-% ======================================================================
-It is easier to understand the problem of multi-monitor scheduling using a series of pseudo-code examples. Note that for simplicity in the following snippets of pseudo-code, waiting and signalling is done using an implicit condition variable, like Java built-in monitors. Indeed, \code{wait} statements always use the implicit condition variable as parameter and explicitly names the monitors (A and B) associated with the condition. Note that in \CFA, condition variables are tied to a \emph{group} of monitors on first use (called branding), which means that using internal scheduling with distinct sets of monitors requires one condition variable per set of monitors. The example below shows the simple case of having two threads (one for each column) and a single monitor A.
+There are two details to note here. First, the \code{signal} is a delayed operation, it only unblocks the waiting thread when it reaches the end of the critical section. This semantic is needed to respect mutual-exclusion, i.e., the signaller and signalled thread cannot be in the monitor simultaneously. The alternative is to return immediately after the call to \code{signal}, which is significantly more restrictive. Second, in \CFA, while it is common to store a \code{condition} as a field of the monitor, a \code{condition} variable can be stored/created independently of a monitor. Here routine \code{foo} waits for the \code{signal} from \code{bar} before making further progress, ensuring a basic ordering.
+
+An important aspect of the implementation is that \CFA does not allow barging, which means that once function \code{bar} releases the monitor, \code{foo} is guaranteed to resume immediately after (unless some other thread waited on the same condition). This guarantee offers the benefit of not having to loop around waits to recheck that a condition is met. The main reason \CFA offers this guarantee is that users can easily introduce barging if it becomes a necessity but adding barging prevention or barging avoidance is more involved without language support. Supporting barging prevention as well as extending internal scheduling to multiple monitors is the main source of complexity in the design and implementation of \CFA concurrency.
+
+% ======================================================================
+% ======================================================================
+\subsection{Internal Scheduling - Multi-Monitor}
+% ======================================================================
+% ======================================================================
+It is easier to understand the problem of multi-monitor scheduling using a series of pseudo-code examples. Note that for simplicity in the following snippets of pseudo-code, waiting and signalling is done using an implicit condition variable, like Java built-in monitors. Indeed, \code{wait} statements always use the implicit condition variable as parameters and explicitly names the monitors (A and B) associated with the condition. Note that in \CFA, condition variables are tied to a \emph{group} of monitors on first use (called branding), which means that using internal scheduling with distinct sets of monitors requires one condition variable per set of monitors. The example below shows the simple case of having two threads (one for each column) and a single monitor A.
 
 \begin{multicols}{2}
@@ -297,7 +297,7 @@
 \end{pseudo}
 \end{multicols}
-This version uses \gls{bulk-acq} (denoted using the {\sf\&} symbol), but the presence of multiple monitors does not add a particularly new meaning. Synchronization happens between the two threads in exactly the same way and order. The only difference is that mutual exclusion covers more monitors. On the implementation side, handling multiple monitors does add a degree of complexity as the next few examples demonstrate.
-
-While deadlock issues can occur when nesting monitors, these issues are only a symptom of the fact that locks, and by extension monitors, are not perfectly composable. For monitors, a well known deadlock problem is the Nested Monitor Problem~\cite{Lister77}, which occurs when a \code{wait} is made by a thread that holds more than one monitor. For example, the following pseudo-code runs into the nested-monitor problem :
+\noindent This version uses \gls{bulk-acq} (denoted using the {\sf\&} symbol), but the presence of multiple monitors does not add a particularly new meaning. Synchronization happens between the two threads in exactly the same way and order. The only difference is that mutual exclusion covers a group of monitors. On the implementation side, handling multiple monitors does add a degree of complexity as the next few examples demonstrate.
+
+While deadlock issues can occur when nesting monitors, these issues are only a symptom of the fact that locks, and by extension monitors, are not perfectly composable. For monitors, a well-known deadlock problem is the Nested Monitor Problem~\cite{Lister77}, which occurs when a \code{wait} is made by a thread that holds more than one monitor. For example, the following pseudo-code runs into the nested-monitor problem :
 \begin{multicols}{2}
 \begin{pseudo}
@@ -319,5 +319,5 @@
 \end{pseudo}
 \end{multicols}
-The \code{wait} only releases monitor \code{B} so the signalling thread cannot acquire monitor \code{A} to get to the \code{signal}. Attempting release of all acquired monitors at the \code{wait} introduces a different set of problems, such as releasing monitor \code{C}, which has nothing to do with the \code{signal}.
+\noindent The \code{wait} only releases monitor \code{B} so the signalling thread cannot acquire monitor \code{A} to get to the \code{signal}. Attempting release of all acquired monitors at the \code{wait} introduces a different set of problems, such as releasing monitor \code{C}, which has nothing to do with the \code{signal}.
 
 However, for monitors as for locks, it is possible to write a program using nesting without encountering any problems if nesting is done correctly. For example, the next pseudo-code snippet acquires monitors {\sf A} then {\sf B} before waiting, while only acquiring {\sf B} when signalling, effectively avoiding the Nested Monitor Problem~\cite{Lister77}.
@@ -343,13 +343,13 @@
 \end{multicols}
 
-This simple refactoring may not be possible, forcing more complex restructuring.
-
-% ======================================================================
-% ======================================================================
-\subsection{Internal Scheduling - in depth}
-% ======================================================================
-% ======================================================================
-
-A larger example is presented to show complex issues for \gls{bulk-acq} and all the implementation options are analyzed. Listing \ref{lst:int-bulk-pseudo} shows an example where \gls{bulk-acq} adds a significant layer of complexity to the internal signalling semantics, and listing \ref{lst:int-bulk-cfa} shows the corresponding \CFA code to implement the pseudo-code in listing \ref{lst:int-bulk-pseudo}. For the purpose of translating the given pseudo-code into \CFA-code, any method of introducing a monitor is acceptable, e.g., \code{mutex} parameter, global variables, pointer parameters or using locals with the \code{mutex}-statement.
+\noindent However, this simple refactoring may not be possible, forcing more complex restructuring.
+
+% ======================================================================
+% ======================================================================
+\subsection{Internal Scheduling - In Depth}
+% ======================================================================
+% ======================================================================
+
+A larger example is presented to show complex issues for \gls{bulk-acq} and all the implementation options are analyzed. Listing \ref{lst:int-bulk-pseudo} shows an example where \gls{bulk-acq} adds a significant layer of complexity to the internal signalling semantics, and listing \ref{lst:int-bulk-cfa} shows the corresponding \CFA code to implement the pseudo-code in listing \ref{lst:int-bulk-pseudo}. For the purpose of translating the given pseudo-code into \CFA-code, any method of introducing a monitor is acceptable, e.g., \code{mutex} parameters, global variables, pointer parameters, or using locals with the \code{mutex}-statement.
 
 \begin{figure}[!t]
@@ -376,5 +376,5 @@
 		|\label{line:signal1}|signal A & B
 		//Code Section 7
-	release A & B
+	|\label{line:releaseFirst}|release A & B
 	//Code Section 8
 |\label{line:lastRelease}|release A
@@ -446,11 +446,10 @@
 \end{figure}
 
-The complexity begins at code sections 4 and 8, which are where the existing semantics of internal scheduling need to be extended for multiple monitors. The root of the problem is that \gls{bulk-acq} is used in a context where one of the monitors is already acquired and is why it is important to define the behaviour of the previous pseudo-code. When the signaller thread reaches the location where it should ``release \code{A & B}'' (listing \ref{lst:int-bulk-pseudo} line \ref{line:signal1}), it must actually transfer ownership of monitor \code{B} to the waiting thread. This ownership transfer is required in order to prevent barging into \code{B} by another thread, since both the signalling and signalled threads still need monitor \code{A}. There are three options.
-
-\subsubsection{Delaying signals}
-The obvious solution to solve the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred. It can be argued that that moment is when the last lock is no longer needed because this semantics fits most closely to the behaviour of single-monitor scheduling. This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from multiple objects to a single group of objects, effectively making the existing single-monitor semantic viable by simply changing monitors to monitor groups. The naive approach to this solution is to only release monitors once every monitor in a group can be released. However, since some monitors are never released (i.e., the monitor of a thread), this interpretation means groups can grow but may never shrink. A more interesting interpretation is to only transfer groups as one but to recreate the groups on every operation, i.e., limit ownership transfer to one per \code{signal}/\code{release}.
-
-However, this solution can become much more complicated depending on what is executed while secretly holding B (listing \ref{lst:int-secret} line \ref{line:secret}).
-The goal in this solution is to avoid the need to transfer ownership of a subset of the condition monitors. However, listing \ref{lst:dependency} shows a slightly different example where a third thread is waiting on monitor \code{A}, using a different condition variable. Because the third thread is signalled when secretly holding \code{B}, the goal  becomes unreachable. Depending on the order of signals (listing \ref{lst:dependency} line \ref{line:signal-ab} and \ref{line:signal-a}) two cases can happen :
+The complexity begins at code sections 4 and 8 in listing \ref{lst:int-bulk-pseudo}, which are where the existing semantics of internal scheduling needs to be extended for multiple monitors. The root of the problem is that \gls{bulk-acq} is used in a context where one of the monitors is already acquired and is why it is important to define the behaviour of the previous pseudo-code. When the signaller thread reaches the location where it should ``release \code{A & B}'' (listing \ref{lst:int-bulk-pseudo} line \ref{line:releaseFirst}), it must actually transfer ownership of monitor \code{B} to the waiting thread. This ownership transfer is required in order to prevent barging into \code{B} by another thread, since both the signalling and signalled threads still need monitor \code{A}. There are three options.
+
+\subsubsection{Delaying Signals}
+The obvious solution to solve the problem of multi-monitor scheduling is to keep ownership of all locks until the last lock is ready to be transferred. It can be argued that that moment is when the last lock is no longer needed because this semantics fits most closely to the behaviour of single-monitor scheduling. This solution has the main benefit of transferring ownership of groups of monitors, which simplifies the semantics from multiple objects to a single group of objects, effectively making the existing single-monitor semantic viable by simply changing monitors to monitor groups. This solution releases the monitors once every monitor in a group can be released. However, since some monitors are never released (i.e., the monitor of a thread), this interpretation means a group might never be released. A more interesting interpretation is to transfer the group until it can be disbanded, which means the group is not passed further and a thread can retain its locks.
+
+However, listing \ref{lst:int-secret} shows this solution can become much more complicated depending on what is executed while secretly holding B at line \ref{line:secret}, while avoiding the need to transfer ownership of a subset of the condition monitors. Listing \ref{lst:dependency} shows a slightly different example where a third thread is waiting on monitor \code{A}, using a different condition variable. Because the third thread is signalled when secretly holding \code{B}, the goal  becomes unreachable. Depending on the order of signals (listing \ref{lst:dependency} line \ref{line:signal-ab} and \ref{line:signal-a}) two cases can happen :
 
 \paragraph{Case 1: thread $\alpha$ goes first.} In this case, the problem is that monitor \code{A} needs to be passed to thread $\beta$ when thread $\alpha$ is done with it.
@@ -460,5 +459,5 @@
 Note that ordering is not determined by a race condition but by whether signalled threads are enqueued in FIFO or FILO order. However, regardless of the answer, users can move line \ref{line:signal-a} before line \ref{line:signal-ab} and get the reverse effect for listing \ref{lst:dependency}.
 
-In both cases, the threads need to be able to distinguish, on a per monitor basis, which ones need to be released and which ones need to be transferred, which means monitors cannot be handled as a single homogeneous group and therefore effectively precludes this approach.
+In both cases, the threads need to be able to distinguish, on a per monitor basis, which ones need to be released and which ones need to be transferred, which means knowing when to dispand a group becomes complex and inefficient (see next section) and therefore effectively precludes this approach.
 
 \subsubsection{Dependency graphs}
@@ -502,5 +501,5 @@
 \end{figure}
 
-In the listing \ref{lst:int-bulk-pseudo} pseudo-code, there is a solution that satisfies both barging prevention and mutual exclusion. If ownership of both monitors is transferred to the waiter when the signaller releases \code{A & B} and then the waiter transfers back ownership of \code{A} back to the signaller when it releases it, then the problem is solved (\code{B} is no longer in use at this point). Dynamically finding the correct order is therefore the second possible solution. The problem is effectively resolving a dependency graph of ownership requirements. Here even the simplest of code snippets requires two transfers and it seems to increase in a manner close to polynomial. This complexity explosion can be seen in listing \ref{lst:explosion}, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions. Furthermore, the presence of multiple solutions for ownership transfer can cause deadlock problems if a specific solution is not consistently picked; In the same way that multiple lock acquiring order can cause deadlocks.
+In listing \ref{lst:int-bulk-pseudo}, there is a solution that satisfies both barging prevention and mutual exclusion. If ownership of both monitors is transferred to the waiter when the signaller releases \code{A & B} and then the waiter transfers back ownership of \code{A} back to the signaller when it releases it, then the problem is solved (\code{B} is no longer in use at this point). Dynamically finding the correct order is therefore the second possible solution. The problem is effectively resolving a dependency graph of ownership requirements. Here even the simplest of code snippets requires two transfers and it seems to increase in a manner close to polynomial. This complexity explosion can be seen in listing \ref{lst:explosion}, which is just a direct extension to three monitors, requires at least three ownership transfer and has multiple solutions. Furthermore, the presence of multiple solutions for ownership transfer can cause deadlock problems if a specific solution is not consistently picked; In the same way that multiple lock acquiring order can cause deadlocks.
 \begin{figure}
 \begin{multicols}{2}
@@ -531,15 +530,14 @@
 \end{figure}
 
-Listing \ref{lst:dependency} is the three threads example used in the delayed signals solution. Figure \ref{fig:dependency} shows the corresponding dependency graph that results, where every node is a statement of one of the three threads, and the arrows the dependency of that statement (e.g., $\alpha1$ must happen before $\alpha2$). The extra challenge is that this dependency graph is effectively post-mortem, but the runtime system needs to be able to build and solve these graphs as the dependency unfolds. Resolving dependency graphs being a complex and expensive endeavour, this solution is not the preferred one.
-
-\subsubsection{Partial signalling} \label{partial-sig}
-Finally, the solution that is chosen for \CFA is to use partial signalling. Again using listing \ref{lst:int-bulk-pseudo}, the partial signalling solution transfers ownership of monitor \code{B} at lines \ref{line:signal1} to the waiter but does not wake the waiting thread since it is still using monitor \code{A}. Only when it reaches line \ref{line:lastRelease} does it actually wakeup the waiting thread. This solution has the benefit that complexity is encapsulated into only two actions, passing monitors to the next owner when they should be released and conditionally waking threads if all conditions are met. This solution has a much simpler implementation than a dependency graph solving algorithm, which is why it was chosen. Furthermore, after being fully implemented, this solution does not appear to have any significant downsides.
-
-While listing \ref{lst:dependency} is a complicated problem for previous solutions, it can be solved easily with partial signalling :
+Given the three threads example in listing \ref{lst:dependency}, figure \ref{fig:dependency} shows the corresponding dependency graph that results, where every node is a statement of one of the three threads, and the arrows the dependency of that statement (e.g., $\alpha1$ must happen before $\alpha2$). The extra challenge is that this dependency graph is effectively post-mortem, but the runtime system needs to be able to build and solve these graphs as the dependency unfolds. Resolving dependency graphs being a complex and expensive endeavour, this solution is not the preferred one.
+
+\subsubsection{Partial Signalling} \label{partial-sig}
+Finally, the solution that is chosen for \CFA is to use partial signalling. Again using listing \ref{lst:int-bulk-pseudo}, the partial signalling solution transfers ownership of monitor \code{B} at lines \ref{line:signal1} to the waiter but does not wake the waiting thread since it is still using monitor \code{A}. Only when it reaches line \ref{line:lastRelease} does it actually wake up the waiting thread. This solution has the benefit that complexity is encapsulated into only two actions, passing monitors to the next owner when they should be released and conditionally waking threads if all conditions are met. This solution has a much simpler implementation than a dependency graph solving algorithms, which is why it was chosen. Furthermore, after being fully implemented, this solution does not appear to have any significant downsides.
+
+Using partial signalling, listing \ref{lst:dependency} can be solved easily :
 \begin{itemize}
 	\item When thread $\gamma$ reaches line \ref{line:release-ab} it transfers monitor \code{B} to thread $\alpha$ and continues to hold monitor \code{A}.
 	\item When thread $\gamma$ reaches line \ref{line:release-a}  it transfers monitor \code{A} to thread $\beta$  and wakes it up.
 	\item When thread $\beta$  reaches line \ref{line:release-aa} it transfers monitor \code{A} to thread $\alpha$ and wakes it up.
-	\item Problem solved!
 \end{itemize}
 
@@ -654,5 +652,5 @@
 An important note is that, until now, signalling a monitor was a delayed operation. The ownership of the monitor is transferred only when the monitor would have otherwise been released, not at the point of the \code{signal} statement. However, in some cases, it may be more convenient for users to immediately transfer ownership to the thread that is waiting for cooperation, which is achieved using the \code{signal_block} routine.
 
-The example in table \ref{tbl:datingservice} highlights the difference in behaviour. As mentioned, \code{signal} only transfers ownership once the current critical section exits, this behaviour requires additional synchronization when a two-way handshake is needed. To avoid this explicit synchronization, the \code{condition} type offers the \code{signal_block} routine, which handles the two-way handshake as shown in the example. This feature removes the need for a second condition variables and simplifies programming. Like every other monitor semantic, \code{signal_block} uses barging prevention, which means mutual-exclusion is baton-passed both on the frond-end and the back-end of the call to \code{signal_block}, meaning no other thread can acquire the monitor either before or after the call.
+The example in table \ref{tbl:datingservice} highlights the difference in behaviour. As mentioned, \code{signal} only transfers ownership once the current critical section exits, this behaviour requires additional synchronization when a two-way handshake is needed. To avoid this explicit synchronization, the \code{condition} type offers the \code{signal_block} routine, which handles the two-way handshake as shown in the example. This feature removes the need for a second condition variables and simplifies programming. Like every other monitor semantic, \code{signal_block} uses barging prevention, which means mutual-exclusion is baton-passed both on the frond end and the back end of the call to \code{signal_block}, meaning no other thread can acquire the monitor either before or after the call.
 
 % ======================================================================
@@ -723,14 +721,14 @@
 \end{tabular}
 \end{center}
-This method is more constrained and explicit, which helps users reduce the non-deterministic nature of concurrency. Indeed, as the following examples demonstrates, external scheduling allows users to wait for events from other threads without the concern of unrelated events occurring. External scheduling can generally be done either in terms of control flow (e.g., Ada with \code{accept}, \uC with \code{_Accept}) or in terms of data (e.g., Go with channels). Of course, both of these paradigms have their own strengths and weaknesses, but for this project control-flow semantics were chosen to stay consistent with the rest of the languages semantics. Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multiple-monitor routines. The previous example shows a simple use \code{_Accept} versus \code{wait}/\code{signal} and its advantages. Note that while other languages often use \code{accept}/\code{select} as the core external scheduling keyword, \CFA uses \code{waitfor} to prevent name collisions with existing socket \acrshort{api}s.
-
-For the \code{P} member above using internal scheduling, the call to \code{wait} only guarantees that \code{V} is the last routine to access the monitor, allowing a third routine, say \code{isInUse()}, acquire mutual exclusion several times while routine \code{P} is waiting. On the other hand, external scheduling guarantees that while routine \code{P} is waiting, no routine other than \code{V} can acquire the monitor.
-
-% ======================================================================
-% ======================================================================
-\subsection{Loose object definitions}
-% ======================================================================
-% ======================================================================
-In \uC, a monitor class declaration includee an exhaustive list of monitor operations. Since \CFA is not object oriented, monitors become both more difficult to implement and less clear for a user:
+This method is more constrained and explicit, which helps users reduce the non-deterministic nature of concurrency. Indeed, as the following examples demonstrates, external scheduling allows users to wait for events from other threads without the concern of unrelated events occurring. External scheduling can generally be done either in terms of control flow (e.g., Ada with \code{accept}, \uC with \code{_Accept}) or in terms of data (e.g., Go with channels). Of course, both of these paradigms have their own strengths and weaknesses, but for this project control-flow semantics was chosen to stay consistent with the rest of the languages semantics. Two challenges specific to \CFA arise when trying to add external scheduling with loose object definitions and multiple-monitor routines. The previous example shows a simple use \code{_Accept} versus \code{wait}/\code{signal} and its advantages. Note that while other languages often use \code{accept}/\code{select} as the core external scheduling keyword, \CFA uses \code{waitfor} to prevent name collisions with existing socket \acrshort{api}s.
+
+For the \code{P} member above using internal scheduling, the call to \code{wait} only guarantees that \code{V} is the last routine to access the monitor, allowing a third routine, say \code{isInUse()}, acquire mutual exclusion several times while routine \code{P} is waiting. On the other hand, external scheduling guarantees that while routine \code{P} is waiting, no other routine than \code{V} can acquire the monitor.
+
+% ======================================================================
+% ======================================================================
+\subsection{Loose Object Definitions}
+% ======================================================================
+% ======================================================================
+In \uC, a monitor class declaration includes an exhaustive list of monitor operations. Since \CFA is not object oriented, monitors become both more difficult to implement and less clear for a user:
 
 \begin{cfacode}
@@ -748,5 +746,5 @@
 \end{cfacode}
 
-Furthermore, external scheduling is an example where implementation constraints become visible from the interface. Here is the pseudo code for the entering phase of a monitor:
+Furthermore, external scheduling is an example where implementation constraints become visible from the interface. Here is the pseudo-code for the entering phase of a monitor:
 \begin{center}
 \begin{tabular}{l}
@@ -763,5 +761,5 @@
 \end{tabular}
 \end{center}
-For the first two conditions, it is easy to implement a check that can evaluate the condition in a few instruction. However, a fast check for \pscode{monitor accepts me} is much harder to implement depending on the constraints put on the monitors. Indeed, monitors are often expressed as an entry queue and some acceptor queue as in the following figure:
+For the first two conditions, it is easy to implement a check that can evaluate the condition in a few instructions. However, a fast check for \pscode{monitor accepts me} is much harder to implement depending on the constraints put on the monitors. Indeed, monitors are often expressed as an entry queue and some acceptor queue as in the following figure:
 
 \begin{figure}[H]
@@ -772,13 +770,11 @@
 \end{figure}
 
-There are other alternatives to these pictures, but in the case of this picture, implementing a fast accept check is relatively easy. Restricted to a fixed number of mutex members, N, the accept check reduces to updating a bitmask when the acceptor queue changes, a check that executes in a single instruction even with a fairly large number (e.g., 128) of mutex members. This approach requires a dense unique ordering of routines with an upper-bound and that ordering must be consistent across translation units. For OO languages these constraints are common, since objects only offer adding member routines consistently across translation units via inheritence. However, in \CFA users can extend objects with mutex routines that are only visible in certain translation unit. This means that establishing a program-wide dense-ordering among mutex routines can only be done in the program linking phase, and still could have issues when using dynamically shared objects.
+There are other alternatives to these pictures, but in the case of this picture, implementing a fast accept check is relatively easy. Restricted to a fixed number of mutex members, N, the accept check reduces to updating a bitmask when the acceptor queue changes, a check that executes in a single instruction even with a fairly large number (e.g., 128) of mutex members. This approach requires a unique dense ordering of routines with an upper-bound and that ordering must be consistent across translation units. For OO languages these constraints are common, since objects only offer adding member routines consistently across translation units via inheritance. However, in \CFA users can extend objects with mutex routines that are only visible in certain translation unit. This means that establishing a program-wide dense-ordering among mutex routines can only be done in the program linking phase, and still could have issues when using dynamically shared objects.
 
 The alternative is to alter the implementation like this:
-
 \begin{center}
 {\resizebox{0.4\textwidth}{!}{\input{ext_monitor}}}
 \end{center}
-
-Here, the mutex routine called is associated with a thread on the entry queue while a list of acceptable routines is kept seperately. Generating a mask dynamically means that the storage for the mask information can vary between calls to \code{waitfor}, allowing for more flexibility and extensions. Storing an array of accepted function-pointers replaces the single instruction bitmask compare with dereferencing a pointer followed by a linear search. Furthermore, supporting nested external scheduling (e.g., listing \ref{lst:nest-ext}) may now require additional searches for the \code{waitfor} statement to check if a routine is already queued.
+Here, the mutex routine called is associated with a thread on the entry queue while a list of acceptable routines is kept separate. Generating a mask dynamically means that the storage for the mask information can vary between calls to \code{waitfor}, allowing for more flexibility and extensions. Storing an array of accepted function pointers replaces the single instruction bitmask comparison with dereferencing a pointer followed by a linear search. Furthermore, supporting nested external scheduling (e.g., listing \ref{lst:nest-ext}) may now require additional searches for the \code{waitfor} statement to check if a routine is already queued.
 
 \begin{figure}
@@ -797,15 +793,15 @@
 \end{figure}
 
-Note that in the second picture, tasks need to always keep track of the monitors associated with mutex routines, and the routine mask needs to have both a function pointer and a set of monitors, as is be discussed in the next section. These details are omitted from the picture for the sake of simplicity.
-
-At this point, a decision must be made between flexibility and performance. Many design decisions in \CFA achieve both flexibility and performance, for example polymorphic routines add significant flexibility but inlining them means the optimizer can easily remove any runtime cost. Here however, the cost of flexibility cannot be trivially removed. In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be  hard to write. This decision is based on the assumption that writing fast but inflexible locks is closer to a solved problems than writing locks that are as flexible as external scheduling in \CFA.
-
-% ======================================================================
-% ======================================================================
-\subsection{Multi-monitor scheduling}
-% ======================================================================
-% ======================================================================
-
-External scheduling, like internal scheduling, becomes significantly more complex when introducing multi-monitor syntax. Even in the simplest possible case, some new semantics need to be established:
+Note that in the second picture, tasks need to always keep track of the monitors associated with mutex routines, and the routine mask needs to have both a function pointer and a set of monitors, as is discussed in the next section. These details are omitted from the picture for the sake of simplicity.
+
+At this point, a decision must be made between flexibility and performance. Many design decisions in \CFA achieve both flexibility and performance, for example polymorphic routines add significant flexibility but inlining them means the optimizer can easily remove any runtime cost. Here, however, the cost of flexibility cannot be trivially removed. In the end, the most flexible approach has been chosen since it allows users to write programs that would otherwise be  hard to write. This decision is based on the assumption that writing fast but inflexible locks is closer to a solved problem than writing locks that are as flexible as external scheduling in \CFA.
+
+% ======================================================================
+% ======================================================================
+\subsection{Multi-Monitor Scheduling}
+% ======================================================================
+% ======================================================================
+
+External scheduling, like internal scheduling, becomes significantly more complex when introducing multi-monitor syntax. Even in the simplest possible case, some new semantics needs to be established:
 \begin{cfacode}
 monitor M {};
@@ -837,5 +833,5 @@
 
 void g(M & mutex a, M & mutex b) {
-	//wait for call to f with argument a and b
+	//wait for call to f with arguments a and b
 	waitfor(f, a, b);
 }
@@ -870,9 +866,9 @@
 % ======================================================================
 % ======================================================================
-\subsection{\code{waitfor} semantics}
-% ======================================================================
-% ======================================================================
-
-Syntactically, the \code{waitfor} statement takes a function identifier and a set of monitors. While the set of monitors can be any list of expression, the function name is more restricted because the compiler validates at compile time the validity of the function type and the parameters used with the \code{waitfor} statement. It checks that the set of monitors passed in matches the requirements for a function call. Listing \ref{lst:waitfor} shows various usage of the waitfor statement and which are acceptable. The choice of the function type is made ignoring any non-\code{mutex} parameter. One limitation of the current implementation is that it does not handle overloading but overloading is possible.
+\subsection{\code{waitfor} Semantics}
+% ======================================================================
+% ======================================================================
+
+Syntactically, the \code{waitfor} statement takes a function identifier and a set of monitors. While the set of monitors can be any list of expressions, the function name is more restricted because the compiler validates at compile time the validity of the function type and the parameters used with the \code{waitfor} statement. It checks that the set of monitors passed in matches the requirements for a function call. Listing \ref{lst:waitfor} shows various usages of the waitfor statement and which are acceptable. The choice of the function type is made ignoring any non-\code{mutex} parameter. One limitation of the current implementation is that it does not handle overloading but overloading is possible.
 \begin{figure}
 \begin{cfacode}[caption={Various correct and incorrect uses of the waitfor statement},label={lst:waitfor}]
@@ -908,5 +904,5 @@
 \end{figure}
 
-Finally, for added flexibility, \CFA supports constructing a complex \code{waitfor} statement using the \code{or}, \code{timeout} and \code{else}. Indeed, multiple \code{waitfor} clauses can be chained together using \code{or}; this chain forms a single statement that uses baton-pass to any one function that fits one of the function+monitor set passed in. To enable users to tell which accepted function executed, \code{waitfor}s are followed by a statement (including the null statement \code{;}) or a compound statement, which is executed after the clause is triggered. A \code{waitfor} chain can also be followed by a \code{timeout}, to signify an upper bound on the wait, or an \code{else}, to signify that the call should be non-blocking, which checks for a matching function call already arrived and otherwise continues. Any and all of these clauses can be preceded by a \code{when} condition to dynamically toggle the accept clauses on or off based on some current state. Listing \ref{lst:waitfor2}, demonstrates several complex masks and some incorrect ones.
+Finally, for added flexibility, \CFA supports constructing a complex \code{waitfor} statement using the \code{or}, \code{timeout} and \code{else}. Indeed, multiple \code{waitfor} clauses can be chained together using \code{or}; this chain forms a single statement that uses baton pass to any function that fits one of the function+monitor set passed in. To enable users to tell which accepted function executed, \code{waitfor}s are followed by a statement (including the null statement \code{;}) or a compound statement, which is executed after the clause is triggered. A \code{waitfor} chain can also be followed by a \code{timeout}, to signify an upper bound on the wait, or an \code{else}, to signify that the call should be non-blocking, which checks for a matching function call already arrived and otherwise continues. Any and all of these clauses can be preceded by a \code{when} condition to dynamically toggle the accept clauses on or off based on some current state. Listing \ref{lst:waitfor2}, demonstrates several complex masks and some incorrect ones.
 
 \begin{figure}
@@ -973,8 +969,8 @@
 % ======================================================================
 % ======================================================================
-\subsection{Waiting for the destructor}
-% ======================================================================
-% ======================================================================
-An interesting use for the \code{waitfor} statement is destructor semantics. Indeed, the \code{waitfor} statement can accept any \code{mutex} routine, which includes the destructor (see section \ref{data}). However, with the semantics discussed until now, waiting for the destructor does not make any sense since using an object after its destructor is called is undefined behaviour. The simplest approach is to disallow \code{waitfor} on a destructor. However, a more expressive approach is to flip execution ordering when waiting for the destructor, meaning that waiting for the destructor allows the destructor to run after the current \code{mutex} routine, similarly to how a condition is signalled.
+\subsection{Waiting For The Destructor}
+% ======================================================================
+% ======================================================================
+An interesting use for the \code{waitfor} statement is destructor semantics. Indeed, the \code{waitfor} statement can accept any \code{mutex} routine, which includes the destructor (see section \ref{data}). However, with the semantics discussed until now, waiting for the destructor does not make any sense since using an object after its destructor is called is undefined behaviour. The simplest approach is to disallow \code{waitfor} on a destructor. However, a more expressive approach is to flip ordering of execution when waiting for the destructor, meaning that waiting for the destructor allows the destructor to run after the current \code{mutex} routine, similarly to how a condition is signalled.
 \begin{figure}
 \begin{cfacode}[caption={Example of an executor which executes action in series until the destructor is called.},label={lst:dtor-order}]
Index: doc/proposals/concurrency/text/frontpgs.tex
===================================================================
--- doc/proposals/concurrency/text/frontpgs.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/frontpgs.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -80,5 +80,5 @@
 \begin{center}\textbf{Abstract}\end{center}
 
-\CFA is a modern, non-object-oriented extension of the C programming language. This thesis serves as a definition and an implementation for the concurrency and parallelism \CFA offers. These features are created from scratch due to the lack of concurrency in ISO C. Monitors are introduced as a high-level tool for control-flow based concurrency. In addition, lightweight threads are also introduced into the language. Specifically, the contribution of this thesis is two-fold: it extends the existing semantics of monitors introduce by~\cite{Hoare74} to handle monitors in groups and also details the engineering effort needed to introduce these features as core language features. Indeed, these features are added in respect with expectations of C programmers and are backwards compatible as much as possible.
+\CFA is a modern, non-object-oriented extension of the C programming language. This thesis serves as a definition and an implementation for the concurrency and parallelism \CFA offers. These features are created from scratch due to the lack of concurrency in ISO C. Lightweight threads are introduced into the language. In addition, monitors are introduced as a high-level tool for control-flow based synchronization and mutual-exclusion. The main contributions of this thesis are two-fold: it extends the existing semantics of monitors introduce by~\cite{Hoare74} to handle monitors in groups and also details the engineering effort needed to introduce these features as core language features. Indeed, these features are added with respect to expectations of C programmers, and integrate with the \CFA type-system and other language features.
 
 
@@ -95,7 +95,7 @@
 I would like to thank Professors Martin Karsten and Gregor Richards, for reading my thesis and providing helpful feedback.
 
-Thanks to Aaron Moss, Rob Schluntz and Andrew Beach for their work on the \CFA project as well as all the discussions which have help me concretize the ideas in this thesis.
+Thanks to Aaron Moss, Rob Schluntz and Andrew Beach for their work on the \CFA project as well as all the discussions which have helped me concretize the ideas in this thesis.
 
-Finally, I acknowledge that this as been possible thanks to the financial help offered by the David R. Cheriton School of Computer Science and the corperate partnership with Huawei Ltd.
+Finally, I acknowledge that this has been possible thanks to the financial help offered by the David R. Cheriton School of Computer Science and the corporate partnership with Huawei Ltd.
 
 \cleardoublepage
Index: doc/proposals/concurrency/text/future.tex
===================================================================
--- doc/proposals/concurrency/text/future.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/future.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -1,5 +1,5 @@
 
 \chapter{Conclusion}
-As mentionned in the introduction, this thesis provides a minimal concurrency \acrshort{api} that is simple, efficient and usable as the basis for higher-level features. The approach presented is based on a lighweight thread system for parallelism which sits on top of clusters of processors. This M:N model is jugded to be both more efficient and allow more flexibility for users. Furthermore, this document introduces monitors as the main concurrency tool for users. This thesis also offers a novel approach which allows using multiple monitors at once without running into the Nested Monitor Problem~\cite{Lister77}. It also offers a full implmentation of the concurrency runtime wirtten enterily in \CFA, effectively the largest \CFA code base to date.
+This thesis has achieved a minimal concurrency \acrshort{api} that is simple, efficient and usable as the basis for higher-level features. The approach presented is based on a lightweight thread-system for parallelism, which sits on top of clusters of processors. This M:N model is judged to be both more efficient and allow more flexibility for users. Furthermore, this document introduces monitors as the main concurrency tool for users. This thesis also offers a novel approach allowing multiple monitors to be accessed simultaneously without running into the Nested Monitor Problem~\cite{Lister77}. It also offers a full implementation of the concurrency runtime written entirely in \CFA, effectively the largest \CFA code base to date.
 
 
@@ -11,17 +11,17 @@
 
 \subsection{Performance} \label{futur:perf}
-This thesis presents a first implementation of the \CFA runtime. Therefore, there is still significant work to do to improve performance. Many of the data structures and algorithms will change in the future to more efficient versions. For example, \CFA the number of monitors in a single \gls{bulk-acq} is only bound by the stack size, this is probably unnecessarily generous. It may be possible that limiting the number help increase performance. However, it is not obvious that the benefit would be significant.
+This thesis presents a first implementation of the \CFA runtime. Therefore, there is still significant work to improve performance. Many of the data structures and algorithms may change in the future to more efficient versions. For example, the number of monitors in a single \gls{bulk-acq} is only bound by the stack size, this is probably unnecessarily generous. It may be possible that limiting the number helps increase performance. However, it is not obvious that the benefit would be significant.
 
 \subsection{Flexible Scheduling} \label{futur:sched}
-An important part of concurrency is scheduling. Different scheduling algorithm can affect performance (both in terms of average and variation). However, no single scheduler is optimal for all workloads and therefore there is value in being able to change the scheduler for given programs. One solution is to offer various tweaking options to users, allowing the scheduler to be adjusted to the requirements of the workload. However, in order to be truly flexible, it would be interesting to allow users to add arbitrary data and arbitrary scheduling algorithms to the scheduler. For example, a web server could attach Type-of-Service information to threads and have a ``ToS aware'' scheduling algorithm tailored to this specific web server. This path of flexible schedulers will be explored for \CFA.
+An important part of concurrency is scheduling. Different scheduling algorithms can affect performance (both in terms of average and variation). However, no single scheduler is optimal for all workloads and therefore there is value in being able to change the scheduler for given programs. One solution is to offer various tweaking options to users, allowing the scheduler to be adjusted to the requirements of the workload. However, in order to be truly flexible, it would be interesting to allow users to add arbitrary data and arbitrary scheduling algorithms. For example, a web server could attach Type-of-Service information to threads and have a ``ToS aware'' scheduling algorithm tailored to this specific web server. This path of flexible schedulers will be explored for \CFA.
 
 \subsection{Non-Blocking IO} \label{futur:nbio}
-While most of the parallelism tools are aimed at data parallelism and control-flow parallelism, many modern workloads are not bound on computation but on IO operations, a common case being web-servers and XaaS (anything as a service). These type of workloads often require significant engineering around amortizing costs of blocking IO operations. At its core, Non-Blocking IO is a operating system level feature that allows queuing IO operations (e.g., network operations) and registering for notifications instead of waiting for requests to complete. In this context, the role of the language make Non-Blocking IO easily available and with low overhead. The current trend is to use asynchronous programming using tools like callbacks and/or futures and promises, which can be seen in frameworks like Node.js~\cite{NodeJs} for JavaScript, Spring MVC~\cite{SpringMVC} for Java and Django~\cite{Django} for Python. However, while these are valid solutions, they lead to code that is harder to read and maintain because it is much less linear.
+While most of the parallelism tools are aimed at data parallelism and control-flow parallelism, many modern workloads are not bound on computation but on IO operations, a common case being web servers and XaaS (anything as a service). These types of workloads often require significant engineering around amortizing costs of blocking IO operations. At its core, Non-Blocking IO is an operating system level feature that allows queuing IO operations (e.g., network operations) and registering for notifications instead of waiting for requests to complete. In this context, the role of the language makes Non-Blocking IO easily available and with low overhead. The current trend is to use asynchronous programming using tools like callbacks and/or futures and promises, which can be seen in frameworks like Node.js~\cite{NodeJs} for JavaScript, Spring MVC~\cite{SpringMVC} for Java and Django~\cite{Django} for Python. However, while these are valid solutions, they lead to code that is harder to read and maintain because it is much less linear.
 
-\subsection{Other concurrency tools} \label{futur:tools}
-While monitors offer a flexible and powerful concurrent core for \CFA, other concurrency tools are also necessary for a complete multi-paradigm concurrency package. Example of such tools can include simple locks and condition variables, futures and promises~\cite{promises}, executors and actors. These additional features are useful when monitors offer a level of abstraction that is inadequate for certain tasks.
+\subsection{Other Concurrency Tools} \label{futur:tools}
+While monitors offer a flexible and powerful concurrent core for \CFA, other concurrency tools are also necessary for a complete multi-paradigm concurrency package. Examples of such tools can include simple locks and condition variables, futures and promises~\cite{promises}, executors and actors. These additional features are useful when monitors offer a level of abstraction that is inadequate for certain tasks.
 
-\subsection{Implicit threading} \label{futur:implcit}
-Simpler applications can benefit greatly from having implicit parallelism. That is, parallelism that does not rely on the user to write concurrency. This type of parallelism can be achieved both at the language level and at the library level. The canonical example of implicit parallelism is parallel for loops, which are the simplest example of a divide and conquer algorithm~\cite{uC++book}. Table \ref{lst:parfor} shows three different code examples that accomplish point-wise sums of large arrays. Note that none of these examples explicitly declare any concurrency or parallelism objects.
+\subsection{Implicit Threading} \label{futur:implcit}
+Simpler applications can benefit greatly from having implicit parallelism. That is, parallelism that does not rely on the user to write concurrency. This type of parallelism can be achieved both at the language level and at the library level. The canonical example of implicit parallelism is parallel for loops, which are the simplest example of a divide and conquer algorithms~\cite{uC++book}. Table \ref{lst:parfor} shows three different code examples that accomplish point-wise sums of large arrays. Note that none of these examples explicitly declare any concurrency or parallelism objects.
 
 \begin{table}
@@ -108,5 +108,5 @@
 \end{table}
 
-Implicit parallelism is a restrictive solution and therefore has its limitations. However, it is a quick and simple approach to parallelism, which may very well be sufficient for smaller applications and reduces the amount of boiler-plate needed to start benefiting from parallelism in modern CPUs.
+Implicit parallelism is a restrictive solution and therefore has its limitations. However, it is a quick and simple approach to parallelism, which may very well be sufficient for smaller applications and reduces the amount of boilerplate needed to start benefiting from parallelism in modern CPUs.
 
 
Index: doc/proposals/concurrency/text/internals.tex
===================================================================
--- doc/proposals/concurrency/text/internals.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/internals.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -1,7 +1,7 @@
 
-\chapter{Behind the scene}
-There are several challenges specific to \CFA when implementing concurrency. These challenges are a direct result of \gls{bulk-acq} and loose object-definitions. These two constraints are the root cause of most design decisions in the implementation. Furthermore, to avoid contention from dynamically allocating memory in a concurrent environment, the internal-scheduling design is (almost) entirely free of mallocs. This approach avoids the chicken and egg problem~\cite{Chicken} of having a memory allocator that relies on the threading system and a threading system that relies on the runtime. This extra goal means that memory management is a constant concern in the design of the system.
-
-The main memory concern for concurrency is queues. All blocking operations are made by parking threads onto queues and all queues are designed with intrusive nodes, where each not has pre-allocated link fields for chaining, to avoid the need for memory allocation. Since several concurrency operations can use an unbound amount of memory (depending on \gls{bulk-acq}), statically defining information in the intrusive fields of threads is insufficient.The only way to use a variable amount of memory without requiring memory allocation is to pre-allocate large buffers of memory eagerly and store the information in these buffers. Conveniently, the callstack fits that description and is easy to use, which is why it is used heavily in the implementation of internal scheduling, particularly variable-length arrays. Since stack allocation is based around scope, the first step of the implementation is to identify the scopes that are available to store the information, and which of these can have a variable-length array. The threads and the condition both have a fixed amount of memory, while mutex-routines and the actual blocking call allow for an unbound amount, within the stack size.
+\chapter{Behind the Scenes}
+There are several challenges specific to \CFA when implementing concurrency. These challenges are a direct result of \gls{bulk-acq} and loose object definitions. These two constraints are the root cause of most design decisions in the implementation. Furthermore, to avoid contention from dynamically allocating memory in a concurrent environment, the internal-scheduling design is (almost) entirely free of mallocs. This approach avoids the chicken and egg problem~\cite{Chicken} of having a memory allocator that relies on the threading system and a threading system that relies on the runtime. This extra goal means that memory management is a constant concern in the design of the system.
+
+The main memory concern for concurrency is queues. All blocking operations are made by parking threads onto queues and all queues are designed with intrusive nodes, where each node has pre-allocated link fields for chaining, to avoid the need for memory allocation. Since several concurrency operations can use an unbound amount of memory (depending on \gls{bulk-acq}), statically defining information in the intrusive fields of threads is insufficient.The only way to use a variable amount of memory without requiring memory allocation is to pre-allocate large buffers of memory eagerly and store the information in these buffers. Conveniently, the call stack fits that description and is easy to use, which is why it is used heavily in the implementation of internal scheduling, particularly variable-length arrays. Since stack allocation is based on scopes, the first step of the implementation is to identify the scopes that are available to store the information, and which of these can have a variable-length array. The threads and the condition both have a fixed amount of memory, while mute routines and blocking calls allow for an unbound amount, within the stack size.
 
 Note that since the major contributions of this thesis are extending monitor semantics to \gls{bulk-acq} and loose object definitions, any challenges that are not resulting of these characteristics of \CFA are considered as solved problems and therefore not discussed.
@@ -9,9 +9,9 @@
 % ======================================================================
 % ======================================================================
-\section{Mutex routines}
-% ======================================================================
-% ======================================================================
-
-The first step towards the monitor implementation is simple mutex-routines. In the single monitor case, mutual-exclusion is done using the entry/exit procedure in listing \ref{lst:entry1}. The entry/exit procedures do not have to be extended to support multiple monitors. Indeed it is sufficient to enter/leave monitors one-by-one as long as the order is correct to prevent deadlock~\cite{Havender68}. In \CFA, ordering of monitor acquisition relies on memory ordering. This approach is sufficient because all objects are guaranteed to have distinct non-overlapping memory layouts and mutual-exclusion for a monitor is only defined for its lifetime, meaning that destroying a monitor while it is acquired is Undefined Behavior. When a mutex call is made, the concerned monitors are aggregated into a variable-length pointer-array and sorted based on pointer values. This array persists for the entire duration of the mutual-exclusion and its ordering reused extensively.
+\section{Mutex Routines}
+% ======================================================================
+% ======================================================================
+
+The first step towards the monitor implementation is simple mute routines. In the single monitor case, mutual-exclusion is done using the entry/exit procedure in listing \ref{lst:entry1}. The entry/exit procedures do not have to be extended to support multiple monitors. Indeed it is sufficient to enter/leave monitors one-by-one as long as the order is correct to prevent deadlock~\cite{Havender68}. In \CFA, ordering of monitor acquisition relies on memory ordering. This approach is sufficient because all objects are guaranteed to have distinct non-overlapping memory layouts and mutual-exclusion for a monitor is only defined for its lifetime, meaning that destroying a monitor while it is acquired is Undefined Behaviour. When a mutex call is made, the concerned monitors are aggregated into a variable-length pointer array and sorted based on pointer values. This array persists for the entire duration of the mutual-exclusion and its ordering reused extensively.
 \begin{figure}
 \begin{multicols}{2}
@@ -109,5 +109,5 @@
 \end{cfacode}
 
-Both entry-point and \gls{callsite-locking} are feasible implementations. The current \CFA implementations uses entry-point locking because it requires less work when using \gls{raii}, effectively transferring the burden of implementation to object construction/destruction. It is harder to use \gls{raii} for call-site locking, as it does not necessarily have an existing scope that matches exactly the scope of the mutual exclusion, i.e.: the function body. For example, the monitor call can appear in the middle of an expression. Furthermore, entry-point locking requires less code generation since any useful routine multiple times, but there is only one entry-point for many call-sites.
+Both entry point and \gls{callsite-locking} are feasible implementations. The current \CFA implementation uses entry-point locking because it requires less work when using \gls{raii}, effectively transferring the burden of implementation to object construction/destruction. It is harder to use \gls{raii} for call-site locking, as it does not necessarily have an existing scope that matches exactly the scope of the mutual exclusion, i.e.: the function body. For example, the monitor call can appear in the middle of an expression. Furthermore, entry-point locking requires less code generation since any useful routine multiple times, but there is only one entry point for many call sites.
 
 % ======================================================================
@@ -117,5 +117,5 @@
 % ======================================================================
 
-Figure \ref{fig:system1} shows a high-level picture if the \CFA runtime system in regards to concurrency. Each component of the picture is explained in details in the flowing sections.
+Figure \ref{fig:system1} shows a high-level picture if the \CFA runtime system in regards to concurrency. Each component of the picture is explained in detail in the flowing sections.
 
 \begin{figure}
@@ -128,14 +128,14 @@
 
 \subsection{Context Switching}
-As mentioned in section \ref{coroutine}, coroutines are a stepping stone for implementing threading, because they share the same mechanism for context-switching between different stacks. To improve performance and simplicity, context-switching is implemented using the following assumption: all context-switches happen inside a specific function call. This assumption means that the context-switch only has to copy the callee-saved registers onto the stack and then switch the stack registers with the ones of the target coroutine/thread. Note that the instruction pointer can be left untouched since the context-switch is always inside the same function. Threads however do not context-switch between each other directly. They context-switch to the scheduler. This method is called a 2-step context-switch and has the advantage of having a clear distinction between user code and the kernel where scheduling and other system operation happen. Obviously, this doubles the context-switch cost because threads must context-switch to an intermediate stack. The alternative 1-step context-switch uses the stack of the ``from'' thread to schedule and then context-switches directly to the ``to'' thread. However, the performance of the 2-step context-switch is still superior to a \code{pthread_yield} (see section \ref{results}). Additionally, for users in need for optimal performance, it is important to note that having a 2-step context-switch as the default does not prevent \CFA from offering a 1-step context-switch (akin to the Microsoft \code{SwitchToFiber}~\cite{switchToWindows} routine). This option is not currently present in \CFA but the changes required to add it are strictly additive.
+As mentioned in section \ref{coroutine}, coroutines are a stepping stone for implementing threading, because they share the same mechanism for context-switching between different stacks. To improve performance and simplicity, context-switching is implemented using the following assumption: all context-switches happen inside a specific function call. This assumption means that the context-switch only has to copy the callee-saved registers onto the stack and then switch the stack registers with the ones of the target coroutine/thread. Note that the instruction pointer can be left untouched since the context-switch is always inside the same function. Threads, however, do not context-switch between each other directly. They context-switch to the scheduler. This method is called a 2-step context-switch and has the advantage of having a clear distinction between user code and the kernel where scheduling and other system operations happen. Obviously, this doubles the context-switch cost because threads must context-switch to an intermediate stack. The alternative 1-step context-switch uses the stack of the ``from'' thread to schedule and then context-switches directly to the ``to'' thread. However, the performance of the 2-step context-switch is still superior to a \code{pthread_yield} (see section \ref{results}). Additionally, for users in need for optimal performance, it is important to note that having a 2-step context-switch as the default does not prevent \CFA from offering a 1-step context-switch (akin to the Microsoft \code{SwitchToFiber}~\cite{switchToWindows} routine). This option is not currently present in \CFA but the changes required to add it are strictly additive.
 
 \subsection{Processors}
-Parallelism in \CFA is built around using processors to specify how much parallelism is desired. \CFA processors are object wrappers around kernel threads, specifically pthreads in the current implementation of \CFA. Indeed, any parallelism must go through operating-system libraries. However, \glspl{uthread} are still the main source of concurrency, processors are simply the underlying source of parallelism. Indeed, processor \glspl{kthread} simply fetch a \gls{uthread} from the scheduler and run it; they are effectively executers for user-threads. The main benefit of this approach is that it offers a well defined boundary between kernel code and user code, for example, kernel thread quiescing, scheduling and interrupt handling. Processors internally use coroutines to take advantage of the existing context-switching semantics.
-
-\subsection{Stack management}
-One of the challenges of this system is to reduce the footprint as much as possible. Specifically, all pthreads created also have a stack created with them, which should be used as much as possible. Normally, coroutines also create there own stack to run on, however, in the case of the coroutines used for processors, these coroutines run directly on the \gls{kthread} stack, effectively stealing the processor stack. The exception to this rule is the Main Processor, i.e. the initial \gls{kthread} that is given to any program. In order to respect C user-expectations, the stack of the initial kernel thread, the main stack of the program, is used by the main user thread rather than the main processor, which can grow very large
+Parallelism in \CFA is built around using processors to specify how much parallelism is desired. \CFA processors are object wrappers around kernel threads, specifically pthreads in the current implementation of \CFA. Indeed, any parallelism must go through operating-system libraries. However, \glspl{uthread} are still the main source of concurrency, processors are simply the underlying source of parallelism. Indeed, processor \glspl{kthread} simply fetch a \gls{uthread} from the scheduler and run it; they are effectively executers for user-threads. The main benefit of this approach is that it offers a well-defined boundary between kernel code and user code, for example, kernel thread quiescing, scheduling and interrupt handling. Processors internally use coroutines to take advantage of the existing context-switching semantics.
+
+\subsection{Stack Management}
+One of the challenges of this system is to reduce the footprint as much as possible. Specifically, all pthreads created also have a stack created with them, which should be used as much as possible. Normally, coroutines also create there own stack to run on, however, in the case of the coroutines used for processors, these coroutines run directly on the \gls{kthread} stack, effectively stealing the processor stack. The exception to this rule is the Main Processor, i.e. the initial \gls{kthread} that is given to any program. In order to respect C user expectations, the stack of the initial kernel thread, the main stack of the program, is used by the main user thread rather than the main processor, which can grow very large.
 
 \subsection{Preemption} \label{preemption}
-Finally, an important aspect for any complete threading system is preemption. As mentioned in chapter \ref{basics}, preemption introduces an extra degree of uncertainty, which enables users to have multiple threads interleave transparently, rather than having to cooperate among threads for proper scheduling and CPU distribution. Indeed, preemption is desirable because it adds a degree of isolation among threads. In a fully cooperative system, any thread that runs a long loop can starve other threads, while in a preemptive system, starvation can still occur but it does not rely on every thread having to yield or block on a regular basis, which reduces significantly a programmer burden. Obviously, preemption is not optimal for every workload, however any preemptive system can become a cooperative system by making the time-slices extremely large. Therefore, \CFA uses a preemptive threading system.
+Finally, an important aspect for any complete threading system is preemption. As mentioned in chapter \ref{basics}, preemption introduces an extra degree of uncertainty, which enables users to have multiple threads interleave transparently, rather than having to cooperate among threads for proper scheduling and CPU distribution. Indeed, preemption is desirable because it adds a degree of isolation among threads. In a fully cooperative system, any thread that runs a long loop can starve other threads, while in a preemptive system, starvation can still occur but it does not rely on every thread having to yield or block on a regular basis, which reduces significantly a programmer burden. Obviously, preemption is not optimal for every workload. However any preemptive system can become a cooperative system by making the time slices extremely large. Therefore, \CFA uses a preemptive threading system.
 
 Preemption in \CFA is based on kernel timers, which are used to run a discrete-event simulation. Every processor keeps track of the current time and registers an expiration time with the preemption system. When the preemption system receives a change in preemption, it inserts the time in a sorted order and sets a kernel timer for the closest one, effectively stepping through preemption events on each signal sent by the timer. These timers use the Linux signal {\tt SIGALRM}, which is delivered to the process rather than the kernel-thread. This results in an implementation problem, because when delivering signals to a process, the kernel can deliver the signal to any kernel thread for which the signal is not blocked, i.e. :
@@ -146,5 +146,5 @@
 For the sake of simplicity and in order to prevent the case of having two threads receiving alarms simultaneously, \CFA programs block the {\tt SIGALRM} signal on every kernel thread except one. Now because of how involuntary context-switches are handled, the kernel thread handling {\tt SIGALRM} cannot also be a processor thread.
 
-Involuntary context-switching is done by sending signal {\tt SIGUSER1} to the corresponding proces\-sor and having the thread yield from inside the signal handler. This approach effectively context-switches away from the signal-handler back to the kernel and the signal-handler frame is eventually unwound when the thread is scheduled again. As a result, a signal-handler can start on one kernel thread and terminate on a second kernel thread (but the same user thread). It is important to note that signal-handlers save and restore signal masks because user-thread migration can cause a signal mask to migrate from one kernel thread to another. This behaviour is only a problem if all kernel threads, among which a user thread can migrate, differ in terms of signal masks\footnote{Sadly, official POSIX documentation is silent on what distinguishes ``async-signal-safe'' functions from other functions.}. However, since the kernel thread handling preemption requires a different signal mask, executing user threads on the kernel-alarm thread can cause deadlocks. For this reason, the alarm thread is in a tight loop around a system call to \code{sigwaitinfo}, requiring very little CPU time for preemption. One final detail about the alarm thread is how to wake it when additional communication is required (e.g., on thread termination). This unblocking is also done using {\tt SIGALRM}, but sent through the \code{pthread_sigqueue}. Indeed, \code{sigwait} can differentiate signals sent from \code{pthread_sigqueue} from signals sent from alarms or the kernel.
+Involuntary context-switching is done by sending signal {\tt SIGUSER1} to the corresponding proces\-sor and having the thread yield from inside the signal handler. This approach effectively context-switches away from the signal handler back to the kernel and the signal-handler frame is eventually unwound when the thread is scheduled again. As a result, a signal-handler can start on one kernel thread and terminate on a second kernel thread (but the same user thread). It is important to note that signal-handlers save and restore signal masks because user-thread migration can cause a signal mask to migrate from one kernel thread to another. This behaviour is only a problem if all kernel threads, among which a user thread can migrate, differ in terms of signal masks\footnote{Sadly, official POSIX documentation is silent on what distinguishes ``async-signal-safe'' functions from other functions.}. However, since the kernel thread handling preemption requires a different signal mask, executing user threads on the kernel-alarm thread can cause deadlocks. For this reason, the alarm thread is in a tight loop around a system call to \code{sigwaitinfo}, requiring very little CPU time for preemption. One final detail about the alarm thread is how to wake it when additional communication is required (e.g., on thread termination). This unblocking is also done using {\tt SIGALRM}, but sent through the \code{pthread_sigqueue}. Indeed, \code{sigwait} can differentiate signals sent from \code{pthread_sigqueue} from signals sent from alarms or the kernel.
 
 \subsection{Scheduler}
@@ -153,5 +153,5 @@
 % ======================================================================
 % ======================================================================
-\section{Internal scheduling} \label{impl:intsched}
+\section{Internal Scheduling} \label{impl:intsched}
 % ======================================================================
 % ======================================================================
@@ -165,5 +165,5 @@
 \end{figure}
 
-This picture has several components, the two most important being the entry-queue and the AS-stack. The entry-queue is an (almost) FIFO list where threads waiting to enter are parked, while the acceptor-signaler (AS) stack is a FILO list used for threads that have been signalled or otherwise marked as running next.
+This picture has several components, the two most important being the entry queue and the AS-stack. The entry queue is an (almost) FIFO list where threads waiting to enter are parked, while the acceptor/signaller (AS) stack is a FILO list used for threads that have been signalled or otherwise marked as running next.
 
 For \CFA, this picture does not have support for blocking multiple monitors on a single condition. To support \gls{bulk-acq} two changes to this picture are required. First, it is no longer helpful to attach the condition to \emph{a single} monitor. Secondly, the thread waiting on the condition has to be separated across multiple monitors, seen in figure \ref{fig:monitor_cfa}.
@@ -173,9 +173,9 @@
 {\resizebox{0.8\textwidth}{!}{\input{int_monitor}}}
 \end{center}
-\caption{Illustration of \CFA monitor}
+\caption{Illustration of \CFA Monitor}
 \label{fig:monitor_cfa}
 \end{figure}
 
-This picture and the proper entry and leave algorithms (see listing \ref{lst:entry2}) is the fundamental implementation of internal scheduling. Note that when a thread is moved from the condition to the AS-stack, it is conceptually split the thread into N pieces, where N is the number of monitors specified in the parameter list. The thread is woken up when all the pieces have popped from the AS-stacks and made active. In this picture, the threads are split into halves but this is only because there are two monitors. For a specific signaling operation every monitor needs a piece of thread on its AS-stack.
+This picture and the proper entry and leave algorithms (see listing \ref{lst:entry2}) is the fundamental implementation of internal scheduling. Note that when a thread is moved from the condition to the AS-stack, it is conceptually split the thread into N pieces, where N is the number of monitors specified in the parameter list. The thread is woken up when all the pieces have popped from the AS-stacks and made active. In this picture, the threads are split into halves but this is only because there are two monitors. For a specific signalling operation every monitor needs a piece of thread on its AS-stack.
 
 \begin{figure}[b]
@@ -210,5 +210,5 @@
 \end{figure}
 
-Some important things to notice about the exit routine. The solution discussed in \ref{intsched} can be seen in the exit routine of listing \ref{lst:entry2}. Basically, the solution boils down to having a separate data structure for the condition queue and the AS-stack, and unconditionally transferring ownership of the monitors but only unblocking the thread when the last monitor has transferred ownership. This solution is deadlock safe as well as preventing any potential barging. The data structure used for the AS-stack are reused extensively for external scheduling, but in the case of internal scheduling, the data is allocated using variable-length arrays on the call-stack of the \code{wait} and \code{signal_block} routines.
+Some important things to notice about the exit routine. The solution discussed in \ref{intsched} can be seen in the exit routine of listing \ref{lst:entry2}. Basically, the solution boils down to having a separate data structure for the condition queue and the AS-stack, and unconditionally transferring ownership of the monitors but only unblocking the thread when the last monitor has transferred ownership. This solution is deadlock safe as well as preventing any potential barging. The data structures used for the AS-stack are reused extensively for external scheduling, but in the case of internal scheduling, the data is allocated using variable-length arrays on the call stack of the \code{wait} and \code{signal_block} routines.
 
 \begin{figure}[H]
@@ -220,9 +220,9 @@
 \end{figure}
 
-Figure \ref{fig:structs} shows a high-level representation of these data-structures. The main idea behind them is that, a thread cannot contain an arbitrary number of intrusive stacks for linking onto monitor. The \code{condition node} is the data structure that is queued onto a condition variable and, when signaled, the condition queue is popped and each \code{condition criterion} are moved to the AS-stack. Once all the criterion have be popped from their respective AS-stacks, the thread is woken-up, which is what is shown in listing \ref{lst:entry2}.
-
-% ======================================================================
-% ======================================================================
-\section{External scheduling}
+Figure \ref{fig:structs} shows a high-level representation of these data structures. The main idea behind them is that, a thread cannot contain an arbitrary number of intrusive stacks for linking onto monitor. The \code{condition node} is the data structure that is queued onto a condition variable and, when signalled, the condition queue is popped and each \code{condition criterion} is moved to the AS-stack. Once all the criteria have been popped from their respective AS-stacks, the thread is woken up, which is what is shown in listing \ref{lst:entry2}.
+
+% ======================================================================
+% ======================================================================
+\section{External Scheduling}
 % ======================================================================
 % ======================================================================
@@ -232,5 +232,5 @@
 \begin{itemize}
 	\item The queue of the monitor with the lowest address is no longer a true FIFO queue because threads can be moved to the front of the queue. These queues need to contain a set of monitors for each of the waiting threads. Therefore, another thread whose set contains the same lowest address monitor but different lower priority monitors may arrive first but enter the critical section after a thread with the correct pairing.
-	\item The queue of the lowest priority monitor is both required and potentially unused. Indeed, since it is not known at compile time which monitor is the monitor with have the lowest address, every monitor needs to have the correct queues even though it is possible that some queues go unused for the entire duration of the program, for example if a monitor is only used in a specific pair.
+	\item The queue of the lowest priority monitor is both required and potentially unused. Indeed, since it is not known at compile time which monitor is the monitor which has the lowest address, every monitor needs to have the correct queues even though it is possible that some queues go unused for the entire duration of the program, for example if a monitor is only used in a specific pair.
 \end{itemize}
 Therefore, the following modifications need to be made to support external scheduling :
@@ -241,6 +241,6 @@
 \end{itemize}
 
-\subsection{External scheduling - destructors}
-Finally, to support the ordering inversion of destructors, the code generation needs to be modified to use a special entry routine. This routine is needed because of the storage requirements of the call order inversion. Indeed, when waiting for the destructors, storage is need for the waiting context and the lifetime of said storage needs to outlive the waiting operation it is needed for. For regular \code{waitfor} statements, the call-stack of the routine itself matches this requirement but it is no longer the case when waiting for the destructor since it is pushed on to the AS-stack for later. The waitfor semantics can then be adjusted correspondingly, as seen in listing \ref{lst:entry-dtor}
+\subsection{External Scheduling - Destructors}
+Finally, to support the ordering inversion of destructors, the code generation needs to be modified to use a special entry routine. This routine is needed because of the storage requirements of the call order inversion. Indeed, when waiting for the destructors, storage is needed for the waiting context and the lifetime of said storage needs to outlive the waiting operation it is needed for. For regular \code{waitfor} statements, the call stack of the routine itself matches this requirement but it is no longer the case when waiting for the destructor since it is pushed on to the AS-stack for later. The waitfor semantics can then be adjusted correspondingly, as seen in listing \ref{lst:entry-dtor}
 
 \begin{figure}
@@ -253,5 +253,5 @@
 	continue
 elif matches waitfor mask
-	push criterions to AS-stack
+	push criteria to AS-stack
 	continue
 else
Index: doc/proposals/concurrency/text/parallelism.tex
===================================================================
--- doc/proposals/concurrency/text/parallelism.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/parallelism.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -10,21 +10,21 @@
 
 \section{Paradigms}
-\subsection{User-level threads}
-A direct improvement on the \gls{kthread} approach is to use \glspl{uthread}. These threads offer most of the same features that the operating system already provide but can be used on a much larger scale. This approach is the most powerful solution as it allows all the features of multi-threading, while removing several of the more expensive costs of kernel threads. The down side is that almost none of the low-level threading problems are hidden; users still have to think about data races, deadlocks and synchronization issues. These issues can be somewhat alleviated by a concurrency toolkit with strong guarantees but the parallelism toolkit offers very little to reduce complexity in itself.
+\subsection{User-Level Threads}
+A direct improvement on the \gls{kthread} approach is to use \glspl{uthread}. These threads offer most of the same features that the operating system already provides but can be used on a much larger scale. This approach is the most powerful solution as it allows all the features of multithreading, while removing several of the more expensive costs of kernel threads. The downside is that almost none of the low-level threading problems are hidden; users still have to think about data races, deadlocks and synchronization issues. These issues can be somewhat alleviated by a concurrency toolkit with strong guarantees but the parallelism toolkit offers very little to reduce complexity in itself.
 
 Examples of languages that support \glspl{uthread} are Erlang~\cite{Erlang} and \uC~\cite{uC++book}.
 
-\subsection{Fibers : user-level threads without preemption} \label{fibers}
-A popular variant of \glspl{uthread} is what is often referred to as \glspl{fiber}. However, \glspl{fiber} do not present meaningful semantical differences with \glspl{uthread}. The significant difference between \glspl{uthread} and \glspl{fiber} is the lack of \gls{preemption} in the latter. Advocates of \glspl{fiber} list their high performance and ease of implementation as majors strengths but the performance difference between \glspl{uthread} and \glspl{fiber} is controversial, and the ease of implementation, while true, is a weak argument in the context of language design. Therefore this proposal largely ignores fibers.
+\subsection{Fibers : User-Level Threads Without Preemption} \label{fibers}
+A popular variant of \glspl{uthread} is what is often referred to as \glspl{fiber}. However, \glspl{fiber} do not present meaningful semantic differences with \glspl{uthread}. The significant difference between \glspl{uthread} and \glspl{fiber} is the lack of \gls{preemption} in the latter. Advocates of \glspl{fiber} list their high performance and ease of implementation as major strengths but the performance difference between \glspl{uthread} and \glspl{fiber} is controversial, and the ease of implementation, while true, is a weak argument in the context of language design. Therefore this proposal largely ignores fibers.
 
 An example of a language that uses fibers is Go~\cite{Go}
 
-\subsection{Jobs and thread pools}
-An approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work, called jobs, and a dependency graph (either explicit or implicit) that tie them together. This approach means users need not worry about concurrency but significantly limit the interaction that can occur among jobs. Indeed, any \gls{job} that blocks also blocks the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. It can be argued that a solution to this problem is to use more workers than available cores. However, unless the number of jobs and the number of workers are comparable, having a significant amount of blocked jobs always results in idles cores.
+\subsection{Jobs and Thread Pools}
+An approach on the opposite end of the spectrum is to base parallelism on \glspl{pool}. Indeed, \glspl{pool} offer limited flexibility but at the benefit of a simpler user interface. In \gls{pool} based systems, users express parallelism as units of work, called jobs, and a dependency graph (either explicit or implicit) that ties them together. This approach means users need not worry about concurrency but significantly limit the interaction that can occur among jobs. Indeed, any \gls{job} that blocks also block the underlying worker, which effectively means the CPU utilization, and therefore throughput, suffers noticeably. It can be argued that a solution to this problem is to use more workers than available cores. However, unless the number of jobs and the number of workers are comparable, having a significant number of blocked jobs always results in idles cores.
 
 The gold standard of this implementation is Intel's TBB library~\cite{TBB}.
 
-\subsection{Paradigm performance}
-While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pin-down the performance implications of choosing a model at the language level. Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. Having a large amount of mostly independent units of work to execute almost guarantees that the \gls{pool} based system has the best performance thanks to the lower memory overhead (i.e., no thread stack per job). However, interactions among jobs can easily exacerbate contention. User-level threads allow fine-grain context switching, which results in better resource utilization, but a context switch is more expensive and the extra control means users need to tweak more variables to get the desired performance. Finally, if the units of uninterrupted work are large enough the paradigm choice is largely amortized by the actual work done.
+\subsection{Paradigm Performance}
+While the choice between the three paradigms listed above may have significant performance implication, it is difficult to pin down the performance implications of choosing a model at the language level. Indeed, in many situations one of these paradigms may show better performance but it all strongly depends on the workload. Having a large amount of mostly independent units of work to execute almost guarantees that the \gls{pool}-based system has the best performance thanks to the lower memory overhead (i.e., no thread stack per job). However, interactions among jobs can easily exacerbate contention. User-level threads allow fine-grain context switching, which results in better resource utilization, but a context switch is more expensive and the extra control means users need to tweak more variables to get the desired performance. Finally, if the units of uninterrupted work are large enough the paradigm choice is largely amortized by the actual work done.
 
 \section{The \protect\CFA\ Kernel : Processors, Clusters and Threads}\label{kernel}
@@ -33,7 +33,7 @@
 \Glspl{cfacluster} have not been fully implemented in the context of this thesis, currently \CFA only supports one \gls{cfacluster}, the initial one.
 
-\subsection{Future Work: Machine setup}\label{machine}
+\subsection{Future Work: Machine Setup}\label{machine}
 While this was not done in the context of this thesis, another important aspect of clusters is affinity. While many common desktop and laptop PCs have homogeneous CPUs, other devices often have more heterogeneous setups. For example, a system using \acrshort{numa} configurations may benefit from users being able to tie clusters and\/or kernel threads to certain CPU cores. OS support for CPU affinity is now common~\cite{affinityLinux, affinityWindows, affinityFreebsd, affinityNetbsd, affinityMacosx} which means it is both possible and desirable for \CFA to offer an abstraction mechanism for portable CPU affinity.
 
 \subsection{Paradigms}\label{cfaparadigms}
-Given these building blocks, it is possible to reproduce all three of the popular paradigms. Indeed, \glspl{uthread} is the default paradigm in \CFA. However, disabling \gls{preemption} on the \gls{cfacluster} means \glspl{cfathread} effectively become \glspl{fiber}. Since several \glspl{cfacluster} with different scheduling policy can coexist in the same application, this allows \glspl{fiber} and \glspl{uthread} to coexist in the runtime of an application. Finally, it is possible to build executors for thread pools from \glspl{uthread} or \glspl{fiber}, which includes specialize jobs like actors~\cite{Actors}.
+Given these building blocks, it is possible to reproduce all three of the popular paradigms. Indeed, \glspl{uthread} is the default paradigm in \CFA. However, disabling \gls{preemption} on the \gls{cfacluster} means \glspl{cfathread} effectively become \glspl{fiber}. Since several \glspl{cfacluster} with different scheduling policy can coexist in the same application, this allows \glspl{fiber} and \glspl{uthread} to coexist in the runtime of an application. Finally, it is possible to build executors for thread pools from \glspl{uthread} or \glspl{fiber}, which includes specialized jobs like actors~\cite{Actors}.
Index: doc/proposals/concurrency/text/results.tex
===================================================================
--- doc/proposals/concurrency/text/results.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/results.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -1,9 +1,9 @@
 % ======================================================================
 % ======================================================================
-\chapter{Performance results} \label{results}
+\chapter{Performance Results} \label{results}
 % ======================================================================
 % ======================================================================
-\section{Machine setup}
-Table \ref{tab:machine} shows the characteristics of the machine used to run the benchmarks. All tests where made on this machine.
+\section{Machine Setup}
+Table \ref{tab:machine} shows the characteristics of the machine used to run the benchmarks. All tests were made on this machine.
 \begin{table}[H]
 \begin{center}
@@ -37,5 +37,5 @@
 \end{table}
 
-\section{Micro benchmarks}
+\section{Micro Benchmarks}
 All benchmarks are run using the same harness to produce the results, seen as the \code{BENCH()} macro in the following examples. This macro uses the following logic to benchmark the code :
 \begin{pseudo}
@@ -46,8 +46,8 @@
 	result = (after - before) / N;
 \end{pseudo}
-The method used to get time is \code{clock_gettime(CLOCK_THREAD_CPUTIME_ID);}. Each benchmark is using many iterations of a simple call to measure the cost of the call. The specific number of iteration depends on the specific benchmark.
-
-\subsection{Context-switching}
-The first interesting benchmark is to measure how long context-switches take. The simplest approach to do this is to yield on a thread, which executes a 2-step context switch. In order to make the comparison fair, coroutines also execute a 2-step context-switch (\gls{uthread} to \gls{kthread} then \gls{kthread} to \gls{uthread}), which is a resume/suspend cycle instead of a yield. Listing \ref{lst:ctx-switch} shows the code for coroutines and threads whith the results in table \ref{tab:ctx-switch}. All omitted tests are functionally identical to one of these tests.
+The method used to get time is \code{clock_gettime(CLOCK_THREAD_CPUTIME_ID);}. Each benchmark is using many iterations of a simple call to measure the cost of the call. The specific number of iterations depends on the specific benchmark.
+
+\subsection{Context-Switching}
+The first interesting benchmark is to measure how long context-switches take. The simplest approach to do this is to yield on a thread, which executes a 2-step context switch. In order to make the comparison fair, coroutines also execute a 2-step context-switch (\gls{uthread} to \gls{kthread} then \gls{kthread} to \gls{uthread}), which is a resume/suspend cycle instead of a yield. Listing \ref{lst:ctx-switch} shows the code for coroutines and threads with the results in table \ref{tab:ctx-switch}. All omitted tests are functionally identical to one of these tests.
 \begin{figure}
 \begin{multicols}{2}
@@ -114,6 +114,6 @@
 \end{table}
 
-\subsection{Mutual-exclusion}
-The next interesting benchmark is to measure the overhead to enter/leave a critical-section. For monitors, the simplest approach is to measure how long it takes to enter and leave a monitor routine. Listing \ref{lst:mutex} shows the code for \CFA. To put the results in context, the cost of entering a non-inline function and the cost of acquiring and releasing a pthread mutex lock are also measured. The results can be shown in table \ref{tab:mutex}.
+\subsection{Mutual-Exclusion}
+The next interesting benchmark is to measure the overhead to enter/leave a critical-section. For monitors, the simplest approach is to measure how long it takes to enter and leave a monitor routine. Listing \ref{lst:mutex} shows the code for \CFA. To put the results in context, the cost of entering a non-inline function and the cost of acquiring and releasing a pthread mutex lock is also measured. The results can be shown in table \ref{tab:mutex}.
 
 \begin{figure}
@@ -156,5 +156,5 @@
 \end{table}
 
-\subsection{Internal scheduling}
+\subsection{Internal Scheduling}
 The internal-scheduling benchmark measures the cost of waiting on and signalling a condition variable. Listing \ref{lst:int-sched} shows the code for \CFA, with results table \ref{tab:int-sched}. As with all other benchmarks, all omitted tests are functionally identical to one of these tests.
 
@@ -211,5 +211,5 @@
 \end{table}
 
-\subsection{External scheduling}
+\subsection{External Scheduling}
 The Internal scheduling benchmark measures the cost of the \code{waitfor} statement (\code{_Accept} in \uC). Listing \ref{lst:ext-sched} shows the code for \CFA, with results in table \ref{tab:ext-sched}. As with all other benchmarks, all omitted tests are functionally identical to one of these tests.
 
@@ -264,6 +264,6 @@
 \end{table}
 
-\subsection{Object creation}
-Finally, the last benchmark measurs the cost of creation for concurrent objects. Listing \ref{lst:creation} shows the code for pthreads and \CFA threads, with results shown in table \ref{tab:creation}. As with all other benchmarks, all omitted tests are functionally identical to one of these tests. The only note here is that the call-stacks of \CFA coroutines are lazily created, therefore without priming the coroutine, the creation cost is very low.
+\subsection{Object Creation}
+Finally, the last benchmark measures the cost of creation for concurrent objects. Listing \ref{lst:creation} shows the code for pthreads and \CFA threads, with results shown in table \ref{tab:creation}. As with all other benchmarks, all omitted tests are functionally identical to one of these tests. The only note here is that the call stacks of \CFA coroutines are lazily created, therefore without priming the coroutine, the creation cost is very low.
 
 \begin{figure}
@@ -327,5 +327,5 @@
 \end{tabular}
 \end{center}
-\caption{Creation comparison. All numbers are in nanoseconds(\si{\nano\second})}
+\caption{Creation comparison. All numbers are in nanoseconds(\si{\nano\second}).}
 \label{tab:creation}
 \end{table}
Index: doc/proposals/concurrency/text/together.tex
===================================================================
--- doc/proposals/concurrency/text/together.tex	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/text/together.tex	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -1,10 +1,10 @@
 % ======================================================================
 % ======================================================================
-\chapter{Putting it all together}
+\chapter{Putting It All Together}
 % ======================================================================
 % ======================================================================
 
 
-\section{Threads as monitors}
+\section{Threads As Monitors}
 As it was subtly alluded in section \ref{threads}, \code{thread}s in \CFA are in fact monitors, which means that all monitor features are available when using threads. For example, here is a very simple two thread pipeline that could be used for a simulator of a game engine :
 \begin{figure}[H]
Index: doc/proposals/concurrency/version
===================================================================
--- doc/proposals/concurrency/version	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ doc/proposals/concurrency/version	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -1,1 +1,1 @@
-0.11.280
+0.11.299
Index: src/CodeGen/FixNames.cc
===================================================================
--- src/CodeGen/FixNames.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/CodeGen/FixNames.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -19,4 +19,5 @@
 #include <string>                  // for string, operator!=, operator==
 
+#include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"  // for SemanticError
 #include "FixMain.h"               // for FixMain
@@ -32,10 +33,10 @@
 
 namespace CodeGen {
-	class FixNames : public Visitor {
+	class FixNames : public WithGuards {
 	  public:
-		virtual void visit( ObjectDecl *objectDecl );
-		virtual void visit( FunctionDecl *functionDecl );
+		void postvisit( ObjectDecl *objectDecl );
+		void postvisit( FunctionDecl *functionDecl );
 
-		virtual void visit( CompoundStmt *compoundStmt );
+		void previsit( CompoundStmt *compoundStmt );
 	  private:
 		int scopeLevel = 1;
@@ -93,10 +94,10 @@
 	}
 
-	void fixNames( std::list< Declaration* > translationUnit ) {
-		FixNames fixer;
+	void fixNames( std::list< Declaration* > & translationUnit ) {
+		PassVisitor<FixNames> fixer;
 		acceptAll( translationUnit, fixer );
 	}
 
-	void FixNames::fixDWT( DeclarationWithType *dwt ) {
+	void FixNames::fixDWT( DeclarationWithType * dwt ) {
 		if ( dwt->get_name() != "" ) {
 			if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) {
@@ -107,11 +108,9 @@
 	}
 
-	void FixNames::visit( ObjectDecl *objectDecl ) {
-		Visitor::visit( objectDecl );
+	void FixNames::postvisit( ObjectDecl * objectDecl ) {
 		fixDWT( objectDecl );
 	}
 
-	void FixNames::visit( FunctionDecl *functionDecl ) {
-		Visitor::visit( functionDecl );
+	void FixNames::postvisit( FunctionDecl * functionDecl ) {
 		fixDWT( functionDecl );
 
@@ -121,13 +120,12 @@
 				throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl);
 			}
-			functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant::from_int( 0 ) ) ) );
+			functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) );
 			CodeGen::FixMain::registerMain( functionDecl );
 		}
 	}
 
-	void FixNames::visit( CompoundStmt *compoundStmt ) {
+	void FixNames::previsit( CompoundStmt * ) {
 		scopeLevel++;
-		Visitor::visit( compoundStmt );
-		scopeLevel--;
+		GuardAction( [this](){ scopeLevel--; } );
 	}
 } // namespace CodeGen
Index: src/CodeGen/FixNames.h
===================================================================
--- src/CodeGen/FixNames.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/CodeGen/FixNames.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixNames.h -- 
+// FixNames.h --
 //
 // Author           : Richard C. Bilson
@@ -22,5 +22,5 @@
 namespace CodeGen {
 	/// mangles object and function names
-	void fixNames( std::list< Declaration* > translationUnit );
+	void fixNames( std::list< Declaration* > & translationUnit );
 } // namespace CodeGen
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/Common/PassVisitor.impl.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -55,5 +55,5 @@
 		it,
 		[](Declaration * decl) -> auto {
-			return new DeclStmt( noLabels, decl );
+			return new DeclStmt( decl );
 		}
 	);
@@ -251,5 +251,5 @@
 	    || ( empty( beforeDecls ) && empty( afterDecls )) );
 
-	CompoundStmt *compound = new CompoundStmt( noLabels );
+	CompoundStmt *compound = new CompoundStmt();
 	if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); }
 	if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/Concurrency/Keywords.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -38,12 +38,4 @@
 
 namespace Concurrency {
-
-	namespace {
-		const std::list<Label> noLabels;
-		const std::list< Attribute * > noAttributes;
-		Type::StorageClasses noStorage;
-		Type::Qualifiers noQualifiers;
-	}
-
 	//=============================================================================================
 	// Pass declarations
@@ -296,5 +288,5 @@
 		ObjectDecl * this_decl = new ObjectDecl(
 			"this",
-			noStorage,
+			noStorageClasses,
 			LinkageSpec::Cforall,
 			nullptr,
@@ -313,5 +305,5 @@
 			new ObjectDecl(
 				"ret",
-				noStorage,
+				noStorageClasses,
 				LinkageSpec::Cforall,
 				nullptr,
@@ -346,5 +338,5 @@
 			main_decl = new FunctionDecl(
 				"main",
-				noStorage,
+				noStorageClasses,
 				LinkageSpec::Cforall,
 				main_type,
@@ -363,5 +355,5 @@
 		ObjectDecl * field = new ObjectDecl(
 			field_name,
-			noStorage,
+			noStorageClasses,
 			LinkageSpec::Cforall,
 			nullptr,
@@ -379,8 +371,7 @@
 
 	void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) {
-		CompoundStmt * statement = new CompoundStmt( noLabels );
+		CompoundStmt * statement = new CompoundStmt();
 		statement->push_back(
 			new ReturnStmt(
-				noLabels,
 				new AddressExpr(
 					new MemberExpr(
@@ -488,5 +479,5 @@
 		ObjectDecl * monitors = new ObjectDecl(
 			"__monitor",
-			noStorage,
+			noStorageClasses,
 			LinkageSpec::Cforall,
 			nullptr,
@@ -509,7 +500,7 @@
 		// monitor_guard_t __guard = { __monitors, #, func };
 		body->push_front(
-			new DeclStmt( noLabels, new ObjectDecl(
+			new DeclStmt( new ObjectDecl(
 				"__guard",
-				noStorage,
+				noStorageClasses,
 				LinkageSpec::Cforall,
 				nullptr,
@@ -530,5 +521,5 @@
 
 		//monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
-		body->push_front( new DeclStmt( noLabels, monitors) );
+		body->push_front( new DeclStmt( monitors) );
 	}
 
@@ -536,5 +527,5 @@
 		ObjectDecl * monitors = new ObjectDecl(
 			"__monitors",
-			noStorage,
+			noStorageClasses,
 			LinkageSpec::Cforall,
 			nullptr,
@@ -569,7 +560,7 @@
 		// monitor_guard_t __guard = { __monitors, #, func };
 		body->push_front(
-			new DeclStmt( noLabels, new ObjectDecl(
+			new DeclStmt( new ObjectDecl(
 				"__guard",
-				noStorage,
+				noStorageClasses,
 				LinkageSpec::Cforall,
 				nullptr,
@@ -591,5 +582,5 @@
 
 		//monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
-		body->push_front( new DeclStmt( noLabels, monitors) );
+		body->push_front( new DeclStmt( monitors) );
 	}
 
@@ -631,5 +622,4 @@
 		stmt->push_back(
 			new ExprStmt(
-				noLabels,
 				new UntypedExpr(
 					new NameExpr( "__thrd_start" ),
Index: src/Concurrency/Waitfor.cc
===================================================================
--- src/Concurrency/Waitfor.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/Concurrency/Waitfor.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -100,12 +100,4 @@
 
 namespace Concurrency {
-
-	namespace {
-		const std::list<Label> noLabels;
-		const std::list< Attribute * > noAttributes;
-		Type::StorageClasses noStorage;
-		Type::Qualifiers noQualifiers;
-	}
-
 	//=============================================================================================
 	// Pass declarations
@@ -203,5 +195,5 @@
 			ResolvExpr::findVoidExpression( expr, indexer );
 
-			return new ExprStmt( noLabels, expr );
+			return new ExprStmt( expr );
 		}
 
@@ -259,5 +251,5 @@
 		if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
 
-		CompoundStmt * stmt = new CompoundStmt( noLabels );
+		CompoundStmt * stmt = new CompoundStmt();
 
 		ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt );
@@ -281,7 +273,6 @@
 		);
 
-		CompoundStmt * compound = new CompoundStmt( noLabels );
+		CompoundStmt * compound = new CompoundStmt();
 		stmt->push_back( new IfStmt(
-			noLabels,
 			safeCond( new VariableExpr( flag ) ),
 			compound,
@@ -313,5 +304,5 @@
 		);
 
-		stmt->push_back( new DeclStmt( noLabels, acceptables) );
+		stmt->push_back( new DeclStmt( acceptables) );
 
 		Expression * set = new UntypedExpr(
@@ -326,5 +317,5 @@
 		ResolvExpr::findVoidExpression( set, indexer );
 
-		stmt->push_back( new ExprStmt( noLabels, set ) );
+		stmt->push_back( new ExprStmt( set ) );
 
 		return acceptables;
@@ -341,5 +332,5 @@
 		);
 
-		stmt->push_back( new DeclStmt( noLabels, flag) );
+		stmt->push_back( new DeclStmt( flag) );
 
 		return flag;
@@ -357,5 +348,5 @@
 		ResolvExpr::findVoidExpression( expr, indexer );
 
-		return new ExprStmt( noLabels, expr );
+		return new ExprStmt( expr );
 	}
 
@@ -399,5 +390,5 @@
 		);
 
-		stmt->push_back( new DeclStmt( noLabels, mon) );
+		stmt->push_back( new DeclStmt( mon) );
 
 		return mon;
@@ -411,5 +402,4 @@
 
 		stmt->push_back( new IfStmt(
-			noLabels,
 			safeCond( clause.condition ),
 			new CompoundStmt({
@@ -447,13 +437,11 @@
 		);
 
-		stmt->push_back( new DeclStmt( noLabels, timeout ) );
+		stmt->push_back( new DeclStmt( timeout ) );
 
 		if( time ) {
 			stmt->push_back( new IfStmt(
-				noLabels,
 				safeCond( time_cond ),
 				new CompoundStmt({
 					new ExprStmt(
-						noLabels,
 						makeOpAssign(
 							new VariableExpr( timeout ),
@@ -471,9 +459,7 @@
 		if( has_else ) {
 			stmt->push_back( new IfStmt(
-				noLabels,
 				safeCond( else_cond ),
 				new CompoundStmt({
 					new ExprStmt(
-						noLabels,
 						makeOpAssign(
 							new VariableExpr( timeout ),
@@ -511,5 +497,5 @@
 		);
 
-		stmt->push_back( new DeclStmt( noLabels, index ) );
+		stmt->push_back( new DeclStmt( index ) );
 
 		ObjectDecl * mask = ObjectDecl::newObject(
@@ -526,8 +512,7 @@
 		);
 
-		stmt->push_back( new DeclStmt( noLabels, mask ) );
+		stmt->push_back( new DeclStmt( mask ) );
 
 		stmt->push_back( new ExprStmt(
-			noLabels,
 			new ApplicationExpr(
 				VariableExpr::functionPointer( decl_waitfor ),
@@ -557,5 +542,4 @@
 	) {
 		SwitchStmt * swtch = new SwitchStmt(
-			noLabels,
 			result,
 			std::list<Statement *>()
@@ -566,10 +550,8 @@
 			swtch->statements.push_back(
 				new CaseStmt(
-					noLabels,
 					new ConstantExpr( Constant::from_ulong( i++ ) ),
 					{
 						clause.statement,
 						new BranchStmt(
-							noLabels,
 							"",
 							BranchStmt::Break
@@ -583,10 +565,8 @@
 			swtch->statements.push_back(
 				new CaseStmt(
-					noLabels,
 					new ConstantExpr( Constant::from_int( -2 ) ),
 					{
 						waitfor->timeout.statement,
 						new BranchStmt(
-							noLabels,
 							"",
 							BranchStmt::Break
@@ -600,10 +580,8 @@
 			swtch->statements.push_back(
 				new CaseStmt(
-					noLabels,
 					new ConstantExpr( Constant::from_int( -1 ) ),
 					{
 						waitfor->orelse.statement,
 						new BranchStmt(
-							noLabels,
 							"",
 							BranchStmt::Break
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -30,5 +30,5 @@
 #include "SynTree/Expression.h"       // for UntypedExpr, ConstantExpr, Name...
 #include "SynTree/Initializer.h"      // for SingleInit, ListInit
-#include "SynTree/Label.h"            // for Label, noLabels
+#include "SynTree/Label.h"            // for Label
 #include "SynTree/Mutator.h"          // for mutateAll
 #include "SynTree/Statement.h"        // for CompoundStmt, CatchStmt, ThrowStmt
@@ -57,5 +57,5 @@
 
 	void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
-		block->push_back(new DeclStmt(noLabels, item));
+		block->push_back(new DeclStmt(item));
 	}
 
@@ -205,5 +205,5 @@
 		throwStmt->set_expr( nullptr );
 		delete throwStmt;
-		return new ExprStmt( noLabels, call );
+		return new ExprStmt( call );
 	}
 
@@ -211,5 +211,5 @@
 			ThrowStmt *throwStmt ) {
 		// __throw_terminate( `throwStmt->get_name()` ); }
-		return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
+		return create_given_throw( "__cfaabi_ehm__throw_terminate", throwStmt );
 	}
 
@@ -220,6 +220,7 @@
 		assert( handler_except_decl );
 
-		CompoundStmt * result = new CompoundStmt( throwStmt->get_labels() );
-		result->push_back( new ExprStmt( noLabels, UntypedExpr::createAssign(
+		CompoundStmt * result = new CompoundStmt();
+		result->labels =  throwStmt->labels;
+		result->push_back( new ExprStmt( UntypedExpr::createAssign(
 			nameOf( handler_except_decl ),
 			new ConstantExpr( Constant::null(
@@ -231,6 +232,5 @@
 			) ) );
 		result->push_back( new ExprStmt(
-			noLabels,
-			new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) )
+			new UntypedExpr( new NameExpr( "__cfaabi_ehm__rethrow_terminate" ) )
 			) );
 		delete throwStmt;
@@ -241,5 +241,5 @@
 			ThrowStmt *throwStmt ) {
 		// __throw_resume( `throwStmt->get_name` );
-		return create_given_throw( "__cfaehm__throw_resume", throwStmt );
+		return create_given_throw( "__cfaabi_ehm__throw_resume", throwStmt );
 	}
 
@@ -248,7 +248,7 @@
 		// return false;
 		Statement * result = new ReturnStmt(
-			throwStmt->get_labels(),
 			new ConstantExpr( Constant::from_bool( false ) )
 			);
+		result->labels = throwStmt->labels;
 		delete throwStmt;
 		return result;
@@ -291,5 +291,5 @@
 			// }
 			// return;
-			CompoundStmt * block = new CompoundStmt( noLabels );
+			CompoundStmt * block = new CompoundStmt();
 
 			// Just copy the exception value. (Post Validation)
@@ -304,10 +304,10 @@
 					) })
 				);
-			block->push_back( new DeclStmt( noLabels, local_except ) );
+			block->push_back( new DeclStmt( local_except ) );
 
 			// Add the cleanup attribute.
 			local_except->get_attributes().push_back( new Attribute(
 				"cleanup",
-				{ new NameExpr( "__cfaehm__cleanup_terminate" ) }
+				{ new NameExpr( "__cfaabi_ehm__cleanup_terminate" ) }
 				) );
 
@@ -324,7 +324,6 @@
 
 			std::list<Statement *> caseBody
-					{ block, new ReturnStmt( noLabels, nullptr ) };
+					{ block, new ReturnStmt( nullptr ) };
 			handler_wrappers.push_back( new CaseStmt(
-				noLabels,
 				new ConstantExpr( Constant::from_int( index ) ),
 				caseBody
@@ -340,9 +339,8 @@
 
 		SwitchStmt * handler_lookup = new SwitchStmt(
-			noLabels,
 			nameOf( index_obj ),
 			stmt_handlers
 			);
-		CompoundStmt * body = new CompoundStmt( noLabels );
+		CompoundStmt * body = new CompoundStmt();
 		body->push_back( handler_lookup );
 
@@ -363,5 +361,5 @@
 		// }
 
-		CompoundStmt * block = new CompoundStmt( noLabels );
+		CompoundStmt * block = new CompoundStmt();
 
 		// Local Declaration
@@ -369,5 +367,5 @@
 			dynamic_cast<ObjectDecl *>( modded_handler->get_decl() );
 		assert( local_except );
-		block->push_back( new DeclStmt( noLabels, local_except ) );
+		block->push_back( new DeclStmt( local_except ) );
 
 		// Check for type match.
@@ -381,5 +379,5 @@
 		}
 		// Construct the match condition.
-		block->push_back( new IfStmt( noLabels,
+		block->push_back( new IfStmt(
 			cond, modded_handler->get_body(), nullptr ) );
 
@@ -397,5 +395,5 @@
 		// }
 
-		CompoundStmt * body = new CompoundStmt( noLabels );
+		CompoundStmt * body = new CompoundStmt();
 
 		FunctionType * func_type = match_func_t.clone();
@@ -413,5 +411,5 @@
 
 			// Create new body.
-			handler->set_body( new ReturnStmt( noLabels,
+			handler->set_body( new ReturnStmt(
 				new ConstantExpr( Constant::from_int( index ) ) ) );
 
@@ -421,5 +419,5 @@
 		}
 
-		body->push_back( new ReturnStmt( noLabels,
+		body->push_back( new ReturnStmt(
 			new ConstantExpr( Constant::from_int( 0 ) ) ) );
 
@@ -432,8 +430,8 @@
 			FunctionDecl * terminate_catch,
 			FunctionDecl * terminate_match ) {
-		// { __cfaehm__try_terminate(`try`, `catch`, `match`); }
+		// { __cfaabi_ehm__try_terminate(`try`, `catch`, `match`); }
 
 		UntypedExpr * caller = new UntypedExpr( new NameExpr(
-			"__cfaehm__try_terminate" ) );
+			"__cfaabi_ehm__try_terminate" ) );
 		std::list<Expression *>& args = caller->get_args();
 		args.push_back( nameOf( try_wrapper ) );
@@ -441,6 +439,6 @@
 		args.push_back( nameOf( terminate_match ) );
 
-		CompoundStmt * callStmt = new CompoundStmt( noLabels );
-		callStmt->push_back( new ExprStmt( noLabels, caller ) );
+		CompoundStmt * callStmt = new CompoundStmt();
+		callStmt->push_back( new ExprStmt( caller ) );
 		return callStmt;
 	}
@@ -451,5 +449,5 @@
 		//     HANDLER WRAPPERS { `hander->body`; return true; }
 		// }
-		CompoundStmt * body = new CompoundStmt( noLabels );
+		CompoundStmt * body = new CompoundStmt();
 
 		FunctionType * func_type = handle_func_t.clone();
@@ -464,8 +462,8 @@
 				dynamic_cast<CompoundStmt*>( handler->get_body() );
 			if ( ! handling_code ) {
-				handling_code = new CompoundStmt( noLabels );
+				handling_code = new CompoundStmt();
 				handling_code->push_back( handler->get_body() );
 			}
-			handling_code->push_back( new ReturnStmt( noLabels,
+			handling_code->push_back( new ReturnStmt(
 				new ConstantExpr( Constant::from_bool( true ) ) ) );
 			handler->set_body( handling_code );
@@ -476,5 +474,5 @@
 		}
 
-		body->push_back( new ReturnStmt( noLabels,
+		body->push_back( new ReturnStmt(
 			new ConstantExpr( Constant::from_bool( false ) ) ) );
 
@@ -486,11 +484,11 @@
 			Statement * wraps,
 			FunctionDecl * resume_handler ) {
-		CompoundStmt * body = new CompoundStmt( noLabels );
+		CompoundStmt * body = new CompoundStmt();
 
 		// struct __try_resume_node __resume_node
-		//  	__attribute__((cleanup( __cfaehm__try_resume_cleanup )));
+		//  	__attribute__((cleanup( __cfaabi_ehm__try_resume_cleanup )));
 		// ** unwinding of the stack here could cause problems **
 		// ** however I don't think that can happen currently **
-		// __cfaehm__try_resume_setup( &__resume_node, resume_handler );
+		// __cfaabi_ehm__try_resume_setup( &__resume_node, resume_handler );
 
 		std::list< Attribute * > attributes;
@@ -498,5 +496,5 @@
 			std::list< Expression * > attr_params;
 			attr_params.push_back( new NameExpr(
-				"__cfaehm__try_resume_cleanup" ) );
+				"__cfaabi_ehm__try_resume_cleanup" ) );
 			attributes.push_back( new Attribute( "cleanup", attr_params ) );
 		}
@@ -517,9 +515,9 @@
 
 		UntypedExpr *setup = new UntypedExpr( new NameExpr(
-			"__cfaehm__try_resume_setup" ) );
+			"__cfaabi_ehm__try_resume_setup" ) );
 		setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) );
 		setup->get_args().push_back( nameOf( resume_handler ) );
 
-		body->push_back( new ExprStmt( noLabels, setup ) );
+		body->push_back( new ExprStmt( setup ) );
 
 		body->push_back( wraps );
@@ -542,5 +540,5 @@
 	ObjectDecl * ExceptionMutatorCore::create_finally_hook(
 			FunctionDecl * finally_wrapper ) {
-		// struct __cfaehm__cleanup_hook __finally_hook
+		// struct __cfaabi_ehm__cleanup_hook __finally_hook
 		//   	__attribute__((cleanup( finally_wrapper )));
 
@@ -596,12 +594,12 @@
 			// Skip children?
 			return;
-		} else if ( structDecl->get_name() == "__cfaehm__base_exception_t" ) {
+		} else if ( structDecl->get_name() == "__cfaabi_ehm__base_exception_t" ) {
 			assert( nullptr == except_decl );
 			except_decl = structDecl;
 			init_func_types();
-		} else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
+		} else if ( structDecl->get_name() == "__cfaabi_ehm__try_resume_node" ) {
 			assert( nullptr == node_decl );
 			node_decl = structDecl;
-		} else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
+		} else if ( structDecl->get_name() == "__cfaabi_ehm__cleanup_hook" ) {
 			assert( nullptr == hook_decl );
 			hook_decl = structDecl;
@@ -646,5 +644,5 @@
 		// Generate a prefix for the function names?
 
-		CompoundStmt * block = new CompoundStmt( noLabels );
+		CompoundStmt * block = new CompoundStmt();
 		CompoundStmt * inner = take_try_block( tryStmt );
 
Index: src/ControlStruct/ForExprMutator.cc
===================================================================
--- src/ControlStruct/ForExprMutator.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/ControlStruct/ForExprMutator.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -29,5 +29,5 @@
 		// Create compound statement, move initializers outside,
 		// the resut of the original stays as is.
-		CompoundStmt *block = new CompoundStmt( std::list< Label >() );
+		CompoundStmt *block = new CompoundStmt();
 		std::list<Statement *> &stmts = block->get_kids();
 		stmts.splice( stmts.end(), init );
Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/ControlStruct/LabelFixer.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -37,21 +37,17 @@
 	}
 
-	void LabelFixer::visit( FunctionDecl *functionDecl ) {
+	void LabelFixer::previsit( FunctionDecl * ) {
 		// need to go into a nested function in a fresh state
-		std::map < Label, Entry *> oldLabelTable = labelTable;
+		GuardValue( labelTable );
 		labelTable.clear();
+	}
 
-		maybeAccept( functionDecl->get_statements(), *this );
-
+	void LabelFixer::postvisit( FunctionDecl * functionDecl ) {
 		MLEMutator mlemut( resolveJumps(), generator );
 		functionDecl->acceptMutator( mlemut );
-
-		// and remember the outer function's labels when
-		// returning to it
-		labelTable = oldLabelTable;
 	}
 
 	// prune to at most one label definition for each statement
-	void LabelFixer::visit( Statement *stmt ) {
+	void LabelFixer::previsit( Statement *stmt ) {
 		std::list< Label > &labels = stmt->get_labels();
 
@@ -62,6 +58,6 @@
 	}
 
-	void LabelFixer::visit( BranchStmt *branchStmt ) {
-		visit ( ( Statement * )branchStmt );
+	void LabelFixer::previsit( BranchStmt *branchStmt ) {
+		previsit( ( Statement *)branchStmt );
 
 		// for labeled branches, add an entry to the label table
@@ -72,15 +68,8 @@
 	}
 
-	void LabelFixer::visit( UntypedExpr *untyped ) {
-		if ( NameExpr * func = dynamic_cast< NameExpr * >( untyped->get_function() ) ) {
-			if ( func->get_name() == "&&" ) {
-				NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() );
-				Label target = arg->get_name();
-				assert( target != "" );
-				setLabelsUsg( target, untyped );
-			} else {
-				Visitor::visit( untyped );
-			}
-		}
+	void LabelFixer::previsit( LabelAddressExpr * addrExpr ) {
+		Label & target = addrExpr->arg;
+		assert( target != "" );
+		setLabelsUsg( target, addrExpr );
 	}
 
Index: src/ControlStruct/LabelFixer.h
===================================================================
--- src/ControlStruct/LabelFixer.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/ControlStruct/LabelFixer.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -19,4 +19,5 @@
 #include <map>                     // for map
 
+#include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"  // for SemanticError
 #include "SynTree/Label.h"         // for Label
@@ -26,8 +27,7 @@
 namespace ControlStruct {
 	/// normalizes label definitions and generates multi-level exit labels
-class LabelGenerator;
+	class LabelGenerator;
 
-	class LabelFixer final : public Visitor {
-		typedef Visitor Parent;
+	class LabelFixer final : public WithGuards {
 	  public:
 		LabelFixer( LabelGenerator *gen = 0 );
@@ -35,26 +35,14 @@
 		std::map < Label, Statement * > *resolveJumps() throw ( SemanticError );
 
-		using Visitor::visit;
-
 		// Declarations
-		virtual void visit( FunctionDecl *functionDecl ) override;
+		void previsit( FunctionDecl *functionDecl );
+		void postvisit( FunctionDecl *functionDecl );
 
 		// Statements
-		void visit( Statement *stmt );
+		void previsit( Statement *stmt );
+		void previsit( BranchStmt *branchStmt );
 
-		virtual void visit( CompoundStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( NullStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( ExprStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( IfStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( WhileStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( ForStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( SwitchStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( CaseStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( ReturnStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( TryStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( CatchStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( DeclStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
-		virtual void visit( BranchStmt *branchStmt ) override;
-		virtual void visit( UntypedExpr *untyped ) override;
+		// Expressions
+		void previsit( LabelAddressExpr *addrExpr );
 
 		Label setLabelsDef( std::list< Label > &, Statement *definition );
Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/ControlStruct/MLEMutator.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -149,6 +149,7 @@
 
 			if ( CaseStmt * c = dynamic_cast< CaseStmt * >( statements.back() ) ) {
-				std::list<Label> temp; temp.push_back( brkLabel );
-				c->get_statements().push_back( new BranchStmt( temp, Label("brkLabel"), BranchStmt::Break ) );
+				Statement * stmt = new BranchStmt( Label("brkLabel"), BranchStmt::Break );
+				stmt->labels.push_back( brkLabel );
+				c->get_statements().push_back( stmt );
 			} else assert(0); // as of this point, all statements of a switch are still CaseStmts
 		} // if
@@ -232,5 +233,5 @@
 		// transform break/continue statements into goto to simplify later handling of branches
 		delete branchStmt;
-		return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
+		return new BranchStmt( exitLabel, BranchStmt::Goto );
 	}
 
@@ -239,5 +240,5 @@
 		CompoundStmt *newBody;
 		if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
-			newBody = new CompoundStmt( std::list< Label >() );
+			newBody = new CompoundStmt();
 			newBody->get_kids().push_back( bodyLoop );
 		} // if
Index: src/ControlStruct/Mutate.cc
===================================================================
--- src/ControlStruct/Mutate.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/ControlStruct/Mutate.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -24,5 +24,4 @@
 #include "SynTree/Declaration.h"   // for Declaration
 #include "SynTree/Mutator.h"       // for mutateAll
-//#include "ExceptMutator.h"
 
 #include "Common/PassVisitor.h"    // for PassVisitor
@@ -37,11 +36,8 @@
 
 		// normalizes label definitions and generates multi-level exit labels
-		LabelFixer lfix;
-
-		//ExceptMutator exc;
+		PassVisitor<LabelFixer> lfix;
 
 		mutateAll( translationUnit, formut );
 		acceptAll( translationUnit, lfix );
-		//mutateAll( translationUnit, exc );
 	}
 } // namespace CodeGen
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/GenPoly/Box.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -49,5 +49,5 @@
 #include "SynTree/Expression.h"          // for ApplicationExpr, UntypedExpr
 #include "SynTree/Initializer.h"         // for SingleInit, Initializer, Lis...
-#include "SynTree/Label.h"               // for Label, noLabels
+#include "SynTree/Label.h"               // for Label
 #include "SynTree/Mutator.h"             // for maybeMutate, Mutator, mutateAll
 #include "SynTree/Statement.h"           // for ExprStmt, DeclStmt, ReturnStmt
@@ -293,5 +293,5 @@
 		FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ),
 													 functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ),
-													 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ),
+													 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(),
 													 std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) );
 		layoutDecl->fixUniqueId();
@@ -321,5 +321,5 @@
 	/// makes an if-statement with a single-expression if-block and no then block
 	Statement *makeCond( Expression *cond, Expression *ifPart ) {
-		return new IfStmt( noLabels, cond, new ExprStmt( noLabels, ifPart ), 0 );
+		return new IfStmt( cond, new ExprStmt( ifPart ), 0 );
 	}
 
@@ -340,5 +340,5 @@
 	/// adds an expression to a compound statement
 	void addExpr( CompoundStmt *stmts, Expression *expr ) {
-		stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) );
+		stmts->get_kids().push_back( new ExprStmt( expr ) );
 	}
 
@@ -629,5 +629,5 @@
 		ObjectDecl *Pass1::makeTemporary( Type *type ) {
 			ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 );
-			stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
+			stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
 			return newObj;
 		}
@@ -740,9 +740,9 @@
 				ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr );
 				newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
-				stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
+				stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
 				UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
 				assign->get_args().push_back( new VariableExpr( newObj ) );
 				assign->get_args().push_back( arg );
-				stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
+				stmtsToAddBefore.push_back( new ExprStmt( assign ) );
 				arg = new AddressExpr( new VariableExpr( newObj ) );
 			} // if
@@ -888,5 +888,5 @@
 				// void return
 				addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
-				bodyStmt = new ExprStmt( noLabels, adapteeApp );
+				bodyStmt = new ExprStmt( adapteeApp );
 			} else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
 				// return type T
@@ -900,11 +900,11 @@
 				addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
 				assign->get_args().push_back( adapteeApp );
-				bodyStmt = new ExprStmt( noLabels, assign );
+				bodyStmt = new ExprStmt( assign );
 			} else {
 				// adapter for a function that returns a monomorphic value
 				addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
-				bodyStmt = new ReturnStmt( noLabels, adapteeApp );
+				bodyStmt = new ReturnStmt( adapteeApp );
 			} // if
-			CompoundStmt *adapterBody = new CompoundStmt( noLabels );
+			CompoundStmt *adapterBody = new CompoundStmt();
 			adapterBody->get_kids().push_back( bodyStmt );
 			std::string adapterName = makeAdapterName( mangleName );
@@ -952,5 +952,5 @@
 						std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
 						adapter = answer.first;
-						stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) );
+						stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) );
 					} // if
 					assert( adapter != adapters.end() );
@@ -1279,5 +1279,5 @@
 						retval->set_name( "_retval" );
 					}
-					functionDecl->get_statements()->get_kids().push_front( new DeclStmt( noLabels, retval ) );
+					functionDecl->get_statements()->get_kids().push_front( new DeclStmt( retval ) );
 					DeclarationWithType * newRet = retval->clone(); // for ownership purposes
 					ftype->get_returnVals().front() = newRet;
@@ -1519,5 +1519,5 @@
 					// (alloca was previously used, but can't be safely used in loops)
 					ObjectDecl *newBuf = ObjectDecl::newObject( bufNamer.newName(), polyToMonoType( objectDecl->type ), nullptr );
-					stmtsToAddBefore.push_back( new DeclStmt( noLabels, newBuf ) );
+					stmtsToAddBefore.push_back( new DeclStmt( newBuf ) );
 
 					delete objectDecl->get_init();
@@ -1598,5 +1598,5 @@
 		ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) {
 			ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init );
-			stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
+			stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
 			return newObj;
 		}
@@ -1677,5 +1677,5 @@
 					addOtypeParamsToLayoutCall( layoutCall, otypeParams );
 
-					stmtsToAddBefore.push_back( new ExprStmt( noLabels, layoutCall ) );
+					stmtsToAddBefore.push_back( new ExprStmt( layoutCall ) );
 				}
 
@@ -1703,5 +1703,5 @@
 				addOtypeParamsToLayoutCall( layoutCall, otypeParams );
 
-				stmtsToAddBefore.push_back( new ExprStmt( noLabels, layoutCall ) );
+				stmtsToAddBefore.push_back( new ExprStmt( layoutCall ) );
 
 				return true;
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -517,5 +517,5 @@
 					Expression * init = new CastExpr( new AddressExpr( memberExpr ), new PointerType( Type::Qualifiers(), concType->clone() ) );
 					ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), new ReferenceType( Type::Qualifiers(), concType ), new SingleInit( init ) );
-					stmtsToAddBefore.push_back( new DeclStmt( noLabels, tmp ) );
+					stmtsToAddBefore.push_back( new DeclStmt( tmp ) );
 					return new VariableExpr( tmp );
 				} else {
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/GenPoly/Specialize.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -35,5 +35,5 @@
 #include "SynTree/Declaration.h"         // for FunctionDecl, DeclarationWit...
 #include "SynTree/Expression.h"          // for ApplicationExpr, Expression
-#include "SynTree/Label.h"               // for Label, noLabels
+#include "SynTree/Label.h"               // for Label
 #include "SynTree/Mutator.h"             // for mutateAll
 #include "SynTree/Statement.h"           // for CompoundStmt, DeclStmt, Expr...
@@ -234,5 +234,5 @@
 		} // if
 		// create new thunk with same signature as formal type (C linkage, empty body)
-		FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Type::StorageClasses(), LinkageSpec::C, newType, new CompoundStmt( noLabels ) );
+		FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Type::StorageClasses(), LinkageSpec::C, newType, new CompoundStmt() );
 		thunkFunc->fixUniqueId();
 
@@ -287,12 +287,12 @@
 		Statement *appStmt;
 		if ( funType->returnVals.empty() ) {
-			appStmt = new ExprStmt( noLabels, appExpr );
-		} else {
-			appStmt = new ReturnStmt( noLabels, appExpr );
+			appStmt = new ExprStmt( appExpr );
+		} else {
+			appStmt = new ReturnStmt( appExpr );
 		} // if
 		thunkFunc->statements->kids.push_back( appStmt );
 
 		// add thunk definition to queue of statements to add
-		stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) );
+		stmtsToAddBefore.push_back( new DeclStmt( thunkFunc ) );
 		// return address of thunk function as replacement expression
 		return new AddressExpr( new VariableExpr( thunkFunc ) );
Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/InitTweak/FixGlobalInit.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -20,4 +20,5 @@
 #include <algorithm>               // for replace_if
 
+#include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/UniqueName.h"     // for UniqueName
@@ -29,5 +30,5 @@
 #include "SynTree/Expression.h"    // for ConstantExpr, Expression (ptr only)
 #include "SynTree/Initializer.h"   // for ConstructorInit, Initializer
-#include "SynTree/Label.h"         // for Label, noLabels
+#include "SynTree/Label.h"         // for Label
 #include "SynTree/Statement.h"     // for CompoundStmt, Statement (ptr only)
 #include "SynTree/Type.h"          // for Type, Type::StorageClasses, Functi...
@@ -35,15 +36,15 @@
 
 namespace InitTweak {
-	class GlobalFixer : public Visitor {
+	class GlobalFixer : public WithShortCircuiting {
 	  public:
 		GlobalFixer( const std::string & name, bool inLibrary );
 
-		virtual void visit( ObjectDecl *objDecl );
-		virtual void visit( FunctionDecl *functionDecl );
-		virtual void visit( StructDecl *aggregateDecl );
-		virtual void visit( UnionDecl *aggregateDecl );
-		virtual void visit( EnumDecl *aggregateDecl );
-		virtual void visit( TraitDecl *aggregateDecl );
-		virtual void visit( TypeDecl *typeDecl );
+		void previsit( ObjectDecl *objDecl );
+		void previsit( FunctionDecl *functionDecl );
+		void previsit( StructDecl *aggregateDecl );
+		void previsit( UnionDecl *aggregateDecl );
+		void previsit( EnumDecl *aggregateDecl );
+		void previsit( TraitDecl *aggregateDecl );
+		void previsit( TypeDecl *typeDecl );
 
 		UniqueName tempNamer;
@@ -53,6 +54,7 @@
 
 	void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) {
-		GlobalFixer fixer( name, inLibrary );
-		acceptAll( translationUnit, fixer );
+		PassVisitor<GlobalFixer> visitor( name, inLibrary );
+		acceptAll( translationUnit, visitor );
+		GlobalFixer & fixer = visitor.pass;
 		// don't need to include function if it's empty
 		if ( fixer.initFunction->get_statements()->get_kids().empty() ) {
@@ -92,11 +94,11 @@
 			dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
 		}
-		initFunction = new FunctionDecl( "_init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ) );
+		initFunction = new FunctionDecl( "_init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
 		initFunction->get_attributes().push_back( new Attribute( "constructor", ctorParameters ) );
-		destroyFunction = new FunctionDecl( "_destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ) );
+		destroyFunction = new FunctionDecl( "_destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
 		destroyFunction->get_attributes().push_back( new Attribute( "destructor", dtorParameters ) );
 	}
 
-	void GlobalFixer::visit( ObjectDecl *objDecl ) {
+	void GlobalFixer::previsit( ObjectDecl *objDecl ) {
 		std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids();
 		std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
@@ -134,10 +136,10 @@
 
 	// only modify global variables
-	void GlobalFixer::visit( __attribute__((unused)) FunctionDecl *functionDecl ) {}
-	void GlobalFixer::visit( __attribute__((unused)) StructDecl *aggregateDecl ) {}
-	void GlobalFixer::visit( __attribute__((unused)) UnionDecl *aggregateDecl ) {}
-	void GlobalFixer::visit( __attribute__((unused)) EnumDecl *aggregateDecl ) {}
-	void GlobalFixer::visit( __attribute__((unused)) TraitDecl *aggregateDecl ) {}
-	void GlobalFixer::visit( __attribute__((unused)) TypeDecl *typeDecl ) {}
+	void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; }
+	void GlobalFixer::previsit( StructDecl * ) { visit_children = false; }
+	void GlobalFixer::previsit( UnionDecl * ) { visit_children = false; }
+	void GlobalFixer::previsit( EnumDecl * ) { visit_children = false; }
+	void GlobalFixer::previsit( TraitDecl * ) { visit_children = false; }
+	void GlobalFixer::previsit( TypeDecl * ) { visit_children = false; }
 
 } // namespace InitTweak
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/InitTweak/FixInit.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -49,5 +49,5 @@
 #include "SynTree/Expression.h"        // for UniqueExpr, VariableExpr, Unty...
 #include "SynTree/Initializer.h"       // for ConstructorInit, SingleInit
-#include "SynTree/Label.h"             // for Label, noLabels, operator<
+#include "SynTree/Label.h"             // for Label, operator<
 #include "SynTree/Mutator.h"           // for mutateAll, Mutator, maybeMutate
 #include "SynTree/Statement.h"         // for ExprStmt, CompoundStmt, Branch...
@@ -544,13 +544,13 @@
 			// add all temporary declarations and their constructors
 			for ( ObjectDecl * obj : tempDecls ) {
-				stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
+				stmtsToAddBefore.push_back( new DeclStmt( obj ) );
 			} // for
 			for ( ObjectDecl * obj : returnDecls ) {
-				stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
+				stmtsToAddBefore.push_back( new DeclStmt( obj ) );
 			} // for
 
 			// add destructors after current statement
 			for ( Expression * dtor : dtors ) {
-				stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );
+				stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
 			} // for
 
@@ -598,14 +598,14 @@
 			if ( ! result->isVoid() ) {
 				for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
-					stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
+					stmtsToAddBefore.push_back( new DeclStmt( obj ) );
 				} // for
 				// add destructors after current statement
 				for ( Expression * dtor : stmtExpr->get_dtors() ) {
-					stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );
+					stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
 				} // for
 				// must have a non-empty body, otherwise it wouldn't have a result
 				assert( ! stmts.empty() );
 				assert( ! stmtExpr->get_returnDecls().empty() );
-				stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
+				stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
 				stmtExpr->get_returnDecls().clear();
 				stmtExpr->get_dtors().clear();
@@ -685,12 +685,12 @@
 
 						// generate body of if
-						CompoundStmt * initStmts = new CompoundStmt( noLabels );
+						CompoundStmt * initStmts = new CompoundStmt();
 						std::list< Statement * > & body = initStmts->get_kids();
 						body.push_back( ctor );
-						body.push_back( new ExprStmt( noLabels, setTrue ) );
+						body.push_back( new ExprStmt( setTrue ) );
 
 						// put it all together
-						IfStmt * ifStmt = new IfStmt( noLabels, new VariableExpr( isUninitializedVar ), initStmts, 0 );
-						stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) );
+						IfStmt * ifStmt = new IfStmt( new VariableExpr( isUninitializedVar ), initStmts, 0 );
+						stmtsToAddAfter.push_back( new DeclStmt( isUninitializedVar ) );
 						stmtsToAddAfter.push_back( ifStmt );
 
@@ -707,5 +707,5 @@
 
 							// void __objName_dtor_atexitN(...) {...}
-							FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ) );
+							FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
 							dtorCaller->fixUniqueId();
 							dtorCaller->get_statements()->push_back( dtorStmt );
@@ -715,5 +715,5 @@
 							callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
 
-							body.push_back( new ExprStmt( noLabels, callAtexit ) );
+							body.push_back( new ExprStmt( callAtexit ) );
 
 							// hoist variable and dtor caller decls to list of decls that will be added into global scope
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/InitTweak/InitTweak.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -5,4 +5,5 @@
 #include <memory>                  // for __shared_ptr
 
+#include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/UniqueName.h"     // for UniqueName
@@ -19,5 +20,5 @@
 #include "SynTree/Expression.h"    // for Expression, UntypedExpr, Applicati...
 #include "SynTree/Initializer.h"   // for Initializer, ListInit, Designation
-#include "SynTree/Label.h"         // for Label, noLabels
+#include "SynTree/Label.h"         // for Label
 #include "SynTree/Statement.h"     // for CompoundStmt, ExprStmt, BranchStmt
 #include "SynTree/Type.h"          // for FunctionType, ArrayType, PointerType
@@ -29,15 +30,23 @@
 namespace InitTweak {
 	namespace {
-		class HasDesignations : public Visitor {
-		public:
+		struct HasDesignations : public WithShortCircuiting {
 			bool hasDesignations = false;
-			virtual void visit( Designation * des ) {
-				if ( ! des->get_designators().empty() ) hasDesignations = true;
-				else Visitor::visit( des );
+
+			void previsit( BaseSyntaxNode * ) {
+				// short circuit if we already know there are designations
+				if ( hasDesignations ) visit_children = false;
+			}
+
+			void previsit( Designation * des ) {
+				// short circuit if we already know there are designations
+				if ( hasDesignations ) visit_children = false;
+				else if ( ! des->get_designators().empty() ) {
+					hasDesignations = true;
+					visit_children = false;
+				}
 			}
 		};
 
-		class InitDepthChecker : public Visitor {
-		public:
+		struct InitDepthChecker : public WithGuards {
 			bool depthOkay = true;
 			Type * type;
@@ -51,48 +60,37 @@
 				maxDepth++;
 			}
-			virtual void visit( ListInit * listInit ) {
+			void previsit( ListInit * ) {
 				curDepth++;
+				GuardAction( [this]() { curDepth--; } );
 				if ( curDepth > maxDepth ) depthOkay = false;
-				Visitor::visit( listInit );
-				curDepth--;
 			}
 		};
 
-		class InitFlattener : public Visitor {
-			public:
-			virtual void visit( SingleInit * singleInit );
-			virtual void visit( ListInit * listInit );
+		struct InitFlattener : public WithShortCircuiting {
+			void previsit( SingleInit * singleInit ) {
+				visit_children = false;
+				argList.push_back( singleInit->value->clone() );
+			}
 			std::list< Expression * > argList;
 		};
 
-		void InitFlattener::visit( SingleInit * singleInit ) {
-			argList.push_back( singleInit->get_value()->clone() );
-		}
-
-		void InitFlattener::visit( ListInit * listInit ) {
-			// flatten nested list inits
-			std::list<Initializer*>::iterator it = listInit->begin();
-			for ( ; it != listInit->end(); ++it ) {
-				(*it)->accept( *this );
-			}
-		}
 	}
 
 	std::list< Expression * > makeInitList( Initializer * init ) {
-		InitFlattener flattener;
+		PassVisitor<InitFlattener> flattener;
 		maybeAccept( init, flattener );
-		return flattener.argList;
+		return flattener.pass.argList;
 	}
 
 	bool isDesignated( Initializer * init ) {
-		HasDesignations finder;
+		PassVisitor<HasDesignations> finder;
 		maybeAccept( init, finder );
-		return finder.hasDesignations;
+		return finder.pass.hasDesignations;
 	}
 
 	bool checkInitDepth( ObjectDecl * objDecl ) {
-		InitDepthChecker checker( objDecl->get_type() );
-		maybeAccept( objDecl->get_init(), checker );
-		return checker.depthOkay;
+		PassVisitor<InitDepthChecker> checker( objDecl->type );
+		maybeAccept( objDecl->init, checker );
+		return checker.pass.depthOkay;
 	}
 
@@ -195,9 +193,9 @@
 			callExpr->get_args().splice( callExpr->get_args().end(), args );
 
-			*out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr );
+			*out++ = new IfStmt( cond, new ExprStmt( callExpr ), nullptr );
 
 			UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) );
 			increment->get_args().push_back( index->clone() );
-			*out++ = new ExprStmt( noLabels, increment );
+			*out++ = new ExprStmt( increment );
 		}
 
@@ -244,10 +242,10 @@
 					std::list< Statement * > stmts;
 					build( callExpr, idx, idxEnd, init, back_inserter( stmts ) );
-					stmts.push_back( new BranchStmt( noLabels, switchLabel, BranchStmt::Break ) );
-					CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts );
+					stmts.push_back( new BranchStmt( switchLabel, BranchStmt::Break ) );
+					CaseStmt * caseStmt = new CaseStmt( condition, stmts );
 					branches.push_back( caseStmt );
 				}
-				*out++ = new SwitchStmt( noLabels, index->clone(), branches );
-				*out++ = new NullStmt( std::list<Label>{ switchLabel } );
+				*out++ = new SwitchStmt( index->clone(), branches );
+				*out++ = new NullStmt( { switchLabel } );
 			}
 		}
@@ -262,5 +260,5 @@
 	Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
 		if ( ! init ) return nullptr;
-		CompoundStmt * block = new CompoundStmt( noLabels );
+		CompoundStmt * block = new CompoundStmt();
 		build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
 		if ( block->get_kids().empty() ) {
@@ -309,14 +307,12 @@
 	}
 
-	class CallFinder : public Visitor {
-	public:
-		typedef Visitor Parent;
+	struct CallFinder {
 		CallFinder( const std::list< std::string > & names ) : names( names ) {}
 
-		virtual void visit( ApplicationExpr * appExpr ) {
+		void postvisit( ApplicationExpr * appExpr ) {
 			handleCallExpr( appExpr );
 		}
 
-		virtual void visit( UntypedExpr * untypedExpr ) {
+		void postvisit( UntypedExpr * untypedExpr ) {
 			handleCallExpr( untypedExpr );
 		}
@@ -328,5 +324,4 @@
 		template< typename CallExpr >
 		void handleCallExpr( CallExpr * expr ) {
-			Parent::visit( expr );
 			std::string fname = getFunctionName( expr );
 			if ( std::find( names.begin(), names.end(), fname ) != names.end() ) {
@@ -337,6 +332,6 @@
 
 	void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) {
-		static CallFinder finder( std::list< std::string >{ "?{}", "^?{}" } );
-		finder.matches = &matches;
+		static PassVisitor<CallFinder> finder( std::list< std::string >{ "?{}", "^?{}" } );
+		finder.pass.matches = &matches;
 		maybeAccept( stmt, finder );
 	}
@@ -544,48 +539,37 @@
 	}
 
-	class ConstExprChecker : public Visitor {
-	public:
-		ConstExprChecker() : isConstExpr( true ) {}
-
-		using Visitor::visit;
-
-		virtual void visit( ApplicationExpr * ) { isConstExpr = false; }
-		virtual void visit( UntypedExpr * ) { isConstExpr = false; }
-		virtual void visit( NameExpr * ) { isConstExpr = false; }
-		// virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
-		virtual void visit( AddressExpr *addressExpr ) {
+	struct ConstExprChecker : public WithShortCircuiting {
+		// most expressions are not const expr
+		void previsit( Expression * ) { isConstExpr = false; visit_children = false; }
+
+		void previsit( AddressExpr *addressExpr ) {
+			visit_children = false;
+
 			// address of a variable or member expression is constexpr
 			Expression * arg = addressExpr->get_arg();
 			if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false;
 		}
-		virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; }
-		virtual void visit( MemberExpr * ) { isConstExpr = false; }
-		virtual void visit( VariableExpr * ) { isConstExpr = false; }
-		// these might be okay?
-		// virtual void visit( SizeofExpr *sizeofExpr );
-		// virtual void visit( AlignofExpr *alignofExpr );
-		// virtual void visit( UntypedOffsetofExpr *offsetofExpr );
-		// virtual void visit( OffsetofExpr *offsetofExpr );
-		// virtual void visit( OffsetPackExpr *offsetPackExpr );
-		// virtual void visit( AttrExpr *attrExpr );
-		// virtual void visit( CommaExpr *commaExpr );
-		// virtual void visit( LogicalExpr *logicalExpr );
-		// virtual void visit( ConditionalExpr *conditionalExpr );
-		virtual void visit( TypeExpr * ) { isConstExpr = false; }
-		virtual void visit( AsmExpr * ) { isConstExpr = false; }
-		virtual void visit( UntypedValofExpr * ) { isConstExpr = false; }
-		virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; }
-		virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; }
-		virtual void visit( TupleExpr * ) { isConstExpr = false; }
-		virtual void visit( TupleAssignExpr * ) { isConstExpr = false; }
-
-		bool isConstExpr;
+
+		// these expressions may be const expr, depending on their children
+		void previsit( SizeofExpr * ) {}
+		void previsit( AlignofExpr * ) {}
+		void previsit( UntypedOffsetofExpr * ) {}
+		void previsit( OffsetofExpr * ) {}
+		void previsit( OffsetPackExpr * ) {}
+		void previsit( AttrExpr * ) {}
+		void previsit( CommaExpr * ) {}
+		void previsit( LogicalExpr * ) {}
+		void previsit( ConditionalExpr * ) {}
+		void previsit( CastExpr * ) {}
+		void previsit( ConstantExpr * ) {}
+
+		bool isConstExpr = true;
 	};
 
 	bool isConstExpr( Expression * expr ) {
 		if ( expr ) {
-			ConstExprChecker checker;
+			PassVisitor<ConstExprChecker> checker;
 			expr->accept( checker );
-			return checker.isConstExpr;
+			return checker.pass.isConstExpr;
 		}
 		return true;
@@ -594,7 +578,7 @@
 	bool isConstExpr( Initializer * init ) {
 		if ( init ) {
-			ConstExprChecker checker;
+			PassVisitor<ConstExprChecker> checker;
 			init->accept( checker );
-			return checker.isConstExpr;
+			return checker.pass.isConstExpr;
 		} // if
 		// for all intents and purposes, no initializer means const expr
Index: src/MakeLibCfa.cc
===================================================================
--- src/MakeLibCfa.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/MakeLibCfa.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -116,5 +116,5 @@
 			} // for
 
-			funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
+			funcDecl->set_statements( new CompoundStmt() );
 			newDecls.push_back( funcDecl );
 
@@ -130,10 +130,10 @@
 			  case CodeGen::OT_INFIXASSIGN:
 					// return the recursive call
-					stmt = new ReturnStmt( noLabels, newExpr );
+					stmt = new ReturnStmt( newExpr );
 					break;
 			  case CodeGen::OT_CTOR:
 			  case CodeGen::OT_DTOR:
 					// execute the recursive call
-					stmt = new ExprStmt( noLabels, newExpr );
+					stmt = new ExprStmt( newExpr );
 					break;
 			  case CodeGen::OT_CONSTANT:
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/Makefile.in	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -215,6 +215,4 @@
 	SymTab/driver_cfa_cpp-Validate.$(OBJEXT) \
 	SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT) \
-	SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) \
-	SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT) \
 	SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Type.$(OBJEXT) \
@@ -514,6 +512,5 @@
 	ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \
 	SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
-	SymTab/FixFunction.cc SymTab/ImplementationType.cc \
-	SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \
+	SymTab/FixFunction.cc SymTab/Autogen.cc SynTree/Type.cc \
 	SynTree/VoidType.cc SynTree/BasicType.cc \
 	SynTree/PointerType.cc SynTree/ArrayType.cc \
@@ -844,8 +841,4 @@
 SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT): SymTab/$(am__dirstamp) \
 	SymTab/$(DEPDIR)/$(am__dirstamp)
-SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT):  \
-	SymTab/$(am__dirstamp) SymTab/$(DEPDIR)/$(am__dirstamp)
-SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \
-	SymTab/$(DEPDIR)/$(am__dirstamp)
 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
 	SymTab/$(DEPDIR)/$(am__dirstamp)
@@ -1040,8 +1033,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@
@@ -2039,32 +2030,4 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-FixFunction.obj `if test -f 'SymTab/FixFunction.cc'; then $(CYGPATH_W) 'SymTab/FixFunction.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/FixFunction.cc'; fi`
-
-SymTab/driver_cfa_cpp-ImplementationType.o: SymTab/ImplementationType.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-ImplementationType.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo -c -o SymTab/driver_cfa_cpp-ImplementationType.o `test -f 'SymTab/ImplementationType.cc' || echo '$(srcdir)/'`SymTab/ImplementationType.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SymTab/ImplementationType.cc' object='SymTab/driver_cfa_cpp-ImplementationType.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-ImplementationType.o `test -f 'SymTab/ImplementationType.cc' || echo '$(srcdir)/'`SymTab/ImplementationType.cc
-
-SymTab/driver_cfa_cpp-ImplementationType.obj: SymTab/ImplementationType.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-ImplementationType.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo -c -o SymTab/driver_cfa_cpp-ImplementationType.obj `if test -f 'SymTab/ImplementationType.cc'; then $(CYGPATH_W) 'SymTab/ImplementationType.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/ImplementationType.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SymTab/ImplementationType.cc' object='SymTab/driver_cfa_cpp-ImplementationType.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-ImplementationType.obj `if test -f 'SymTab/ImplementationType.cc'; then $(CYGPATH_W) 'SymTab/ImplementationType.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/ImplementationType.cc'; fi`
-
-SymTab/driver_cfa_cpp-TypeEquality.o: SymTab/TypeEquality.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-TypeEquality.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo -c -o SymTab/driver_cfa_cpp-TypeEquality.o `test -f 'SymTab/TypeEquality.cc' || echo '$(srcdir)/'`SymTab/TypeEquality.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SymTab/TypeEquality.cc' object='SymTab/driver_cfa_cpp-TypeEquality.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-TypeEquality.o `test -f 'SymTab/TypeEquality.cc' || echo '$(srcdir)/'`SymTab/TypeEquality.cc
-
-SymTab/driver_cfa_cpp-TypeEquality.obj: SymTab/TypeEquality.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-TypeEquality.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo -c -o SymTab/driver_cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SymTab/TypeEquality.cc' object='SymTab/driver_cfa_cpp-TypeEquality.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`
 
 SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/Parser/StatementNode.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -37,5 +37,5 @@
 	DeclarationNode *agg = decl->extractAggregate();
 	if ( agg ) {
-		StatementNode *nextStmt = new StatementNode( new DeclStmt( noLabels, maybeBuild< Declaration >( decl ) ) );
+		StatementNode *nextStmt = new StatementNode( new DeclStmt( maybeBuild< Declaration >( decl ) ) );
 		set_next( nextStmt );
 		if ( decl->get_next() ) {
@@ -50,5 +50,5 @@
 		agg = decl;
 	} // if
-	stmt.reset( new DeclStmt( noLabels, maybeMoveBuild< Declaration >(agg) ) );
+	stmt.reset( new DeclStmt( maybeMoveBuild< Declaration >(agg) ) );
 } // StatementNode::StatementNode
 
@@ -75,7 +75,7 @@
 
 	if ( e )
-		return new ExprStmt( noLabels, e );
+		return new ExprStmt( e );
 	else
-		return new NullStmt( noLabels );
+		return new NullStmt();
 }
 
@@ -113,5 +113,5 @@
 	}
 	delete ctl;
-	return new IfStmt( noLabels, cond, thenb, elseb, init );
+	return new IfStmt( cond, thenb, elseb, init );
 }
 
@@ -120,13 +120,13 @@
 	buildMoveList< Statement, StatementNode >( stmt, branches );
 	// branches.size() == 0 for switch (...) {}, i.e., no declaration or statements
-	return new SwitchStmt( noLabels, maybeMoveBuild< Expression >(ctl), branches );
+	return new SwitchStmt( maybeMoveBuild< Expression >(ctl), branches );
 }
 Statement *build_case( ExpressionNode *ctl ) {
 	std::list< Statement * > branches;
-	return new CaseStmt( noLabels, maybeMoveBuild< Expression >(ctl), branches );
+	return new CaseStmt( maybeMoveBuild< Expression >(ctl), branches );
 }
 Statement *build_default() {
 	std::list< Statement * > branches;
-	return new CaseStmt( noLabels, nullptr, branches, true );
+	return new CaseStmt( nullptr, branches, true );
 }
 
@@ -135,5 +135,5 @@
 	buildMoveList< Statement, StatementNode >( stmt, branches );
 	assert( branches.size() == 1 );
-	return new WhileStmt( noLabels, notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind );
+	return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind );
 }
 
@@ -157,18 +157,18 @@
 
 	delete forctl;
-	return new ForStmt( noLabels, init, cond, incr, branches.front() );
+	return new ForStmt( init, cond, incr, branches.front() );
 }
 
 Statement *build_branch( BranchStmt::Type kind ) {
-	Statement * ret = new BranchStmt( noLabels, "", kind );
+	Statement * ret = new BranchStmt( "", kind );
 	return ret;
 }
 Statement *build_branch( std::string *identifier, BranchStmt::Type kind ) {
-	Statement * ret = new BranchStmt( noLabels, *identifier, kind );
+	Statement * ret = new BranchStmt( *identifier, kind );
 	delete identifier; 									// allocated by lexer
 	return ret;
 }
 Statement *build_computedgoto( ExpressionNode *ctl ) {
-	return new BranchStmt( noLabels, maybeMoveBuild< Expression >(ctl), BranchStmt::Goto );
+	return new BranchStmt( maybeMoveBuild< Expression >(ctl), BranchStmt::Goto );
 }
 
@@ -176,5 +176,5 @@
 	std::list< Expression * > exps;
 	buildMoveList( ctl, exps );
-	return new ReturnStmt( noLabels, exps.size() > 0 ? exps.back() : nullptr );
+	return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr );
 }
 
@@ -183,5 +183,5 @@
 	buildMoveList( ctl, exps );
 	assertf( exps.size() < 2, "This means we are leaking memory");
-	return new ThrowStmt( noLabels, ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
+	return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
 }
 
@@ -190,5 +190,5 @@
 	buildMoveList( ctl, exps );
 	assertf( exps.size() < 2, "This means we are leaking memory");
-	return new ThrowStmt( noLabels, ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
+	return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
 }
 
@@ -204,5 +204,5 @@
 	CompoundStmt *tryBlock = strict_dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_stmt));
 	FinallyStmt *finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_stmt) );
-	return new TryStmt( noLabels, tryBlock, branches, finallyBlock );
+	return new TryStmt( tryBlock, branches, finallyBlock );
 }
 Statement *build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body ) {
@@ -210,5 +210,5 @@
 	buildMoveList< Statement, StatementNode >( body, branches );
 	assert( branches.size() == 1 );
-	return new CatchStmt( noLabels, kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() );
+	return new CatchStmt( kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() );
 }
 Statement *build_finally( StatementNode *stmt ) {
@@ -216,5 +216,5 @@
 	buildMoveList< Statement, StatementNode >( stmt, branches );
 	assert( branches.size() == 1 );
-	return new FinallyStmt( noLabels, dynamic_cast< CompoundStmt * >( branches.front() ) );
+	return new FinallyStmt( dynamic_cast< CompoundStmt * >( branches.front() ) );
 }
 
@@ -296,5 +296,5 @@
 
 Statement *build_compound( StatementNode *first ) {
-	CompoundStmt *cs = new CompoundStmt( noLabels );
+	CompoundStmt *cs = new CompoundStmt();
 	buildMoveList( first, cs->get_kids() );
 	return cs;
@@ -308,5 +308,5 @@
 	buildMoveList( input, in );
 	buildMoveList( clobber, clob );
-	return new AsmStmt( noLabels, voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
+	return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
 }
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/ResolvExpr/Resolver.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -370,5 +370,5 @@
 		if ( throwStmt->get_expr() ) {
 			StructDecl * exception_decl =
-				indexer.lookupStruct( "__cfaehm__base_exception_t" );
+				indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
 			assert( exception_decl );
 			Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
Index: src/SymTab/AddVisit.h
===================================================================
--- src/SymTab/AddVisit.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SymTab/AddVisit.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -24,5 +24,5 @@
 			// add any new declarations after the previous statement
 			for ( std::list< Declaration* >::iterator decl = visitor.declsToAddAfter.begin(); decl != visitor.declsToAddAfter.end(); ++decl ) {
-				DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
+				DeclStmt *declStmt = new DeclStmt( *decl );
 				stmts.insert( stmt, declStmt );
 			}
@@ -36,5 +36,5 @@
 			// add any new declarations before the statement
 			for ( std::list< Declaration* >::iterator decl = visitor.declsToAdd.begin(); decl != visitor.declsToAdd.end(); ++decl ) {
-				DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
+				DeclStmt *declStmt = new DeclStmt( *decl );
 				stmts.insert( stmt, declStmt );
 			}
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SymTab/Autogen.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -264,5 +264,5 @@
 		Type::StorageClasses scs = functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static );
 		LinkageSpec::Spec spec = isIntrinsic ? LinkageSpec::Intrinsic : LinkageSpec::AutoGen;
-		FunctionDecl * decl = new FunctionDecl( fname, scs, spec, ftype, new CompoundStmt( noLabels ),
+		FunctionDecl * decl = new FunctionDecl( fname, scs, spec, ftype, new CompoundStmt(),
 												std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) );
 		decl->fixUniqueId();
@@ -299,5 +299,5 @@
 				assert( assignType->returnVals.size() == 1 );
 				ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.front() );
-				dcl->statements->push_back( new ReturnStmt( noLabels, new VariableExpr( dstParam ) ) );
+				dcl->statements->push_back( new ReturnStmt( new VariableExpr( dstParam ) ) );
 			}
 			resolve( dcl );
@@ -468,5 +468,5 @@
 		copy->args.push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
 		copy->args.push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
-		*out++ = new ExprStmt( noLabels, copy );
+		*out++ = new ExprStmt( copy );
 	}
 
@@ -544,5 +544,5 @@
 			callExpr->get_args().push_back( new VariableExpr( dstParam ) );
 			callExpr->get_args().push_back( new VariableExpr( srcParam ) );
-			funcDecl->statements->push_back( new ExprStmt( noLabels, callExpr ) );
+			funcDecl->statements->push_back( new ExprStmt( callExpr ) );
 		} else {
 			// default ctor/dtor body is empty - add unused attribute to parameter to silence warnings
@@ -569,5 +569,5 @@
 		expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) );
 		if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) );
-		dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) );
+		dcl->statements->kids.push_back( new ExprStmt( expr ) );
 	};
 
@@ -664,6 +664,6 @@
 			untyped->get_args().push_back( new VariableExpr( ftype->get_parameters().back() ) );
 		}
-		function->get_statements()->get_kids().push_back( new ExprStmt( noLabels, untyped ) );
-		function->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) );
+		function->get_statements()->get_kids().push_back( new ExprStmt( untyped ) );
+		function->get_statements()->get_kids().push_back( new ReturnStmt( UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) );
 	}
 
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SymTab/Autogen.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -104,5 +104,5 @@
 		fExpr->args.splice( fExpr->args.end(), args );
 
-		*out++ = new ExprStmt( noLabels, fExpr );
+		*out++ = new ExprStmt( fExpr );
 
 		srcParam.clearArrayIndices();
@@ -162,13 +162,13 @@
 
 		// for stmt's body, eventually containing call
-		CompoundStmt * body = new CompoundStmt( noLabels );
+		CompoundStmt * body = new CompoundStmt();
 		Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->kids ), array->base, addCast, forward );
 
 		// block containing for stmt and index variable
 		std::list<Statement *> initList;
-		CompoundStmt * block = new CompoundStmt( noLabels );
-		block->push_back( new DeclStmt( noLabels, index ) );
+		CompoundStmt * block = new CompoundStmt();
+		block->push_back( new DeclStmt( index ) );
 		if ( listInit ) block->get_kids().push_back( listInit );
-		block->push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
+		block->push_back( new ForStmt( initList, cond, inc, body ) );
 
 		*out++ = block;
Index: c/SymTab/ImplementationType.cc
===================================================================
--- src/SymTab/ImplementationType.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,114 +1,0 @@
-//
-// 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.
-//
-// ImplementationType.cc --
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 21:32:01 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Mar 16 15:54:08 2017
-// Update Count     : 4
-//
-
-#include "ImplementationType.h"
-
-#include <list>                   // for list, _List_iterator, list<>::iterator
-
-#include "SymTab/Indexer.h"       // for Indexer
-#include "SynTree/Declaration.h"  // for NamedTypeDecl
-#include "SynTree/Type.h"         // for TupleType, Type, ArrayType, Pointer...
-#include "SynTree/Visitor.h"      // for Visitor
-
-
-namespace SymTab {
-	class ImplementationType : public Visitor {
-	  public:
-		ImplementationType( const SymTab::Indexer &indexer );
-
-		Type *get_result() { return result; }
-	  private:
-		virtual void visit(VoidType *voidType);
-		virtual void visit(BasicType *basicType);
-		virtual void visit(PointerType *pointerType);
-		virtual void visit(ArrayType *arrayType);
-		virtual void visit(FunctionType *functionType);
-		virtual void visit(StructInstType *aggregateUseType);
-		virtual void visit(UnionInstType *aggregateUseType);
-		virtual void visit(EnumInstType *aggregateUseType);
-		virtual void visit(TraitInstType *aggregateUseType);
-		virtual void visit(TypeInstType *aggregateUseType);
-		virtual void visit(TupleType *tupleType);
-		virtual void visit(VarArgsType *varArgsType);
-		virtual void visit(ZeroType *zeroType);
-		virtual void visit(OneType *oneType);
-
-		Type *result;			// synthesized
-		const SymTab::Indexer &indexer;
-	};
-
-	Type * implementationType( Type *type, const SymTab::Indexer& indexer ) {
-		ImplementationType implementor( indexer );
-		type->accept( implementor );
-		if ( implementor.get_result() == 0 ) {
-			return type->clone();
-		} else {
-			return implementor.get_result();
-		} // if
-	}
-
-	ImplementationType::ImplementationType( const SymTab::Indexer &indexer ) : result( 0 ), indexer( indexer ) {
-	}
-
-	void ImplementationType::visit( __attribute__((unused)) VoidType *voidType ) {}
-	void ImplementationType::visit( __attribute__((unused)) BasicType *basicType ) {}
-
-	void ImplementationType::visit(PointerType *pointerType) {
-		PointerType *newType = pointerType->clone();
-		newType->set_base( implementationType( pointerType->get_base(), indexer ) );
-		result = newType;
-	}
-
-	void ImplementationType::visit(ArrayType *arrayType) {
-		ArrayType *newType = arrayType->clone();
-		newType->set_base( implementationType( arrayType->get_base(), indexer ) );
-		result = newType;
-	}
-
-	void ImplementationType::visit( __attribute__((unused)) FunctionType *functionType ) {}
-	void ImplementationType::visit( __attribute__((unused)) StructInstType * aggregateUseType ) {}
-	void ImplementationType::visit( __attribute__((unused)) UnionInstType * aggregateUseType ) {}
-	void ImplementationType::visit( __attribute__((unused)) EnumInstType * aggregateUseType ) {}
-	void ImplementationType::visit( __attribute__((unused)) TraitInstType * aggregateUseType ) {}
-
-	void ImplementationType::visit(TypeInstType *inst) {
-		NamedTypeDecl *typeDecl = indexer.lookupType( inst->get_name() );
-		if ( typeDecl && typeDecl->get_base() ) {
-			Type *base = implementationType( typeDecl->get_base(), indexer );
-			base->get_qualifiers() |= inst->get_qualifiers();
-			result = base;
-		} // if
-	}
-
-	void ImplementationType::visit(TupleType *tupleType) {
-		std::list< Type * > types;
-		for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
-			Type *implType = implementationType( *i, indexer );
-			implType->get_qualifiers() |= tupleType->get_qualifiers();
-			types.push_back( implType );
-		} // for
-		result = new TupleType( Type::Qualifiers(), types );
-	}
-
-	void ImplementationType::visit( __attribute__((unused)) VarArgsType *varArgsType ) {}
-	void ImplementationType::visit( __attribute__((unused)) ZeroType *zeroType ) {}
-	void ImplementationType::visit( __attribute__((unused)) OneType *oneType ) {}
-} // namespace SymTab
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: c/SymTab/ImplementationType.h
===================================================================
--- src/SymTab/ImplementationType.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,37 +1,0 @@
-//
-// 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.
-//
-// ImplementationType.h -- 
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 21:35:41 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:46:19 2017
-// Update Count     : 3
-//
-
-#pragma once
-
-class Type;
-
-namespace SymTab {
-class Indexer;
-
-	Type *implementationType( Type *, const SymTab::Indexer &indexer );
-
-	template< typename InputIterator, typename OutputIterator >
-	void implementationTypeList( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer ) {
-		while ( begin != end ) {
-			*out++ = implementationType( *begin++, indexer );
-		} // while
-	}
-} // namespace SymTab
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: c/SymTab/TypeEquality.cc
===================================================================
--- src/SymTab/TypeEquality.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,218 +1,0 @@
-//
-// 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.
-//
-// TypeEquality.cc --
-//
-// Author           : Rob Schluntz
-// Created On       : Tue Jul 07 16:28:29 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Mon Jul 20 14:16:11 2015
-// Update Count     : 37
-//
-#include "TypeEquality.h"
-
-#include <cassert>                // for assert
-#include <list>                   // for list, list<>::iterator, _List_iterator
-#include <string>                 // for operator==, string, basic_string
-
-#include "SynTree/Constant.h"     // for Constant
-#include "SynTree/Declaration.h"  // for DeclarationWithType
-#include "SynTree/Expression.h"   // for ConstantExpr, Expression
-#include "SynTree/Type.h"         // for Type, ArrayType, FunctionType, Enum...
-#include "SynTree/Visitor.h"      // for Visitor
-
-namespace SymTab {
-	class TypeEquality : public Visitor {
-  public:
-		TypeEquality( Type * other, bool vlaErr ) : result( true ), other( other ),
-			vlaErr( vlaErr ) {}
-		bool result;
-
-  private:
-		virtual void visit( FunctionType *funcType );
-		virtual void visit( VoidType *voidType );
-		virtual void visit( BasicType *basicType );
-		virtual void visit( PointerType *pointerType );
-		virtual void visit( ArrayType *arrayType );
-		virtual void visit( StructInstType *structInst );
-		virtual void visit( UnionInstType *unionInst );
-		virtual void visit( EnumInstType *enumInst );
-		virtual void visit( TypeInstType *typeInst );
-		virtual void visit( VarArgsType *varArgsType );
-		virtual void visit( ZeroType *zeroType );
-		virtual void visit( OneType *oneType );
-
-		void handleQualifiers( Type * t );
-
-		Type * other;
-		bool vlaErr;
-	};
-
-	bool typeEquals( Type * t1, Type * t2, bool vlaErr ) {
-		TypeEquality teq( t2, vlaErr );
-		t1->accept( teq );
-		return teq.result;
-	}
-
-	void TypeEquality::handleQualifiers( Type * t ) {
-		result = result && t->get_qualifiers() == other->get_qualifiers();
-	}
-
-	void TypeEquality::visit( VoidType *voidType ) {
-		handleQualifiers( voidType );
-		if ( ! dynamic_cast< VoidType * >( other ) ) {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( BasicType *basicType ) {
-		handleQualifiers( basicType );
-		if ( BasicType * bt = dynamic_cast< BasicType * >( other ) ) {
-			result = result && basicType->get_kind() == bt->get_kind();
-		} else {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( PointerType *pointerType ) {
-		handleQualifiers( pointerType );
-		if ( PointerType * pt = dynamic_cast< PointerType * >( other ) ) {
-			other = pt->get_base();
-			pointerType->get_base()->accept( *this );
-		} else {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( ArrayType *arrayType ) {
-		handleQualifiers( arrayType );
-
-		if ( ArrayType * at = dynamic_cast< ArrayType * >( other ) ) {
-			// to be equal, array types must both be VLA or both not VLA
-			// and must both have a dimension expression or not have a dimension
-			result = result	&& arrayType->get_isVarLen() == at->get_isVarLen()
-				&& ((arrayType->get_dimension() != 0 && at->get_dimension() != 0)
-					|| (arrayType->get_dimension() == 0 && at->get_dimension() == 0));
-
-			if ( vlaErr ) {
-				// useful for comparing typedef types - in this case, we
-				// want types to appear distinct if either is a VLA type
-				if ( arrayType->get_isVarLen() || at->get_isVarLen() ) {
-					result = false;
-				}
-			}
-
-			if ( ! arrayType->get_isVarLen() && ! at->get_isVarLen() &&
-				arrayType->get_dimension() != 0 && at->get_dimension() != 0 ) {
-				ConstantExpr * ce1 = dynamic_cast< ConstantExpr * >( arrayType->get_dimension() );
-				ConstantExpr * ce2 = dynamic_cast< ConstantExpr * >( at->get_dimension() );
-				assert(ce1 && ce2);
-
-				Constant * c1 = ce1->get_constant();
-				Constant * c2 = ce2->get_constant();
-
-				result = result && c1->get_value() == c2->get_value();
-			}
-
-			other = at->get_base();
-			arrayType->get_base()->accept( *this );
-		} else {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( FunctionType *funcType ) {
-		handleQualifiers( funcType );
-
-		if ( FunctionType * ft = dynamic_cast< FunctionType * >( other ) ) {
-			// function types must have the same number of return types
-			// and parameters to be equivalent
-			result = result && funcType->get_returnVals().size() == ft->get_returnVals().size()
-				&& funcType->get_parameters().size() == ft->get_parameters().size()
-				&& funcType->get_isVarArgs() == ft->get_isVarArgs();
-
-			std::list< DeclarationWithType * >::iterator it1, it2;
-
-			// return types must be equivalent
-			it1 = funcType->get_returnVals().begin();
-			it2 = ft->get_returnVals().begin();
-			for ( ; it1 != funcType->get_returnVals().end(); ++it1, ++it2 ) {
-				if ( ! result ) return;
-				other = (*it2)->get_type();
-				(*it1)->get_type()->accept( *this );
-			}
-
-			// parameter types must be equivalent
-			it1 = funcType->get_parameters().begin();
-			it2 = ft->get_parameters().begin();
-			for ( ; it1 != funcType->get_parameters().end(); ++it1, ++it2 ) {
-				if ( ! result ) return;
-				other = (*it2)->get_type();
-				(*it1)->get_type()->accept( *this );
-			}
-		} else {
-			result = false;
-		}
-	}
-
-	// aggregate types only need to have the same name
-	void TypeEquality::visit( StructInstType *structInst )  {
-		handleQualifiers( structInst );
-		if ( StructInstType * st = dynamic_cast< StructInstType * >( other ) ) {
-			result = result && structInst->get_name() == st->get_name();
-		} else {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( UnionInstType *unionInst ) {
-		handleQualifiers( unionInst );
-		if ( UnionInstType * ut = dynamic_cast< UnionInstType * >( other ) ) {
-			result = result && unionInst->get_name() == ut->get_name();
-		} else {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( EnumInstType *enumInst ) {
-		handleQualifiers( enumInst );
-		if ( EnumInstType * et = dynamic_cast< EnumInstType * >( other ) ) {
-			result = result && enumInst->get_name() == et->get_name();
-		} else {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( TypeInstType *typeInst ) {
-		handleQualifiers( typeInst );
-		if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( other ) ) {
-			result = result && typeInst->get_name() == tt->get_name();
-		} else {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( VarArgsType *varArgsType ) {
-		handleQualifiers( varArgsType );
-		if ( ! dynamic_cast< VarArgsType * >( other ) ) {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( ZeroType *zeroType ) {
-		handleQualifiers( zeroType );
-		if ( ! dynamic_cast< ZeroType * >( other ) ) {
-			result = false;
-		}
-	}
-
-	void TypeEquality::visit( OneType *oneType ) {
-		handleQualifiers( oneType );
-		if ( ! dynamic_cast< OneType * >( other ) ) {
-			result = false;
-		}
-	}
-} // namespace SymTab
Index: c/SymTab/TypeEquality.h
===================================================================
--- src/SymTab/TypeEquality.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,23 +1,0 @@
-//
-// 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.
-//
-// TypeEquality.h --
-//
-// Author           : Rob Schluntz
-// Created On       : Tue Jul 07 16:30:07 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Wed Jul 08 12:41:15 2015
-// Update Count     : 6
-//
-
-class Type;
-
-namespace SymTab {
-  // compare types t1 and t2 for equality
-  // if vlaErr is true, then if at least one of the types is a
-  // variable-length array type, then the result will be false
-  bool typeEquals( Type * t1, Type * t2, bool vlaErr = false );
-} // namespace SymTab
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SymTab/Validate.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -81,30 +81,18 @@
 
 namespace SymTab {
-	class HoistStruct final : public Visitor {
-		template< typename Visitor >
-		friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
-	    template< typename Visitor >
-	    friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor );
-	  public:
+	struct HoistStruct final : public WithDeclsToAdd, public WithGuards {
 		/// Flattens nested struct types
 		static void hoistStruct( std::list< Declaration * > &translationUnit );
 
-		std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
-
-		virtual void visit( EnumInstType *enumInstType );
-		virtual void visit( StructInstType *structInstType );
-		virtual void visit( UnionInstType *unionInstType );
-		virtual void visit( StructDecl *aggregateDecl );
-		virtual void visit( UnionDecl *aggregateDecl );
-
-		virtual void visit( CompoundStmt *compoundStmt );
-		virtual void visit( SwitchStmt *switchStmt );
+		void previsit( EnumInstType * enumInstType );
+		void previsit( StructInstType * structInstType );
+		void previsit( UnionInstType * unionInstType );
+		void previsit( StructDecl * aggregateDecl );
+		void previsit( UnionDecl * aggregateDecl );
+
 	  private:
-		HoistStruct();
-
 		template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
 
-		std::list< Declaration * > declsToAdd, declsToAddAfter;
-		bool inStruct;
+		bool inStruct = false;
 	};
 
@@ -305,9 +293,6 @@
 
 	void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
-		HoistStruct hoister;
-		acceptAndAdd( translationUnit, hoister );
-	}
-
-	HoistStruct::HoistStruct() : inStruct( false ) {
+		PassVisitor<HoistStruct> hoister;
+		acceptAll( translationUnit, hoister );
 	}
 
@@ -320,47 +305,37 @@
 		if ( inStruct ) {
 			// Add elements in stack order corresponding to nesting structure.
-			declsToAdd.push_front( aggregateDecl );
-			Visitor::visit( aggregateDecl );
+			declsToAddBefore.push_front( aggregateDecl );
 		} else {
+			GuardValue( inStruct );
 			inStruct = true;
-			Visitor::visit( aggregateDecl );
-			inStruct = false;
 		} // if
 		// Always remove the hoisted aggregate from the inner structure.
-		filter( aggregateDecl->get_members(), isStructOrUnion, false );
-	}
-
-	void HoistStruct::visit( EnumInstType *structInstType ) {
-		if ( structInstType->get_baseEnum() ) {
-			declsToAdd.push_front( structInstType->get_baseEnum() );
-		}
-	}
-
-	void HoistStruct::visit( StructInstType *structInstType ) {
-		if ( structInstType->get_baseStruct() ) {
-			declsToAdd.push_front( structInstType->get_baseStruct() );
-		}
-	}
-
-	void HoistStruct::visit( UnionInstType *structInstType ) {
-		if ( structInstType->get_baseUnion() ) {
-			declsToAdd.push_front( structInstType->get_baseUnion() );
-		}
-	}
-
-	void HoistStruct::visit( StructDecl *aggregateDecl ) {
+		GuardAction( [this, aggregateDecl]() { filter( aggregateDecl->members, isStructOrUnion, false ); } );
+	}
+
+	void HoistStruct::previsit( EnumInstType * inst ) {
+		if ( inst->baseEnum ) {
+			declsToAddBefore.push_front( inst->baseEnum );
+		}
+	}
+
+	void HoistStruct::previsit( StructInstType * inst ) {
+		if ( inst->baseStruct ) {
+			declsToAddBefore.push_front( inst->baseStruct );
+		}
+	}
+
+	void HoistStruct::previsit( UnionInstType * inst ) {
+		if ( inst->baseUnion ) {
+			declsToAddBefore.push_front( inst->baseUnion );
+		}
+	}
+
+	void HoistStruct::previsit( StructDecl * aggregateDecl ) {
 		handleAggregate( aggregateDecl );
 	}
 
-	void HoistStruct::visit( UnionDecl *aggregateDecl ) {
+	void HoistStruct::previsit( UnionDecl * aggregateDecl ) {
 		handleAggregate( aggregateDecl );
-	}
-
-	void HoistStruct::visit( CompoundStmt *compoundStmt ) {
-		addVisit( compoundStmt, *this );
-	}
-
-	void HoistStruct::visit( SwitchStmt *switchStmt ) {
-		addVisit( switchStmt, *this );
 	}
 
Index: src/SymTab/module.mk
===================================================================
--- src/SymTab/module.mk	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SymTab/module.mk	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -19,5 +19,3 @@
        SymTab/Validate.cc \
        SymTab/FixFunction.cc \
-       SymTab/ImplementationType.cc \
-       SymTab/TypeEquality.cc \
        SymTab/Autogen.cc
Index: src/SynTree/CompoundStmt.cc
===================================================================
--- src/SynTree/CompoundStmt.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SynTree/CompoundStmt.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -28,8 +28,8 @@
 using std::endl;
 
-CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) {
+CompoundStmt::CompoundStmt() : Statement() {
 }
 
-CompoundStmt::CompoundStmt( std::list<Statement *> stmts ) : Statement( noLabels ), kids( stmts ) {
+CompoundStmt::CompoundStmt( std::list<Statement *> stmts ) : Statement(), kids( stmts ) {
 }
 
Index: src/SynTree/DeclStmt.cc
===================================================================
--- src/SynTree/DeclStmt.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SynTree/DeclStmt.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -23,5 +23,5 @@
 #include "SynTree/Label.h"   // for Label
 
-DeclStmt::DeclStmt( std::list<Label> labels, Declaration *decl ) : Statement( labels ), decl( decl ) {
+DeclStmt::DeclStmt( Declaration *decl ) : Statement(), decl( decl ) {
 }
 
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SynTree/Statement.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -32,5 +32,5 @@
 using std::endl;
 
-Statement::Statement( std::list<Label> labels ) : labels( labels ) {}
+Statement::Statement( const std::list<Label> & labels ) : labels( labels ) {}
 
 void Statement::print( std::ostream & os, Indenter ) const {
@@ -46,5 +46,5 @@
 Statement::~Statement() {}
 
-ExprStmt::ExprStmt( std::list<Label> labels, Expression *expr ) : Statement( labels ), expr( expr ) {}
+ExprStmt::ExprStmt( Expression *expr ) : Statement(), expr( expr ) {}
 
 ExprStmt::ExprStmt( const ExprStmt &other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
@@ -60,5 +60,5 @@
 
 
-AsmStmt::AsmStmt( std::list<Label> labels, bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement( labels ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
+AsmStmt::AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement(), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
 
 AsmStmt::AsmStmt( const AsmStmt & other ) : Statement( other ), voltile( other.voltile ), instruction( maybeClone( other.instruction ) ), gotolabels( other.gotolabels ) {
@@ -96,6 +96,6 @@
 const char *BranchStmt::brType[] = { "Goto", "Break", "Continue" };
 
-BranchStmt::BranchStmt( std::list<Label> labels, Label target, Type type ) throw ( SemanticError ) :
-	Statement( labels ), originalTarget( target ), target( target ), computedTarget( nullptr ), type( type ) {
+BranchStmt::BranchStmt( Label target, Type type ) throw ( SemanticError ) :
+	Statement(), originalTarget( target ), target( target ), computedTarget( nullptr ), type( type ) {
 	//actually this is a syntactic error signaled by the parser
 	if ( type == BranchStmt::Goto && target.empty() ) {
@@ -104,6 +104,6 @@
 }
 
-BranchStmt::BranchStmt( std::list<Label> labels, Expression *computedTarget, Type type ) throw ( SemanticError ) :
-	Statement( labels ), computedTarget( computedTarget ), type( type ) {
+BranchStmt::BranchStmt( Expression *computedTarget, Type type ) throw ( SemanticError ) :
+	Statement(), computedTarget( computedTarget ), type( type ) {
 	if ( type != BranchStmt::Goto || computedTarget == nullptr ) {
 		throw SemanticError("Computed target not valid in branch statement");
@@ -118,5 +118,5 @@
 }
 
-ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *expr ) : Statement( labels ), expr( expr ) {}
+ReturnStmt::ReturnStmt( Expression *expr ) : Statement(), expr( expr ) {}
 
 ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) {}
@@ -135,6 +135,6 @@
 }
 
-IfStmt::IfStmt( std::list<Label> labels, Expression *condition, Statement *thenPart, Statement *elsePart, std::list<Statement *> initialization ):
-	Statement( labels ), condition( condition ), thenPart( thenPart ), elsePart( elsePart ), initialization( initialization ) {}
+IfStmt::IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart, std::list<Statement *> initialization ):
+	Statement(), condition( condition ), thenPart( thenPart ), elsePart( elsePart ), initialization( initialization ) {}
 
 IfStmt::IfStmt( const IfStmt & other ) :
@@ -176,6 +176,6 @@
 }
 
-SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, const std::list<Statement *> &statements ):
-	Statement( labels ), condition( condition ), statements( statements ) {
+SwitchStmt::SwitchStmt( Expression * condition, const std::list<Statement *> &statements ):
+	Statement(), condition( condition ), statements( statements ) {
 }
 
@@ -201,6 +201,6 @@
 }
 
-CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
-	Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) {
+CaseStmt::CaseStmt( Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
+	Statement(), condition( condition ), stmts( statements ), _isDefault( deflt ) {
 	if ( isDefault() && condition != 0 ) throw SemanticError("default case with condition: ", condition);
 }
@@ -216,6 +216,8 @@
 }
 
-CaseStmt * CaseStmt::makeDefault( std::list<Label> labels, std::list<Statement *> stmts ) {
-	return new CaseStmt( labels, 0, stmts, true );
+CaseStmt * CaseStmt::makeDefault( const std::list<Label> & labels, std::list<Statement *> stmts ) {
+	CaseStmt * stmt = new CaseStmt( nullptr, stmts, true );
+	stmt->labels = labels;
+	return stmt;
 }
 
@@ -233,6 +235,6 @@
 }
 
-WhileStmt::WhileStmt( std::list<Label> labels, Expression *condition, Statement *body, bool isDoWhile ):
-	Statement( labels ), condition( condition), body( body), isDoWhile( isDoWhile) {
+WhileStmt::WhileStmt( Expression *condition, Statement *body, bool isDoWhile ):
+	Statement(), condition( condition), body( body), isDoWhile( isDoWhile) {
 }
 
@@ -255,6 +257,6 @@
 }
 
-ForStmt::ForStmt( std::list<Label> labels, std::list<Statement *> initialization, Expression *condition, Expression *increment, Statement *body ):
-	Statement( labels ), initialization( initialization ), condition( condition ), increment( increment ), body( body ) {
+ForStmt::ForStmt( std::list<Statement *> initialization, Expression *condition, Expression *increment, Statement *body ):
+	Statement(), initialization( initialization ), condition( condition ), increment( increment ), body( body ) {
 }
 
@@ -302,6 +304,6 @@
 }
 
-ThrowStmt::ThrowStmt( std::list<Label> labels, Kind kind, Expression * expr, Expression * target ) :
-		Statement( labels ), kind(kind), expr(expr), target(target)	{
+ThrowStmt::ThrowStmt( Kind kind, Expression * expr, Expression * target ) :
+		Statement(), kind(kind), expr(expr), target(target)	{
 	assertf(Resume == kind || nullptr == target, "Non-local termination throw is not accepted." );
 }
@@ -326,6 +328,6 @@
 }
 
-TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock ) :
-	Statement( labels ), block( tryBlock ),  handlers( handlers ), finallyBlock( finallyBlock ) {
+TryStmt::TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock ) :
+	Statement(), block( tryBlock ),  handlers( handlers ), finallyBlock( finallyBlock ) {
 }
 
@@ -359,6 +361,6 @@
 }
 
-CatchStmt::CatchStmt( std::list<Label> labels, Kind kind, Declaration *decl, Expression *cond, Statement *body ) :
-	Statement( labels ), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) {
+CatchStmt::CatchStmt( Kind kind, Declaration *decl, Expression *cond, Statement *body ) :
+	Statement(), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) {
 		assertf( decl, "Catch clause must have a declaration." );
 }
@@ -391,6 +393,5 @@
 
 
-FinallyStmt::FinallyStmt( std::list<Label> labels, CompoundStmt *block ) : Statement( labels ), block( block ) {
-	assert( labels.empty() ); // finally statement cannot be labeled
+FinallyStmt::FinallyStmt( CompoundStmt *block ) : Statement(), block( block ) {
 }
 
@@ -408,5 +409,5 @@
 }
 
-WaitForStmt::WaitForStmt( std::list<Label> labels ) : Statement( labels ) {
+WaitForStmt::WaitForStmt() : Statement() {
 	timeout.time      = nullptr;
 	timeout.statement = nullptr;
@@ -456,5 +457,5 @@
 
 
-WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement( std::list<Label>() ), exprs( exprs ), stmt( stmt ) {}
+WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}
 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {
 	cloneAll( other.exprs, exprs );
@@ -472,6 +473,6 @@
 
 
-NullStmt::NullStmt( std::list<Label> labels ) : Statement( labels ) {}
-NullStmt::NullStmt() : Statement( std::list<Label>() ) {}
+NullStmt::NullStmt( const std::list<Label> & labels ) : Statement( labels ) {
+}
 
 void NullStmt::print( std::ostream &os, Indenter ) const {
@@ -479,5 +480,5 @@
 }
 
-ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( Statement * callStmt ) : Statement( std::list<Label>() ), callStmt( callStmt ) {
+ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( Statement * callStmt ) : Statement(), callStmt( callStmt ) {
 	assert( callStmt );
 }
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SynTree/Statement.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -37,5 +37,5 @@
 	std::list<Label> labels;
 
-	Statement( std::list<Label> labels );
+	Statement( const std::list<Label> & labels = {} );
 	virtual ~Statement();
 
@@ -53,5 +53,5 @@
 	std::list<Statement*> kids;
 
-	CompoundStmt( std::list<Label> labels );
+	CompoundStmt();
 	CompoundStmt( std::list<Statement *> stmts );
 	CompoundStmt( const CompoundStmt &other );
@@ -70,6 +70,5 @@
 class NullStmt : public Statement {
   public:
-	NullStmt();
-	NullStmt( std::list<Label> labels );
+	NullStmt( const std::list<Label> & labels = {} );
 
 	virtual NullStmt *clone() const override { return new NullStmt( *this ); }
@@ -83,5 +82,5 @@
 	Expression *expr;
 
-	ExprStmt( std::list<Label> labels, Expression *expr );
+	ExprStmt( Expression *expr );
 	ExprStmt( const ExprStmt &other );
 	virtual ~ExprStmt();
@@ -104,5 +103,5 @@
 	std::list<Label> gotolabels;
 
-	AsmStmt( std::list<Label> labels, bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
+	AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
 	AsmStmt( const AsmStmt &other );
 	virtual ~AsmStmt();
@@ -134,5 +133,5 @@
 	std::list<Statement *> initialization;
 
-	IfStmt( std::list<Label> labels, Expression *condition, Statement *thenPart, Statement *elsePart,
+	IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart,
 			std::list<Statement *> initialization = std::list<Statement *>() );
 	IfStmt( const IfStmt &other );
@@ -158,5 +157,5 @@
 	std::list<Statement *> statements;
 
-	SwitchStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements );
+	SwitchStmt( Expression *condition, const std::list<Statement *> &statements );
 	SwitchStmt( const SwitchStmt &other );
 	virtual ~SwitchStmt();
@@ -180,9 +179,9 @@
 	std::list<Statement *> stmts;
 
-	CaseStmt( std::list<Label> labels, Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
+	CaseStmt( Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
 	CaseStmt( const CaseStmt &other );
 	virtual ~CaseStmt();
 
-	static CaseStmt * makeDefault( std::list<Label> labels = std::list<Label>(), std::list<Statement *> stmts = std::list<Statement *>() );
+	static CaseStmt * makeDefault( const std::list<Label> & labels = {}, std::list<Statement *> stmts = std::list<Statement *>() );
 
 	bool isDefault() const { return _isDefault; }
@@ -210,5 +209,5 @@
 	bool isDoWhile;
 
-	WhileStmt( std::list<Label> labels, Expression *condition,
+	WhileStmt( Expression *condition,
 	       Statement *body, bool isDoWhile = false );
 	WhileStmt( const WhileStmt &other );
@@ -235,5 +234,5 @@
 	Statement *body;
 
-	ForStmt( std::list<Label> labels, std::list<Statement *> initialization,
+	ForStmt( std::list<Statement *> initialization,
 	     Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
 	ForStmt( const ForStmt &other );
@@ -264,6 +263,6 @@
 	Type type;
 
-	BranchStmt( std::list<Label> labels, Label target, Type ) throw (SemanticError);
-	BranchStmt( std::list<Label> labels, Expression *computedTarget, Type ) throw (SemanticError);
+	BranchStmt( Label target, Type ) throw (SemanticError);
+	BranchStmt( Expression *computedTarget, Type ) throw (SemanticError);
 
 	Label get_originalTarget() { return originalTarget; }
@@ -289,5 +288,5 @@
 	Expression *expr;
 
-	ReturnStmt( std::list<Label> labels, Expression *expr );
+	ReturnStmt( Expression *expr );
 	ReturnStmt( const ReturnStmt &other );
 	virtual ~ReturnStmt();
@@ -310,5 +309,5 @@
 	Expression * target;
 
-	ThrowStmt( std::list<Label> labels, Kind kind, Expression * expr, Expression * target = nullptr );
+	ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr );
 	ThrowStmt( const ThrowStmt &other );
 	virtual ~ThrowStmt();
@@ -332,5 +331,5 @@
 	FinallyStmt * finallyBlock;
 
-	TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
+	TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
 	TryStmt( const TryStmt &other );
 	virtual ~TryStmt();
@@ -358,5 +357,5 @@
 	Statement *body;
 
-	CatchStmt( std::list<Label> labels, Kind kind, Declaration *decl,
+	CatchStmt( Kind kind, Declaration *decl,
 	           Expression *cond, Statement *body );
 	CatchStmt( const CatchStmt &other );
@@ -381,5 +380,5 @@
 	CompoundStmt *block;
 
-	FinallyStmt( std::list<Label> labels, CompoundStmt *block );
+	FinallyStmt( CompoundStmt *block );
 	FinallyStmt( const FinallyStmt &other );
 	virtual ~FinallyStmt();
@@ -408,5 +407,5 @@
 	};
 
-	WaitForStmt( std::list<Label> labels = noLabels );
+	WaitForStmt();
 	WaitForStmt( const WaitForStmt & );
 	virtual ~WaitForStmt();
@@ -453,5 +452,5 @@
 	Declaration *decl;
 
-	DeclStmt( std::list<Label> labels, Declaration *decl );
+	DeclStmt( Declaration *decl );
 	DeclStmt( const DeclStmt &other );
 	virtual ~DeclStmt();
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/SynTree/TupleExpr.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -23,5 +23,5 @@
 #include "Declaration.h"        // for ObjectDecl
 #include "Expression.h"         // for Expression, TupleExpr, TupleIndexExpr
-#include "SynTree/Label.h"      // for Label, noLabels
+#include "SynTree/Label.h"      // for Label
 #include "SynTree/Statement.h"  // for CompoundStmt, DeclStmt, ExprStmt, Sta...
 #include "Tuples/Tuples.h"      // for makeTupleType
@@ -89,12 +89,12 @@
 	// convert internally into a StmtExpr which contains the declarations and produces the tuple of the assignments
 	set_result( Tuples::makeTupleType( assigns ) );
-	CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
+	CompoundStmt * compoundStmt = new CompoundStmt();
 	std::list< Statement * > & stmts = compoundStmt->get_kids();
 	for ( ObjectDecl * obj : tempDecls ) {
-		stmts.push_back( new DeclStmt( noLabels, obj ) );
+		stmts.push_back( new DeclStmt( obj ) );
 	}
 	TupleExpr * tupleExpr = new TupleExpr( assigns );
 	assert( tupleExpr->get_result() );
-	stmts.push_back( new ExprStmt( noLabels, tupleExpr ) );
+	stmts.push_back( new ExprStmt( tupleExpr ) );
 	stmtExpr = new StmtExpr( compoundStmt );
 }
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/Tuples/TupleAssignment.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -23,4 +23,5 @@
 
 #include "CodeGen/OperatorTable.h"
+#include "Common/PassVisitor.h"
 #include "Common/UniqueName.h"             // for UniqueName
 #include "Common/utility.h"                // for zipWith
@@ -61,5 +62,5 @@
 		struct Matcher {
 		  public:
-			Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const 
+			Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const
 				ResolvExpr::AltList& rhs );
 			virtual ~Matcher() {}
@@ -75,5 +76,5 @@
 		struct MassAssignMatcher : public Matcher {
 		  public:
-			MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 
+			MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
 				const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
 			virtual void match( std::list< Expression * > &out );
@@ -82,5 +83,5 @@
 		struct MultipleAssignMatcher : public Matcher {
 		  public:
-			MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 
+			MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
 				const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
 			virtual void match( std::list< Expression * > &out );
@@ -119,5 +120,5 @@
 	}
 
-	void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, 
+	void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr,
 				std::vector<ResolvExpr::AlternativeFinder> &args ) {
 		TupleAssignSpotter spotter( currentFinder );
@@ -128,5 +129,5 @@
 		: currentFinder(f) {}
 
-	void TupleAssignSpotter::spot( UntypedExpr * expr, 
+	void TupleAssignSpotter::spot( UntypedExpr * expr,
 			std::vector<ResolvExpr::AlternativeFinder> &args ) {
 		if (  NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) {
@@ -137,5 +138,5 @@
 				if ( args.size() == 0 ) return;
 
-				// if an assignment only takes 1 argument, that's odd, but maybe someone wrote 
+				// if an assignment only takes 1 argument, that's odd, but maybe someone wrote
 				// the function, in which case AlternativeFinder will handle it normally
 				if ( args.size() == 1 && CodeGen::isAssignment( fname ) ) return;
@@ -146,11 +147,11 @@
 					if ( ! refToTuple(lhsAlt.expr) ) continue;
 
-					// explode is aware of casts - ensure every LHS expression is sent into explode 
+					// explode is aware of casts - ensure every LHS expression is sent into explode
 					// with a reference cast
-					// xxx - this seems to change the alternatives before the normal 
+					// xxx - this seems to change the alternatives before the normal
 					//  AlternativeFinder flow; maybe this is desired?
 					if ( ! dynamic_cast<CastExpr*>( lhsAlt.expr ) ) {
-						lhsAlt.expr = new CastExpr( lhsAlt.expr, 
-								new ReferenceType( Type::Qualifiers(), 
+						lhsAlt.expr = new CastExpr( lhsAlt.expr,
+								new ReferenceType( Type::Qualifiers(),
 									lhsAlt.expr->get_result()->clone() ) );
 					}
@@ -160,9 +161,9 @@
 					explode( lhsAlt, currentFinder.get_indexer(), back_inserter(lhs), true );
 					for ( ResolvExpr::Alternative& alt : lhs ) {
-						// each LHS value must be a reference - some come in with a cast expression, 
+						// each LHS value must be a reference - some come in with a cast expression,
 						// if not just cast to reference here
 						if ( ! dynamic_cast<ReferenceType*>( alt.expr->get_result() ) ) {
-							alt.expr = new CastExpr( alt.expr, 
-								new ReferenceType( Type::Qualifiers(), 
+							alt.expr = new CastExpr( alt.expr,
+								new ReferenceType( Type::Qualifiers(),
 									alt.expr->get_result()->clone() ) );
 						}
@@ -178,10 +179,10 @@
 						// TODO build iterative version of this instead of using combos
 						std::vector< ResolvExpr::AltList > rhsAlts;
-						combos( std::next(args.begin(), 1), args.end(), 
+						combos( std::next(args.begin(), 1), args.end(),
 							std::back_inserter( rhsAlts ) );
 						for ( const ResolvExpr::AltList& rhsAlt : rhsAlts ) {
 							// multiple assignment
 							ResolvExpr::AltList rhs;
-							explode( rhsAlt, currentFinder.get_indexer(), 
+							explode( rhsAlt, currentFinder.get_indexer(),
 								std::back_inserter(rhs), true );
 							matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) );
@@ -193,5 +194,5 @@
 							if ( isTuple(rhsAlt.expr) ) {
 								// multiple assignment
-								explode( rhsAlt, currentFinder.get_indexer(),  
+								explode( rhsAlt, currentFinder.get_indexer(),
 									std::back_inserter(rhs), true );
 								matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) );
@@ -222,5 +223,5 @@
 		ResolvExpr::AltList current;
 		// now resolve new assignments
-		for ( std::list< Expression * >::iterator i = new_assigns.begin(); 
+		for ( std::list< Expression * >::iterator i = new_assigns.begin();
 				i != new_assigns.end(); ++i ) {
 			PRINT(
@@ -229,5 +230,5 @@
 			)
 
-			ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(), 
+			ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(),
 				currentFinder.get_environ() };
 			try {
@@ -253,11 +254,11 @@
 		// xxx -- was push_front
 		currentFinder.get_alternatives().push_back( ResolvExpr::Alternative(
-			new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 
+			new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv,
 			ResolvExpr::sumCost( current ) + matcher->baseCost ) );
 	}
 
-	TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, 
-		const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs ) 
-	: lhs(lhs), rhs(rhs), spotter(spotter), 
+	TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter,
+		const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs )
+	: lhs(lhs), rhs(rhs), spotter(spotter),
 	  baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {
 		simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv );
@@ -277,9 +278,8 @@
 	// xxx - maybe this should happen in alternative finder for every StmtExpr?
 	// xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv
-	struct EnvRemover : public Visitor {
-		virtual void visit( ExprStmt * stmt ) {
-			delete stmt->get_expr()->get_env();
-			stmt->get_expr()->set_env( nullptr );
-			Visitor::visit( stmt );
+	struct EnvRemover {
+		void previsit( ExprStmt * stmt ) {
+			delete stmt->expr->env;
+			stmt->expr->env = nullptr;
 		}
 	};
@@ -293,5 +293,5 @@
 			ret->set_init( ctorInit );
 			ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
-			EnvRemover rm; // remove environments from subexpressions of StmtExprs
+			PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs
 			ctorInit->accept( rm );
 		}
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/Tuples/TupleExpansion.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -315,15 +315,14 @@
 	namespace {
 		/// determines if impurity (read: side-effects) may exist in a piece of code. Currently gives a very crude approximation, wherein any function call expression means the code may be impure
-		class ImpurityDetector : public Visitor {
-		public:
+		struct ImpurityDetector : public WithShortCircuiting {
 			ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {}
 
-			typedef Visitor Parent;
-			virtual void visit( ApplicationExpr * appExpr ) {
+			void previsit( ApplicationExpr * appExpr ) {
+				visit_children = false;
 				if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {
 					if ( function->get_linkage() == LinkageSpec::Intrinsic ) {
 						if ( function->get_name() == "*?" || function->get_name() == "?[?]" ) {
 							// intrinsic dereference, subscript are pure, but need to recursively look for impurity
-							Parent::visit( appExpr );
+							visit_children = true;
 							return;
 						}
@@ -332,13 +331,13 @@
 				maybeImpure = true;
 			}
-			virtual void visit( UntypedExpr * ) { maybeImpure = true; }
-			virtual void visit( UniqueExpr * unq ) {
+			void previsit( UntypedExpr * ) { maybeImpure = true; visit_children = false; }
+			void previsit( UniqueExpr * ) {
 				if ( ignoreUnique ) {
 					// bottom out at unique expression.
 					// The existence of a unique expression doesn't change the purity of an expression.
 					// That is, even if the wrapped expression is impure, the wrapper protects the rest of the expression.
+					visit_children = false;
 					return;
 				}
-				maybeAccept( unq->expr, *this );
 			}
 
@@ -349,13 +348,13 @@
 
 	bool maybeImpure( Expression * expr ) {
-		ImpurityDetector detector( false );
+		PassVisitor<ImpurityDetector> detector( false );
 		expr->accept( detector );
-		return detector.maybeImpure;
+		return detector.pass.maybeImpure;
 	}
 
 	bool maybeImpureIgnoreUnique( Expression * expr ) {
-		ImpurityDetector detector( true );
+		PassVisitor<ImpurityDetector> detector( true );
 		expr->accept( detector );
-		return detector.maybeImpure;
+		return detector.pass.maybeImpure;
 	}
 } // namespace Tuples
Index: src/driver/cfa.cc
===================================================================
--- src/driver/cfa.cc	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/driver/cfa.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -275,5 +275,5 @@
 		args[nargs] = "-Xlinker";
 		nargs += 1;
-		args[nargs] = "--undefined=__lib_debug_write";
+		args[nargs] = "--undefined=__cfaabi_dbg_bits_write";
 		nargs += 1;
 
Index: src/libcfa/Makefile.am
===================================================================
--- src/libcfa/Makefile.am	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/Makefile.am	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -55,5 +55,5 @@
 
 libobjs = ${headers:=.o}
-libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
+libsrc = libcfa-prelude.c interpose.c bits/debug.c ${headers:=.c} \
 	 assert.c exception.c virtual.c
 
@@ -100,12 +100,10 @@
 	math 				\
 	gmp 				\
+	bits/align.h 		\
 	bits/containers.h		\
 	bits/defs.h 		\
+	bits/debug.h 		\
 	bits/locks.h 		\
-	concurrency/invoke.h 	\
-	libhdr.h 			\
-	libhdr/libalign.h 	\
-	libhdr/libdebug.h 	\
-	libhdr/libtools.h
+	concurrency/invoke.h
 
 CLEANFILES = libcfa-prelude.c
Index: src/libcfa/Makefile.in
===================================================================
--- src/libcfa/Makefile.in	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/Makefile.in	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -149,5 +149,5 @@
 libcfa_d_a_LIBADD =
 am__libcfa_d_a_SOURCES_DIST = libcfa-prelude.c interpose.c \
-	libhdr/libdebug.c fstream.c iostream.c iterator.c limits.c \
+	bits/debug.c fstream.c iostream.c iterator.c limits.c \
 	rational.c stdlib.c containers/maybe.c containers/pair.c \
 	containers/result.c containers/vector.c \
@@ -175,21 +175,20 @@
 @BUILD_CONCURRENCY_TRUE@	concurrency/libcfa_d_a-preemption.$(OBJEXT)
 am__objects_4 = libcfa_d_a-libcfa-prelude.$(OBJEXT) \
-	libcfa_d_a-interpose.$(OBJEXT) \
-	libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \
-	libcfa_d_a-assert.$(OBJEXT) libcfa_d_a-exception.$(OBJEXT) \
-	libcfa_d_a-virtual.$(OBJEXT) $(am__objects_3)
+	libcfa_d_a-interpose.$(OBJEXT) bits/libcfa_d_a-debug.$(OBJEXT) \
+	$(am__objects_2) libcfa_d_a-assert.$(OBJEXT) \
+	libcfa_d_a-exception.$(OBJEXT) libcfa_d_a-virtual.$(OBJEXT) \
+	$(am__objects_3)
 am_libcfa_d_a_OBJECTS = $(am__objects_4)
 libcfa_d_a_OBJECTS = $(am_libcfa_d_a_OBJECTS)
 libcfa_a_AR = $(AR) $(ARFLAGS)
 libcfa_a_LIBADD =
-am__libcfa_a_SOURCES_DIST = libcfa-prelude.c interpose.c \
-	libhdr/libdebug.c fstream.c iostream.c iterator.c limits.c \
-	rational.c stdlib.c containers/maybe.c containers/pair.c \
-	containers/result.c containers/vector.c \
-	concurrency/coroutine.c concurrency/thread.c \
-	concurrency/kernel.c concurrency/monitor.c assert.c \
-	exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
-	concurrency/alarm.c concurrency/invoke.c \
-	concurrency/preemption.c
+am__libcfa_a_SOURCES_DIST = libcfa-prelude.c interpose.c bits/debug.c \
+	fstream.c iostream.c iterator.c limits.c rational.c stdlib.c \
+	containers/maybe.c containers/pair.c containers/result.c \
+	containers/vector.c concurrency/coroutine.c \
+	concurrency/thread.c concurrency/kernel.c \
+	concurrency/monitor.c assert.c exception.c virtual.c \
+	concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
+	concurrency/invoke.c concurrency/preemption.c
 @BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \
 @BUILD_CONCURRENCY_TRUE@	concurrency/libcfa_a-thread.$(OBJEXT) \
@@ -208,8 +207,8 @@
 @BUILD_CONCURRENCY_TRUE@	concurrency/libcfa_a-preemption.$(OBJEXT)
 am__objects_8 = libcfa_a-libcfa-prelude.$(OBJEXT) \
-	libcfa_a-interpose.$(OBJEXT) \
-	libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \
-	libcfa_a-assert.$(OBJEXT) libcfa_a-exception.$(OBJEXT) \
-	libcfa_a-virtual.$(OBJEXT) $(am__objects_7)
+	libcfa_a-interpose.$(OBJEXT) bits/libcfa_a-debug.$(OBJEXT) \
+	$(am__objects_6) libcfa_a-assert.$(OBJEXT) \
+	libcfa_a-exception.$(OBJEXT) libcfa_a-virtual.$(OBJEXT) \
+	$(am__objects_7)
 am_libcfa_a_OBJECTS = $(am__objects_8)
 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
@@ -264,7 +263,6 @@
 	containers/result containers/vector concurrency/coroutine \
 	concurrency/thread concurrency/kernel concurrency/monitor \
-	${shell echo stdhdr/*} math gmp bits/containers.h bits/defs.h \
-	bits/locks.h concurrency/invoke.h libhdr.h libhdr/libalign.h \
-	libhdr/libdebug.h libhdr/libtools.h
+	${shell echo stdhdr/*} math gmp bits/align.h bits/containers.h \
+	bits/defs.h bits/debug.h bits/locks.h concurrency/invoke.h
 HEADERS = $(nobase_cfa_include_HEADERS)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
@@ -424,5 +422,5 @@
 	containers/vector $(am__append_3)
 libobjs = ${headers:=.o}
-libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
+libsrc = libcfa-prelude.c interpose.c bits/debug.c ${headers:=.c} \
 	assert.c exception.c virtual.c $(am__append_4)
 libcfa_a_SOURCES = ${libsrc}
@@ -437,12 +435,10 @@
 	math 				\
 	gmp 				\
+	bits/align.h 		\
 	bits/containers.h		\
 	bits/defs.h 		\
+	bits/debug.h 		\
 	bits/locks.h 		\
-	concurrency/invoke.h 	\
-	libhdr.h 			\
-	libhdr/libalign.h 	\
-	libhdr/libdebug.h 	\
-	libhdr/libtools.h
+	concurrency/invoke.h
 
 CLEANFILES = libcfa-prelude.c
@@ -511,12 +507,12 @@
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
-libhdr/$(am__dirstamp):
-	@$(MKDIR_P) libhdr
-	@: > libhdr/$(am__dirstamp)
-libhdr/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) libhdr/$(DEPDIR)
-	@: > libhdr/$(DEPDIR)/$(am__dirstamp)
-libhdr/libcfa_d_a-libdebug.$(OBJEXT): libhdr/$(am__dirstamp) \
-	libhdr/$(DEPDIR)/$(am__dirstamp)
+bits/$(am__dirstamp):
+	@$(MKDIR_P) bits
+	@: > bits/$(am__dirstamp)
+bits/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) bits/$(DEPDIR)
+	@: > bits/$(DEPDIR)/$(am__dirstamp)
+bits/libcfa_d_a-debug.$(OBJEXT): bits/$(am__dirstamp) \
+	bits/$(DEPDIR)/$(am__dirstamp)
 containers/$(am__dirstamp):
 	@$(MKDIR_P) containers
@@ -563,6 +559,6 @@
 	$(AM_V_AR)$(libcfa_d_a_AR) libcfa-d.a $(libcfa_d_a_OBJECTS) $(libcfa_d_a_LIBADD)
 	$(AM_V_at)$(RANLIB) libcfa-d.a
-libhdr/libcfa_a-libdebug.$(OBJEXT): libhdr/$(am__dirstamp) \
-	libhdr/$(DEPDIR)/$(am__dirstamp)
+bits/libcfa_a-debug.$(OBJEXT): bits/$(am__dirstamp) \
+	bits/$(DEPDIR)/$(am__dirstamp)
 containers/libcfa_a-maybe.$(OBJEXT): containers/$(am__dirstamp) \
 	containers/$(DEPDIR)/$(am__dirstamp)
@@ -596,7 +592,7 @@
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
+	-rm -f bits/*.$(OBJEXT)
 	-rm -f concurrency/*.$(OBJEXT)
 	-rm -f containers/*.$(OBJEXT)
-	-rm -f libhdr/*.$(OBJEXT)
 
 distclean-compile:
@@ -625,4 +621,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-stdlib.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_a-debug.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_d_a-debug.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/CtxSwitch-@MACHINE_TYPE@.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-alarm.Po@am__quote@
@@ -648,6 +646,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@containers/$(DEPDIR)/libcfa_d_a-result.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@containers/$(DEPDIR)/libcfa_d_a-vector.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@libhdr/$(DEPDIR)/libcfa_a-libdebug.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Po@am__quote@
 
 .S.o:
@@ -704,17 +700,17 @@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-interpose.obj `if test -f 'interpose.c'; then $(CYGPATH_W) 'interpose.c'; else $(CYGPATH_W) '$(srcdir)/interpose.c'; fi`
 
-libhdr/libcfa_d_a-libdebug.o: libhdr/libdebug.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_d_a-libdebug.o -MD -MP -MF libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo -c -o libhdr/libcfa_d_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libhdr/libdebug.c' object='libhdr/libcfa_d_a-libdebug.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_d_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c
-
-libhdr/libcfa_d_a-libdebug.obj: libhdr/libdebug.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_d_a-libdebug.obj -MD -MP -MF libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo -c -o libhdr/libcfa_d_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libhdr/libdebug.c' object='libhdr/libcfa_d_a-libdebug.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_d_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`
+bits/libcfa_d_a-debug.o: bits/debug.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_d_a-debug.o -MD -MP -MF bits/$(DEPDIR)/libcfa_d_a-debug.Tpo -c -o bits/libcfa_d_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_d_a-debug.Tpo bits/$(DEPDIR)/libcfa_d_a-debug.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='bits/debug.c' object='bits/libcfa_d_a-debug.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_d_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c
+
+bits/libcfa_d_a-debug.obj: bits/debug.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_d_a-debug.obj -MD -MP -MF bits/$(DEPDIR)/libcfa_d_a-debug.Tpo -c -o bits/libcfa_d_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_d_a-debug.Tpo bits/$(DEPDIR)/libcfa_d_a-debug.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='bits/debug.c' object='bits/libcfa_d_a-debug.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_d_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi`
 
 libcfa_d_a-fstream.o: fstream.c
@@ -998,17 +994,17 @@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-interpose.obj `if test -f 'interpose.c'; then $(CYGPATH_W) 'interpose.c'; else $(CYGPATH_W) '$(srcdir)/interpose.c'; fi`
 
-libhdr/libcfa_a-libdebug.o: libhdr/libdebug.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_a-libdebug.o -MD -MP -MF libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo -c -o libhdr/libcfa_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_a-libdebug.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libhdr/libdebug.c' object='libhdr/libcfa_a-libdebug.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c
-
-libhdr/libcfa_a-libdebug.obj: libhdr/libdebug.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_a-libdebug.obj -MD -MP -MF libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo -c -o libhdr/libcfa_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_a-libdebug.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libhdr/libdebug.c' object='libhdr/libcfa_a-libdebug.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`
+bits/libcfa_a-debug.o: bits/debug.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_a-debug.o -MD -MP -MF bits/$(DEPDIR)/libcfa_a-debug.Tpo -c -o bits/libcfa_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_a-debug.Tpo bits/$(DEPDIR)/libcfa_a-debug.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='bits/debug.c' object='bits/libcfa_a-debug.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c
+
+bits/libcfa_a-debug.obj: bits/debug.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_a-debug.obj -MD -MP -MF bits/$(DEPDIR)/libcfa_a-debug.Tpo -c -o bits/libcfa_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_a-debug.Tpo bits/$(DEPDIR)/libcfa_a-debug.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='bits/debug.c' object='bits/libcfa_a-debug.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi`
 
 libcfa_a-fstream.o: fstream.c
@@ -1411,10 +1407,10 @@
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f bits/$(DEPDIR)/$(am__dirstamp)
+	-rm -f bits/$(am__dirstamp)
 	-rm -f concurrency/$(DEPDIR)/$(am__dirstamp)
 	-rm -f concurrency/$(am__dirstamp)
 	-rm -f containers/$(DEPDIR)/$(am__dirstamp)
 	-rm -f containers/$(am__dirstamp)
-	-rm -f libhdr/$(DEPDIR)/$(am__dirstamp)
-	-rm -f libhdr/$(am__dirstamp)
 
 maintainer-clean-generic:
@@ -1426,5 +1422,5 @@
 
 distclean: distclean-am
-	-rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) libhdr/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) bits/$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
@@ -1472,5 +1468,5 @@
 
 maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) libhdr/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) bits/$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic \
Index: src/libcfa/assert.c
===================================================================
--- src/libcfa/assert.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/assert.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -17,5 +17,5 @@
 #include <stdarg.h>								// varargs
 #include <stdio.h>								// fprintf
-#include "libhdr/libdebug.h"
+#include "bits/debug.h"
 
 extern "C" {
@@ -26,5 +26,5 @@
 	// called by macro assert in assert.h
 	void __assert_fail( const char *assertion, const char *file, unsigned int line, const char *function ) {
-		__lib_debug_print_safe( CFA_ASSERT_FMT ".\n", __progname, function, line, file );
+		__cfaabi_dbg_bits_print_safe( CFA_ASSERT_FMT ".\n", __progname, function, line, file );
 		abort();
 	}
@@ -32,14 +32,14 @@
 	// called by macro assertf
 	void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) {
-		__lib_debug_acquire();
-		__lib_debug_print_nolock( CFA_ASSERT_FMT ": ", __progname, function, line, file );
+		__cfaabi_dbg_bits_acquire();
+		__cfaabi_dbg_bits_print_nolock( CFA_ASSERT_FMT ": ", __progname, function, line, file );
 
 		va_list args;
 		va_start( args, fmt );
-		__lib_debug_print_vararg( fmt, args );
+		__cfaabi_dbg_bits_print_vararg( fmt, args );
 		va_end( args );
 
-		__lib_debug_print_nolock( "\n" );
-		__lib_debug_release();
+		__cfaabi_dbg_bits_print_nolock( "\n" );
+		__cfaabi_dbg_bits_release();
 		abort();
 	}
Index: src/libcfa/bits/align.h
===================================================================
--- src/libcfa/bits/align.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
+++ src/libcfa/bits/align.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -0,0 +1,62 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// align.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Mon Nov 28 12:27:26 2016
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Fri Jul 21 23:05:35 2017
+// Update Count     : 2
+//
+// This  library is free  software; you  can redistribute  it and/or  modify it
+// under the terms of the GNU Lesser General Public License as published by the
+// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
+// option) any later version.
+//
+// This library is distributed in the  hope that it will be useful, but WITHOUT
+// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+// for more details.
+//
+// You should  have received a  copy of the  GNU Lesser General  Public License
+// along  with this library.
+//
+
+#pragma once
+
+#include <assert.h>
+#include <stdbool.h>
+
+// Minimum size used to align memory boundaries for memory allocations.
+#define libAlign() (sizeof(double))
+
+// Check for power of 2
+static inline bool libPow2( unsigned long int value ) {
+    // clears all bits below value, rounding value down to the next lower multiple of value
+    return (value & (value - 1ul)) == 0ul;
+} // libPow2
+
+
+// Returns value aligned at the floor of align.
+static inline unsigned long int libFloor( unsigned long int value, unsigned long int align ) {
+    assert( libPow2( align ) );
+    // clears all bits above or equal to align, getting (value % align), the phase of value with regards to align
+    return value & -align;
+} // libFloor
+
+
+// Returns value aligned at the ceiling of align.
+
+static inline unsigned long int libCeiling( unsigned long int value, unsigned long int align ) {
+    assert( libPow2( align ) );
+    // "negate, round down, negate" is the same as round up
+    return -libFloor( -value, align );
+} // uCeiling
+
+// Local Variables: //
+// compile-command: "make install" //
+// End: //
Index: src/libcfa/bits/containers.h
===================================================================
--- src/libcfa/bits/containers.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/bits/containers.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -15,6 +15,6 @@
 #pragma once
 
+#include "bits/align.h"
 #include "bits/defs.h"
-#include "libhdr.h"
 
 //-----------------------------------------------------------------------------
Index: src/libcfa/bits/debug.c
===================================================================
--- src/libcfa/bits/debug.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
+++ src/libcfa/bits/debug.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -0,0 +1,88 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// debug.c --
+//
+// Author           : Thierry Delisle
+// Created On       : Thu Mar 30 12:30:01 2017
+// Last Modified By :
+// Last Modified On :
+// Update Count     : 0
+//
+
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+}
+
+enum { buffer_size = 512 };
+static char buffer[ buffer_size ];
+
+extern "C" {
+
+	void __cfaabi_dbg_bits_write( const char *in_buffer, int len ) {
+		// ensure all data is written
+		for ( int count = 0, retcode; count < len; count += retcode ) {
+			in_buffer += count;
+
+			for ( ;; ) {
+				retcode = write( STDERR_FILENO, in_buffer, len - count );
+
+				// not a timer interrupt ?
+				if ( retcode != -1 || errno != EINTR ) break;
+			}
+
+			if ( retcode == -1 ) _exit( EXIT_FAILURE );
+		}
+	}
+
+	void __cfaabi_dbg_bits_acquire() __attribute__((__weak__)) {}
+	void __cfaabi_dbg_bits_release() __attribute__((__weak__)) {}
+
+	void __cfaabi_dbg_bits_print_safe  ( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) {
+		va_list args;
+
+		va_start( args, fmt );
+		__cfaabi_dbg_bits_acquire();
+
+		int len = vsnprintf( buffer, buffer_size, fmt, args );
+		__cfaabi_dbg_bits_write( buffer, len );
+
+		__cfaabi_dbg_bits_release();
+		va_end( args );
+	}
+
+	void __cfaabi_dbg_bits_print_nolock( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) {
+		va_list args;
+
+		va_start( args, fmt );
+
+		int len = vsnprintf( buffer, buffer_size, fmt, args );
+		__cfaabi_dbg_bits_write( buffer, len );
+
+		va_end( args );
+	}
+
+	void __cfaabi_dbg_bits_print_vararg( const char fmt[], va_list args ) {
+		int len = vsnprintf( buffer, buffer_size, fmt, args );
+		__cfaabi_dbg_bits_write( buffer, len );
+	}
+
+	void __cfaabi_dbg_bits_print_buffer( char in_buffer[], int in_buffer_size, const char fmt[], ... ) __attribute__(( format (printf, 3, 4) )) {
+		va_list args;
+
+		va_start( args, fmt );
+
+		int len = vsnprintf( in_buffer, in_buffer_size, fmt, args );
+		__cfaabi_dbg_bits_write( in_buffer, len );
+
+		va_end( args );
+	}
+}
Index: src/libcfa/bits/debug.h
===================================================================
--- src/libcfa/bits/debug.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
+++ src/libcfa/bits/debug.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -0,0 +1,74 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// debug.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Mon Nov 28 12:27:26 2016
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Jul 22 10:02:24 2017
+// Update Count     : 1
+//
+
+#pragma once
+
+#ifdef __CFA_DEBUG__
+	#define __cfaabi_dbg_debug_do(...) __VA_ARGS__
+	#define __cfaabi_dbg_no_debug_do(...)
+	#define __cfaabi_dbg_ctx __PRETTY_FUNCTION__
+	#define __cfaabi_dbg_ctx2 , __PRETTY_FUNCTION__
+	#define __cfaabi_dbg_ctx_param const char * caller
+	#define __cfaabi_dbg_ctx_param2 , const char * caller
+#else
+	#define __cfaabi_dbg_debug_do(...)
+	#define __cfaabi_dbg_no_debug_do(...) __VA_ARGS__
+	#define __cfaabi_dbg_ctx
+	#define __cfaabi_dbg_ctx2
+	#define __cfaabi_dbg_ctx_param
+	#define __cfaabi_dbg_ctx_param2
+#endif
+
+#ifdef __cforall
+extern "C" {
+#endif
+	#include <stdarg.h>
+	#include <stdio.h>
+
+      extern void __cfaabi_dbg_bits_write( const char *buffer, int len );
+      extern void __cfaabi_dbg_bits_acquire();
+      extern void __cfaabi_dbg_bits_release();
+      extern void __cfaabi_dbg_bits_print_safe  ( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) ));
+      extern void __cfaabi_dbg_bits_print_nolock( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) ));
+      extern void __cfaabi_dbg_bits_print_vararg( const char fmt[], va_list arg );
+      extern void __cfaabi_dbg_bits_print_buffer( char buffer[], int buffer_size, const char fmt[], ... ) __attribute__(( format (printf, 3, 4) ));
+#ifdef __cforall
+}
+#endif
+
+#ifdef __CFA_DEBUG_PRINT__
+	#define __cfaabi_dbg_write( buffer, len )         __cfaabi_dbg_bits_write( buffer, len )
+	#define __cfaabi_dbg_acquire()                    __cfaabi_dbg_bits_acquire()
+	#define __cfaabi_dbg_release()                    __cfaabi_dbg_bits_release()
+	#define __cfaabi_dbg_print_safe(...)              __cfaabi_dbg_bits_print_safe   (__VA_ARGS__)
+	#define __cfaabi_dbg_print_nolock(...)            __cfaabi_dbg_bits_print_nolock (__VA_ARGS__)
+	#define __cfaabi_dbg_print_buffer(...)            __cfaabi_dbg_bits_print_buffer (__VA_ARGS__)
+	#define __cfaabi_dbg_print_buffer_decl(...)       char __dbg_text[256]; int __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __cfaabi_dbg_bits_write( __dbg_text, __dbg_len );
+	#define __cfaabi_dbg_print_buffer_local(...)      __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __cfaabi_dbg_bits_write( __dbg_text, __dbg_len );
+#else
+	#define __cfaabi_dbg_write(...)               ((void)0)
+	#define __cfaabi_dbg_acquire()                ((void)0)
+	#define __cfaabi_dbg_release()                ((void)0)
+	#define __cfaabi_dbg_print_safe(...)          ((void)0)
+	#define __cfaabi_dbg_print_nolock(...)        ((void)0)
+	#define __cfaabi_dbg_print_buffer(...)        ((void)0)
+	#define __cfaabi_dbg_print_buffer_decl(...)   ((void)0)
+	#define __cfaabi_dbg_print_buffer_local(...)  ((void)0)
+#endif
+
+// Local Variables: //
+// mode: c //
+// tab-width: 4 //
+// End: //
Index: src/libcfa/bits/defs.h
===================================================================
--- src/libcfa/bits/defs.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/bits/defs.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -32,2 +32,10 @@
 #define __cfa_anonymous_object __cfa_anonymous_object
 #endif
+
+#ifdef __cforall
+extern "C" {
+#endif
+void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__));
+#ifdef __cforall
+}
+#endif
Index: src/libcfa/bits/locks.h
===================================================================
--- src/libcfa/bits/locks.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/bits/locks.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -16,7 +16,6 @@
 #pragma once
 
+#include "bits/debug.h"
 #include "bits/defs.h"
-
-#include "libhdr.h"
 
 // pause to prevent excess processor bus usage
@@ -65,7 +64,7 @@
 
 	// Lock the spinlock, return false if already acquired
-	static inline _Bool try_lock  ( __spinlock_t & this DEBUG_CTX_PARAM2 ) {
+	static inline _Bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
 		_Bool result = __lock_test_and_test_and_set( this.lock );
-		LIB_DEBUG_DO(
+		__cfaabi_dbg_debug_do(
 			if( result ) {
 				this.prev_name = caller;
@@ -77,5 +76,5 @@
 
 	// Lock the spinlock, spin if already acquired
-	static inline void lock( __spinlock_t & this DEBUG_CTX_PARAM2 ) {
+	static inline void lock( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
 		#ifndef NOEXPBACK
 			enum { SPIN_START = 4, SPIN_END = 64 * 1024, };
@@ -98,5 +97,5 @@
 			#endif
 		}
-		LIB_DEBUG_DO(
+		__cfaabi_dbg_debug_do(
 			this.prev_name = caller;
 			this.prev_thrd = this_thread;
@@ -105,10 +104,10 @@
 
 	// Lock the spinlock, spin if already acquired
-	static inline void lock_yield( __spinlock_t & this DEBUG_CTX_PARAM2 ) {
+	static inline void lock_yield( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
 		for ( unsigned int i = 1;; i += 1 ) {
 			if ( __lock_test_and_test_and_set( this.lock ) ) break;
 			yield( i );
 		}
-		LIB_DEBUG_DO(
+		__cfaabi_dbg_debug_do(
 			this.prev_name = caller;
 			this.prev_thrd = this_thread;
Index: src/libcfa/concurrency/alarm.c
===================================================================
--- src/libcfa/concurrency/alarm.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/alarm.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -23,6 +23,4 @@
 }
 
-#include "libhdr.h"
-
 #include "alarm.h"
 #include "kernel_private.h"
@@ -110,5 +108,5 @@
 }
 
-LIB_DEBUG_DO( bool validate( alarm_list_t * this ) {
+__cfaabi_dbg_debug_do( bool validate( alarm_list_t * this ) {
 	alarm_node_t ** it = &this->head;
 	while( (*it) ) {
@@ -186,5 +184,5 @@
 
 	disable_interrupts();
-	lock( event_kernel->lock DEBUG_CTX2 );
+	lock( event_kernel->lock __cfaabi_dbg_ctx2 );
 	{
 		verify( validate( alarms ) );
@@ -198,10 +196,10 @@
 	unlock( event_kernel->lock );
 	this->set = true;
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
 void unregister_self( alarm_node_t * this ) {
 	disable_interrupts();
-	lock( event_kernel->lock DEBUG_CTX2 );
+	lock( event_kernel->lock __cfaabi_dbg_ctx2 );
 	{
 		verify( validate( &event_kernel->alarms ) );
@@ -209,5 +207,5 @@
 	}
 	unlock( event_kernel->lock );
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 	this->set = false;
 }
Index: src/libcfa/concurrency/coroutine.c
===================================================================
--- src/libcfa/concurrency/coroutine.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/coroutine.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -29,5 +29,4 @@
 #define __CFA_INVOKE_PRIVATE__
 #include "invoke.h"
-
 
 //-----------------------------------------------------------------------------
@@ -76,5 +75,5 @@
 void ^?{}(coStack_t & this) {
 	if ( ! this.userStack && this.storage ) {
-		LIB_DEBUG_DO(
+		__cfaabi_dbg_debug_do(
 			if ( mprotect( this.storage, pageSize, PROT_READ | PROT_WRITE ) == -1 ) {
 				abortf( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
@@ -131,8 +130,8 @@
 
 		// assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
-		LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
-		LIB_NO_DEBUG_DO( this->storage = malloc( cxtSize + this->size + 8 ) );
+		__cfaabi_dbg_debug_do( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );
+		__cfaabi_dbg_no_debug_do( this->storage = malloc( cxtSize + this->size + 8 ) );
 
-		LIB_DEBUG_DO(
+		__cfaabi_dbg_debug_do(
 			if ( mprotect( this->storage, pageSize, PROT_NONE ) == -1 ) {
 				abortf( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) );
@@ -144,6 +143,6 @@
 		} // if
 
-		LIB_DEBUG_DO( this->limit = (char *)this->storage + pageSize );
-		LIB_NO_DEBUG_DO( this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ) ); // minimum alignment
+		__cfaabi_dbg_debug_do( this->limit = (char *)this->storage + pageSize );
+		__cfaabi_dbg_no_debug_do( this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ) ); // minimum alignment
 
 	} else {
Index: src/libcfa/concurrency/invoke.c
===================================================================
--- src/libcfa/concurrency/invoke.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/invoke.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -18,5 +18,4 @@
 #include <stdio.h>
 
-#include "libhdr.h"
 #include "invoke.h"
 
@@ -31,70 +30,66 @@
 extern void __leave_thread_monitor( struct thread_desc * this );
 extern void disable_interrupts();
-extern void enable_interrupts( DEBUG_CTX_PARAM );
+extern void enable_interrupts( __cfaabi_dbg_ctx_param );
 
 void CtxInvokeCoroutine(
-      void (*main)(void *),
-      struct coroutine_desc *(*get_coroutine)(void *),
-      void *this
+	void (*main)(void *),
+	struct coroutine_desc *(*get_coroutine)(void *),
+	void *this
 ) {
-      // LIB_DEBUG_PRINTF("Invoke Coroutine : Received %p (main %p, get_c %p)\n", this, main, get_coroutine);
+	struct coroutine_desc* cor = get_coroutine( this );
 
-      struct coroutine_desc* cor = get_coroutine( this );
+	if(cor->state == Primed) {
+		__suspend_internal();
+	}
 
-      if(cor->state == Primed) {
-            __suspend_internal();
-      }
+	cor->state = Active;
 
-      cor->state = Active;
+	main( this );
 
-      main( this );
+	cor->state = Halted;
 
-      cor->state = Halted;
-
-      //Final suspend, should never return
-      __leave_coroutine();
-      abortf("Resumed dead coroutine");
+	//Final suspend, should never return
+	__leave_coroutine();
+	abortf("Resumed dead coroutine");
 }
 
 void CtxInvokeThread(
-      void (*dtor)(void *),
-      void (*main)(void *),
-      struct thread_desc *(*get_thread)(void *),
-      void *this
+	void (*dtor)(void *),
+	void (*main)(void *),
+	struct thread_desc *(*get_thread)(void *),
+	void *this
 ) {
-      // First suspend, once the thread arrives here,
-      // the function pointer to main can be invalidated without risk
-      __suspend_internal();
+	// First suspend, once the thread arrives here,
+	// the function pointer to main can be invalidated without risk
+	__suspend_internal();
 
-      // Fetch the thread handle from the user defined thread structure
-      struct thread_desc* thrd = get_thread( this );
+	// Fetch the thread handle from the user defined thread structure
+	struct thread_desc* thrd = get_thread( this );
 
-      // Officially start the thread by enabling preemption
-      enable_interrupts( DEBUG_CTX );
+	// Officially start the thread by enabling preemption
+	enable_interrupts( __cfaabi_dbg_ctx );
 
-      // Call the main of the thread
-      main( this );
+	// Call the main of the thread
+	main( this );
 
-      // To exit a thread we must :
-      // 1 - Mark it as halted
-      // 2 - Leave its monitor
-      // 3 - Disable the interupts
-      // 4 - Final suspend
-      // The order of these 4 operations is very important
-      //Final suspend, should never return
-      __leave_thread_monitor( thrd );
-      abortf("Resumed dead thread");
+	// To exit a thread we must :
+	// 1 - Mark it as halted
+	// 2 - Leave its monitor
+	// 3 - Disable the interupts
+	// 4 - Final suspend
+	// The order of these 4 operations is very important
+	//Final suspend, should never return
+	__leave_thread_monitor( thrd );
+	abortf("Resumed dead thread");
 }
 
 
 void CtxStart(
-      void (*main)(void *),
-      struct coroutine_desc *(*get_coroutine)(void *),
-      void *this,
-      void (*invoke)(void *)
+	void (*main)(void *),
+	struct coroutine_desc *(*get_coroutine)(void *),
+	void *this,
+	void (*invoke)(void *)
 ) {
-      // LIB_DEBUG_PRINTF("StartCoroutine : Passing in %p (main %p) to invoke (%p) from start (%p)\n", this, main, invoke, CtxStart);
-
-      struct coStack_t* stack = &get_coroutine( this )->stack;
+	struct coStack_t* stack = &get_coroutine( this )->stack;
 
 #if defined( __i386__ )
@@ -103,5 +98,5 @@
 	    void *fixedRegisters[3];		  	// fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)
 	    uint32_t mxcr;                        // SSE Status and Control bits (control bits are preserved across function calls)
-          uint16_t fcw;                         // X97 FPU control word (preserved across function calls)
+	    uint16_t fcw;                         // X97 FPU control word (preserved across function calls)
 	    void *rturn;                          // where to go on return from uSwitch
 	    void *dummyReturn;				// fake return compiler would have pushed on call to uInvoke
@@ -116,28 +111,28 @@
 	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this;     // argument to invoke
 	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
 
 #elif defined( __x86_64__ )
 
-      struct FakeStack {
-            void *fixedRegisters[5];            // fixed registers rbx, r12, r13, r14, r15
-            uint32_t mxcr;                      // SSE Status and Control bits (control bits are preserved across function calls)
-            uint16_t fcw;                       // X97 FPU control word (preserved across function calls)
-            void *rturn;                        // where to go on return from uSwitch
-            void *dummyReturn;                  // NULL return address to provide proper alignment
-      };
+	struct FakeStack {
+		void *fixedRegisters[5];            // fixed registers rbx, r12, r13, r14, r15
+		uint32_t mxcr;                      // SSE Status and Control bits (control bits are preserved across function calls)
+		uint16_t fcw;                       // X97 FPU control word (preserved across function calls)
+		void *rturn;                        // where to go on return from uSwitch
+		void *dummyReturn;                  // NULL return address to provide proper alignment
+	};
 
-      ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );
-      ((struct machine_context_t *)stack->context)->FP = NULL;		// terminate stack with NULL fp
+	((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );
+	((struct machine_context_t *)stack->context)->FP = NULL;		// terminate stack with NULL fp
 
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub;
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this;
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
-      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub;
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this;
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
+	((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
 #else
-      #error Only __i386__ and __x86_64__ is supported for threads in cfa
+	#error Only __i386__ and __x86_64__ is supported for threads in cfa
 #endif
 }
Index: src/libcfa/concurrency/kernel.c
===================================================================
--- src/libcfa/concurrency/kernel.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/kernel.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -14,6 +14,4 @@
 //
 
-#include "libhdr.h"
-
 //C Includes
 #include <stddef.h>
@@ -150,5 +148,5 @@
 
 	this.runner = &runner;
-	LIB_DEBUG_PRINT_SAFE("Kernel : constructing main processor context %p\n", &runner);
+	__cfaabi_dbg_print_safe("Kernel : constructing main processor context %p\n", &runner);
 	runner{ &this };
 }
@@ -156,5 +154,5 @@
 void ^?{}(processor & this) {
 	if( ! this.do_terminate ) {
-		LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", &this);
+		__cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
 		this.do_terminate = true;
 		P( this.terminated );
@@ -181,5 +179,5 @@
 	processor * this = runner.proc;
 
-	LIB_DEBUG_PRINT_SAFE("Kernel : core %p starting\n", this);
+	__cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
 
 	{
@@ -187,5 +185,5 @@
 		preemption_scope scope = { this };
 
-		LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);
+		__cfaabi_dbg_print_safe("Kernel : core %p started\n", this);
 
 		thread_desc * readyThread = NULL;
@@ -213,10 +211,10 @@
 		}
 
-		LIB_DEBUG_PRINT_SAFE("Kernel : core %p stopping\n", this);
+		__cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this);
 	}
 
 	V( this->terminated );
 
-	LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
+	__cfaabi_dbg_print_safe("Kernel : core %p terminated\n", this);
 }
 
@@ -292,5 +290,5 @@
 	processorCtx_t proc_cor_storage = { proc, &info };
 
-	LIB_DEBUG_PRINT_SAFE("Coroutine : created stack %p\n", proc_cor_storage.__cor.stack.base);
+	__cfaabi_dbg_print_safe("Coroutine : created stack %p\n", proc_cor_storage.__cor.stack.base);
 
 	//Set global state
@@ -299,5 +297,5 @@
 
 	//We now have a proper context from which to schedule threads
-	LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
+	__cfaabi_dbg_print_safe("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
 
 	// SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
@@ -310,5 +308,5 @@
 
 	// Main routine of the core returned, the core is now fully terminated
-	LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner);
+	__cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, proc->runner);
 
 	return NULL;
@@ -316,9 +314,9 @@
 
 void start(processor * this) {
-	LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
+	__cfaabi_dbg_print_safe("Kernel : Starting core %p\n", this);
 
 	pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
 
-	LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);
+	__cfaabi_dbg_print_safe("Kernel : core %p started\n", this);
 }
 
@@ -334,5 +332,5 @@
 	verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
 
-	lock(   this_processor->cltr->ready_queue_lock DEBUG_CTX2 );
+	lock(   this_processor->cltr->ready_queue_lock __cfaabi_dbg_ctx2 );
 	append( this_processor->cltr->ready_queue, thrd );
 	unlock( this_processor->cltr->ready_queue_lock );
@@ -343,5 +341,5 @@
 thread_desc * nextThread(cluster * this) {
 	verify( disable_preempt_count > 0 );
-	lock( this->ready_queue_lock DEBUG_CTX2 );
+	lock( this->ready_queue_lock __cfaabi_dbg_ctx2 );
 	thread_desc * head = pop_head( this->ready_queue );
 	unlock( this->ready_queue_lock );
@@ -355,5 +353,5 @@
 	suspend();
 	verify( disable_preempt_count > 0 );
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
@@ -367,5 +365,5 @@
 	verify( disable_preempt_count > 0 );
 
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
@@ -381,5 +379,5 @@
 	verify( disable_preempt_count > 0 );
 
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
@@ -395,5 +393,5 @@
 	verify( disable_preempt_count > 0 );
 
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
@@ -408,5 +406,5 @@
 	verify( disable_preempt_count > 0 );
 
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
@@ -423,5 +421,5 @@
 	verify( disable_preempt_count > 0 );
 
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
@@ -441,5 +439,5 @@
 // Kernel boot procedures
 void kernel_startup(void) {
-	LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");
+	__cfaabi_dbg_print_safe("Kernel : Starting\n");
 
 	// Start by initializing the main thread
@@ -450,5 +448,5 @@
 	(*mainThread){ &info };
 
-	LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
+	__cfaabi_dbg_print_safe("Kernel : Main thread ready\n");
 
 	// Initialize the main cluster
@@ -456,5 +454,5 @@
 	(*mainCluster){};
 
-	LIB_DEBUG_PRINT_SAFE("Kernel : main cluster ready\n");
+	__cfaabi_dbg_print_safe("Kernel : main cluster ready\n");
 
 	// Initialize the main processor and the main processor ctx
@@ -483,11 +481,11 @@
 
 	// THE SYSTEM IS NOW COMPLETELY RUNNING
-	LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
-
-	enable_interrupts( DEBUG_CTX );
+	__cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
+
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
 void kernel_shutdown(void) {
-	LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
+	__cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
 
 	disable_interrupts();
@@ -513,5 +511,5 @@
 	^(mainThread){};
 
-	LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");
+	__cfaabi_dbg_print_safe("Kernel : Shutdown complete\n");
 }
 
@@ -523,5 +521,5 @@
 	// abort cannot be recursively entered by the same or different processors because all signal handlers return when
 	// the globalAbort flag is true.
-	lock( kernel_abort_lock DEBUG_CTX2 );
+	lock( kernel_abort_lock __cfaabi_dbg_ctx2 );
 
 	// first task to abort ?
@@ -548,21 +546,21 @@
 
 	int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd );
-	__lib_debug_write( abort_text, len );
+	__cfaabi_dbg_bits_write( abort_text, len );
 
 	if ( thrd != this_coroutine ) {
 		len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
-		__lib_debug_write( abort_text, len );
+		__cfaabi_dbg_bits_write( abort_text, len );
 	}
 	else {
-		__lib_debug_write( ".\n", 2 );
+		__cfaabi_dbg_bits_write( ".\n", 2 );
 	}
 }
 
 extern "C" {
-	void __lib_debug_acquire() {
-		lock( kernel_debug_lock DEBUG_CTX2 );
-	}
-
-	void __lib_debug_release() {
+	void __cfaabi_dbg_bits_acquire() {
+		lock( kernel_debug_lock __cfaabi_dbg_ctx2 );
+	}
+
+	void __cfaabi_dbg_bits_release() {
 		unlock( kernel_debug_lock );
 	}
@@ -582,5 +580,5 @@
 
 void P(semaphore & this) {
-	lock( this.lock DEBUG_CTX2 );
+	lock( this.lock __cfaabi_dbg_ctx2 );
 	this.count -= 1;
 	if ( this.count < 0 ) {
@@ -598,5 +596,5 @@
 void V(semaphore & this) {
 	thread_desc * thrd = NULL;
-	lock( this.lock DEBUG_CTX2 );
+	lock( this.lock __cfaabi_dbg_ctx2 );
 	this.count += 1;
 	if ( this.count <= 0 ) {
Index: src/libcfa/concurrency/kernel_private.h
===================================================================
--- src/libcfa/concurrency/kernel_private.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/kernel_private.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -16,6 +16,4 @@
 #pragma once
 
-#include "libhdr.h"
-
 #include "kernel"
 #include "thread"
@@ -30,5 +28,5 @@
 	void disable_interrupts();
 	void enable_interrupts_noPoll();
-	void enable_interrupts( DEBUG_CTX_PARAM );
+	void enable_interrupts( __cfaabi_dbg_ctx_param );
 }
 
@@ -39,5 +37,5 @@
 	disable_interrupts();
 	ScheduleThread( thrd );
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 thread_desc * nextThread(cluster * this);
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/monitor.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -19,5 +19,4 @@
 #include <inttypes.h>
 
-#include "libhdr.h"
 #include "kernel_private.h"
 
@@ -91,8 +90,8 @@
 	static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) {
 		// Lock the monitor spinlock
-		DO_LOCK( this->lock DEBUG_CTX2 );
+		DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
 		thread_desc * thrd = this_thread;
 
-		LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
+		__cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
 
 		if( !this->owner ) {
@@ -100,5 +99,5 @@
 			set_owner( this, thrd );
 
-			LIB_DEBUG_PRINT_SAFE("Kernel :  mon is free \n");
+			__cfaabi_dbg_print_safe("Kernel :  mon is free \n");
 		}
 		else if( this->owner == thrd) {
@@ -106,5 +105,5 @@
 			this->recursion += 1;
 
-			LIB_DEBUG_PRINT_SAFE("Kernel :  mon already owned \n");
+			__cfaabi_dbg_print_safe("Kernel :  mon already owned \n");
 		}
 		else if( is_accepted( this, group) ) {
@@ -115,8 +114,8 @@
 			reset_mask( this );
 
-			LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts \n");
+			__cfaabi_dbg_print_safe("Kernel :  mon accepts \n");
 		}
 		else {
-			LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
+			__cfaabi_dbg_print_safe("Kernel :  blocking \n");
 
 			// Some one else has the monitor, wait in line for it
@@ -124,5 +123,5 @@
 			BlockInternal( &this->lock );
 
-			LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
+			__cfaabi_dbg_print_safe("Kernel : %10p Entered  mon %p\n", thrd, this);
 
 			// BlockInternal will unlock spinlock, no need to unlock ourselves
@@ -130,5 +129,5 @@
 		}
 
-		LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
+		__cfaabi_dbg_print_safe("Kernel : %10p Entered  mon %p\n", thrd, this);
 
 		// Release the lock and leave
@@ -139,12 +138,12 @@
 	static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
 		// Lock the monitor spinlock
-		DO_LOCK( this->lock DEBUG_CTX2 );
+		DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
 		thread_desc * thrd = this_thread;
 
-		LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
+		__cfaabi_dbg_print_safe("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
 
 
 		if( !this->owner ) {
-			LIB_DEBUG_PRINT_SAFE("Kernel : Destroying free mon %p\n", this);
+			__cfaabi_dbg_print_safe("Kernel : Destroying free mon %p\n", this);
 
 			// No one has the monitor, just take it
@@ -164,5 +163,5 @@
 		__monitor_group_t group = { &this, 1, func };
 		if( is_accepted( this, group) ) {
-			LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts dtor, block and signal it \n");
+			__cfaabi_dbg_print_safe("Kernel :  mon accepts dtor, block and signal it \n");
 
 			// Wake the thread that is waiting for this
@@ -183,5 +182,5 @@
 		}
 		else {
-			LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
+			__cfaabi_dbg_print_safe("Kernel :  blocking \n");
 
 			wait_ctx( this_thread, 0 )
@@ -196,5 +195,5 @@
 		}
 
-		LIB_DEBUG_PRINT_SAFE("Kernel : Destroying %p\n", this);
+		__cfaabi_dbg_print_safe("Kernel : Destroying %p\n", this);
 
 	}
@@ -203,7 +202,7 @@
 	void __leave_monitor_desc( monitor_desc * this ) {
 		// Lock the monitor spinlock, DO_LOCK to reduce contention
-		DO_LOCK( this->lock DEBUG_CTX2 );
-
-		LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
+		DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
+
+		__cfaabi_dbg_print_safe("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
 
 		verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", this_thread, this->owner, this->recursion, this );
@@ -215,5 +214,5 @@
 		// it means we don't need to do anything
 		if( this->recursion != 0) {
-			LIB_DEBUG_PRINT_SAFE("Kernel :  recursion still %d\n", this->recursion);
+			__cfaabi_dbg_print_safe("Kernel :  recursion still %d\n", this->recursion);
 			unlock( this->lock );
 			return;
@@ -232,5 +231,5 @@
 	// Leave single monitor for the last time
 	void __leave_dtor_monitor_desc( monitor_desc * this ) {
-		LIB_DEBUG_DO(
+		__cfaabi_dbg_debug_do(
 			if( this_thread != this->owner ) {
 				abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);
@@ -249,5 +248,5 @@
 
 		// Lock the monitor now
-		DO_LOCK( this->lock DEBUG_CTX2 );
+		DO_LOCK( this->lock __cfaabi_dbg_ctx2 );
 
 		disable_interrupts();
@@ -308,5 +307,5 @@
 	(this_thread->monitors){m, count, func};
 
-	// LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
+	// __cfaabi_dbg_print_safe("MGUARD : enter %d\n", count);
 
 	// Enter the monitors in order
@@ -314,5 +313,5 @@
 	enter( group );
 
-	// LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n");
+	// __cfaabi_dbg_print_safe("MGUARD : entered\n");
 }
 
@@ -320,10 +319,10 @@
 // Dtor for monitor guard
 void ^?{}( monitor_guard_t & this ) {
-	// LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);
+	// __cfaabi_dbg_print_safe("MGUARD : leaving %d\n", this.count);
 
 	// Leave the monitors in order
 	leave( this.m, this.count );
 
-	// LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");
+	// __cfaabi_dbg_print_safe("MGUARD : left\n");
 
 	// Restore thread context
@@ -430,5 +429,5 @@
 
 	//Some more checking in debug
-	LIB_DEBUG_DO(
+	__cfaabi_dbg_debug_do(
 		thread_desc * this_thrd = this_thread;
 		if ( this.monitor_count != this_thrd->monitors.size ) {
@@ -487,5 +486,5 @@
 	set_owner( monitors, count, signallee );
 
-	LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
+	__cfaabi_dbg_print_buffer_decl( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );
 
 	//Everything is ready to go to sleep
@@ -496,5 +495,5 @@
 
 
-	LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel :   signal_block returned\n" );
+	__cfaabi_dbg_print_buffer_local( "Kernel :   signal_block returned\n" );
 
 	//We are back, restore the masks and recursions
@@ -535,9 +534,9 @@
 	__lock_size_t actual_count = aggregate( mon_storage, mask );
 
-	LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max);
+	__cfaabi_dbg_print_buffer_decl( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max);
 
 	if(actual_count == 0) return;
 
-	LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : waitfor internal proceeding\n");
+	__cfaabi_dbg_print_buffer_local( "Kernel : waitfor internal proceeding\n");
 
 	// Create storage for monitor context
@@ -556,5 +555,5 @@
 			__acceptable_t& accepted = mask[index];
 			if( accepted.is_dtor ) {
-				LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : dtor already there\n");
+				__cfaabi_dbg_print_buffer_local( "Kernel : dtor already there\n");
 				verifyf( accepted.size == 1,  "ERROR: Accepted dtor has more than 1 mutex parameter." );
 
@@ -568,5 +567,5 @@
 			}
 			else {
-				LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : thread present, baton-passing\n");
+				__cfaabi_dbg_print_buffer_local( "Kernel : thread present, baton-passing\n");
 
 				// Create the node specific to this wait operation
@@ -576,11 +575,11 @@
 				monitor_save;
 
-				LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel :  baton of %d monitors : ", count );
+				__cfaabi_dbg_print_buffer_local( "Kernel :  baton of %d monitors : ", count );
 				#ifdef __CFA_DEBUG_PRINT__
 					for( int i = 0; i < count; i++) {
-						LIB_DEBUG_PRINT_BUFFER_LOCAL( "%p %p ", monitors[i], monitors[i]->signal_stack.top );
+						__cfaabi_dbg_print_buffer_local( "%p %p ", monitors[i], monitors[i]->signal_stack.top );
 					}
 				#endif
-				LIB_DEBUG_PRINT_BUFFER_LOCAL( "\n");
+				__cfaabi_dbg_print_buffer_local( "\n");
 
 				// Set the owners to be the next thread
@@ -593,8 +592,8 @@
 				monitor_restore;
 
-				LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : thread present, returned\n");
+				__cfaabi_dbg_print_buffer_local( "Kernel : thread present, returned\n");
 			}
 
-			LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : accepted %d\n", *mask.accepted);
+			__cfaabi_dbg_print_buffer_local( "Kernel : accepted %d\n", *mask.accepted);
 			return;
 		}
@@ -603,9 +602,9 @@
 
 	if( duration == 0 ) {
-		LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : non-blocking, exiting\n");
+		__cfaabi_dbg_print_buffer_local( "Kernel : non-blocking, exiting\n");
 
 		unlock_all( locks, count );
 
-		LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : accepted %d\n", *mask.accepted);
+		__cfaabi_dbg_print_buffer_local( "Kernel : accepted %d\n", *mask.accepted);
 		return;
 	}
@@ -614,5 +613,5 @@
 	verifyf( duration < 0, "Timeout on waitfor statments not supported yet.");
 
-	LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : blocking waitfor\n");
+	__cfaabi_dbg_print_buffer_local( "Kernel : blocking waitfor\n");
 
 	// Create the node specific to this wait operation
@@ -636,7 +635,7 @@
 	monitor_restore;
 
-	LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : exiting\n");
-
-	LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : accepted %d\n", *mask.accepted);
+	__cfaabi_dbg_print_buffer_local( "Kernel : exiting\n");
+
+	__cfaabi_dbg_print_buffer_local( "Kernel : accepted %d\n", *mask.accepted);
 }
 
@@ -645,5 +644,5 @@
 
 static inline void set_owner( monitor_desc * this, thread_desc * owner ) {
-	// LIB_DEBUG_PRINT_SAFE("Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
+	// __cfaabi_dbg_print_safe("Kernal :   Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );
 
 	//Pass the monitor appropriately
@@ -677,5 +676,5 @@
 static inline thread_desc * next_thread( monitor_desc * this ) {
 	//Check the signaller stack
-	LIB_DEBUG_PRINT_SAFE("Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
+	__cfaabi_dbg_print_safe("Kernel :  mon %p AS-stack top %p\n", this, this->signal_stack.top);
 	__condition_criterion_t * urgent = pop( this->signal_stack );
 	if( urgent ) {
@@ -729,5 +728,5 @@
 	for( __lock_size_t i = 0; i < count; i++) {
 		(criteria[i]){ monitors[i], waiter };
-		LIB_DEBUG_PRINT_SAFE( "Kernel :  target %p = %p\n", criteria[i].target, &criteria[i] );
+		__cfaabi_dbg_print_safe( "Kernel :  target %p = %p\n", criteria[i].target, &criteria[i] );
 		push( criteria[i].target->signal_stack, &criteria[i] );
 	}
@@ -738,5 +737,5 @@
 static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) {
 	for( __lock_size_t i = 0; i < count; i++ ) {
-		DO_LOCK( *locks[i] DEBUG_CTX2 );
+		DO_LOCK( *locks[i] __cfaabi_dbg_ctx2 );
 	}
 }
@@ -745,5 +744,5 @@
 	for( __lock_size_t i = 0; i < count; i++ ) {
 		__spinlock_t * l = &source[i]->lock;
-		DO_LOCK( *l DEBUG_CTX2 );
+		DO_LOCK( *l __cfaabi_dbg_ctx2 );
 		if(locks) locks[i] = l;
 	}
@@ -803,8 +802,8 @@
 	for(	int i = 0; i < count; i++ ) {
 
-		// LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
+		// __cfaabi_dbg_print_safe( "Checking %p for %p\n", &criteria[i], target );
 		if( &criteria[i] == target ) {
 			criteria[i].ready = true;
-			// LIB_DEBUG_PRINT_SAFE( "True\n" );
+			// __cfaabi_dbg_print_safe( "True\n" );
 		}
 
@@ -812,5 +811,5 @@
 	}
 
-	LIB_DEBUG_PRINT_SAFE( "Kernel :  Runing %i (%p)\n", ready2run, ready2run ? node->waiting_thread : NULL );
+	__cfaabi_dbg_print_safe( "Kernel :  Runing %i (%p)\n", ready2run, ready2run ? node->waiting_thread : NULL );
 	return ready2run ? node->waiting_thread : NULL;
 }
@@ -819,5 +818,5 @@
 	thread_desc * thrd = this_thread;
 	if( !this.monitors ) {
-		// LIB_DEBUG_PRINT_SAFE("Branding\n");
+		// __cfaabi_dbg_print_safe("Branding\n");
 		assertf( thrd->monitors.data != NULL, "No current monitor to brand condition %p", thrd->monitors.data );
 		this.monitor_count = thrd->monitors.size;
Index: src/libcfa/concurrency/preemption.c
===================================================================
--- src/libcfa/concurrency/preemption.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/preemption.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -14,5 +14,4 @@
 //
 
-#include "libhdr.h"
 #include "preemption.h"
 
@@ -148,5 +147,5 @@
 //=============================================================================================
 
-LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; )
+__cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; )
 
 extern "C" {
@@ -159,5 +158,5 @@
 	// Enable interrupts by decrementing the counter
 	// If counter reaches 0, execute any pending CtxSwitch
-	void enable_interrupts( DEBUG_CTX_PARAM ) {
+	void enable_interrupts( __cfaabi_dbg_ctx_param ) {
 		processor * proc   = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
 		thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
@@ -173,5 +172,5 @@
 
 		// For debugging purposes : keep track of the last person to enable the interrupts
-		LIB_DEBUG_DO( proc->last_enable = caller; )
+		__cfaabi_dbg_debug_do( proc->last_enable = caller; )
 	}
 
@@ -233,5 +232,5 @@
 // Called from kernel_startup
 void kernel_start_preemption() {
-	LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n");
+	__cfaabi_dbg_print_safe("Kernel : Starting preemption\n");
 
 	// Start with preemption disabled until ready
@@ -255,5 +254,5 @@
 // Called from kernel_shutdown
 void kernel_stop_preemption() {
-	LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopping\n");
+	__cfaabi_dbg_print_safe("Kernel : Preemption stopping\n");
 
 	// Block all signals since we are already shutting down
@@ -271,5 +270,5 @@
 	// Preemption is now fully stopped
 
-	LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");
+	__cfaabi_dbg_print_safe("Kernel : Preemption stopped\n");
 }
 
@@ -297,5 +296,5 @@
 // Receives SIGUSR1 signal and causes the current thread to yield
 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
-	LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
+	__cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
 
 	// Check if it is safe to preempt here
@@ -346,5 +345,5 @@
 		assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int);
 
-		// LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
+		// __cfaabi_dbg_print_safe("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
 		// Switch on the code (a.k.a. the sender) to
 		switch( info.si_code )
@@ -354,6 +353,6 @@
 		case SI_TIMER:
 		case SI_KERNEL:
-			// LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
-			lock( event_kernel->lock DEBUG_CTX2 );
+			// __cfaabi_dbg_print_safe("Kernel : Preemption thread tick\n");
+			lock( event_kernel->lock __cfaabi_dbg_ctx2 );
 			tick_preemption();
 			unlock( event_kernel->lock );
@@ -368,5 +367,5 @@
 
 EXIT:
-	LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n");
+	__cfaabi_dbg_print_safe("Kernel : Preemption thread stopping\n");
 	return NULL;
 }
@@ -380,5 +379,5 @@
 
 	if ( sigaction( sig, &act, NULL ) == -1 ) {
-		LIB_DEBUG_PRINT_BUFFER_DECL(
+		__cfaabi_dbg_print_buffer_decl(
 			" __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
 			sig, handler, flags, errno, strerror( errno )
@@ -397,5 +396,5 @@
 
 	if ( sigaction( sig, &act, NULL ) == -1 ) {
-		LIB_DEBUG_PRINT_BUFFER_DECL(
+		__cfaabi_dbg_print_buffer_decl(
 			" __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
 			sig, errno, strerror( errno )
@@ -409,5 +408,5 @@
 //=============================================================================================
 
-LIB_DEBUG_DO(
+__cfaabi_dbg_debug_do(
 	static void __kernel_backtrace( int start ) {
 		// skip first N stack frames
@@ -476,5 +475,5 @@
 
 // void sigHandler_segv( __CFA_SIGPARMS__ ) {
-// 	LIB_DEBUG_DO(
+// 	__cfaabi_dbg_debug_do(
 // 		#ifdef __USE_STREAM__
 // 		serr 	| "*CFA runtime error* program cfa-cpp terminated with"
@@ -493,5 +492,5 @@
 // void sigHandler_abort( __CFA_SIGPARMS__ ) {
 // 	// skip first 6 stack frames
-// 	LIB_DEBUG_DO( __kernel_backtrace( 6 ); )
+// 	__cfaabi_dbg_debug_do( __kernel_backtrace( 6 ); )
 
 // 	// reset default signal handler
Index: src/libcfa/concurrency/thread.c
===================================================================
--- src/libcfa/concurrency/thread.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/concurrency/thread.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -17,5 +17,4 @@
 
 #include "kernel_private.h"
-#include "libhdr.h"
 
 #define __CFA_INVOKE_PRIVATE__
@@ -72,5 +71,5 @@
 	thrd_c->last = this_coroutine;
 
-	// LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
+	// __cfaabi_dbg_print_safe("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
 
 	disable_interrupts();
@@ -82,5 +81,5 @@
 
 	ScheduleThread(thrd_h);
-	enable_interrupts( DEBUG_CTX );
+	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
Index: src/libcfa/exception.c
===================================================================
--- src/libcfa/exception.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/exception.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -23,5 +23,5 @@
 #include <stdio.h>
 #include <unwind.h>
-#include <libhdr/libdebug.h>
+#include <bits/debug.h>
 
 // FIX ME: temporary hack to keep ARM build working
@@ -37,6 +37,6 @@
 
 // Base exception vtable is abstract, you should not have base exceptions.
-struct __cfaehm__base_exception_t_vtable
-		___cfaehm__base_exception_t_vtable_instance = {
+struct __cfaabi_ehm__base_exception_t_vtable
+		___cfaabi_ehm__base_exception_t_vtable_instance = {
 	.parent = NULL,
 	.size = 0,
@@ -49,6 +49,6 @@
 // Temperary global exception context. Does not work with concurency.
 struct exception_context_t {
-    struct __cfaehm__try_resume_node * top_resume;
-    struct __cfaehm__try_resume_node * current_resume;
+    struct __cfaabi_ehm__try_resume_node * top_resume;
+    struct __cfaabi_ehm__try_resume_node * current_resume;
 
     exception * current_exception;
@@ -78,10 +78,10 @@
 // RESUMPTION ================================================================
 
-void __cfaehm__throw_resume(exception * except) {
-
-	LIB_DEBUG_PRINT_SAFE("Throwing resumption exception\n");
-
-	struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume;
-	struct __cfaehm__try_resume_node * current =
+void __cfaabi_ehm__throw_resume(exception * except) {
+
+	__cfaabi_dbg_print_safe("Throwing resumption exception\n");
+
+	struct __cfaabi_ehm__try_resume_node * original_head = shared_stack.current_resume;
+	struct __cfaabi_ehm__try_resume_node * current =
 		(original_head) ? original_head->next : shared_stack.top_resume;
 
@@ -94,9 +94,9 @@
 	}
 
-	LIB_DEBUG_PRINT_SAFE("Unhandled exception\n");
+	__cfaabi_dbg_print_safe("Unhandled exception\n");
 	shared_stack.current_resume = original_head;
 
 	// Fall back to termination:
-	__cfaehm__throw_terminate(except);
+	__cfaabi_ehm__throw_terminate(except);
 	// TODO: Default handler for resumption.
 }
@@ -105,5 +105,5 @@
 // hook has to be added after the node is built but before it is made the top node.
 
-void __cfaehm__try_resume_setup(struct __cfaehm__try_resume_node * node,
+void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node,
                         _Bool (*handler)(exception * except)) {
 	node->next = shared_stack.top_resume;
@@ -112,5 +112,5 @@
 }
 
-void __cfaehm__try_resume_cleanup(struct __cfaehm__try_resume_node * node) {
+void __cfaabi_ehm__try_resume_cleanup(struct __cfaabi_ehm__try_resume_node * node) {
 	shared_stack.top_resume = node->next;
 }
@@ -122,18 +122,18 @@
 // May have to move to cfa for constructors and destructors (references).
 
-struct __cfaehm__node {
-	struct __cfaehm__node * next;
+struct __cfaabi_ehm__node {
+	struct __cfaabi_ehm__node * next;
 };
 
 #define NODE_TO_EXCEPT(node) ((exception *)(1 + (node)))
-#define EXCEPT_TO_NODE(except) ((struct __cfaehm__node *)(except) - 1)
+#define EXCEPT_TO_NODE(except) ((struct __cfaabi_ehm__node *)(except) - 1)
 
 // Creates a copy of the indicated exception and sets current_exception to it.
-static void __cfaehm__allocate_exception( exception * except ) {
+static void __cfaabi_ehm__allocate_exception( exception * except ) {
 	struct exception_context_t * context = this_exception_context();
 
 	// Allocate memory for the exception.
-	struct __cfaehm__node * store = malloc(
-		sizeof( struct __cfaehm__node ) + except->virtual_table->size );
+	struct __cfaabi_ehm__node * store = malloc(
+		sizeof( struct __cfaabi_ehm__node ) + except->virtual_table->size );
 
 	if ( ! store ) {
@@ -151,12 +151,12 @@
 
 // Delete the provided exception, unsetting current_exception if relivant.
-static void __cfaehm__delete_exception( exception * except ) {
+static void __cfaabi_ehm__delete_exception( exception * except ) {
 	struct exception_context_t * context = this_exception_context();
 
-	LIB_DEBUG_PRINT_SAFE("Deleting Exception\n");
+	__cfaabi_dbg_print_safe("Deleting Exception\n");
 
 	// Remove the exception from the list.
-	struct __cfaehm__node * to_free = EXCEPT_TO_NODE(except);
-	struct __cfaehm__node * node;
+	struct __cfaabi_ehm__node * to_free = EXCEPT_TO_NODE(except);
+	struct __cfaabi_ehm__node * node;
 
 	if ( context->current_exception == except ) {
@@ -178,6 +178,6 @@
 
 // If this isn't a rethrow (*except==0), delete the provided exception.
-void __cfaehm__cleanup_terminate( void * except ) {
-	if ( *(void**)except ) __cfaehm__delete_exception( *(exception**)except );
+void __cfaabi_ehm__cleanup_terminate( void * except ) {
+	if ( *(void**)except ) __cfaabi_ehm__delete_exception( *(exception**)except );
 }
 
@@ -202,5 +202,5 @@
 
 // The exception that is being thrown must already be stored.
-__attribute__((noreturn)) void __cfaehm__begin_unwind(void) {
+__attribute__((noreturn)) void __cfaabi_ehm__begin_unwind(void) {
 	if ( ! this_exception_context()->current_exception ) {
 		printf("UNWIND ERROR missing exception in begin unwind\n");
@@ -233,15 +233,15 @@
 }
 
-void __cfaehm__throw_terminate( exception * val ) {
-	LIB_DEBUG_PRINT_SAFE("Throwing termination exception\n");
-
-	__cfaehm__allocate_exception( val );
-	__cfaehm__begin_unwind();
-}
-
-void __cfaehm__rethrow_terminate(void) {
-	LIB_DEBUG_PRINT_SAFE("Rethrowing termination exception\n");
-
-	__cfaehm__begin_unwind();
+void __cfaabi_ehm__throw_terminate( exception * val ) {
+	__cfaabi_dbg_print_safe("Throwing termination exception\n");
+
+	__cfaabi_ehm__allocate_exception( val );
+	__cfaabi_ehm__begin_unwind();
+}
+
+void __cfaabi_ehm__rethrow_terminate(void) {
+	__cfaabi_dbg_print_safe("Rethrowing termination exception\n");
+
+	__cfaabi_ehm__begin_unwind();
 }
 
@@ -254,6 +254,6 @@
 {
 
-	//LIB_DEBUG_PRINT_SAFE("CFA: 0x%lx\n", _Unwind_GetCFA(context));
-	LIB_DEBUG_PRINT_SAFE("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
+	//__cfaabi_dbg_print_safe("CFA: 0x%lx\n", _Unwind_GetCFA(context));
+	__cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
 
 	// If we've reached the end of the stack then there is nothing much we can do...
@@ -261,8 +261,8 @@
 
 	if (actions & _UA_SEARCH_PHASE) {
-		LIB_DEBUG_PRINT_SAFE(" lookup phase");
+		__cfaabi_dbg_print_safe(" lookup phase");
 	}
 	else if (actions & _UA_CLEANUP_PHASE) {
-		LIB_DEBUG_PRINT_SAFE(" cleanup phase");
+		__cfaabi_dbg_print_safe(" cleanup phase");
 	}
 	// Just in case, probably can't actually happen
@@ -307,5 +307,5 @@
 			void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
 			void * ip = (void*)instruction_ptr;
-			LIB_DEBUG_PRINT_SAFE("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
+			__cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
 #endif // __CFA_DEBUG_PRINT__
 			continue;
@@ -346,5 +346,5 @@
 
 					// Get a function pointer from the relative offset and call it
-					// _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;					
+					// _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;
 
 					_Unwind_Reason_Code (*matcher)(exception *) =
@@ -357,7 +357,7 @@
 					// Based on the return value, check if we matched the exception
 					if( ret == _URC_HANDLER_FOUND) {
-						LIB_DEBUG_PRINT_SAFE(" handler found\n");
+						__cfaabi_dbg_print_safe(" handler found\n");
 					} else {
-						LIB_DEBUG_PRINT_SAFE(" no handler\n");
+						__cfaabi_dbg_print_safe(" no handler\n");
 					}
 					return ret;
@@ -365,5 +365,5 @@
 
 				// This is only a cleanup handler, ignore it
-				LIB_DEBUG_PRINT_SAFE(" no action");
+				__cfaabi_dbg_print_safe(" no action");
 			}
 			else if (actions & _UA_CLEANUP_PHASE) {
@@ -385,5 +385,5 @@
 				_Unwind_SetIP( context, ((lsd_info.LPStart) + (callsite_landing_pad)) );
 
-				LIB_DEBUG_PRINT_SAFE(" action\n");
+				__cfaabi_dbg_print_safe(" action\n");
 
 				// Return have some action to run
@@ -393,11 +393,11 @@
 
 		// Nothing to do, move along
-		LIB_DEBUG_PRINT_SAFE(" no landing pad");
+		__cfaabi_dbg_print_safe(" no landing pad");
 	}
 	// No handling found
-	LIB_DEBUG_PRINT_SAFE(" table end reached\n");
+	__cfaabi_dbg_print_safe(" table end reached\n");
 
 	UNWIND:
-	LIB_DEBUG_PRINT_SAFE(" unwind\n");
+	__cfaabi_dbg_print_safe(" unwind\n");
 
 	// Keep unwinding the stack
@@ -408,5 +408,5 @@
 // libcfa but there is one problem left, see the exception table for details
 __attribute__((noinline))
-void __cfaehm__try_terminate(void (*try_block)(),
+void __cfaabi_ehm__try_terminate(void (*try_block)(),
 		void (*catch_block)(int index, exception * except),
 		__attribute__((unused)) int (*match_block)(exception * except)) {
@@ -466,11 +466,11 @@
 	// Body uses language specific data and therefore could be modified arbitrarily
 	".LLSDACSBCFA2:\n"						// BODY start
-	"	.uleb128 .TRYSTART-__cfaehm__try_terminate\n"		// Handled area start  (relative to start of function)
+	"	.uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"		// Handled area start  (relative to start of function)
 	"	.uleb128 .TRYEND-.TRYSTART\n"				// Handled area length
-	"	.uleb128 .CATCH-__cfaehm__try_terminate\n"				// Hanlder landing pad adress  (relative to start of function)
+	"	.uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"				// Hanlder landing pad adress  (relative to start of function)
 	"	.uleb128 1\n"						// Action code, gcc seems to use always 0
 	".LLSDACSECFA2:\n"						// BODY end
 	"	.text\n"							// TABLE footer
-	"	.size	__cfaehm__try_terminate, .-__cfaehm__try_terminate\n"
+	"	.size	__cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
 	"	.ident	\"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
 //	"	.section	.note.GNU-stack,\"x\",@progbits\n"
Index: src/libcfa/exception.h
===================================================================
--- src/libcfa/exception.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/exception.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -21,28 +21,28 @@
 #endif
 
-struct __cfaehm__base_exception_t;
-typedef struct __cfaehm__base_exception_t exception;
-struct __cfaehm__base_exception_t_vtable {
-	const struct __cfaehm__base_exception_t_vtable * parent;
+struct __cfaabi_ehm__base_exception_t;
+typedef struct __cfaabi_ehm__base_exception_t exception;
+struct __cfaabi_ehm__base_exception_t_vtable {
+	const struct __cfaabi_ehm__base_exception_t_vtable * parent;
 	size_t size;
-	void (*copy)(struct __cfaehm__base_exception_t *this,
-	             struct __cfaehm__base_exception_t * other);
-	void (*free)(struct __cfaehm__base_exception_t *this);
-	const char * (*msg)(struct __cfaehm__base_exception_t *this);
+	void (*copy)(struct __cfaabi_ehm__base_exception_t *this,
+	             struct __cfaabi_ehm__base_exception_t * other);
+	void (*free)(struct __cfaabi_ehm__base_exception_t *this);
+	const char * (*msg)(struct __cfaabi_ehm__base_exception_t *this);
 };
-struct __cfaehm__base_exception_t {
-	struct __cfaehm__base_exception_t_vtable const * virtual_table;
+struct __cfaabi_ehm__base_exception_t {
+	struct __cfaabi_ehm__base_exception_t_vtable const * virtual_table;
 };
-extern struct __cfaehm__base_exception_t_vtable
-	___cfaehm__base_exception_t_vtable_instance;
+extern struct __cfaabi_ehm__base_exception_t_vtable
+	___cfaabi_ehm__base_exception_t_vtable_instance;
 
 
 // Used in throw statement translation.
-void __cfaehm__throw_terminate(exception * except) __attribute__((noreturn));
-void __cfaehm__rethrow_terminate() __attribute__((noreturn));
-void __cfaehm__throw_resume(exception * except);
+void __cfaabi_ehm__throw_terminate(exception * except) __attribute__((noreturn));
+void __cfaabi_ehm__rethrow_terminate() __attribute__((noreturn));
+void __cfaabi_ehm__throw_resume(exception * except);
 
 // Function catches termination exceptions.
-void __cfaehm__try_terminate(
+void __cfaabi_ehm__try_terminate(
     void (*try_block)(),
     void (*catch_block)(int index, exception * except),
@@ -50,21 +50,21 @@
 
 // Clean-up the exception in catch blocks.
-void __cfaehm__cleanup_terminate(void * except);
+void __cfaabi_ehm__cleanup_terminate(void * except);
 
 // Data structure creates a list of resume handlers.
-struct __cfaehm__try_resume_node {
-    struct __cfaehm__try_resume_node * next;
+struct __cfaabi_ehm__try_resume_node {
+    struct __cfaabi_ehm__try_resume_node * next;
     _Bool (*handler)(exception * except);
 };
 
 // These act as constructor and destructor for the resume node.
-void __cfaehm__try_resume_setup(
-    struct __cfaehm__try_resume_node * node,
+void __cfaabi_ehm__try_resume_setup(
+    struct __cfaabi_ehm__try_resume_node * node,
     _Bool (*handler)(exception * except));
-void __cfaehm__try_resume_cleanup(
-    struct __cfaehm__try_resume_node * node);
+void __cfaabi_ehm__try_resume_cleanup(
+    struct __cfaabi_ehm__try_resume_node * node);
 
 // Check for a standard way to call fake deconstructors.
-struct __cfaehm__cleanup_hook {};
+struct __cfaabi_ehm__cleanup_hook {};
 
 #ifdef __cforall
Index: src/libcfa/interpose.c
===================================================================
--- src/libcfa/interpose.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/interpose.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -24,6 +24,6 @@
 }
 
-#include "libhdr/libdebug.h"
-#include "libhdr/libtools.h"
+#include "bits/debug.h"
+#include "bits/defs.h"
 #include "startup.h"
 
@@ -69,6 +69,4 @@
 __typeof__( exit ) libc_exit __attribute__(( noreturn ));
 __typeof__( abort ) libc_abort __attribute__(( noreturn ));
-
-// #define INIT_REALRTN( x, ver ) libc_##x = (__typeof__(libc_##x))interpose_symbol( #x, ver )
 
 forall(dtype T)
@@ -127,10 +125,10 @@
 			va_end( args );
 
-			__lib_debug_write( abort_text, len );
-			__lib_debug_write( "\n", 1 );
+			__cfaabi_dbg_bits_write( abort_text, len );
+			__cfaabi_dbg_bits_write( "\n", 1 );
 		}
 
 		len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld)\n", (long int)getpid() ); // use UNIX pid (versus getPid)
-		__lib_debug_write( abort_text, len );
+		__cfaabi_dbg_bits_write( abort_text, len );
 
 
Index: c/libcfa/libhdr.h
===================================================================
--- src/libcfa/libhdr.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,25 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// libhdr.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Mon Nov 28 12:27:26 2016
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:56:32 2017
-// Update Count     : 1
-//
-
-#pragma once
-
-#include "libhdr/libalign.h"
-#include "libhdr/libdebug.h"
-#include "libhdr/libtools.h"
-
-// Local Variables: //
-// mode: c //
-// tab-width: 4 //
-// End: //
Index: c/libcfa/libhdr/libalign.h
===================================================================
--- src/libcfa/libhdr/libalign.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,62 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// libdebug.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Mon Nov 28 12:27:26 2016
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul 21 23:05:35 2017
-// Update Count     : 2
-//
-// This  library is free  software; you  can redistribute  it and/or  modify it
-// under the terms of the GNU Lesser General Public License as published by the
-// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
-// option) any later version.
-//
-// This library is distributed in the  hope that it will be useful, but WITHOUT
-// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
-// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
-// for more details.
-//
-// You should  have received a  copy of the  GNU Lesser General  Public License
-// along  with this library.
-//
-
-#pragma once
-
-#include <assert.h>
-#include <stdbool.h>
-
-// Minimum size used to align memory boundaries for memory allocations.
-#define libAlign() (sizeof(double))
-
-// Check for power of 2
-static inline bool libPow2( unsigned long int value ) {
-    // clears all bits below value, rounding value down to the next lower multiple of value
-    return (value & (value - 1ul)) == 0ul;
-} // libPow2
-
-
-// Returns value aligned at the floor of align.
-static inline unsigned long int libFloor( unsigned long int value, unsigned long int align ) {
-    assert( libPow2( align ) );
-    // clears all bits above or equal to align, getting (value % align), the phase of value with regards to align
-    return value & -align;
-} // libFloor
-
-
-// Returns value aligned at the ceiling of align.
-
-static inline unsigned long int libCeiling( unsigned long int value, unsigned long int align ) {
-    assert( libPow2( align ) );
-    // "negate, round down, negate" is the same as round up
-    return -libFloor( -value, align );
-} // uCeiling
-
-// Local Variables: //
-// compile-command: "make install" //
-// End: //
Index: c/libcfa/libhdr/libdebug.c
===================================================================
--- src/libcfa/libhdr/libdebug.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,88 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// libdebug.c --
-//
-// Author           : Thierry Delisle
-// Created On       : Thu Mar 30 12:30:01 2017
-// Last Modified By :
-// Last Modified On :
-// Update Count     : 0
-//
-
-extern "C" {
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <unistd.h>
-}
-
-enum { buffer_size = 512 };
-static char buffer[ buffer_size ];
-
-extern "C" {
-
-	void __lib_debug_write( const char *in_buffer, int len ) {
-		// ensure all data is written
-		for ( int count = 0, retcode; count < len; count += retcode ) {
-			in_buffer += count;
-
-			for ( ;; ) {
-				retcode = write( STDERR_FILENO, in_buffer, len - count );
-
-				// not a timer interrupt ?
-				if ( retcode != -1 || errno != EINTR ) break;
-			}
-
-			if ( retcode == -1 ) _exit( EXIT_FAILURE );
-		}
-	}
-
-	void __lib_debug_acquire() __attribute__((__weak__)) {}
-	void __lib_debug_release() __attribute__((__weak__)) {}
-
-	void __lib_debug_print_safe  ( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) {
-		va_list args;
-
-		va_start( args, fmt );
-		__lib_debug_acquire();
-
-		int len = vsnprintf( buffer, buffer_size, fmt, args );
-		__lib_debug_write( buffer, len );
-
-		__lib_debug_release();
-		va_end( args );
-	}
-
-	void __lib_debug_print_nolock( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) {
-		va_list args;
-
-		va_start( args, fmt );
-
-		int len = vsnprintf( buffer, buffer_size, fmt, args );
-		__lib_debug_write( buffer, len );
-
-		va_end( args );
-	}
-
-	void __lib_debug_print_vararg( const char fmt[], va_list args ) {
-		int len = vsnprintf( buffer, buffer_size, fmt, args );
-		__lib_debug_write( buffer, len );
-	}
-
-	void __lib_debug_print_buffer( char in_buffer[], int in_buffer_size, const char fmt[], ... ) __attribute__(( format (printf, 3, 4) )) {
-		va_list args;
-
-		va_start( args, fmt );
-
-		int len = vsnprintf( in_buffer, in_buffer_size, fmt, args );
-		__lib_debug_write( in_buffer, len );
-
-		va_end( args );
-	}
-}
Index: c/libcfa/libhdr/libdebug.h
===================================================================
--- src/libcfa/libhdr/libdebug.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,83 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// libdebug.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Mon Nov 28 12:27:26 2016
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 10:02:24 2017
-// Update Count     : 1
-//
-
-#pragma once
-
-#ifdef __CFA_DEBUG__
-	#define LIB_DEBUG_DO(...) __VA_ARGS__
-	#define LIB_NO_DEBUG_DO(...)
-	#define DEBUG_CTX __PRETTY_FUNCTION__
-	#define DEBUG_CTX2 , __PRETTY_FUNCTION__
-	#define DEBUG_CTX_PARAM const char * caller
-	#define DEBUG_CTX_PARAM2 , const char * caller
-#else
-	#define LIB_DEBUG_DO(...)
-	#define LIB_NO_DEBUG_DO(...) __VA_ARGS__
-	#define DEBUG_CTX
-	#define DEBUG_CTX2
-	#define DEBUG_CTX_PARAM
-	#define DEBUG_CTX_PARAM2
-#endif
-
-#if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__))
-	#define verify(x) assert(x)
-	#define verifyf(x, ...) assertf(x, __VA_ARGS__)
-#else
-	#define verify(x)
-	#define verifyf(x, ...)
-#endif
-
-
-#ifdef __cforall
-extern "C" {
-#endif
-	#include <stdarg.h>
-	#include <stdio.h>
-
-      extern void __lib_debug_write( const char *buffer, int len );
-      extern void __lib_debug_acquire();
-      extern void __lib_debug_release();
-      extern void __lib_debug_print_safe  ( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) ));
-      extern void __lib_debug_print_nolock( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) ));
-      extern void __lib_debug_print_vararg( const char fmt[], va_list arg );
-      extern void __lib_debug_print_buffer( char buffer[], int buffer_size, const char fmt[], ... ) __attribute__(( format (printf, 3, 4) ));
-#ifdef __cforall
-}
-#endif
-
-#ifdef __CFA_DEBUG_PRINT__
-	#define LIB_DEBUG_WRITE( buffer, len )         __lib_debug_write( buffer, len )
-	#define LIB_DEBUG_ACQUIRE()                    __lib_debug_acquire()
-	#define LIB_DEBUG_RELEASE()                    __lib_debug_release()
-	#define LIB_DEBUG_PRINT_SAFE(...)              __lib_debug_print_safe   (__VA_ARGS__)
-	#define LIB_DEBUG_PRINT_NOLOCK(...)            __lib_debug_print_nolock (__VA_ARGS__)
-	#define LIB_DEBUG_PRINT_BUFFER(...)            __lib_debug_print_buffer (__VA_ARGS__)
-	#define LIB_DEBUG_PRINT_BUFFER_DECL(...)       char __dbg_text[256]; int __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __lib_debug_write( __dbg_text, __dbg_len );
-	#define LIB_DEBUG_PRINT_BUFFER_LOCAL(...)      __dbg_len = snprintf( __dbg_text, 256, __VA_ARGS__ ); __lib_debug_write( __dbg_text, __dbg_len );
-#else
-	#define LIB_DEBUG_WRITE(...)               ((void)0)
-	#define LIB_DEBUG_ACQUIRE()                ((void)0)
-	#define LIB_DEBUG_RELEASE()                ((void)0)
-	#define LIB_DEBUG_PRINT_SAFE(...)          ((void)0)
-	#define LIB_DEBUG_PRINT_NOLOCK(...)        ((void)0)
-	#define LIB_DEBUG_PRINT_BUFFER(...)        ((void)0)
-	#define LIB_DEBUG_PRINT_BUFFER_DECL(...)   ((void)0)
-	#define LIB_DEBUG_PRINT_BUFFER_LOCAL(...)  ((void)0)
-#endif
-
-// Local Variables: //
-// mode: c //
-// tab-width: 4 //
-// End: //
Index: c/libcfa/libhdr/libtools.h
===================================================================
--- src/libcfa/libhdr/libtools.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ 	(revision )
@@ -1,34 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// ools.h --
-//
-// Author           : Thierry Delisle
-// Created On       : Mon Nov 28 12:27:26 2016
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 10:02:10 2017
-// Update Count     : 1
-//
-
-#pragma once
-
-// void abortf( const char *fmt, ... ) {
-//     abort();
-//     // CONTROL NEVER REACHES HERE!
-// } // libAbort
-
-#ifdef __cforall
-extern "C" {
-#endif
-void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__));
-#ifdef __cforall
-}
-#endif
-
-// Local Variables: //
-// mode: c //
-// tab-width: 4 //
-// End: //
Index: src/libcfa/stdhdr/assert.h
===================================================================
--- src/libcfa/stdhdr/assert.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/libcfa/stdhdr/assert.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -30,4 +30,12 @@
 #endif
 
+#if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__))
+	#define verify(x) assert(x)
+	#define verifyf(x, ...) assertf(x, __VA_ARGS__)
+#else
+	#define verify(x)
+	#define verifyf(x, ...)
+#endif
+
 #ifdef __cforall
 } // extern "C"
Index: src/prelude/builtins.c
===================================================================
--- src/prelude/builtins.c	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/prelude/builtins.c	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -16,5 +16,5 @@
 // exception implementation
 
-typedef unsigned long long __cfaabi_exception_type_t;
+typedef unsigned long long __cfaabi_abi_exception_type_t;
 
 #include "../libcfa/virtual.h"
@@ -80,7 +80,7 @@
 } // ?\?
 
-// FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither 
-// defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify 
-// X as a type that casts to double, yet it doesn't make sense to write functions with that type 
+// FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither
+// defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify
+// X as a type that casts to double, yet it doesn't make sense to write functions with that type
 // signature where X is double.
 
Index: src/tests/except-mac.h
===================================================================
--- src/tests/except-mac.h	(revision 882ad37047443824102ef071eaf49540b434c634)
+++ src/tests/except-mac.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
@@ -7,5 +7,5 @@
 
 // The fully (perhaps overly) qualified name of the base exception type:
-#define BASE_EXCEPT __cfaehm__base_exception_t
+#define BASE_EXCEPT __cfaabi_ehm__base_exception_t
 
 // Get the name of the vtable type and vtable instance for an exception type:
