Index: Jenkins/FullBuild
===================================================================
--- Jenkins/FullBuild	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ Jenkins/FullBuild	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -9,28 +9,25 @@
 
 	try {
-		//Prevent the build from exceeding 30 minutes
-		timeout(60) {
+		//Wrap build to add timestamp to command line
+		wrap([$class: 'TimestamperBuildWrapper']) {
 
-			//Wrap build to add timestamp to command line
-			wrap([$class: 'TimestamperBuildWrapper']) {
+			stage('Build') {
 
-				stage 'Build'
+				results = [null, null]
 
-					results = [null, null]
+				parallel (
+					gcc_6_x64: { trigger_build( 'gcc-6',   'x64', true  ) },
+					gcc_6_x86: { trigger_build( 'gcc-6',   'x86', true  ) },
+					gcc_5_x64: { trigger_build( 'gcc-5',   'x64', false ) },
+					gcc_5_x86: { trigger_build( 'gcc-5',   'x86', false ) },
+					gcc_4_x64: { trigger_build( 'gcc-4.9', 'x64', false ) },
+					gcc_4_x86: { trigger_build( 'gcc-4.9', 'x86', false ) },
+					clang_x64: { trigger_build( 'clang',   'x64', false ) },
+					clang_x86: { trigger_build( 'clang',   'x86', false ) },
+				)
+			}
 
-					parallel (
-						gcc_6_x64: { trigger_build( 'gcc-6',   'x64', true  ) },
-						gcc_6_x86: { trigger_build( 'gcc-6',   'x86', true  ) },
-						gcc_5_x64: { trigger_build( 'gcc-5',   'x64', false ) },
-						gcc_5_x86: { trigger_build( 'gcc-5',   'x86', false ) },
-						gcc_4_x64: { trigger_build( 'gcc-4.9', 'x64', false ) },
-						gcc_4_x86: { trigger_build( 'gcc-4.9', 'x86', false ) },
-						clang_x64: { trigger_build( 'clang',   'x64', false ) },
-						clang_x86: { trigger_build( 'clang',   'x86', false ) },
-					)
-
-				//Push latest changes to do-lang repo
-				push_build()
-			}
+			//Push latest changes to do-lang repo
+			push_build()
 		}
 	}
@@ -99,5 +96,5 @@
 def push_build() {
 	//Don't use the build_stage function which outputs the compiler
-	stage 'Push'
+	stage('Push') {
 
 		status_prefix = 'Push'
@@ -122,4 +119,5 @@
 		//sh "GIT_SSH_COMMAND=\"ssh -v\" git push DoLang ${gitRefNewValue}:master"
 		echo('BUILD NOT PUSH SINCE DO-LANG SERVER WAS DOWN')
+	}
 }
 
Index: Jenkinsfile
===================================================================
--- Jenkinsfile	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ Jenkinsfile	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -28,27 +28,23 @@
 		wrap([$class: 'TimestamperBuildWrapper']) {
 
-			//Prevent the build from exceeding 60 minutes
-			timeout(60) {
-
-				notify_server()
-
-				prepare_build()
-
-				checkout()
-
-				build()
-
-				test()
-
-				benchmark()
-
-				clean()
-
-				build_doc()
-
-				publish()
-
-				notify_server()
-			}
+			notify_server()
+
+			prepare_build()
+
+			checkout()
+
+			build()
+
+			test()
+
+			benchmark()
+
+			clean()
+
+			build_doc()
+
+			publish()
+
+			notify_server()
 		}
 	}
@@ -89,4 +85,6 @@
 def collect_git_info() {
 
+	checkout scm
+
 	//create the temporary output directory in case it doesn't already exist
 	def out_dir = pwd tmp: true
@@ -95,7 +93,5 @@
 	//parse git logs to find what changed
 	gitRefName = env.BRANCH_NAME
-	dir("../${gitRefName}@script") {
-		sh "git reflog > ${out_dir}/GIT_COMMIT"
-	}
+	sh "git reflog > ${out_dir}/GIT_COMMIT"
 	git_reflog = readFile("${out_dir}/GIT_COMMIT")
 	gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1]
@@ -170,7 +166,7 @@
 }
 
-def build_stage(String name) {
+def build_stage(String name, Closure block ) {
 	stage_name = name
-	stage name
+	stage(name, block)
 }
 
@@ -245,5 +241,5 @@
 //Compilation script is done here but environnement set-up and error handling is done in main loop
 def checkout() {
-	build_stage'Checkout'
+	build_stage('Checkout') {
 		//checkout the source code and clean the repo
 		checkout scm
@@ -254,8 +250,9 @@
 		//Reset the git repo so no local changes persist
 		sh 'git reset --hard'
+	}
 }
 
 def build() {
-	build_stage'Build'
+	build_stage('Build') {
 	
 		def install_dir = pwd tmp: true
@@ -269,21 +266,23 @@
 		//Compile the project
 		sh 'make -j 8 --no-print-directory V=0 install'
+	}
 }
 
 def test() {
-	build_stage'Test'
+	build_stage('Test') {
 
 		//Run the tests from the tests directory
 		if ( do_alltests ) {
-			sh 'make -C src/tests all-tests debug=yes'
-			sh 'make -C src/tests all-tests debug=no'
+			sh 'make -C src/tests all-tests debug=yes --no-print-directory'
+			sh 'make -C src/tests all-tests debug=no --no-print-directory'
 		}
 		else {
-			sh 'make -C src/tests'
-		}
+			sh 'make -C src/tests --no-print-directory'
+		}
+	}
 }
 
 def benchmark() {
-	build_stage'Benchmark'
+	build_stage('Benchmark') {
 
 		if( !do_benchmark ) return
@@ -294,15 +293,17 @@
 		//Append bench results
 		sh 'make -C src/benchmark --no-print-directory csv-data >> bench.csv'
+	}
 }
 
 def clean() {
-	build_stage'Cleanup'
+	build_stage('Cleanup') {
 
 		//do a maintainer-clean to make sure we need to remake from scratch
 		sh 'make maintainer-clean > /dev/null'
+	}
 }
 
 def build_doc() {
-	build_stage'Documentation'
+	build_stage('Documentation') {
 
 		if( !do_doc ) return
@@ -315,8 +316,9 @@
 			make_doc()
 		}
+	}
 }
 
 def publish() {
-	build_stage'Publish'
+	build_stage('Publish') {
 
 		if( !do_publish ) return
@@ -324,4 +326,5 @@
 		//Then publish the results
 		sh 'curl --silent --data @bench.csv http://plg2:8082/jenkins/publish > /dev/null || true'
+	}
 }
 
@@ -371,5 +374,5 @@
 """
 
-	def email_to = "pabuhr@uwaterloo.ca, rschlunt@uwaterloo.ca, a3moss@uwaterloo.ca, tdelisle@uwaterloo.ca, brice.dobry@huawei.com"
+	def email_to = "pabuhr@uwaterloo.ca, rschlunt@uwaterloo.ca, a3moss@uwaterloo.ca, tdelisle@uwaterloo.ca, brice.dobry@huawei.com, ajbeach@edu.uwaterloo.ca"
 
 	//send email notification
Index: doc/rob_thesis/cfa-format.tex
===================================================================
--- doc/rob_thesis/cfa-format.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/cfa-format.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -1,4 +1,4 @@
-\usepackage{xcolor}
-\usepackage{listings}
+% \usepackage{xcolor}
+% \usepackage{listings}
 % \usepackage{booktabs}
 % \usepackage{array}
@@ -103,4 +103,6 @@
 
 \renewcommand{\ttdefault}{pcr}
+
+\newcommand{\basicstylesmall}{\scriptsize\ttfamily\color{basicCol}}
 
 \lstdefinestyle{defaultStyle}{
@@ -131,5 +133,5 @@
   style=defaultStyle
 }
-\lstMakeShortInline[basewidth=0.5em,breaklines=true,basicstyle=\normalsize\ttfamily\color{basicCol}]@  % single-character for \lstinline
+\lstMakeShortInline[basewidth=0.5em,breaklines=true,breakatwhitespace,basicstyle=\normalsize\ttfamily\color{basicCol}]@  % single-character for \lstinline
 
 \lstnewenvironment{cfacode}[1][]{
@@ -195,4 +197,6 @@
 \newcommand{\one}{\lstinline{one_t}\xspace}
 \newcommand{\ateq}{\lstinline{\@=}\xspace}
+
+\newenvironment{newtext}{\color{red}}{\ignorespacesafterend}
 
 % \lstset{ %
Index: doc/rob_thesis/conclusions.tex
===================================================================
--- doc/rob_thesis/conclusions.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/conclusions.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -6,5 +6,6 @@
 On the surface, the work may appear as a rehash of similar mechanisms in \CC.
 However, every added feature is different than its \CC counterpart, often with extended functionality, better integration with C and its programmers, and always supports separate compilation.
-All of these new features are being used by the \CFA development-team to build the \CFA runtime system.
+All of these new features are being used extensively by the \CFA development-team to build the \CFA runtime system.
+In particular, the concurrency system is built on top of RAII, library functions @new@ and @delete@ are used to manage dynamically allocated objects, and tuples are used to provide uniform interfaces to C library routines such as @div@ and @remquo@.
 
 \section{Constructors and Destructors}
@@ -245,6 +246,26 @@
 That is, structure fields can be accessed and modified by any block of code without restriction, so while it is possible to ensure that an object is initially set to a valid state, it is not possible to ensure that it remains in a consistent state throughout its lifetime.
 A popular technique for ensuring consistency in object-oriented programming languages is to provide access modifiers such as @private@, which provides compile-time checks that only privileged code accesses private data.
-This approach could be added to \CFA, but it requires an idiomatic way of specifying what code is privileged.
+This approach could be added to \CFA, but it requires an idiomatic way of specifying what code is privileged and what data is protected.
 One possibility is to tie access control into an eventual module system.
+
+\begin{sloppypar}
+The current implementation of implicit subobject-construction is currently an all-or-nothing check.
+That is, if a subobject is conditionally constructed, \eg within an if-statement, no implicit constructors for that object are added.
+\begin{cfacode}
+struct A { ... };
+void ?{}(A * a) { ... }
+
+struct B {
+  A a;
+};
+void ?{}(B * b) {
+  if (...) {
+    (&b->a){};  // explicitly constructed
+  } // does not construct in else case
+}
+\end{cfacode}
+This behaviour is unsafe and breaks the guarantee that constructors fully initialize objects.
+This situation should be properly handled, either by examining all paths and inserting implicit constructor calls only in the paths missing construction, or by emitting an error or warning.
+\end{sloppypar}
 
 \subsection{Tuples}
@@ -252,5 +273,5 @@
 This feature ties nicely into named tuples, as seen in D and Swift.
 
-Currently, tuple flattening and structuring conversions are 0-cost.
+Currently, tuple flattening and structuring conversions are 0-cost conversions in the resolution algorithm.
 This makes tuples conceptually very simple to work with, but easily causes unnecessary ambiguity in situations where the type system should be able to differentiate between alternatives.
 Adding an appropriate cost function to tuple conversions will allow tuples to interact with the rest of the programming language more cohesively.
Index: doc/rob_thesis/ctordtor.tex
===================================================================
--- doc/rob_thesis/ctordtor.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/ctordtor.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -6,6 +6,7 @@
 % doesn't seem possible to do this without allowing ttype on generic structs?
 
-Since \CFA is a true systems language, it does not provide a garbage collector.
-As well, \CFA is not an object-oriented programming language, \ie, structures cannot have routine members.
+Since \CFA is a true systems language, it does not require a garbage collector.
+As well, \CFA is not an object-oriented programming language, \ie, structures cannot have methods.
+While structures can have function pointer members, this is different from methods, since methods have implicit access to structure members and methods cannot be reassigned.
 Nevertheless, one important goal is to reduce programming complexity and increase safety.
 To that end, \CFA provides support for implicit pre/post-execution of routines for objects, via constructors and destructors.
@@ -32,5 +33,5 @@
 The key difference between assignment and initialization being that assignment occurs on a live object (\ie, an object that contains data).
 It is important to note that this means @x@ could have been used uninitialized prior to being assigned, while @y@ could not be used uninitialized.
-Use of uninitialized variables yields undefined behaviour, which is a common source of errors in C programs.
+Use of uninitialized variables yields undefined behaviour \cite[p.~558]{C11}, which is a common source of errors in C programs.
 
 Initialization of a declaration is strictly optional, permitting uninitialized variables to exist.
@@ -70,11 +71,11 @@
 int x2 = opaque_get(x, 2);
 \end{cfacode}
-This pattern is cumbersome to use since every access becomes a function call.
+This pattern is cumbersome to use since every access becomes a function call, requiring awkward syntax and a performance cost.
 While useful in some situations, this compromise is too restrictive.
 Furthermore, even with this idiom it is easy to make mistakes, such as forgetting to destroy an object or destroying it multiple times.
 
 A constructor provides a way of ensuring that the necessary aspects of object initialization is performed, from setting up invariants to providing compile- and run-time checks for appropriate initialization parameters.
-This goal is achieved through a guarantee that a constructor is called implicitly after every object is allocated from a type with associated constructors, as part of an object's definition.
-Since a constructor is called on every object of a managed type, it is impossible to forget to initialize such objects, as long as all constructors perform some sensible form of initialization.
+This goal is achieved through a \emph{guarantee} that a constructor is called \emph{implicitly} after every object is allocated from a type with associated constructors, as part of an object's \emph{definition}.
+Since a constructor is called on every object of a managed type, it is \emph{impossible} to forget to initialize such objects, as long as all constructors perform some sensible form of initialization.
 
 In \CFA, a constructor is a function with the name @?{}@.
@@ -114,5 +115,5 @@
 In other words, a default constructor is a constructor that takes a single argument: the @this@ parameter.
 
-In \CFA, a destructor is a function much like a constructor, except that its name is \lstinline!^?{}! and it takes only one argument.
+In \CFA, a destructor is a function much like a constructor, except that its name is \lstinline!^?{}! \footnote{Originally, the name @~?{}@ was chosen for destructors, to provide familiarity to \CC programmers. Unforunately, this name causes parsing conflicts with the bitwise-not operator when used with operator syntax (see section \ref{sub:syntax}.)} and it takes only one argument.
 A destructor for the @Array@ type can be defined as:
 \begin{cfacode}
@@ -135,5 +136,6 @@
 On line 2, @z@ is initialized with the value of @x@, while on line 3, @y@ is assigned the value of @x@.
 The key distinction between initialization and assignment is that a value to be initialized does not hold any meaningful values, whereas an object to be assigned might.
-In particular, these cases cannot be handled the same way because in the former case @z@ does not currently own an array, while @y@ does.
+In particular, these cases cannot be handled the same way because in the former case @z@ has no array, while @y@ does.
+A \emph{copy constructor} is used to perform initialization using another object of the same type.
 
 \begin{cfacode}[emph={other}, emphstyle=\color{red}]
@@ -151,7 +153,9 @@
 }
 \end{cfacode}
-The two functions above handle these cases.
-The first function is called a \emph{copy constructor}, because it constructs its argument by copying the values from another object of the same type.
+The two functions above handle the cases of initialization and assignment.
+The first function is called a copy constructor, because it constructs its argument by copying the values from another object of the same type.
 The second function is the standard copy-assignment operator.
+\CFA does not currently have the concept of reference types, so the most appropriate type for the source object in copy constructors and assignment operators is a value type.
+Appropriate care is taken in the implementation to avoid recursive calls to the copy constructor.
 The four functions (default constructor, destructor, copy constructor, and assignment operator) are special in that they safely control the state of most objects.
 
@@ -216,8 +220,8 @@
 A * y = malloc();  // copy construct: ?{}(&y, malloc())
 
+^?{}(&x);   // explicit destroy x, in different order
 ?{}(&x);    // explicit construct x, second construction
+^?{}(y);    // explicit destroy y
 ?{}(y, x);  // explit construct y from x, second construction
-^?{}(&x);   // explicit destroy x, in different order
-^?{}(y);    // explicit destroy y
 
 // implicit ^?{}(&y);
@@ -279,4 +283,7 @@
 \end{cfacode}
 In this example, @malloc@ dynamically allocates storage and initializes it using a constructor, all before assigning it into the variable @x@.
+Intuitively, the expression-resolver determines that @malloc@ returns some type @T *@, as does the constructor expression since it returns the type of its argument.
+This type flows outwards to the declaration site where the expected type is known to be @X *@, thus the first argument to the constructor must be @X *@, narrowing the search space.
+
 If this extension is not present, constructing dynamically allocated objects is much more cumbersome, requiring separate initialization of the pointer and initialization of the pointed-to memory.
 \begin{cfacode}
@@ -300,5 +307,5 @@
 It should be noted that this technique is not exclusive to @malloc@, and allows a user to write a custom allocator that can be idiomatically used in much the same way as a constructed @malloc@ call.
 
-It should be noted that while it is possible to use operator syntax with destructors, destructors invalidate their argument, thus operator syntax with destructors is a statement and does not produce a value.
+While it is possible to use operator syntax with destructors, destructors invalidate their argument, thus operator syntax with destructors is void-typed expression.
 
 \subsection{Function Generation}
@@ -308,10 +315,25 @@
 If the translator can expect these functions to exist, then it can unconditionally attempt to resolve them.
 Moreover, the existence of a standard interface allows polymorphic code to interoperate with new types seamlessly.
+While automatic generation of assignment functions is present in previous versions of \CFA, the the implementation has been largely rewritten to accomodate constructors and destructors.
 
 To mimic the behaviour of standard C, the default constructor and destructor for all of the basic types and for all pointer types are defined to do nothing, while the copy constructor and assignment operator perform a bitwise copy of the source parameter (as in \CC).
+This default is intended to maintain backwards compatibility and performance, by not imposing unexpected operations for a C programmer, as a zero-default behaviour would.
+However, it is possible for a user to define such constructors so that variables are safely zeroed by default, if desired.
+%%%%%%%%%%%%%%%%%%%%%%%%%% line width %%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{cfacode}
+void ?{}(int * i) { *i = 0; }
+forall(dtype T) void ?{}(T ** p) { *p = 0; }  // any pointer type
+void f() {
+  int x;    // initialized to 0
+  int * p;  // initialized to 0
+}
+\end{cfacode}
+%%%%%%%%%%%%%%%%%%%%%%%%%% line width %%%%%%%%%%%%%%%%%%%%%%%%%%
 
 There are several options for user-defined types: structures, unions, and enumerations.
 To aid in ease of use, the standard set of four functions is automatically generated for a user-defined type after its definition is completed.
 By auto-generating these functions, it is ensured that legacy C code continues to work correctly in every context where \CFA expects these functions to exist, since they are generated for every complete type.
+As well, these functions are always generated, since they may be needed by polymorphic functions.
+With that said, the generated functions are not called implicitly unless they are non-trivial, and are never exported, making it simple for the optimizer to strip them away when they are not used.
 
 The generated functions for enumerations are the simplest.
@@ -338,5 +360,5 @@
 }
 \end{cfacode}
-In the future, \CFA will introduce strongly-typed enumerations, like those in \CC.
+In the future, \CFA will introduce strongly-typed enumerations, like those in \CC, wherein enumerations create a new type distinct from @int@ so that integral values require an explicit cast to be stored in an enumeration variable.
 The existing generated routines are sufficient to express this restriction, since they are currently set up to take in values of that enumeration type.
 Changes related to this feature only need to affect the expression resolution phase, where more strict rules will be applied to prevent implicit conversions from integral types to enumeration types, but should continue to permit conversions from enumeration types to @int@.
@@ -492,5 +514,5 @@
 In addition to freedom, \ateq provides a simple path for migrating legacy C code to \CFA, in that objects can be moved from C-style initialization to \CFA gradually and individually.
 It is worth noting that the use of unmanaged objects can be tricky to get right, since there is no guarantee that the proper invariants are established on an unmanaged object.
-It is recommended that most objects be managed by sensible constructors and destructors, except where absolutely necessary.
+It is recommended that most objects be managed by sensible constructors and destructors, except where absolutely necessary, such as memory-mapped devices, trigger devices, I/O controllers, etc.
 
 When a user declares any constructor or destructor, the corresponding intrinsic/generated function and all field constructors for that type are hidden, so that they are not found during expression resolution until the user-defined function goes out of scope.
@@ -545,4 +567,6 @@
 \end{cfacode}
 However, if the translator sees a sub-object used within the body of a constructor, but does not see a constructor call that uses the sub-object as the target of a constructor, then the translator assumes the object is to be implicitly constructed (copy constructed in a copy constructor and default constructed in any other constructor).
+To override this rule, \ateq can be used to force the translator to trust the programmer's discretion.
+This form of \ateq is not yet implemented.
 \begin{cfacode}
 void ?{}(A * a) {
@@ -556,11 +580,15 @@
 }
 
+void ?{}(A * a, int x) {
+  // object forwarded to another constructor,
+  // does not implicitly construct any members
+  (&a){};
+}
+
 void ^?{}(A * a) {
   ^(&a->x){}; // explicit destructor call
 } // z, y, w implicitly destructed, in this order
 \end{cfacode}
-If at any point, the @this@ parameter is passed directly as the target of another constructor, then it is assumed that constructor handles the initialization of all of the object's members and no implicit constructor calls are added.
-To override this rule, \ateq can be used to force the translator to trust the programmer's discretion.
-This form of \ateq is not yet implemented.
+If at any point, the @this@ parameter is passed directly as the target of another constructor, then it is assumed the other constructor handles the initialization of all of the object's members and no implicit constructor calls are added to the current constructor.
 
 Despite great effort, some forms of C syntax do not work well with constructors in \CFA.
@@ -619,6 +647,19 @@
 The body of @A@ has been omitted, since only the constructor interfaces are important.
 
-It should be noted that unmanaged objects can still make use of designations and nested initializers in \CFA.
+It should be noted that unmanaged objects, i.e. objects that have only trivial constructors, can still make use of designations and nested initializers in \CFA.
 It is simple to overcome this limitation for managed objects by making use of compound literals, so that the arguments to the constructor call are explicitly typed.
+%%%%%%%%%%%%%%%%%%%%%%%%%% line width %%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{cfacode}
+struct B { int x; };
+struct C { int y; };
+struct A { B b; C c; };
+void ?{}(A *, B);
+void ?{}(A *, C);
+
+A a = {
+  (C){ 10 } // disambiguate with compound literal
+};
+\end{cfacode}
+%%%%%%%%%%%%%%%%%%%%%%%%%% line width %%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \subsection{Implicit Destructors}
@@ -744,4 +785,18 @@
 \end{cfacode}
 
+While \CFA supports the GCC computed-goto extension, the behaviour of managed objects in combination with computed-goto is undefined.
+\begin{cfacode}
+void f(int val) {
+  void * l = val == 0 ? &&L1 : &&L2;
+  {
+      A x;
+    L1: ;
+      goto *l;  // branches differently depending on argument
+  }
+  L2: ;
+}
+\end{cfacode}
+Likewise, destructors are not executed at scope-exit due to a computed-goto in \CC, as of g++ version 6.2.
+
 \subsection{Implicit Copy Construction}
 \label{s:implicit_copy_construction}
@@ -750,8 +805,8 @@
 Exempt from these rules are intrinsic and built-in functions.
 It should be noted that unmanaged objects are subject to copy constructor calls when passed as arguments to a function or when returned from a function, since they are not the \emph{target} of the copy constructor call.
-That is, since the parameter is not marked as an unmanaged object using \ateq, it is be copy constructed if it is returned by value or passed as an argument to another function, so to guarantee consistent behaviour, unmanaged objects must be copy constructed when passed as arguments.
+That is, since the parameter is not marked as an unmanaged object using \ateq, it is copy constructed if it is returned by value or passed as an argument to another function, so to guarantee consistent behaviour, unmanaged objects must be copy constructed when passed as arguments.
 These semantics are important to bear in mind when using unmanaged objects, and could produce unexpected results when mixed with objects that are explicitly constructed.
 \begin{cfacode}
-struct A;
+struct A { ... };
 void ?{}(A *);
 void ?{}(A *, A);
@@ -810,4 +865,9 @@
 It should be noted that reference types will allow specifying that a value does not need to be copied, however reference types do not provide a means of preventing implicit copy construction from uses of the reference, so the problem is still present when passing or returning the reference by value.
 
+Adding implicit copy construction imposes the additional runtime cost of the copy constructor for every argument and return value in a function call.
+This cost is necessary to maintain appropriate value semantics when calling a function.
+In the future, return-value-optimization (RVO) can be implemented for \CFA to elide unnecessary copy construction and destruction of temporary objects.
+This cost is not present for types with trivial copy constructors and destructors.
+
 A known issue with this implementation is that the argument and return value temporaries are not guaranteed to have the same address for their entire lifetimes.
 In the previous example, since @_retval_f@ is allocated and constructed in @f@, then returned by value, the internal data is bitwise copied into the caller's stack frame.
@@ -908,5 +968,5 @@
 \subsection{Array Initialization}
 Arrays are a special case in the C type-system.
-C arrays do not carry around their size, making it impossible to write a standalone \CFA function that constructs or destructs an array while maintaining the standard interface for constructors and destructors.
+Type checking largely ignores size information for C arrays, making it impossible to write a standalone \CFA function that constructs or destructs an array, while maintaining the standard interface for constructors and destructors.
 Instead, \CFA defines the initialization and destruction of an array recursively.
 That is, when an array is defined, each of its elements is constructed in order from element 0 up to element $n-1$.
@@ -1147,4 +1207,10 @@
 \end{cfacode}
 
+This implementation comes at the runtime cost of an additional branch for every @static@ local variable, each time the function is called.
+Since initializers are not required to be compile-time constant expressions, they can involve global variables, function arguments, function calls, etc.
+As a direct consequence, @static@ local variables cannot be initialized with an attribute-constructor routines like global variables can.
+However, in the case where the variable is unmanaged and has a compile-time constant initializer, a C-compliant initializer is generated and the additional cost is not present.
+\CC shares the same semantics for its @static@ local variables.
+
 \subsection{Polymorphism}
 As mentioned in section \ref{sub:polymorphism}, \CFA currently has 3 type-classes that are used to designate polymorphic data types: @otype@, @dtype@, and @ftype@.
@@ -1172,2 +1238,22 @@
 These additions allow @f@'s body to create and destroy objects of type @T@, and pass objects of type @T@ as arguments to other functions, following the normal \CFA rules.
 A point of note here is that objects can be missing default constructors (and eventually other functions through deleted functions), so it is important for \CFA programmers to think carefully about the operations needed by their function, as to not over-constrain the acceptable parameter types and prevent potential reuse.
+
+These additional assertion parameters impose a runtime cost on all managed temporary objects created in polymorphic code, even those with trivial constructors and destructors.
+This cost is necessary because polymorphic code does not know the actual type at compile-time, due to separate compilation.
+Since trivial constructors and destructors either do not perform operations or are simply bit-wise copy operations, the imposed cost is essentially the cost of the function calls.
+
+\section{Summary}
+
+When creating a new object of a managed type, it is guaranteed that a constructor is be called to initialize the object at its definition point, and is destructed when the object's lifetime ends.
+Destructors are called in the reverse order of construction.
+
+Every argument passed to a function is copy constructed into a temporary object that is passed by value to the functions and destructed at the end of the statement.
+Function return values are copy constructed inside the function at the return statement, passed by value to the call-site, and destructed at the call-site at the end of the statement.
+
+Every complete object type has a default constructor, copy constructor, assignment operator, and destructor.
+To accomplish this, these functions are generated as appropriate for new types.
+User-defined functions shadow built-in and automatically generated functions, so it is possible to specialize the behaviour of a type.
+Furthermore, default constructors and aggregate field constructors are hidden when \emph{any} constructor is defined.
+
+Objects dynamically allocated with @malloc@, \ateq objects, and objects with only trivial constructors and destructors are unmanaged.
+Unmanaged objects are never the target of an implicit constructor or destructor call.
Index: doc/rob_thesis/examples/malloc.cc
===================================================================
--- doc/rob_thesis/examples/malloc.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ doc/rob_thesis/examples/malloc.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,20 @@
+#include <cstdlib>
+#include <iostream>
+using namespace std;
+
+class A {
+public:
+  A() {
+    cout << "A()" << endl;  
+  }
+  ~A(){
+    cout << "~A()" << endl;
+  }
+};
+
+int main() {
+  A * x = (A*)malloc(sizeof(A));
+  A * y = new A;
+  delete y;
+  free(x);
+}
Index: doc/rob_thesis/examples/poly.c
===================================================================
--- doc/rob_thesis/examples/poly.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ doc/rob_thesis/examples/poly.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,14 @@
+forall(dtype T)
+void foo(T x) {
+
+}
+
+forall(dtype T)
+void bar(T * y) { }
+
+int main() {
+  foo(5);
+  foo("baz");
+  foo(foo);
+  bar(foo);
+}
Index: doc/rob_thesis/intro.tex
===================================================================
--- doc/rob_thesis/intro.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/intro.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -19,10 +19,15 @@
 Unfortunately, \CC is actively diverging from C, so incremental additions require significant effort and training, coupled with multiple legacy design-choices that cannot be updated.
 
-The remainder of this section describes some of the important new features that currently exist in \CFA, to give the reader the necessary context in which the new features presented in this thesis must dovetail.
+The current implementation of \CFA is a source-to-source translator from \CFA to GNU C \cite{GCCExtensions}.
+
+The remainder of this section describes some of the important features that currently exist in \CFA, to give the reader the necessary context in which the new features presented in this thesis must dovetail.
 
 \subsection{C Background}
 \label{sub:c_background}
+In the context of this work, the term \emph{object} refers to a region of data storage in the execution environment, the contents of which can represent values \cite[p.~6]{C11}.
+
 One of the lesser-known features of standard C is \emph{designations}.
 Designations are similar to named parameters in languages such as Python and Scala, except that they only apply to aggregate initializers.
+Note that in \CFA, designations use a colon separator, rather than an equals sign as in C, because this syntax is one of the few places that conflicts with the new language features.
 \begin{cfacode}
 struct A {
@@ -43,5 +48,4 @@
 Later initializers override earlier initializers, so a sub-object for which there is more than one initializer is only initialized by its last initializer.
 These semantics can be seen in the initialization of @a0@, where @x@ is designated twice, and thus initialized to @8@.
-Note that in \CFA, designations use a colon separator, rather than an equals sign as in C, because this syntax is one of the few places that conflicts with the new language features.
 
 C also provides \emph{compound literal} expressions, which provide a first-class mechanism for creating unnamed objects.
@@ -57,4 +61,28 @@
 Compound literals create an unnamed object, and result in an lvalue, so it is legal to assign a value into a compound literal or to take its address \cite[p.~86]{C11}.
 Syntactically, compound literals look like a cast operator followed by a brace-enclosed initializer, but semantically are different from a C cast, which only applies basic conversions and coercions and is never an lvalue.
+
+The \CFA translator makes use of several GNU C extensions, including \emph{nested functions} and \emph{attributes}.
+Nested functions make it possible to access data that is lexically in scope in the nested function's body.
+\begin{cfacode}
+int f() {
+  int x = 0;
+  void g() {
+    x++;
+  }
+  g();  // changes x
+}
+\end{cfacode}
+Nested functions come with the usual C caveat that they should not leak into the containing environment, since they are only valid as long as the containing function's stack frame is active.
+
+Attributes make it possible to inform the compiler of certain properties of the code.
+For example, a function can be marked as deprecated, so that legacy APIs can be identified and slowly removed, or as \emph{hot}, so that the compiler knows the function is called frequently and should be aggresively optimized.
+\begin{cfacode}
+__attribute__((deprecated("foo is deprecated, use bar instead")))
+void foo();
+__attribute__((hot)) void bar(); // heavily optimized
+
+foo();  // warning
+bar();
+\end{cfacode}
 
 \subsection{Overloading}
@@ -64,33 +92,69 @@
 C provides a small amount of built-in overloading, \eg + is overloaded for the basic types.
 Like in \CC, \CFA allows user-defined overloading based both on the number of parameters and on the types of parameters.
-  \begin{cfacode}
-  void f(void);  // (1)
-  void f(int);   // (2)
-  void f(char);  // (3)
-
-  f('A');        // selects (3)
-  \end{cfacode}
+\begin{cfacode}
+void f(void);  // (1)
+void f(int);   // (2)
+void f(char);  // (3)
+
+f('A');        // selects (3)
+\end{cfacode}
 In this case, there are three @f@ procedures, where @f@ takes either 0 or 1 arguments, and if an argument is provided then it may be of type @int@ or of type @char@.
 Exactly which procedure is executed depends on the number and types of arguments passed.
 If there is no exact match available, \CFA attempts to find a suitable match by examining the C built-in conversion heuristics.
-  \begin{cfacode}
-  void g(long long);
-
-  g(12345);
-  \end{cfacode}
+The \CFA expression resolution algorithm uses a cost function to determine the interpretation that uses the fewest conversions and polymorphic type bindings.
+\begin{cfacode}
+void g(long long);
+
+g(12345);
+\end{cfacode}
 In the above example, there is only one instance of @g@, which expects a single parameter of type @long long@.
 Here, the argument provided has type @int@, but since all possible values of type @int@ can be represented by a value of type @long long@, there is a safe conversion from @int@ to @long long@, and so \CFA calls the provided @g@ routine.
 
+Overloading solves the problem present in C where there can only be one function with a given name, requiring multiple names for functions that perform the same operation but take in different types.
+This can be seen in the example of the absolute value functions C:
+\begin{cfacode}
+// stdlib.h
+int abs(int);
+long int labs(long int);
+long long int llabs(long long int);
+\end{cfacode}
+In \CFA, the functions @labs@ and @llabs@ are replaced by appropriate overloads of @abs@.
+
 In addition to this form of overloading, \CFA also allows overloading based on the number and types of \emph{return} values.
 This extension is a feature that is not available in \CC, but is available in other programming languages such as Ada \cite{Ada95}.
-  \begin{cfacode}
-  int g();         // (1)
-  double g();      // (2)
-
-  int x = g();     // selects (1)
-  \end{cfacode}
+\begin{cfacode}
+int g();         // (1)
+double g();      // (2)
+
+int x = g();     // selects (1)
+\end{cfacode}
 Here, the only difference between the signatures of the different versions of @g@ is in the return values.
 The result context is used to select an appropriate routine definition.
 In this case, the result of @g@ is assigned into a variable of type @int@, so \CFA prefers the routine that returns a single @int@, because it is an exact match.
+
+Return-type overloading solves similar problems to parameter-list overloading, in that multiple functions that perform similar operations can have the same, but produce different values.
+One use case for this feature is to provide two versions of the @bsearch@ routine:
+\begin{cfacode}
+forall(otype T | { int ?<?( T, T ); })
+T * bsearch(T key, const T * arr, size_t dimension) {
+  int comp(const void * t1, const void * t2) {
+    return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0;
+  }
+  return (T *)bsearch(&key, arr, dimension, sizeof(T), comp);
+}
+forall(otype T | { int ?<?( T, T ); })
+unsigned int bsearch(T key, const T * arr, size_t dimension) {
+  T *result = bsearch(key, arr, dimension);
+  // pointer subtraction includes sizeof(T)
+  return result ? result - arr : dimension;
+}
+double key = 5.0;
+double vals[10] = { /* 10 floating-point values */ };
+
+double * val = bsearch( 5.0, vals, 10 ); // selection based on return type
+int posn = bsearch( 5.0, vals, 10 );
+\end{cfacode}
+The first version provides a thin wrapper around the C @bsearch@ routine, converting untyped @void *@ to the polymorphic type @T *@, allowing the \CFA compiler to catch errors when the type of @key@, @arr@, and the target at the call-site do not agree.
+The second version provides an alternate return of the index in the array of the selected element, rather than its address.
 
 There are times when a function should logically return multiple values.
@@ -145,32 +209,52 @@
 
 An extra quirk introduced by multiple return values is in the resolution of function calls.
-  \begin{cfacode}
-  int f();            // (1)
-  [int, int] f();     // (2)
-
-  void g(int, int);
-
-  int x, y;
-  [x, y] = f();       // selects (2)
-  g(f());             // selects (2)
-  \end{cfacode}
+\begin{cfacode}
+int f();            // (1)
+[int, int] f();     // (2)
+
+void g(int, int);
+
+int x, y;
+[x, y] = f();       // selects (2)
+g(f());             // selects (2)
+\end{cfacode}
 In this example, the only possible call to @f@ that can produce the two @int@s required for assigning into the variables @x@ and @y@ is the second option.
 A similar reasoning holds calling the function @g@.
+
+This duality between aggregation and aliasing can be seen in the C standard library in the @div@ and @remquo@ functions, which return the quotient and remainder for a division of integer and floating-point values, respectively.
+\begin{cfacode}
+typedef struct { int quo, rem; } div_t; // from stdlib.h
+div_t div( int num, int den );
+double remquo( double num, double den, int * quo );
+div_t qr = div( 13, 5 );            // return quotient/remainder aggregate
+int q;
+double r = remquo( 13.5, 5.2, &q ); // return remainder, alias quotient
+\end{cfacode}
+@div@ aggregates the quotient/remainder in a structure, while @remquo@ aliases a parameter to an argument.
+Alternatively, a programming language can directly support returning multiple values, \eg in \CFA:
+\begin{lstlisting}
+[int, int] div(int num, int den);               // return two integers
+[double, double] div( double num, double den ); // return two doubles
+int q, r;                     // overloaded variable names
+double q, r;
+[q, r] = div(13, 5);          // select appropriate div and q, r
+[q, r] = div(13.5, 5.2);
+\end{lstlisting}
 
 In \CFA, overloading also applies to operator names, known as \emph{operator overloading}.
 Similar to function overloading, a single operator is given multiple meanings by defining new versions of the operator with different signatures.
 In \CC, this can be done as follows
-  \begin{cppcode}
-  struct A { int i; };
-  int operator+(A x, A y);
-  bool operator<(A x, A y);
-  \end{cppcode}
+\begin{cppcode}
+struct A { int i; };
+A operator+(A x, A y);
+bool operator<(A x, A y);
+\end{cppcode}
 
 In \CFA, the same example can be written as follows.
-  \begin{cfacode}
-  struct A { int i; };
-  int ?+?(A x, A y);    // '?'s represent operands
-  bool ?<?(A x, A y);
-  \end{cfacode}
+\begin{cfacode}
+struct A { int i; };
+A ?+?(A x, A y);    // '?'s represent operands
+int ?<?(A x, A y);
+\end{cfacode}
 Notably, the only difference is syntax.
 Most of the operators supported by \CC for operator overloading are also supported in \CFA.
@@ -179,16 +263,16 @@
 Finally, \CFA also permits overloading variable identifiers.
 This feature is not available in \CC.
-  \begin{cfacode}
-  struct Rational { int numer, denom; };
-  int x = 3;               // (1)
-  double x = 1.27;         // (2)
-  Rational x = { 4, 11 };  // (3)
-
-  void g(double);
-
-  x += 1;                  // chooses (1)
-  g(x);                    // chooses (2)
-  Rational y = x;          // chooses (3)
-  \end{cfacode}
+\begin{cfacode}
+struct Rational { int numer, denom; };
+int x = 3;               // (1)
+double x = 1.27;         // (2)
+Rational x = { 4, 11 };  // (3)
+
+void g(double);
+
+x += 1;                  // chooses (1)
+g(x);                    // chooses (2)
+Rational y = x;          // chooses (3)
+\end{cfacode}
 In this example, there are three definitions of the variable @x@.
 Based on the context, \CFA attempts to choose the variable whose type best matches the expression context.
@@ -208,20 +292,20 @@
 Due to these rewrite rules, the values @0@ and @1@ have the types \zero and \one in \CFA, which allow for overloading various operations that connect to @0@ and @1@ \footnote{In the original design of \CFA, @0@ and @1@ were overloadable names \cite[p.~7]{cforall}.}.
 The types \zero and \one have special built-in implicit conversions to the various integral types, and a conversion to pointer types for @0@, which allows standard C code involving @0@ and @1@ to work as normal.
-  \begin{cfacode}
-  // lvalue is similar to returning a reference in C++
-  lvalue Rational ?+=?(Rational *a, Rational b);
-  Rational ?=?(Rational * dst, zero_t) {
-    return *dst = (Rational){ 0, 1 };
-  }
-
-  Rational sum(Rational *arr, int n) {
-    Rational r;
-    r = 0;     // use rational-zero_t assignment
-    for (; n > 0; n--) {
-      r += arr[n-1];
-    }
-    return r;
-  }
-  \end{cfacode}
+\begin{cfacode}
+// lvalue is similar to returning a reference in C++
+lvalue Rational ?+=?(Rational *a, Rational b);
+Rational ?=?(Rational * dst, zero_t) {
+  return *dst = (Rational){ 0, 1 };
+}
+
+Rational sum(Rational *arr, int n) {
+  Rational r;
+  r = 0;     // use rational-zero_t assignment
+  for (; n > 0; n--) {
+    r += arr[n-1];
+  }
+  return r;
+}
+\end{cfacode}
 This function takes an array of @Rational@ objects and produces the @Rational@ representing the sum of the array.
 Note the use of an overloaded assignment operator to set an object of type @Rational@ to an appropriate @0@ value.
@@ -232,41 +316,46 @@
 In particular, \CFA supports the notion of parametric polymorphism.
 Parametric polymorphism allows a function to be written generically, for all values of all types, without regard to the specifics of a particular type.
-For example, in \CC, the simple identity function for all types can be written as
-  \begin{cppcode}
-  template<typename T>
-  T identity(T x) { return x; }
-  \end{cppcode}
-\CC uses the template mechanism to support parametric polymorphism. In \CFA, an equivalent function can be written as
-  \begin{cfacode}
-  forall(otype T)
-  T identity(T x) { return x; }
-  \end{cfacode}
+For example, in \CC, the simple identity function for all types can be written as:
+\begin{cppcode}
+template<typename T>
+T identity(T x) { return x; }
+\end{cppcode}
+\CC uses the template mechanism to support parametric polymorphism. In \CFA, an equivalent function can be written as:
+\begin{cfacode}
+forall(otype T)
+T identity(T x) { return x; }
+\end{cfacode}
 Once again, the only visible difference in this example is syntactic.
 Fundamental differences can be seen by examining more interesting examples.
-In \CC, a generic sum function is written as follows
-  \begin{cppcode}
-  template<typename T>
-  T sum(T *arr, int n) {
-    T t;  // default construct => 0
-    for (; n > 0; n--) t += arr[n-1];
-    return t;
-  }
-  \end{cppcode}
+In \CC, a generic sum function is written as follows:
+\begin{cppcode}
+template<typename T>
+T sum(T *arr, int n) {
+  T t;  // default construct => 0
+  for (; n > 0; n--) t += arr[n-1];
+  return t;
+}
+\end{cppcode}
 Here, the code assumes the existence of a default constructor, assignment operator, and an addition operator over the provided type @T@.
 If any of these required operators are not available, the \CC compiler produces an error message stating which operators could not be found.
 
-A similar sum function can be written in \CFA as follows
-  \begin{cfacode}
-  forall(otype T | **R**{ T ?=?(T *, zero_t); T ?+=?(T *, T); }**R**)
-  T sum(T *arr, int n) {
-    T t = 0;
-    for (; n > 0; n--) t = t += arr[n-1];
-    return t;
-  }
-  \end{cfacode}
+A similar sum function can be written in \CFA as follows:
+\begin{cfacode}
+forall(otype T | **R**{ T ?=?(T *, zero_t); T ?+=?(T *, T); }**R**)
+T sum(T *arr, int n) {
+  T t = 0;
+  for (; n > 0; n--) t = t += arr[n-1];
+  return t;
+}
+\end{cfacode}
 The first thing to note here is that immediately following the declaration of @otype T@ is a list of \emph{type assertions} that specify restrictions on acceptable choices of @T@.
 In particular, the assertions above specify that there must be an assignment from \zero to @T@ and an addition assignment operator from @T@ to @T@.
 The existence of an assignment operator from @T@ to @T@ and the ability to create an object of type @T@ are assumed implicitly by declaring @T@ with the @otype@ type-class.
 In addition to @otype@, there are currently two other type-classes.
+
+@dtype@, short for \emph{data type}, serves as the top type for object types; any object type, complete or incomplete, can be bound to a @dtype@ type variable.
+To contrast, @otype@, short for \emph{object type}, is a @dtype@ with known size, alignment, and an assignment operator, and thus bind only to complete object types.
+With this extra information, complete objects can be used in polymorphic code in the same way they are used in monomorphic code, providing familiarity and ease of use.
+The third type-class is @ftype@, short for \emph{function type}, matching only function types.
 The three type parameter kinds are summarized in \autoref{table:types}
 
@@ -275,5 +364,5 @@
     \begin{tabular}{|c||c|c|c||c|c|c|}
                                                                                                     \hline
-    name    & object type & incomplete type & function type & can assign value & can create & has size \\ \hline
+    name    & object type & incomplete type & function type & can assign & can create & has size \\ \hline
     @otype@ & X           &                 &               & X                & X          & X        \\ \hline
     @dtype@ & X           & X               &               &                  &            &          \\ \hline
@@ -288,24 +377,24 @@
 In contrast, the explicit nature of assertions allows \CFA's polymorphic functions to be separately compiled, as the function prototype states all necessary requirements separate from the implementation.
 For example, the prototype for the previous sum function is
-  \begin{cfacode}
-  forall(otype T | **R**{ T ?=?(T *, zero_t); T ?+=?(T *, T); }**R**)
-  T sum(T *arr, int n);
-  \end{cfacode}
+\begin{cfacode}
+forall(otype T | **R**{ T ?=?(T *, zero_t); T ?+=?(T *, T); }**R**)
+T sum(T *arr, int n);
+\end{cfacode}
 With this prototype, a caller in another translation unit knows all of the constraints on @T@, and thus knows all of the operations that need to be made available to @sum@.
 
 In \CFA, a set of assertions can be factored into a \emph{trait}.
 \begin{cfacode}
-  trait Addable(otype T) {
-    T ?+?(T, T);
-    T ++?(T);
-    T ?++(T);
-  }
-  forall(otype T | Addable(T)) void f(T);
-  forall(otype T | Addable(T) | { T --?(T); }) T g(T);
-  forall(otype T, U | Addable(T) | { T ?/?(T, U); }) U h(T, U);
+trait Addable(otype T) {
+  T ?+?(T, T);
+  T ++?(T);
+  T ?++(T);
+}
+forall(otype T | Addable(T)) void f(T);
+forall(otype T | Addable(T) | { T --?(T); }) T g(T);
+forall(otype T, U | Addable(T) | { T ?/?(T, U); }) U h(T, U);
 \end{cfacode}
 This capability allows specifying the same set of assertions in multiple locations, without the repetition and likelihood of mistakes that come with manually writing them out for each function declaration.
 
-An interesting application of return-type resolution and polymorphism is a type-safe version of @malloc@.
+An interesting application of return-type resolution and polymorphism is a polymorphic version of @malloc@.
 \begin{cfacode}
 forall(dtype T | sized(T))
@@ -321,4 +410,52 @@
 The built-in trait @sized@ ensures that size and alignment information for @T@ is available in the body of @malloc@ through @sizeof@ and @_Alignof@ expressions respectively.
 In calls to @malloc@, the type @T@ is bound based on call-site information, allowing \CFA code to allocate memory without the potential for errors introduced by manually specifying the size of the allocated block.
+
+\subsection{Planned Features}
+
+One of the planned features \CFA is \emph{reference types}.
+At a high level, the current proposal is to add references as a way to cleanup pointer syntax.
+With references, it will be possible to store any address, as with a pointer, with the key difference being that references are automatically dereferenced.
+\begin{cfacode}
+int x = 0;
+int * p = &x;  // needs &
+int & ref = x; // no &
+
+printf("%d %d\n", *p, ref); // pointer needs *, ref does not
+\end{cfacode}
+
+It is possible to add new functions or shadow existing functions for the duration of a scope, using normal C scoping rules.
+One application of this feature is to reverse the order of @qsort@.
+\begin{cfacode}
+forall(otype T | { int ?<?( T, T ); })
+void qsort(const T * arr, size_t size) {
+  int comp(const void * t1, const void * t2) {
+    return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0;
+  }
+  qsort(arr, dimension, sizeof(T), comp);
+
+}
+double vals[10] = { ... };
+qsort(vals, 10);                // ascending order
+{
+  int ?<?(double x, double y) { // locally override behaviour
+    return x > y;
+  }
+  qsort(vals, 10);              // descending sort
+}
+\end{cfacode}
+Currently, there is no way to \emph{remove} a function from consideration from the duration of a scope.
+For example, it may be desirable to eliminate assignment from a scope, to reduce accidental mutation.
+To address this desire, \emph{deleted functions} are a planned feature for \CFA.
+\begin{cfacode}
+forall(otype T) void f(T *);
+
+int x = 0;
+f(&x);  // might modify x
+{
+  int ?=?(int *, int) = delete;
+  f(&x);   // error, no assignment for int
+}
+\end{cfacode}
+Now, if the deleted function is chosen as the best match, the expression resolver emits an error.
 
 \section{Invariants}
@@ -450,5 +587,5 @@
 \end{javacode}
 In Java 7, a new \emph{try-with-resources} construct was added to alleviate most of the pain of working with resources, but ultimately it still places the burden squarely on the user rather than on the library designer.
-Furthermore, for complete safety this pattern requires nested objects to be declared separately, otherwise resources that can throw an exception on close can leak nested resources \cite{TryWithResources}.
+Furthermore, for complete safety this pattern requires nested objects to be declared separately, otherwise resources that can throw an exception on close can leak nested resources \footnote{Since close is only guaranteed to be called on objects declared in the try-list and not objects passed as constructor parameters, the @B@ object may not be closed in @new A(new B())@ if @A@'s close raises an exception.} \cite{TryWithResources}.
 \begin{javacode}
 public void write(String filename, String msg) throws Exception {
@@ -521,6 +658,6 @@
 % these are declared in the struct, so they're closer to C++ than to CFA, at least syntactically. Also do not allow for default constructors
 % D has a GC, which already makes the situation quite different from C/C++
-The programming language, D, also manages resources with constructors and destructors \cite{D}.
-In D, @struct@s are stack allocated and managed via scoping like in \CC, whereas @class@es are managed automatically by the garbage collector.
+The programming language D also manages resources with constructors and destructors \cite{D}.
+In D, @struct@s are stack allocatable and managed via scoping like in \CC, whereas @class@es are managed automatically by the garbage collector.
 Like Java, using the garbage collector means that destructors are called indeterminately, requiring the use of finally statements to ensure dynamically allocated resources that are not managed by the garbage collector, such as open files, are cleaned up.
 Since D supports RAII, it is possible to use the same techniques as in \CC to ensure that resources are released in a timely manner.
@@ -755,2 +892,19 @@
 
 Type-safe variadic functions are added to \CFA and discussed in Chapter 4.
+
+\section{Contributions}
+\label{s:contributions}
+
+No prior work on constructors or destructors had been done for \CFA.
+I did both the design and implementation work.
+While the overall design is based on constructors and destructors in object-oriented C++, it had to be re-engineered into non-object-oriented \CFA.
+I also had to make changes to the \CFA expression-resolver to integrate constructors and destructors into the type system.
+
+Prior work on the design of tuples for \CFA was done by Till, and some initial implementation work by Esteves.
+I largely took the Till design but added tuple indexing, which exists in a number of programming languages with tuples, simplified the implicit tuple conversions, and integrated with the \CFA polymorphism and assertion satisfaction model.
+I did a new implementation of tuples, and extensively
+augmented initial work by Bilson to incorporate tuples into the \CFA expression-resolver and type-unifier.
+
+No prior work on variadic functions had been done for \CFA.
+I did both the design and implementation work.
+While the overall design is based on variadic templates in C++, my design is novel in the way it is incorporated into the \CFA polymorphism model, and is engineered into \CFA so it dovetails with tuples.
Index: doc/rob_thesis/thesis-frontpgs.tex
===================================================================
--- doc/rob_thesis/thesis-frontpgs.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/thesis-frontpgs.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -86,13 +86,32 @@
 %\newpage
 
-% % A C K N O W L E D G E M E N T S
-% % -------------------------------
+% A C K N O W L E D G E M E N T S
+% -------------------------------
 
-% \begin{center}\textbf{Acknowledgements}\end{center}
+\begin{center}\textbf{Acknowledgements}\end{center}
 
-% % I would like to thank all the little people who made this possible.
-% TODO
-% \cleardoublepage
-% %\newpage
+I would like to thank my supervisor, Professor Peter Buhr, for all of his help, including reading the many drafts of this thesis and providing guidance throughout my degree.
+This work would not have been as enjoyable, nor would it have been as strong without Peter's knowledge, help, and encouragement.
+
+I would like to thank my readers, Professors Gregor Richards and Patrick Lam for all of their helpful feedback.
+
+Thanks to Aaron Moss and Thierry Delisle for many helpful discussions, both work-related and not, and for all of the work they have put into the \CFA project.
+This thesis would not have been the same without their efforts.
+
+I thank Glen Ditchfield and Richard Bilson, for all of their help with both the design and implementation of \CFA.
+
+I thank my partner, Erin Blackmere, for all of her love and support.
+Without her, I would not be who I am today.
+
+Thanks to my parents, Bob and Jackie Schluntz, for their love and support throughout my life, and for always encouraging me to be my best.
+
+Thanks to my best friends, Travis Bartlett, Abraham Dubrisingh, and Kevin Wu, whose companionship is always appreciated.
+The time we've spent together over the past 4 years has always kept me entertained.
+An extra shout-out to Kaleb Alway, Max Bardakov, Ten Bradley, and Ed Lee, with whom I've shared many a great meal; thank you for being my friend.
+
+Finally, I would like to acknowledge financial support in the form of a David R. Cheriton Graduate Scholarship and a corporate partnership with Huawei Ltd.
+
+\cleardoublepage
+%\newpage
 
 % % D E D I C A T I O N
Index: doc/rob_thesis/thesis.tex
===================================================================
--- doc/rob_thesis/thesis.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/thesis.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -118,4 +118,7 @@
 \usepackage[pdftex]{graphicx} % For including graphics N.B. pdftex graphics driver
 
+\usepackage{xcolor}
+\usepackage{listings}
+
 \input{cfa-format.tex}
 
@@ -138,5 +141,5 @@
     pdftitle={Resource Management and Tuples in \CFA},    % title: CHANGE THIS TEXT!
     pdfauthor={Rob Schluntz},    % author: CHANGE THIS TEXT! and uncomment this line
-%    pdfsubject={Subject},  % subject: CHANGE THIS TEXT! and uncomment this line
+    pdfsubject={Programming Languages},  % subject: CHANGE THIS TEXT! and uncomment this line
 %    pdfkeywords={keyword1} {key2} {key3}, % list of keywords, and uncomment this line if desired
     pdfnewwindow=true,      % links in new window
Index: doc/rob_thesis/tuples.tex
===================================================================
--- doc/rob_thesis/tuples.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/tuples.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -161,6 +161,7 @@
 \end{cfacode}
 
+\begin{sloppypar}
 In addition to variables of tuple type, it is also possible to have pointers to tuples, and arrays of tuples.
-Tuple types can be composed of any types, except for array types, since arrays do not carry their size around, which makes tuple assignment difficult when a tuple contains an array.
+Tuple types can be composed of any types, except for array types, since array assignment is disallowed, which makes tuple assignment difficult when a tuple contains an array.
 \begin{cfacode}
 [double, int] di;
@@ -169,4 +170,5 @@
 \end{cfacode}
 This examples declares a variable of type @[double, int]@, a variable of type pointer to @[double, int]@, and an array of ten @[double, int]@.
+\end{sloppypar}
 
 \subsection{Tuple Indexing}
@@ -212,5 +214,5 @@
 The flexible structure of tuples permits a simple and expressive function-call syntax to work seamlessly with both single- and multiple-return-value functions, and with any number of arguments of arbitrarily complex structure.
 
-In \KWC \cite{Buhr94a,Till89}, a precursor to \CFA, there were 4 tuple coercions: opening, closing, flattening, and structuring.
+In \KWC \cite{Buhr94a,Till89}, there were 4 tuple coercions: opening, closing, flattening, and structuring.
 Opening coerces a tuple value into a tuple of values, while closing converts a tuple of values into a single tuple value.
 Flattening coerces a nested tuple into a flat tuple, \ie it takes a tuple with tuple components and expands it into a tuple with only non-tuple components.
@@ -218,4 +220,5 @@
 
 In \CFA, the design has been simplified to require only the two conversions previously described, which trigger only in function call and return situations.
+This simplification is a primary contribution of this thesis to the design of tuples in \CFA.
 Specifically, the expression resolution algorithm examines all of the possible alternatives for an expression to determine the best match.
 In resolving a function call expression, each combination of function value and list of argument alternatives is examined.
@@ -254,5 +257,11 @@
 Let $L_i$ for $i$ in $[0, n)$ represent each component of the flattened left side, $R_i$ represent each component of the flattened right side of a multiple assignment, and $R$ represent the right side of a mass assignment.
 
-For a multiple assignment to be valid, both tuples must have the same number of elements when flattened. Multiple assignment assigns $R_i$ to $L_i$ for each $i$.
+For a multiple assignment to be valid, both tuples must have the same number of elements when flattened.
+For example, the following is invalid because the number of components on the left does not match the number of components on the right.
+\begin{cfacode}
+[int, int] x, y, z;
+[x, y] = z;   // multiple assignment, invalid 4 != 2
+\end{cfacode}
+Multiple assignment assigns $R_i$ to $L_i$ for each $i$.
 That is, @?=?(&$L_i$, $R_i$)@ must be a well-typed expression.
 In the previous example, @[x, y] = z@, @z@ is flattened into @z.0, z.1@, and the assignments @x = z.0@ and @y = z.1@ happen.
@@ -265,5 +274,5 @@
 
 Both kinds of tuple assignment have parallel semantics, such that each value on the left side and right side is evaluated \emph{before} any assignments occur.
-As a result, it is possible to swap the values in two variables without explicitly creating any temporary variables or calling a function,
+As a result, it is possible to swap the values in two variables without explicitly creating any temporary variables or calling a function.
 \begin{cfacode}
 int x = 10, y = 20;
@@ -296,4 +305,5 @@
 \subsection{Tuple Construction}
 Tuple construction and destruction follow the same rules and semantics as tuple assignment, except that in the case where there is no right side, the default constructor or destructor is called on each component of the tuple.
+As constructors and destructors did not exist in previous versions of \CFA or in \KWC, this is a primary contribution of this thesis to the design of tuples.
 \begin{cfacode}
 struct S;
@@ -433,5 +443,5 @@
 \section{Casting}
 In C, the cast operator is used to explicitly convert between types.
-In \CFA, the cast operator has a secondary use, which is type ascription, since it force the expression resolution algorithm to choose the lowest cost conversion to the target type.
+In \CFA, the cast operator has a secondary use, which is type ascription, since it forces the expression resolution algorithm to choose the lowest cost conversion to the target type.
 That is, a cast can be used to select the type of an expression when it is ambiguous, as in the call to an overloaded function.
 \begin{cfacode}
@@ -487,4 +497,5 @@
 \section{Polymorphism}
 Due to the implicit flattening and structuring conversions involved in argument passing, @otype@ and @dtype@ parameters are restricted to matching only with non-tuple types.
+The integration of polymorphism, type assertions, and monomorphic specialization of tuple-assertions are a primary contribution of this thesis to the design of tuples.
 \begin{cfacode}
 forall(otype T, dtype U)
@@ -524,5 +535,5 @@
 It is also important to note that these calls could be disambiguated if the function return types were different, as they likely would be for a reasonable implementation of @?+?@, since the return type is used in overload resolution.
 Still, these semantics are a deficiency of the current argument matching algorithm, and depending on the function, differing return values may not always be appropriate.
-These issues could be rectified by applying an appropriate cost to the structuring and flattening conversions, which are currently 0-cost conversions.
+These issues could be rectified by applying an appropriate conversion cost to the structuring and flattening conversions, which are currently 0-cost conversions in the expression resolver.
 Care would be needed in this case to ensure that exact matches do not incur such a cost.
 \begin{cfacode}
@@ -559,4 +570,7 @@
 \section{Implementation}
 Tuples are implemented in the \CFA translator via a transformation into generic types.
+Generic types are an independent contribution developed at the same time.
+The transformation into generic types and the generation of tuple-specific code are primary contributions of this thesis to tuples.
+
 The first time an $N$-tuple is seen for each $N$ in a scope, a generic type with $N$ type parameters is generated.
 For example,
Index: doc/rob_thesis/variadic.tex
===================================================================
--- doc/rob_thesis/variadic.tex	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ doc/rob_thesis/variadic.tex	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -5,8 +5,8 @@
 \section{Design Criteria} % TODO: better section name???
 C provides variadic functions through the manipulation of @va_list@ objects.
-A variadic function is one which contains at least one parameter, followed by @...@ as the last token in the parameter list.
-In particular, some form of \emph{argument descriptor} is needed to inform the function of the number of arguments and their types.
+In C, a variadic function is one which contains at least one parameter, followed by @...@ as the last token in the parameter list.
+In particular, some form of \emph{argument descriptor} or \emph{sentinel value} is needed to inform the function of the number of arguments and their types.
 Two common argument descriptors are format strings or counter parameters.
-It is important to note that both of these mechanisms are inherently redundant, because they require the user to explicitly specify information that the compiler already knows.
+It is important to note that both of these mechanisms are inherently redundant, because they require the user to explicitly specify information that the compiler already knows \footnote{While format specifiers can convey some information the compiler does not know, such as whether to print a number in decimal or hexadecimal, the number of arguments is wholly redundant.}.
 This required repetition is error prone, because it is easy for the user to add or remove arguments without updating the argument descriptor.
 In addition, C requires the programmer to hard code all of the possible expected types.
@@ -152,4 +152,5 @@
 That is to say, the programmer who writes @sum@ does not need full program knowledge of every possible data type, unlike what is necessary to write an equivalent function using the standard C mechanisms.
 
+\begin{sloppypar}
 Going one last step, it is possible to achieve full generality in \CFA, allowing the summation of arbitrary lists of summable types.
 \begin{cfacode}
@@ -170,4 +171,5 @@
 \end{cfacode}
 The \CFA translator requires adding explicit @double ?+?(int, double)@ and @double ?+?(double, int)@ functions for this call to work, since implicit conversions are not supported for assertions.
+\end{sloppypar}
 
 A notable limitation of this approach is that it heavily relies on recursive assertions.
@@ -226,5 +228,5 @@
 In the call to @new@, @Array@ is selected to match @T@, and @Params@ is expanded to match @[int, int, int, int]@. To satisfy the assertions, a constructor with an interface compatible with @void ?{}(Array *, int, int, int)@ must exist in the current scope.
 
-The @new@ function provides the combination of type-safe @malloc@ with a constructor call, so that it becomes impossible to forget to construct dynamically-allocated objects.
+The @new@ function provides the combination of polymorphic @malloc@ with a constructor call, so that it becomes impossible to forget to construct dynamically-allocated objects.
 This approach provides the type-safety of @new@ in \CC, without the need to specify the allocated type, thanks to return-type inference.
 
Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/CodeGen/CodeGenerator.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Mar 30 16:38:01 2017
-// Update Count     : 482
+// Last Modified By : Andrew Beach
+// Last Modified On : Tus May  9 16:50:00 2017
+// Update Count     : 484
 //
 
@@ -41,4 +41,17 @@
 namespace CodeGen {
 	int CodeGenerator::tabsize = 4;
+
+	// Pseudo Function: output << lineDirective(currentNode);
+    struct lineDirective {
+        CodeLocation const & loc;
+		lineDirective(CodeLocation const & location) : loc(location) {}
+		lineDirective(BaseSyntaxNode const * node) : loc(node->location) {}
+	};
+	std::ostream & operator<<(std::ostream & out, lineDirective const & ld) {
+		if (ld.loc.isSet())
+			return out << "\n# " << ld.loc.linenumber << " \""
+				<< ld.loc.filename << "\"\n";
+		return out << "\n// Unset Location\n";
+	}
 
 	// the kinds of statements that would ideally be followed by whitespace
@@ -128,6 +141,8 @@
 
 
-	//*** Declarations
+	// *** Declarations
 	void CodeGenerator::visit( FunctionDecl * functionDecl ) {
+		output << lineDirective( functionDecl );
+
 		extension( functionDecl );
 		genAttributes( functionDecl->get_attributes() );
@@ -153,4 +168,6 @@
 		}
 
+		output << lineDirective( objectDecl );
+
 		extension( objectDecl );
 		genAttributes( objectDecl->get_attributes() );
@@ -192,5 +209,5 @@
 			cur_indent += CodeGenerator::tabsize;
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) {
-				output << indent;
+				output << lineDirective( *i ) << indent;
 				(*i)->accept( *this );
 				output << ";" << endl;
@@ -204,4 +221,6 @@
 
 	void CodeGenerator::visit( StructDecl * structDecl ) {
+		output << lineDirective( structDecl );
+
 		extension( structDecl );
 		handleAggregate( structDecl, "struct " );
@@ -209,4 +228,6 @@
 
 	void CodeGenerator::visit( UnionDecl * unionDecl ) {
+		output << lineDirective( unionDecl );
+
 		extension( unionDecl );
 		handleAggregate( unionDecl, "union " );
@@ -215,4 +236,5 @@
 	void CodeGenerator::visit( EnumDecl * enumDecl ) {
 		extension( enumDecl );
+		output << lineDirective ( enumDecl );
 		output << "enum ";
 		genAttributes( enumDecl->get_attributes() );
@@ -230,5 +252,5 @@
 				ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
 				assert( obj );
-				output << indent << mangleName( obj );
+				output << lineDirective( obj ) << indent << mangleName( obj );
 				if ( obj->get_init() ) {
 					output << " = ";
@@ -248,4 +270,5 @@
 	void CodeGenerator::visit( TypedefDecl * typeDecl ) {
 		assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
+		output << lineDirective( typeDecl );
 		output << "typedef ";
 		output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
@@ -262,5 +285,8 @@
 			} // if
 		} else {
-			output << typeDecl->typeString() << " " << typeDecl->get_name();
+			output << typeDecl->genTypeString() << " " << typeDecl->get_name();
+			if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->get_sized() ) {
+				output << " | sized(" << typeDecl->get_name() << ")";
+			}
 			if ( ! typeDecl->get_assertions().empty() ) {
 				output << " | { ";
@@ -316,5 +342,5 @@
 	}
 
-	//*** Expressions
+	// *** Expressions
 	void CodeGenerator::visit( ApplicationExpr * applicationExpr ) {
 		extension( applicationExpr );
@@ -719,10 +745,11 @@
 	void CodeGenerator::visit( StmtExpr * stmtExpr ) {
 		std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
-		output << "({" << std::endl;
+		output << lineDirective( stmtExpr) << "({" << std::endl;
 		cur_indent += CodeGenerator::tabsize;
 		unsigned int numStmts = stmts.size();
 		unsigned int i = 0;
 		for ( Statement * stmt : stmts ) {
-			output << indent << printLabels( stmt->get_labels() );
+			output << lineDirective( stmt ) << indent;
+            output << printLabels( stmt->get_labels() );
 			if ( i+1 == numStmts ) {
 				// last statement in a statement expression needs to be handled specially -
@@ -746,5 +773,5 @@
 	}
 
-	//*** Statements
+	// *** Statements
 	void CodeGenerator::visit( CompoundStmt * compoundStmt ) {
 		std::list<Statement*> ks = compoundStmt->get_kids();
@@ -769,6 +796,9 @@
 	void CodeGenerator::visit( ExprStmt * exprStmt ) {
 		assert( exprStmt );
-		// cast the top-level expression to void to reduce gcc warnings.
-		Expression * expr = new CastExpr( exprStmt->get_expr() );
+		Expression * expr = exprStmt->get_expr();
+		if ( genC ) {
+			// cast the top-level expression to void to reduce gcc warnings.
+			expr = new CastExpr( expr );
+		}
 		expr->accept( *this );
 		output << ";";
@@ -807,4 +837,5 @@
 
 	void CodeGenerator::visit( IfStmt * ifStmt ) {
+		output << lineDirective( ifStmt );
 		output << "if ( ";
 		ifStmt->get_condition()->accept( *this );
@@ -820,4 +851,5 @@
 
 	void CodeGenerator::visit( SwitchStmt * switchStmt ) {
+		output << lineDirective( switchStmt );
 		output << "switch ( " ;
 		switchStmt->get_condition()->accept( *this );
@@ -832,4 +864,5 @@
 
 	void CodeGenerator::visit( CaseStmt * caseStmt ) {
+		output << lineDirective( caseStmt );
 		output << indent;
 		if ( caseStmt->isDefault()) {
Index: src/CodeGen/Generate.cc
===================================================================
--- src/CodeGen/Generate.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/CodeGen/Generate.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -22,5 +22,9 @@
 #include "SynTree/Declaration.h"
 #include "CodeGenerator.h"
-#include "Tuples/Tuples.h"
+#include "GenType.h"
+#include "SynTree/SynTree.h"
+#include "SynTree/Type.h"
+#include "SynTree/BaseSyntaxNode.h"
+// #include "Tuples/Tuples.h"
 
 using namespace std;
@@ -39,4 +43,14 @@
 		} // for
 	}
+
+	void generate( BaseSyntaxNode * node, std::ostream & os ) {
+		if ( Type * type = dynamic_cast< Type * >( node ) ) {
+			os << CodeGen::genPrettyType( type, "" );
+		} else {
+			CodeGen::CodeGenerator cgv( os, true, false );
+			node->accept( cgv );
+		}
+		os << std::endl;
+	}
 } // namespace CodeGen
 
Index: src/CodeGen/Generate.h
===================================================================
--- src/CodeGen/Generate.h	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/CodeGen/Generate.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -25,4 +25,7 @@
 	/// Generates code. doIntrinsics determines if intrinsic functions are printed, pretty formats output nicely (e.g., uses unmangled names, etc.), generateC is true when the output must consist only of C code (allows some assertions, etc.)
 	void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false );
+
+	/// Generate code for a single node -- helpful for debugging in gdb
+	void generate( BaseSyntaxNode * node, std::ostream & os );
 } // namespace CodeGen
 
Index: src/CodeGen/LineStream.cc
===================================================================
--- src/CodeGen/LineStream.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/CodeGen/LineStream.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,97 @@
+//
+// 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.
+//
+// LineStream.cc -- Modified stream that inserts line directives into output.
+//
+// Author           : Andrew Beach
+// Created On       : Thr May 4 13:15:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon May 8 12:08:00 2017
+// Update Count     : 0
+//
+
+#include "LineStream.h"
+
+namespace CodeGen {
+
+	void LineStream::printLineDirective(CodeLocation const & location) {
+		baseStream << "\n# " << location.linenumber;
+		if (std::string("") != location.filename) {
+			baseStream << " \"" << location.filename  << '"';
+		}
+		baseStream << '\n';
+	}
+
+	bool LineStream::actualDiffersFromExpected() const {
+		return actualLocation.isSet() &&
+			// actualLocation & expectedLocation must match at the line.
+			(actualLocation.linenumber != expectedLocation.linenumber ||
+			 actualLocation.filename != expectedLocation.filename);
+	}
+
+	void LineStream::emptyBuffer(bool addNewline) {
+		if (actualDiffersFromExpected()) {
+			printLineDirective(actualLocation);
+			expectedLocation = actualLocation;
+		}
+		actualLocation.unset();
+
+		if (addNewline) {
+			expectedLocation.linenumber += 1;
+			buffer.put('\n');
+		}
+
+		baseStream << buffer.str() << std::flush;
+		buffer.str("");
+	}
+
+	void LineStream::setLoc(CodeLocation const & location) {
+		if (insertLines) {
+			if (expectedLocation.isUnset()) {
+				expectedLocation = actualLocation = location;
+			} else if (actualLocation.isUnset()) {
+				actualLocation = location;
+			} else if (actualLocation.filename != location.filename) {
+				emptyBuffer(true);
+				actualLocation = location;
+			} else if (location.linenumber <= actualLocation.linenumber){
+				actualLocation.linenumber = location.linenumber;
+			}
+		}
+	}
+
+	LineStream & LineStream::operator<<(char const * str) {
+		buffer << str;
+		return *this;
+	}
+
+	LineStream & LineStream::operator<<(std::string const & str) {
+		buffer << str;
+		return *this;
+	}
+
+	LineStream & LineStream::operator<<(StreamFlag flag) {
+		static StreamFlag const endlCopy = std::endl;
+		if (!insertLines) {
+			baseStream << flag;
+		} else if (endlCopy == flag) {
+			emptyBuffer(true);
+		} else {
+			buffer << flag;
+		}
+		return *this;
+	}
+
+	LineStream & LineStream::flush() {
+		if (insertLines) {
+			emptyBuffer(false);
+		} else {
+			baseStream.flush();
+		}
+		return *this;
+	}
+
+} // CodeGen
Index: src/CodeGen/LineStream.h
===================================================================
--- src/CodeGen/LineStream.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/CodeGen/LineStream.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,62 @@
+//
+// 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.
+//
+// LineStream.h -- Modified stream that inserts line directives into output.
+//
+// Author           : Andrew Beach
+// Created On       : Wed May 4 09:15:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon May 8 14:03:00 2017
+// Update Count     : 1
+//
+
+#ifndef LINE_STREAM_H
+#define LINE_STREAM_H
+
+#include <ostream>
+#include <sstream>
+#include <string>
+
+#include "Common/utility.h"
+
+namespace CodeGen {
+
+	class LineStream {
+		std::ostream & baseStream;
+		std::ostringstream buffer;
+
+		bool const insertLines;
+
+		CodeLocation actualLocation;
+		CodeLocation expectedLocation;
+
+		void printLineDirective(CodeLocation const & location);
+		bool actualDiffersFromExpected() const;
+		void emptyBuffer(bool addNewline);
+
+	public:
+		typedef std::ostream &(*StreamFlag)(std::ostream &);
+
+		LineStream(std::ostream & baseStream, bool insertLines) :
+			baseStream(baseStream), insertLines(insertLines)
+		{}
+
+		/// Update the currentLocation in source code.
+		void setLoc(CodeLocation const & location);
+
+		/// Formated output is buffered until flushed.
+		LineStream & operator<<(char const *str);
+		LineStream & operator<<(std::string const & str);
+		LineStream & operator<<(StreamFlag flag);
+
+		/// Flush all buffered output.
+		LineStream & flush();
+
+	}; // LineStream
+
+} // CodeGen
+
+#endif // LINE_STREAM_H
Index: src/CodeTools/TrackLoc.cc
===================================================================
--- src/CodeTools/TrackLoc.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/CodeTools/TrackLoc.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,191 @@
+//
+// 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.
+//
+// TrackLoc.cc --
+//
+// Author           : Andrew Beach
+// Created On       : Tues May 2 15:46:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed May 3 14:43:00 2017
+// Update Count     : 0
+//
+
+#include "TrackLoc.h"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <cstdlib>
+
+#include "Common/utility.h"
+#include "Common/VectorMap.h"
+#include "GenPoly/GenPoly.h"
+#include "Parser/LinkageSpec.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Visitor.h"
+
+namespace CodeTools {
+
+    std::ostream & operator<<(std::ostream & out, CodeLocation const & loc) {
+        return out << loc.filename << '[' << loc.linenumber << ']';
+    }
+
+	class LocationPrinter : public Visitor {
+		unsigned int printLevel;
+		unsigned int currentLevel;
+
+		CodeLocation *parent;
+		CodeLocation *lastNode;
+
+    public:
+        LocationPrinter(unsigned int printLevel) :
+            Visitor(), printLevel(printLevel), currentLevel(0),
+			parent(nullptr), lastNode(nullptr)
+        {}
+
+        void print(char const * name, BaseSyntaxNode *node) {
+            for (unsigned int i = 0 ; i < currentLevel ; ++i) {
+				std::cout << "    ";
+			}
+            if (2 <= printLevel) {
+				std::cout << name << '@';
+			}
+			std::cout << node->location << std::endl;
+        }
+
+		void atNode(char const * name, BaseSyntaxNode *node) {
+			if (-1 == node->location.linenumber) {
+				if (nullptr != parent) {
+					node->location.linenumber = parent->linenumber;
+					node->location.filename = parent->filename;
+				} else if (nullptr != lastNode) {
+					node->location.linenumber = lastNode->linenumber;
+					node->location.filename = lastNode->filename;
+				} else {
+					std::cerr << "Top level node has no CodeLocation " <<
+								 name << std::endl;
+					exit(EXIT_FAILURE);
+				}
+			}
+			if (0 < printLevel) {
+				print(name, node);
+			}
+			lastNode = &node->location;
+		}
+
+#define VISIT_FUNCTION(SyntaxNodeType)				\
+		virtual void visit(SyntaxNodeType *node) {	\
+			atNode(#SyntaxNodeType, node);			\
+			++currentLevel;							\
+			CodeLocation * myParent = parent;		\
+			parent = &node->location;				\
+			Visitor::visit(node);					\
+			parent = myParent;						\
+			--currentLevel;							\
+		}
+
+		VISIT_FUNCTION(ObjectDecl)
+		VISIT_FUNCTION(FunctionDecl)
+		VISIT_FUNCTION(StructDecl)
+		VISIT_FUNCTION(UnionDecl)
+		VISIT_FUNCTION(EnumDecl)
+		VISIT_FUNCTION(TraitDecl)
+		VISIT_FUNCTION(TypeDecl)
+		VISIT_FUNCTION(TypedefDecl)
+		VISIT_FUNCTION(AsmDecl)
+
+		VISIT_FUNCTION(CompoundStmt)
+		VISIT_FUNCTION(ExprStmt)
+		VISIT_FUNCTION(AsmStmt)
+		VISIT_FUNCTION(IfStmt)
+		VISIT_FUNCTION(WhileStmt)
+		VISIT_FUNCTION(ForStmt)
+		VISIT_FUNCTION(SwitchStmt)
+		VISIT_FUNCTION(CaseStmt)
+		VISIT_FUNCTION(BranchStmt)
+		VISIT_FUNCTION(ReturnStmt)
+		VISIT_FUNCTION(TryStmt)
+		VISIT_FUNCTION(CatchStmt)
+		VISIT_FUNCTION(FinallyStmt)
+		VISIT_FUNCTION(NullStmt)
+		VISIT_FUNCTION(DeclStmt)
+		VISIT_FUNCTION(ImplicitCtorDtorStmt)
+
+		VISIT_FUNCTION(ApplicationExpr)
+		VISIT_FUNCTION(UntypedExpr)
+		VISIT_FUNCTION(NameExpr)
+		VISIT_FUNCTION(CastExpr)
+		VISIT_FUNCTION(AddressExpr)
+		VISIT_FUNCTION(LabelAddressExpr)
+		VISIT_FUNCTION(UntypedMemberExpr)
+		VISIT_FUNCTION(MemberExpr)
+		VISIT_FUNCTION(VariableExpr)
+		VISIT_FUNCTION(ConstantExpr)
+		VISIT_FUNCTION(SizeofExpr)
+		VISIT_FUNCTION(AlignofExpr)
+		VISIT_FUNCTION(UntypedOffsetofExpr)
+		VISIT_FUNCTION(OffsetofExpr)
+		VISIT_FUNCTION(OffsetPackExpr)
+		VISIT_FUNCTION(AttrExpr)
+		VISIT_FUNCTION(LogicalExpr)
+		VISIT_FUNCTION(ConditionalExpr)
+		VISIT_FUNCTION(CommaExpr)
+		VISIT_FUNCTION(TypeExpr)
+		VISIT_FUNCTION(AsmExpr)
+		VISIT_FUNCTION(ImplicitCopyCtorExpr)
+		VISIT_FUNCTION(ConstructorExpr)
+		VISIT_FUNCTION(CompoundLiteralExpr)
+		VISIT_FUNCTION(UntypedValofExpr)
+		VISIT_FUNCTION(RangeExpr)
+		VISIT_FUNCTION(UntypedTupleExpr)
+		VISIT_FUNCTION(TupleExpr)
+		VISIT_FUNCTION(TupleIndexExpr)
+		VISIT_FUNCTION(MemberTupleExpr)
+		VISIT_FUNCTION(TupleAssignExpr)
+		VISIT_FUNCTION(StmtExpr)
+		VISIT_FUNCTION(UniqueExpr)
+
+		VISIT_FUNCTION(VoidType)
+		VISIT_FUNCTION(BasicType)
+		VISIT_FUNCTION(PointerType)
+		VISIT_FUNCTION(ArrayType)
+		VISIT_FUNCTION(FunctionType)
+		VISIT_FUNCTION(StructInstType)
+		VISIT_FUNCTION(UnionInstType)
+		VISIT_FUNCTION(EnumInstType)
+		VISIT_FUNCTION(TraitInstType)
+		VISIT_FUNCTION(TypeInstType)
+		VISIT_FUNCTION(TupleType)
+		VISIT_FUNCTION(TypeofType)
+		VISIT_FUNCTION(AttrType)
+		VISIT_FUNCTION(VarArgsType)
+		VISIT_FUNCTION(ZeroType)
+		VISIT_FUNCTION(OneType)
+
+		VISIT_FUNCTION(SingleInit)
+		VISIT_FUNCTION(ListInit)
+		VISIT_FUNCTION(ConstructorInit)
+
+		//VISIT_FUNCTION(Subrange)
+
+		//VISIT_FUNCTION(Constant)
+
+	}; // LocationPrinter
+
+	void fillLocations( std::list< Declaration * > & translationUnit,
+			unsigned int printLevel) {
+		LocationPrinter printer(printLevel);
+		acceptAll( translationUnit, printer );
+	}
+
+} // namespace CodeTools
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/CodeTools/TrackLoc.h
===================================================================
--- src/CodeTools/TrackLoc.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/CodeTools/TrackLoc.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,37 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// TrackLoc.h -- Track CodeLocation information in a translation unit's declarations.
+//
+// Author           : Andrew Beach
+// Created On       : Tues May 2 15:40:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed May 3 14:42:00 2017
+// Update Count     : 0
+//
+
+#ifndef TRACKLOC_H
+#define TRACKLOC_H
+
+#include "SynTree/SynTree.h"
+
+namespace CodeTools {
+
+	/// Fill in an approximate CodeLocation for each syntax node.
+	// printLevel: how much printing while filling in the node locations.
+	// 0 - No Printing, 1 - Print Location, 2 - Print Node Type and Location
+	void fillLocations( std::list< Declaration * > &translationUnit,
+			unsigned int printLevel = 0 );
+
+}  // namespace CodeTools
+
+#endif // TRACKLOC_H
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/CodeTools/module.mk
===================================================================
--- src/CodeTools/module.mk	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/CodeTools/module.mk	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -15,3 +15,4 @@
 ###############################################################################
 
-SRC += CodeTools/DeclStats.cc
+SRC += CodeTools/DeclStats.cc \
+	CodeTools/TrackLoc.cc
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/Common/utility.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec 14 21:25:25 2016
-// Update Count     : 31
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri May 5 11:03:00 2017
+// Update Count     : 32
 //
 
@@ -322,17 +322,34 @@
 	std::string filename;
 
-	CodeLocation() 
+    /// Create a new unset CodeLocation.
+	CodeLocation()
 		: linenumber( -1 )
 		, filename("")
 	{}
 
+    /// Create a new CodeLocation with the given values.
 	CodeLocation( const char* filename, int lineno )
 		: linenumber( lineno )
 		, filename(filename ? filename : "")
 	{}
+
+    bool isSet () const {
+        return -1 != linenumber;
+    }
+
+    bool isUnset () const {
+        return !isSet();
+    }
+
+	void unset () {
+		linenumber = -1;
+		filename = "";
+	}
+
+	// Use field access for set.
 };
 
 inline std::string to_string( const CodeLocation& location ) {
-	return location.linenumber >= 0 ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
+	return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
 }
 #endif // _UTILITY_H
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/Concurrency/Keywords.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -246,4 +246,5 @@
 	//=============================================================================================
 	void ConcurrentSueKeyword::visit(StructDecl * decl) {
+		Visitor::visit(decl);
 		if( decl->get_name() == type_name ) {
 			assert( !type_decl );
@@ -385,4 +386,6 @@
 	//=============================================================================================
 	void MutexKeyword::visit(FunctionDecl* decl) {
+		Visitor::visit(decl);		
+
 		std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
 		if( mutexArgs.empty() ) return;
@@ -402,4 +405,6 @@
 
 	void MutexKeyword::visit(StructDecl* decl) {
+		Visitor::visit(decl);
+
 		if( decl->get_name() == "monitor_desc" ) {
 			assert( !monitor_decl );
@@ -504,4 +509,6 @@
 	//=============================================================================================
 	void ThreadStarter::visit(FunctionDecl * decl) {
+		Visitor::visit(decl);
+		
 		if( ! InitTweak::isConstructor(decl->get_name()) ) return;
 
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -233,5 +233,5 @@
 				} else {
 					// normalize possibly dtype-static parameter type
-					out.push_back( new TypeExpr{ 
+					out.push_back( new TypeExpr{
 						ScrubTyVars::scrubAll( paramType->get_type()->clone() ) } );
 					gt |= genericType::concrete;
@@ -369,4 +369,5 @@
 				DeclMutator::addDeclaration( concDecl );
 				insert( inst, typeSubs, concDecl );
+				concDecl->acceptMutator( *this ); // recursively instantiate members
 			}
 			StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
@@ -423,4 +424,5 @@
 				DeclMutator::addDeclaration( concDecl );
 				insert( inst, typeSubs, concDecl );
+				concDecl->acceptMutator( *this ); // recursively instantiate members
 			}
 			UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
Index: src/GenPoly/PolyMutator.cc
===================================================================
--- src/GenPoly/PolyMutator.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/GenPoly/PolyMutator.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -50,4 +50,11 @@
 
 	Statement * PolyMutator::mutateStatement( Statement *stmt ) {
+		// don't want statements from outer CompoundStmts to be added to this CompoundStmt
+		ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd );
+		ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter );
+		ValueGuard< TypeSubstitution * > oldEnv( env );
+		stmtsToAdd.clear();
+		stmtsToAddAfter.clear();
+
 		Statement *newStmt = maybeMutate( stmt, *this );
 		if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) {
@@ -83,33 +90,33 @@
 
 	Statement * PolyMutator::mutate(IfStmt *ifStmt) {
+		ifStmt->set_condition(  mutateExpression( ifStmt->get_condition() ) );
 		ifStmt->set_thenPart(  mutateStatement( ifStmt->get_thenPart() ) );
 		ifStmt->set_elsePart(  mutateStatement( ifStmt->get_elsePart() ) );
-		ifStmt->set_condition(  mutateExpression( ifStmt->get_condition() ) );
 		return ifStmt;
 	}
 
 	Statement * PolyMutator::mutate(WhileStmt *whileStmt) {
+		whileStmt->set_condition(  mutateExpression( whileStmt->get_condition() ) );
 		whileStmt->set_body(  mutateStatement( whileStmt->get_body() ) );
-		whileStmt->set_condition(  mutateExpression( whileStmt->get_condition() ) );
 		return whileStmt;
 	}
 
 	Statement * PolyMutator::mutate(ForStmt *forStmt) {
-		forStmt->set_body(  mutateStatement( forStmt->get_body() ) );
 		mutateAll( forStmt->get_initialization(), *this );
 		forStmt->set_condition(  mutateExpression( forStmt->get_condition() ) );
 		forStmt->set_increment(  mutateExpression( forStmt->get_increment() ) );
+		forStmt->set_body(  mutateStatement( forStmt->get_body() ) );
 		return forStmt;
 	}
 
 	Statement * PolyMutator::mutate(SwitchStmt *switchStmt) {
+		switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) );
 		mutateStatementList( switchStmt->get_statements() );
-		switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) );
 		return switchStmt;
 	}
 
 	Statement * PolyMutator::mutate(CaseStmt *caseStmt) {
+		caseStmt->set_condition(  mutateExpression( caseStmt->get_condition() ) );
 		mutateStatementList( caseStmt->get_statements() );
-		caseStmt->set_condition(  mutateExpression( caseStmt->get_condition() ) );
 		return caseStmt;
 	}
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/Makefile.in	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -108,4 +108,5 @@
 	CodeGen/driver_cfa_cpp-OperatorTable.$(OBJEXT) \
 	CodeTools/driver_cfa_cpp-DeclStats.$(OBJEXT) \
+	CodeTools/driver_cfa_cpp-TrackLoc.$(OBJEXT) \
 	Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT) \
 	Common/driver_cfa_cpp-SemanticError.$(OBJEXT) \
@@ -388,6 +389,7 @@
 	CodeGen/FixNames.cc CodeGen/FixMain.cc \
 	CodeGen/OperatorTable.cc CodeTools/DeclStats.cc \
-	Concurrency/Keywords.cc Common/SemanticError.cc \
-	Common/UniqueName.cc Common/DebugMalloc.cc Common/Assert.cc \
+	CodeTools/TrackLoc.cc Concurrency/Keywords.cc \
+	Common/SemanticError.cc Common/UniqueName.cc \
+	Common/DebugMalloc.cc Common/Assert.cc \
 	ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
 	ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
@@ -545,4 +547,6 @@
 	@: > CodeTools/$(DEPDIR)/$(am__dirstamp)
 CodeTools/driver_cfa_cpp-DeclStats.$(OBJEXT):  \
+	CodeTools/$(am__dirstamp) CodeTools/$(DEPDIR)/$(am__dirstamp)
+CodeTools/driver_cfa_cpp-TrackLoc.$(OBJEXT):  \
 	CodeTools/$(am__dirstamp) CodeTools/$(DEPDIR)/$(am__dirstamp)
 Concurrency/$(am__dirstamp):
@@ -843,4 +847,5 @@
 	-rm -f CodeGen/driver_cfa_cpp-OperatorTable.$(OBJEXT)
 	-rm -f CodeTools/driver_cfa_cpp-DeclStats.$(OBJEXT)
+	-rm -f CodeTools/driver_cfa_cpp-TrackLoc.$(OBJEXT)
 	-rm -f Common/driver_cfa_cpp-Assert.$(OBJEXT)
 	-rm -f Common/driver_cfa_cpp-DebugMalloc.$(OBJEXT)
@@ -954,4 +959,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po@am__quote@
@@ -1195,4 +1201,18 @@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-DeclStats.obj `if test -f 'CodeTools/DeclStats.cc'; then $(CYGPATH_W) 'CodeTools/DeclStats.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/DeclStats.cc'; fi`
 
+CodeTools/driver_cfa_cpp-TrackLoc.o: CodeTools/TrackLoc.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-TrackLoc.o -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo -c -o CodeTools/driver_cfa_cpp-TrackLoc.o `test -f 'CodeTools/TrackLoc.cc' || echo '$(srcdir)/'`CodeTools/TrackLoc.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='CodeTools/TrackLoc.cc' object='CodeTools/driver_cfa_cpp-TrackLoc.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 CodeTools/driver_cfa_cpp-TrackLoc.o `test -f 'CodeTools/TrackLoc.cc' || echo '$(srcdir)/'`CodeTools/TrackLoc.cc
+
+CodeTools/driver_cfa_cpp-TrackLoc.obj: CodeTools/TrackLoc.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-TrackLoc.obj -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo -c -o CodeTools/driver_cfa_cpp-TrackLoc.obj `if test -f 'CodeTools/TrackLoc.cc'; then $(CYGPATH_W) 'CodeTools/TrackLoc.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/TrackLoc.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='CodeTools/TrackLoc.cc' object='CodeTools/driver_cfa_cpp-TrackLoc.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 CodeTools/driver_cfa_cpp-TrackLoc.obj `if test -f 'CodeTools/TrackLoc.cc'; then $(CYGPATH_W) 'CodeTools/TrackLoc.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/TrackLoc.cc'; fi`
+
 Concurrency/driver_cfa_cpp-Keywords.o: Concurrency/Keywords.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Keywords.o -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo -c -o Concurrency/driver_cfa_cpp-Keywords.o `test -f 'Concurrency/Keywords.cc' || echo '$(srcdir)/'`Concurrency/Keywords.cc
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/Parser/parser.yy	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -393,4 +393,10 @@
 	| '(' compound_statement ')'						// GCC, lambda expression
 		{ $$ = new ExpressionNode( build_valexpr( $2 ) ); }
+	| primary_expression '{' argument_expression_list '}' // CFA
+		{
+			Token fn;
+			fn.str = new std::string( "?{}" );			// location undefined - use location of '{'?
+			$$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
+		}
 	;
 
@@ -425,9 +431,9 @@
 	| '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99, compound-literal
 		{ $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
-	| postfix_expression '{' argument_expression_list '}' // CFA
+	| '^' primary_expression '{' argument_expression_list '}' // CFA
 		{
 			Token fn;
-			fn.str = new std::string( "?{}" );			// location undefined - use location of '{'?
-			$$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
+			fn.str = new string( "^?{}" );				// location undefined
+			$$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
 		}
 	;
@@ -730,11 +736,4 @@
 	| exception_statement
 	| asm_statement
-	| '^' postfix_expression '{' argument_expression_list '}' ';' // CFA
-		{
-			Token fn;
-			fn.str = new string( "^?{}" );				// location undefined
-			$$ = new StatementNode( build_expr( new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) ) ) );
-		}
-	;
 
 labeled_statement:
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -766,13 +766,16 @@
 			} // if
 		} // for
-		// function may return struct or union value, in which case we need to add alternatives for implicit conversions to each of the anonymous members
+
+		candidates.clear();
+		candidates.splice( candidates.end(), alternatives );
+
+		findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
+
+		// function may return struct or union value, in which case we need to add alternatives for implicit
+		// conversions to each of the anonymous members, must happen after findMinCost since anon conversions
+		// are never the cheapest expression
 		for ( const Alternative & alt : alternatives ) {
 			addAnonConversions( alt );
 		}
-
-		candidates.clear();
-		candidates.splice( candidates.end(), alternatives );
-
-		findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
 
 		if ( alternatives.empty() && targetType && ! targetType->isVoid() ) {
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SymTab/Validate.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -240,13 +240,13 @@
 		ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
 		acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
+		acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist
+		VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
 		Concurrency::applyKeywords( translationUnit );
 		autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
 		Concurrency::implementMutexFuncs( translationUnit );
 		Concurrency::implementThreadStarter( translationUnit );
-		acceptAll( translationUnit, epc );
 		ReturnChecker::checkFunctionReturns( translationUnit );
 		compoundliteral.mutateDeclarationList( translationUnit );
 		acceptAll( translationUnit, pass3 );
-		VerifyCtorDtorAssign::verify( translationUnit );
 		ArrayLength::computeLength( translationUnit );
 	}
@@ -817,5 +817,6 @@
 				throw SemanticError( "Constructors, destructors, and assignment functions require at least one parameter ", funcDecl );
 			}
-			if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
+			PointerType * ptrType = dynamic_cast< PointerType * >( params.front()->get_type() );
+			if ( ! ptrType || ptrType->is_array() ) {
 				throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a pointer ", funcDecl );
 			}
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SynTree/BaseSyntaxNode.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -18,8 +18,11 @@
 
 #include "Common/utility.h"
+#include "Visitor.h"
 
 class BaseSyntaxNode {
   public:
 	CodeLocation location;
+
+	virtual void accept( Visitor & v ) = 0; // temporary -- needs to be here so that BaseSyntaxNode is polymorphic and can be dynamic_cast
 };
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SynTree/Declaration.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -204,4 +204,5 @@
 
 	virtual std::string typeString() const;
+	virtual std::string genTypeString() const;
 
 	virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
Index: src/SynTree/PointerType.cc
===================================================================
--- src/SynTree/PointerType.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SynTree/PointerType.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// PointerType.cc -- 
+// PointerType.cc --
 //
 // Author           : Richard C. Bilson
@@ -38,14 +38,19 @@
 void PointerType::print( std::ostream &os, int indent ) const {
 	Type::print( os, indent );
-	os << "pointer to ";
-	if ( isStatic ) {
-		os << "static ";
-	} // if
-	if ( isVarLen ) {
-		os << "variable length array of ";
-	} else if ( dimension ) {
-		os << "array of ";
-		dimension->print( os, indent );
-	} // if
+	if ( ! is_array() ) {
+		os << "pointer to ";
+	} else {
+		os << "decayed ";
+		if ( isStatic ) {
+			os << "static ";
+		} // if
+		if ( isVarLen ) {
+			os << "variable length array of ";
+		} else if ( dimension ) {
+			os << "array of ";
+			dimension->print( os, indent );
+			os << " ";
+		} // if
+	}
 	if ( base ) {
 		base->print( os, indent );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SynTree/SynTree.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -21,4 +21,6 @@
 #include <map>
 #include <iostream>
+
+class BaseSyntaxNode;
 
 class Declaration;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SynTree/Type.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -247,4 +247,6 @@
 	void set_isStatic( bool newValue ) { isStatic = newValue; }
 
+	bool is_array() const { return isStatic || isVarLen || dimension; }
+
 	virtual PointerType *clone() const { return new PointerType( *this ); }
 	virtual void accept( Visitor & v ) { v.visit( this ); }
Index: src/SynTree/TypeDecl.cc
===================================================================
--- src/SynTree/TypeDecl.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SynTree/TypeDecl.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -29,4 +29,9 @@
 }
 
+std::string TypeDecl::genTypeString() const {
+	static const std::string kindNames[] = { "otype", "dtype", "ftype", "ttype" };
+	return kindNames[ kind ];
+}
+
 std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data ) {
   return os << data.kind << ", " << data.isComplete;
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/SynTree/Visitor.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -9,6 +9,6 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb  9 14:23:24 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed May  3 08:58:00 2017
 // Update Count     : 10
 //
@@ -26,4 +26,7 @@
 	virtual ~Visitor();
   public:
+	// visit: Default implementation of all functions visits the children
+    // of the given syntax node, but performs no other action.
+
 	virtual void visit( ObjectDecl *objectDecl );
 	virtual void visit( FunctionDecl *functionDecl );
Index: src/benchmark/CorCtxSwitch.c
===================================================================
--- src/benchmark/CorCtxSwitch.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/benchmark/CorCtxSwitch.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -3,29 +3,7 @@
 #include <thread>
 
-#include <unistd.h>					// sysconf
-#include <sys/times.h>					// times
-#include <time.h>
+#include "bench.h"
 
-inline unsigned long long int Time() {
-    timespec ts;
-    clock_gettime(
-#if defined( __linux__ )
-	 CLOCK_THREAD_CPUTIME_ID,
-#elif defined( __freebsd__ )
-	 CLOCK_PROF,
-#elif defined( __solaris__ )
-	 CLOCK_HIGHRES,
-#else
-    #error uC++ : internal error, unsupported architecture
-#endif
-	 &ts );
-    return 1000000000LL * ts.tv_sec + ts.tv_nsec;
-} // Time
-
-struct GreatSuspender {
-	coroutine_desc __cor;
-};
-
-DECL_COROUTINE(GreatSuspender);
+coroutine GreatSuspender {};
 
 void ?{}( GreatSuspender * this ) {
@@ -46,8 +24,4 @@
 }
 
-#ifndef N
-#define N 100000000
-#endif
-
 int main() {
 	const unsigned int NoOfTimes = N;
Index: src/benchmark/Makefile.am
===================================================================
--- src/benchmark/Makefile.am	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/benchmark/Makefile.am	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -44,4 +44,18 @@
 	@rm -f ./a.out
 
+sched-int:
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
+	@for number in 1 2 3 4 5 6 7 8 9 10; do \
+                ./a.out ; \
+        done
+	@rm -f ./a.out
+
+monitor:
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
+	@for number in 1 2 3 4 5 6 7 8 9 10; do \
+                ./a.out ; \
+        done
+	@rm -f ./a.out
+
 csv-data:
 	@${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
Index: src/benchmark/Makefile.in
===================================================================
--- src/benchmark/Makefile.in	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/benchmark/Makefile.in	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -492,4 +492,18 @@
 	@rm -f ./a.out
 
+sched-int:
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
+	@for number in 1 2 3 4 5 6 7 8 9 10; do \
+                ./a.out ; \
+        done
+	@rm -f ./a.out
+
+monitor:
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
+	@for number in 1 2 3 4 5 6 7 8 9 10; do \
+                ./a.out ; \
+        done
+	@rm -f ./a.out
+
 csv-data:
 	@${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
Index: src/benchmark/Monitor.c
===================================================================
--- src/benchmark/Monitor.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/benchmark/Monitor.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,32 @@
+#include <fstream>
+#include <stdlib>
+#include <thread>
+
+#include "bench.h"
+
+monitor mon_t {};
+
+mon_t mon1, mon2;
+
+void dummy( mon_t * mutex a ) {}
+void dummy( mon_t * mutex a, mon_t * mutex b ) {}
+
+int main() {
+	long long int StartTime, EndTime;
+
+	StartTime = Time();
+	for( int i = 0; i < N; i++ ) {
+		dummy( &mon1 );
+	}
+	EndTime = Time();
+
+	sout | ( EndTime - StartTime ) / N;
+
+	StartTime = Time();
+	for( int i = 0; i < N; i++ ) {
+		dummy( &mon1, &mon2 );
+	}
+	EndTime = Time();
+
+	sout | ( EndTime - StartTime ) / N | endl;
+}
Index: src/benchmark/SchedInt.c
===================================================================
--- src/benchmark/SchedInt.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/benchmark/SchedInt.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,83 @@
+#include <fstream>
+#include <stdlib>
+#include <thread>
+
+#include "bench.h"
+
+condition condA; 
+condition condB;
+condition condC;
+condition condD;
+
+monitor mon_t {};
+
+mon_t mon1, mon2;
+
+thread thrdA {};
+thread thrdB {};
+thread thrdC {};
+thread thrdD {};
+
+//-------------------------------------------------------------------
+// 1 monitor signal cycle
+void sideA( mon_t * mutex a ) {
+	long long int StartTime, EndTime;
+
+	StartTime = Time();
+	for( int i = 0;; i++ ) {
+		signal(&condA);
+		if( i > N ) break;
+		wait(&condB);
+	}
+	EndTime = Time();
+
+	sout | ( EndTime - StartTime ) / N;
+}
+
+void sideB( mon_t * mutex a ) {
+	for( int i = 0;; i++ ) {
+		signal(&condB);
+		if( i > N ) break;
+		wait(&condA);
+	}
+}
+
+//-------------------------------------------------------------------
+// 2 monitor signal cycle
+void sideC( mon_t * mutex a, mon_t * mutex b ) {
+	long long int StartTime, EndTime;
+
+	StartTime = Time();
+	for( int i = 0;; i++ ) {
+		signal(&condC);
+		if( i > N ) break;
+		wait(&condD);
+	}
+	EndTime = Time();
+
+	sout | ( EndTime - StartTime ) / N | endl;
+}
+
+void sideD( mon_t * mutex a, mon_t * mutex b ) {
+	for( int i = 0;; i++ ) {
+		signal(&condD);
+		if( i > N ) break;
+		wait(&condC);
+	}
+}
+
+void main( thrdA * this ) { sideA( &mon1 ); }
+void main( thrdB * this ) { sideB( &mon1 ); }
+void main( thrdC * this ) { sideC( &mon1, &mon2 ); }
+void main( thrdD * this ) { sideD( &mon1, &mon2 ); }
+
+int main() {
+	{
+		thrdA a;
+		thrdB b;
+	}
+	{
+		thrdC c;
+		thrdD d;
+	}
+}
Index: src/benchmark/ThrdCtxSwitch.c
===================================================================
--- src/benchmark/ThrdCtxSwitch.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/benchmark/ThrdCtxSwitch.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -3,27 +3,5 @@
 #include <thread>
 
-#include <unistd.h>					// sysconf
-#include <sys/times.h>					// times
-#include <time.h>
-
-inline unsigned long long int Time() {
-    timespec ts;
-    clock_gettime(
-#if defined( __linux__ )
-	 CLOCK_THREAD_CPUTIME_ID,
-#elif defined( __freebsd__ )
-	 CLOCK_PROF,
-#elif defined( __solaris__ )
-	 CLOCK_HIGHRES,
-#else
-    #error uC++ : internal error, unsupported architecture
-#endif
-	 &ts );
-    return 1000000000LL * ts.tv_sec + ts.tv_nsec;
-} // Time
- 
-#ifndef N
-#define N 100000000
-#endif
+#include "bench.h"
 
 int main() {
Index: src/benchmark/bench.c
===================================================================
--- src/benchmark/bench.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/benchmark/bench.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -4,23 +4,5 @@
 #include <thread>
 
-#include <unistd.h>					// sysconf
-#include <sys/times.h>					// times
-#include <time.h>
-
-inline unsigned long long int Time() {
-    timespec ts;
-    clock_gettime(
-#if defined( __linux__ )
-	 CLOCK_THREAD_CPUTIME_ID,
-#elif defined( __freebsd__ )
-	 CLOCK_PROF,
-#elif defined( __solaris__ )
-	 CLOCK_HIGHRES,
-#else
-    #error uC++ : internal error, unsupported architecture
-#endif
-	 &ts );
-    return 1000000000LL * ts.tv_sec + ts.tv_nsec;
-} // Time
+#include "bench.h"
 
 //=======================================
@@ -86,6 +68,5 @@
 //=======================================
 
-struct CoroutineDummy { coroutine_desc __cor; };
-DECL_COROUTINE(CoroutineDummy);
+coroutine CoroutineDummy {};
 void main(CoroutineDummy * this) {}
 
@@ -117,10 +98,7 @@
 }
 
-struct CoroutineResume {
+coroutine CoroutineResume {
     int N;
-    coroutine_desc __cor;
 };
-
-DECL_COROUTINE(CoroutineResume);
 
 void ?{}(CoroutineResume* this, int N) {
@@ -150,6 +128,5 @@
 //=======================================
 
-struct ThreadDummy { thread_desc __thrd; };
-DECL_THREAD(ThreadDummy);
+thread ThreadDummy {};
 void main(ThreadDummy * this) {}
 
@@ -177,11 +154,8 @@
 }
 
-struct ContextSwitch {
+thread ContextSwitch {
     int N;
     long long result;
-    thread_desc __thrd;
 };
-
-DECL_THREAD(ContextSwitch);
 
 void main(ContextSwitch * this) {    
@@ -241,5 +215,5 @@
 	DynamicTaskCreateDelete( NoOfTimes );
 	{
-		scoped(ContextSwitch) dummy = { (int)NoOfTimes };		// context switch
+		ContextSwitch dummy = { (int)NoOfTimes };		// context switch
 	}
 	sout | "\t" | endl;
Index: src/benchmark/bench.h
===================================================================
--- src/benchmark/bench.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/benchmark/bench.h	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,27 @@
+#pragma once
+
+extern "C" {
+	#include <unistd.h>					// sysconf
+	#include <sys/times.h>					// times
+	#include <time.h>
+}
+
+inline unsigned long long int Time() {
+    timespec ts;
+    clock_gettime(
+#if defined( __linux__ )
+	 CLOCK_THREAD_CPUTIME_ID,
+#elif defined( __freebsd__ )
+	 CLOCK_PROF,
+#elif defined( __solaris__ )
+	 CLOCK_HIGHRES,
+#else
+    #error uC++ : internal error, unsupported architecture
+#endif
+	 &ts );
+    return 1000000000LL * ts.tv_sec + ts.tv_nsec;
+} // Time
+
+#ifndef N
+#define N 10000000
+#endif
Index: src/benchmark/csv-data.c
===================================================================
--- src/benchmark/csv-data.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/benchmark/csv-data.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -1,33 +1,10 @@
 #include <fstream>
+#include <monitor>
 #include <stdlib>
 #include <thread>
 
-extern "C" {
-#include <unistd.h>					// sysconf
-#include <sys/times.h>					// times
-#include <time.h>
-}
-
-inline unsigned long long int Time() {
-    timespec ts;
-    clock_gettime(
-#if defined( __linux__ )
-	 CLOCK_THREAD_CPUTIME_ID,
-#elif defined( __freebsd__ )
-	 CLOCK_PROF,
-#elif defined( __solaris__ )
-	 CLOCK_HIGHRES,
-#else
-    #error uC++ : internal error, unsupported architecture
-#endif
-	 &ts );
-    return 1000000000LL * ts.tv_sec + ts.tv_nsec;
-} // Time
-
-struct GreatSuspender {
-	coroutine_desc __cor;
-};
-
-DECL_COROUTINE(GreatSuspender);
+#include "bench.h"
+
+coroutine GreatSuspender {};
 
 void ?{}( GreatSuspender * this ) {
@@ -52,6 +29,6 @@
 #endif
 
-
-
+//-----------------------------------------------------------------------------
+// coroutine context switch
 long long int measure_coroutine() {
 	const unsigned int NoOfTimes = N;
@@ -71,4 +48,6 @@
 }
 
+//-----------------------------------------------------------------------------
+// thread context switch
 long long int measure_thread() {
 	const unsigned int NoOfTimes = N;
@@ -84,6 +63,147 @@
 }
 
+//-----------------------------------------------------------------------------
+// single monitor entry
+monitor mon_t {};
+void dummy( mon_t * mutex m ) {}
+
+long long int measure_1_monitor_entry() {
+	const unsigned int NoOfTimes = N;
+	long long int StartTime, EndTime;
+	mon_t mon;
+
+	StartTime = Time();
+	for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
+		dummy( &mon );
+	}
+	EndTime = Time();
+
+	return ( EndTime - StartTime ) / NoOfTimes;
+}
+
+//-----------------------------------------------------------------------------
+// multi monitor entry
+void dummy( mon_t * mutex m1,  mon_t * mutex m2 ) {}
+
+long long int measure_2_monitor_entry() {
+	const unsigned int NoOfTimes = N;
+	long long int StartTime, EndTime;
+	mon_t mon1, mon2;
+
+	StartTime = Time();
+	for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
+		dummy( &mon1, &mon2 );
+	}
+	EndTime = Time();
+
+	return ( EndTime - StartTime ) / NoOfTimes;
+}
+
+//-----------------------------------------------------------------------------
+// single internal sched entry
+mon_t mon1;
+
+condition cond1a; 
+condition cond1b;
+
+thread thrd1a { long long int * out; };
+thread thrd1b {};
+
+void ?{}( thrd1a * this, long long int * out ) {
+	this->out = out;
+}
+
+void side1A( mon_t * mutex a, long long int * out ) {
+	long long int StartTime, EndTime;
+
+	StartTime = Time();
+	for( int i = 0;; i++ ) {
+		signal(&cond1a);
+		if( i > N ) break;
+		wait(&cond1b);
+	}
+	EndTime = Time();
+
+	*out = ( EndTime - StartTime ) / N;
+}
+
+void side1B( mon_t * mutex a ) {
+	for( int i = 0;; i++ ) {
+		signal(&cond1b);
+		if( i > N ) break;
+		wait(&cond1a);
+	}
+}
+
+void main( thrd1a * this ) { side1A( &mon1, this->out ); }
+void main( thrd1b * this ) { side1B( &mon1 ); }
+
+long long int measure_1_sched_int() {
+	long long int t;
+	{
+		thrd1a a = { &t };
+		thrd1b b;
+	}
+	return t;
+}
+
+//-----------------------------------------------------------------------------
+// multi internal sched entry
+mon_t mon2;
+
+condition cond2a; 
+condition cond2b;
+
+thread thrd2a { long long int * out; };
+thread thrd2b {};
+
+void ?{}( thrd2a * this, long long int * out ) {
+	this->out = out;
+}
+
+void side2A( mon_t * mutex a, mon_t * mutex b, long long int * out ) {
+	long long int StartTime, EndTime;
+
+	StartTime = Time();
+	for( int i = 0;; i++ ) {
+		signal(&cond2a);
+		if( i > N ) break;
+		wait(&cond2b);
+	}
+	EndTime = Time();
+
+	*out = ( EndTime - StartTime ) / N;
+}
+
+void side2B( mon_t * mutex a, mon_t * mutex b ) {
+	for( int i = 0;; i++ ) {
+		signal(&cond2b);
+		if( i > N ) break;
+		wait(&cond2a);
+	}
+}
+
+void main( thrd2a * this ) { side2A( &mon1, &mon2, this->out ); }
+void main( thrd2b * this ) { side2B( &mon1, &mon2 ); }
+
+long long int measure_2_sched_int() {
+	long long int t;
+	{
+		thrd2a a = { &t };
+		thrd2b b;
+	}
+	return t;
+}
+
+//-----------------------------------------------------------------------------
+// main loop
 int main()
 {
-	sout | time(NULL) | ',' | measure_coroutine() | ',' | measure_thread() | endl;
-}
+	sout | time(NULL) | ',';
+	sout | measure_coroutine() | ',';
+	sout | measure_thread() | ',';
+	sout | measure_1_monitor_entry() | ',';
+	sout | measure_2_monitor_entry() | ',';
+	sout | measure_1_sched_int() | ',';
+	sout | measure_2_sched_int() | endl;
+}
Index: src/libcfa/concurrency/monitor
===================================================================
--- src/libcfa/concurrency/monitor	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/libcfa/concurrency/monitor	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -81,4 +81,8 @@
 }
 
+static inline void ^?{}( condition * this ) {
+	free( this->monitors );
+}
+
 void wait( condition * this );
 void signal( condition * this );
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/libcfa/concurrency/monitor.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -17,4 +17,6 @@
 #include "monitor"
 
+#include <stdlib>
+
 #include "kernel_private.h"
 #include "libhdr.h"
@@ -130,4 +132,9 @@
 	this_thread()->current_monitors      = this->prev_mntrs;
 	this_thread()->current_monitor_count = this->prev_count;
+}
+
+void debug_break() __attribute__(( noinline ))
+{
+	
 }
 
@@ -171,11 +178,18 @@
 
 	//Find the next thread(s) to run
-	unsigned short thread_count = count;
+	unsigned short thread_count = 0;
 	thread_desc * threads[ count ];
+	for(int i = 0; i < count; i++) {
+		threads[i] = 0;
+	}
+
+	debug_break();
 
 	for( int i = 0; i < count; i++) {
 		thread_desc * new_owner = next_thread( this->monitors[i] );
-		thread_count = insert_unique( threads, i, new_owner );
-	}
+		thread_count = insert_unique( threads, thread_count, new_owner );
+	}
+
+	debug_break();
 
 	LIB_DEBUG_PRINT_SAFE("Will unblock: ");
@@ -339,11 +353,17 @@
 		LIB_DEBUG_PRINT_SAFE("Branding\n");
 		assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
-		this->monitors = thrd->current_monitors;
 		this->monitor_count = thrd->current_monitor_count;
+
+		this->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) );
+		for( int i = 0; i < this->monitor_count; i++ ) {
+			this->monitors[i] = thrd->current_monitors[i];
+		}
 	}
 }
 
 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ) {
-	for(int i = 0; i < end; i++) {
+	if( !val ) return end;
+
+	for(int i = 0; i <= end; i++) {
 		if( thrds[i] == val ) return end;
 	}
Index: src/libcfa/concurrency/thread.c
===================================================================
--- src/libcfa/concurrency/thread.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/libcfa/concurrency/thread.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -40,6 +40,6 @@
 	this->next = NULL;
 
-	this->current_monitors      = NULL;
-	this->current_monitor_count = 0;
+	this->current_monitors      = &this->mon;
+	this->current_monitor_count = 1;
 }
 
Index: src/libcfa/rational
===================================================================
--- src/libcfa/rational	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/libcfa/rational	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -12,7 +12,8 @@
 // Created On       : Wed Apr  6 17:56:25 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May  4 14:11:45 2016
-// Update Count     : 16
+// Last Modified On : Mon May  1 08:25:06 2017
+// Update Count     : 33
 //
+
 #ifndef RATIONAL_H
 #define RATIONAL_H
@@ -21,6 +22,7 @@
 
 // implementation
+typedef long int RationalImpl;
 struct Rational {
-	long int numerator, denominator;					// invariant: denominator > 0
+	RationalImpl numerator, denominator;					// invariant: denominator > 0
 }; // Rational
 
@@ -31,12 +33,14 @@
 // constructors
 void ?{}( Rational * r );
-void ?{}( Rational * r, long int n );
-void ?{}( Rational * r, long int n, long int d );
+void ?{}( Rational * r, RationalImpl n );
+void ?{}( Rational * r, RationalImpl n, RationalImpl d );
 
-// getter/setter for numerator/denominator
-long int numerator( Rational r );
-long int numerator( Rational r, long int n );
-long int denominator( Rational r );
-long int denominator( Rational r, long int d );
+// getter for numerator/denominator
+RationalImpl numerator( Rational r );
+RationalImpl denominator( Rational r );
+[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src );
+// setter for numerator/denominator
+RationalImpl numerator( Rational r, RationalImpl n );
+RationalImpl denominator( Rational r, RationalImpl d );
 
 // comparison
@@ -57,5 +61,5 @@
 // conversion
 double widen( Rational r );
-Rational narrow( double f, long int md );
+Rational narrow( double f, RationalImpl md );
 
 // I/O
Index: src/libcfa/rational.c
===================================================================
--- src/libcfa/rational.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/libcfa/rational.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 17:54:28 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul  9 11:18:04 2016
-// Update Count     : 40
+// Last Modified On : Thu Apr 27 17:05:06 2017
+// Update Count     : 51
 // 
 
@@ -30,7 +30,7 @@
 // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals.
 // alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
-static long int gcd( long int a, long int b ) {
+static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
 	for ( ;; ) {										// Euclid's algorithm
-		long int r = a % b;
+		RationalImpl r = a % b;
 	  if ( r == 0 ) break;
 		a = b;
@@ -40,5 +40,5 @@
 } // gcd
 
-static long int simplify( long int *n, long int *d ) {
+static RationalImpl simplify( RationalImpl *n, RationalImpl *d ) {
 	if ( *d == 0 ) {
 		serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl;
@@ -56,10 +56,10 @@
 } // rational
 
-void ?{}( Rational * r, long int n ) {
+void ?{}( Rational * r, RationalImpl n ) {
 	r{ n, 1 };
 } // rational
 
-void ?{}( Rational * r, long int n, long int d ) {
-	long int t = simplify( &n, &d );					// simplify
+void ?{}( Rational * r, RationalImpl n, RationalImpl d ) {
+	RationalImpl t = simplify( &n, &d );				// simplify
 	r->numerator = n / t;
 	r->denominator = d / t;
@@ -67,13 +67,23 @@
 
 
-// getter/setter for numerator/denominator
-
-long int numerator( Rational r ) {
+// getter for numerator/denominator
+
+RationalImpl numerator( Rational r ) {
 	return r.numerator;
 } // numerator
 
-long int numerator( Rational r, long int n ) {
-	long int prev = r.numerator;
-	long int t = gcd( abs( n ), r.denominator );		// simplify
+RationalImpl denominator( Rational r ) {
+	return r.denominator;
+} // denominator
+
+[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src ) {
+	return *dest = src.[ numerator, denominator ];
+}
+
+// setter for numerator/denominator
+
+RationalImpl numerator( Rational r, RationalImpl n ) {
+	RationalImpl prev = r.numerator;
+	RationalImpl t = gcd( abs( n ), r.denominator );		// simplify
 	r.numerator = n / t;
 	r.denominator = r.denominator / t;
@@ -81,11 +91,7 @@
 } // numerator
 
-long int denominator( Rational r ) {
-	return r.denominator;
-} // denominator
-
-long int denominator( Rational r, long int d ) {
-	long int prev = r.denominator;
-	long int t = simplify( &r.numerator, &d );			// simplify
+RationalImpl denominator( Rational r, RationalImpl d ) {
+	RationalImpl prev = r.denominator;
+	RationalImpl t = simplify( &r.numerator, &d );			// simplify
 	r.numerator = r.numerator / t;
 	r.denominator = d / t;
@@ -170,5 +176,5 @@
 
 // http://www.ics.uci.edu/~eppstein/numth/frap.c
-Rational narrow( double f, long int md ) {
+Rational narrow( double f, RationalImpl md ) {
 	if ( md <= 1 ) {									// maximum fractional digits too small?
 		return (Rational){ f, 1};						// truncate fraction
@@ -176,10 +182,10 @@
 
 	// continued fraction coefficients
-	long int m00 = 1, m11 = 1, m01 = 0, m10 = 0;
-	long int ai, t;
+	RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0;
+	RationalImpl ai, t;
 
 	// find terms until denom gets too big
 	for ( ;; ) {
-		ai = (long int)f;
+		ai = (RationalImpl)f;
 	  if ( ! (m10 * ai + m11 <= md) ) break;
 		t = m00 * ai + m01;
@@ -202,5 +208,5 @@
 forall( dtype istype | istream( istype ) )
 istype * ?|?( istype *is, Rational *r ) {
-	long int t;
+	RationalImpl t;
 	is | &(r->numerator) | &(r->denominator);
 	t = simplify( &(r->numerator), &(r->denominator) );
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/main.cc	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -37,4 +37,5 @@
 #include "CodeGen/FixMain.h"
 #include "CodeTools/DeclStats.h"
+#include "CodeTools/TrackLoc.h"
 #include "ControlStruct/Mutate.h"
 #include "SymTab/Validate.h"
@@ -308,4 +309,5 @@
 		} // if
 
+		CodeTools::fillLocations( translationUnit );
 		CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true );
 
Index: src/tests/.expect/concurrent/sched-int-barge.txt
===================================================================
--- src/tests/.expect/concurrent/sched-int-barge.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/tests/.expect/concurrent/sched-int-barge.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,100 @@
+1000
+2000
+3000
+4000
+5000
+6000
+7000
+8000
+9000
+10000
+11000
+12000
+13000
+14000
+15000
+16000
+17000
+18000
+19000
+20000
+21000
+22000
+23000
+24000
+25000
+26000
+27000
+28000
+29000
+30000
+31000
+32000
+33000
+34000
+35000
+36000
+37000
+38000
+39000
+40000
+41000
+42000
+43000
+44000
+45000
+46000
+47000
+48000
+49000
+50000
+51000
+52000
+53000
+54000
+55000
+56000
+57000
+58000
+59000
+60000
+61000
+62000
+63000
+64000
+65000
+66000
+67000
+68000
+69000
+70000
+71000
+72000
+73000
+74000
+75000
+76000
+77000
+78000
+79000
+80000
+81000
+82000
+83000
+84000
+85000
+86000
+87000
+88000
+89000
+90000
+91000
+92000
+93000
+94000
+95000
+96000
+97000
+98000
+99000
+100000
Index: src/tests/.expect/concurrent/sched-int-disjoint.txt
===================================================================
--- src/tests/.expect/concurrent/sched-int-disjoint.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/tests/.expect/concurrent/sched-int-disjoint.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,101 @@
+1000
+2000
+3000
+4000
+5000
+6000
+7000
+8000
+9000
+10000
+11000
+12000
+13000
+14000
+15000
+16000
+17000
+18000
+19000
+20000
+21000
+22000
+23000
+24000
+25000
+26000
+27000
+28000
+29000
+30000
+31000
+32000
+33000
+34000
+35000
+36000
+37000
+38000
+39000
+40000
+41000
+42000
+43000
+44000
+45000
+46000
+47000
+48000
+49000
+50000
+51000
+52000
+53000
+54000
+55000
+56000
+57000
+58000
+59000
+60000
+61000
+62000
+63000
+64000
+65000
+66000
+67000
+68000
+69000
+70000
+71000
+72000
+73000
+74000
+75000
+76000
+77000
+78000
+79000
+80000
+81000
+82000
+83000
+84000
+85000
+86000
+87000
+88000
+89000
+90000
+91000
+92000
+93000
+94000
+95000
+96000
+97000
+98000
+99000
+100000
+All waiter done
Index: c/tests/.expect/concurrent/sched-int-multi.txt
===================================================================
--- src/tests/.expect/concurrent/sched-int-multi.txt	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ 	(revision )
@@ -1,7 +1,0 @@
-Waiting All
-Entering A
-Entering A & B
-Signal
-Leaving  A & B
-Leaving  A
-Done waiting
Index: c/tests/.expect/concurrent/sched-int.txt
===================================================================
--- src/tests/.expect/concurrent/sched-int.txt	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Step 1
-Step 2
-Step 3
Index: src/tests/.expect/rational.txt
===================================================================
--- src/tests/.expect/rational.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/tests/.expect/rational.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,36 @@
+constructor
+3/1 4/1 0/1
+1/2 5/7
+2/3 -3/2
+-2/3 3/2
+logical
+-2/1 -3/2
+1
+1
+1
+0
+0
+arithmetic
+-2/1 -3/2
+-7/2
+-1/2
+3/1
+4/3
+conversion
+0.75
+0.142857142857143
+3.14159292035398
+3/4
+1/7
+355/113
+decompose
+more tests
+-3/2
+0
+1/2 1 1/2
+2/1 1 2/1
+0/1
+1/2 1 1/2
+2/2147483647
+5/2147483647
+2/3 4/5
Index: src/tests/.in/rational.txt
===================================================================
--- src/tests/.in/rational.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/tests/.in/rational.txt	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,1 @@
+2 3 4 5
Index: src/tests/Makefile.am
===================================================================
--- src/tests/Makefile.am	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/tests/Makefile.am	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -22,5 +22,5 @@
 concurrent=yes
 quick_test+= coroutine thread monitor
-concurrent_test=coroutine thread monitor multi-monitor sched-int sched-ext preempt
+concurrent_test=coroutine thread monitor multi-monitor sched-int-disjoint sched-int-barge sched-int-wait sched-ext sched-ext-multi preempt
 else
 concurrent=no
Index: src/tests/Makefile.in
===================================================================
--- src/tests/Makefile.in	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/tests/Makefile.in	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -230,10 +230,10 @@
 @BUILD_CONCURRENCY_TRUE@concurrent = yes
 @BUILD_CONCURRENCY_FALSE@concurrent_test = 
-@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int sched-ext preempt
-TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
+@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-disjoint sched-int-barge sched-int-wait sched-ext sched-ext-multi preempt
 
 # applies to both programs
 EXTRA_FLAGS = 
 BUILD_FLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
+TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
 fstream_test_SOURCES = fstream_test.c
 vector_test_SOURCES = vector/vector_int.c vector/array.c vector/vector_test.c
Index: src/tests/rational.c
===================================================================
--- src/tests/rational.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ src/tests/rational.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -10,6 +10,6 @@
 // Created On       : Mon Mar 28 08:43:12 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul  5 18:29:37 2016
-// Update Count     : 25
+// Last Modified On : Tue May  2 22:11:05 2017
+// Update Count     : 41
 // 
 
@@ -36,5 +36,5 @@
 	b = (Rational){ -3, 2 };
 	sout | a | b | endl;
-	sout | a == 1 | endl;
+//	sout | a == 1 | endl; // FIX ME
 	sout | a != b | endl;
 	sout | a <  b | endl;
@@ -61,4 +61,10 @@
 	sout | narrow( 3.14159265358979, 256 ) | endl;
 
+	sout | "decompose" | endl;
+	RationalImpl n, d;
+//	[n, d] = a;
+//	sout | a | n | d | endl;
+
+	sout | "more tests" | endl;
 	Rational x = { 1, 2 }, y = { 2 };
 	sout | x - y | endl;
Index: src/tests/sched-int-barge.c
===================================================================
--- src/tests/sched-int-barge.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/tests/sched-int-barge.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,97 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+enum state_t { WAIT, SIGNAL, BARGE };
+
+monitor global_t {};
+
+monitor global_data_t {
+	bool done;
+	int counter;
+	state_t state;
+
+	unsigned short do_signal;
+	unsigned short do_wait2;
+	unsigned short do_wait1;
+};
+
+void ?{} ( global_data_t * this ) {
+	this->done = false;
+	this->counter = 0;
+	this->state = BARGE;
+
+	this->do_signal = 6;
+	this->do_wait1  = 1;
+	this->do_wait2  = 3;
+}
+
+void ^?{} ( global_data_t * this ) {}
+
+global_t globalA;
+global_t globalB;
+global_data_t globalC;
+
+condition cond;
+
+thread Threads {};
+
+bool logicC( global_t * mutex a, global_t * mutex b, global_data_t * mutex c ) {
+	c->counter++;
+
+	if( (c->counter % 1000) == 0 ) sout | c->counter | endl;
+
+	int action = c->counter % 10;
+
+	if( action == 0 ) {
+		c->do_signal = max( ((unsigned)rand48()) % 10, 1);
+		c->do_wait1 = ((unsigned)rand48()) % (c->do_signal);
+		c->do_wait2 = ((unsigned)rand48()) % (c->do_signal);
+
+		// if(c->do_wait1 == c->do_wait2) sout | "Same" | endl;
+	}
+
+	if( action == c->do_wait1 || action == c->do_wait2 ) {
+		c->state = WAIT;
+		wait( &cond );
+
+		if(c->state != SIGNAL) {
+			sout | "ERROR Barging detected" | c->counter | endl;
+			abort();
+		}
+	}
+	else if( action == c->do_signal ) {
+		c->state = SIGNAL;
+
+		signal( &cond );
+		signal( &cond );
+	}
+	else {
+		c->state = BARGE;
+	}
+
+	if( c->counter >= 100_000 ) c->done = true;
+	return !c->done;
+}
+
+bool logicB( global_t * mutex a, global_t * mutex b ) {
+	return logicC(a, b, &globalC);
+}
+
+bool logicA( global_t * mutex a ) {
+	return logicB(a, &globalB);
+}
+
+void main( Threads* this ) {
+	while( logicA(&globalA) ) { yield(); };
+}
+
+int main(int argc, char* argv[]) {
+	rand48seed(0);
+	processor p;
+	{
+		Threads t[17];
+	}
+}
Index: src/tests/sched-int-disjoint.c
===================================================================
--- src/tests/sched-int-disjoint.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/tests/sched-int-disjoint.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,115 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <thread>
+
+#define N 100_000
+
+enum state_t { WAIT, SIGNAL, BARGE };
+
+monitor global_t {};
+global_t mut;
+
+monitor global_data_t;
+void ?{}( global_data_t * this );
+void ^?{} ( global_data_t * this );
+
+monitor global_data_t {
+	int counter;
+	state_t state;
+} data;
+
+condition cond;
+
+volatile bool all_done;
+
+void ?{}( global_data_t * this ) {
+	this->counter == 0;
+	this->state = BARGE;
+}
+
+void ^?{} ( global_data_t * this ) {}
+
+//------------------------------------------------------------------------------
+// Barging logic
+void barge( global_data_t * mutex d ) {
+	d->state = BARGE;
+}
+
+thread Barger {};
+
+void main( Barger * this ) {
+	while( !all_done ) { 
+		barge( &data );
+		yield(); 
+	}
+}
+
+//------------------------------------------------------------------------------
+// Waiting logic
+bool wait( global_t * mutex m, global_data_t * mutex d ) {
+	wait( &cond );
+	if( d->state != SIGNAL ) {
+		sout | "ERROR barging!" | endl; 
+	}
+
+	d->counter++;
+
+	if( (d->counter % 1000) == 0 ) sout | d->counter | endl;
+
+	return d->counter < N;
+}
+
+thread Waiter {};
+
+void main( Waiter * this ) {
+	while( wait( &mut, &data ) ) { yield(); }
+}
+
+
+//------------------------------------------------------------------------------
+// Signalling logic
+void signal( condition * cond, global_t * mutex a, global_data_t * mutex b ) {
+	b->state = SIGNAL;
+	signal( cond );
+}
+
+void logic( global_t * mutex a ) {
+	signal( &cond, a, &data );
+
+	int pauses = (unsigned)rand48() % 10;
+	for(int i = 0; i < pauses; i++) {
+		yield();
+	}
+
+	//This is technically a mutual exclusion violation but the mutex monitor protects us
+	bool running = data.counter < N && data.counter > 0;
+	if( data.state != SIGNAL && running ) {
+		sout | "ERROR Eager signal" | data.state | endl; 
+	}
+}
+
+thread Signaller {};
+
+void main( Signaller * this ) {
+	while( !all_done ) { 
+		logic( &mut );
+		yield(); 
+	}
+}
+
+//------------------------------------------------------------------------------
+// Main loop
+int main(int argc, char* argv[]) {
+	all_done = false;
+	processor p;
+	{
+		Signaller s;
+		Barger b[17];
+		{
+			Waiter w[4];
+		}
+		sout | "All waiter done" | endl;
+		all_done = true;
+	}	
+}
Index: c/tests/sched-int-multi.c
===================================================================
--- src/tests/sched-int-multi.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ 	(revision )
@@ -1,53 +1,0 @@
-#include <fstream>
-#include <kernel>
-#include <monitor>
-#include <thread>
-
-monitor global_t {};
-
-global_t globalB;
-global_t globalA;
-
-condition cond;
-
-thread Signalee {};
-thread Signaler {};
-
-void signalee_action( global_t * mutex a, global_t * mutex b ) {
-	sout | "Waiting All" | endl;
-	wait( &cond );
-	sout | "Done waiting" | endl;
-}
-
-void main( Signalee* this ) {
-	signalee_action( &globalA, &globalB );
-}
-
-void signaler_action_inner( global_t * mutex a, global_t * mutex b ) {
-	sout | "Entering A & B" | endl;
-	sout | "Signal" | endl;
-	signal( &cond );
-	sout | "Leaving  A & B" | endl;
-}
-
-void signaler_action( global_t * mutex a, global_t * b ) {
-	sout | "Entering A" | endl;
-	signaler_action_inner( a, b );
-	sout | "Leaving  A" | endl;
-}
-
-void main( Signaler* this ) {
-	for(int i = 0; i < 10_000; i++) {
-		asm volatile ("" : : : "memory");
-	}
-
-	signaler_action( &globalA, &globalB );
-}
-
-int main(int argc, char* argv[]) {
-	processor p;
-	{
-		Signalee a;
-		Signaler b;
-	}
-}
Index: src/tests/sched-int-wait.c
===================================================================
--- src/tests/sched-int-wait.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ src/tests/sched-int-wait.c	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,124 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+static const int N = 10_000;
+
+monitor global_t {};
+
+global_t globalA;
+global_t globalB;
+global_t globalC;
+
+condition condAB, condAC, condBC, condABC;
+
+thread Signaler {};
+thread WaiterAB {};
+thread WaiterAC {};
+thread WaiterBC {};
+thread WaiterABC{};
+
+volatile int waiter_left;
+
+//----------------------------------------------------------------------------------------------------
+// Tools
+void signal( condition * cond, global_t * mutex a, global_t * mutex b ) {
+	signal( cond );
+}
+
+void signal( condition * cond, global_t * mutex a, global_t * mutex b, global_t * mutex c ) {
+	signal( cond );
+}
+
+void wait( condition * cond, global_t * mutex a, global_t * mutex b ) {
+	wait( cond );
+}
+
+void wait( condition * cond, global_t * mutex a, global_t * mutex b, global_t * mutex c ) {
+	wait( cond );
+}
+
+//----------------------------------------------------------------------------------------------------
+// Signaler
+void main( Signaler* this ) {
+
+	while( waiter_left != 0 ) {
+		unsigned action = (unsigned)rand48() % 4;
+		switch( action ) {
+			case 0: 
+				signal( &condABC, &globalA, &globalB, &globalC );
+				break;
+			case 1: 
+				signal( &condAB , &globalA, &globalB );
+				break;
+			case 2: 
+				signal( &condBC , &globalB, &globalC );
+				break;
+			case 3: 
+				signal( &condAC , &globalA, &globalC );
+				break;
+			default:
+				sout | "Something went wrong" | endl;
+				abort();
+		}
+		yield();
+	}	
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter ABC
+void main( WaiterABC* this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( &condABC, &globalA, &globalB, &globalC );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter AB
+void main( WaiterAB* this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( &condAB , &globalA, &globalB );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter AC
+void main( WaiterAC* this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( &condAC , &globalA, &globalC );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter BC
+void main( WaiterBC* this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( &condBC , &globalB, &globalC );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Main
+int main(int argc, char* argv[]) {
+	waiter_left = 4;
+	processor p;
+	{
+		Signaler  e;
+		{
+			WaiterABC a;
+			WaiterAB  b;
+			WaiterBC  c;
+			WaiterAC  d;
+		}
+	}
+}
Index: c/tests/sched-int.c
===================================================================
--- src/tests/sched-int.c	(revision 0f9bef3575f6b5dcfb3d73967a6f4243f09f9a01)
+++ 	(revision )
@@ -1,60 +1,0 @@
-#include <fstream>
-#include <kernel>
-#include <monitor>
-#include <thread>
-
-monitor global_t {
-	int value;
-};
-
-global_t global;
-
-condition cond;
-
-thread Signalee {};
-thread Signaler {};
-
-void step1( global_t * mutex this ) {
-	sout | "Step 1" | endl;
-	this->value = 1;
-	wait( &cond );
-}
-
-void step2( global_t * mutex this ) {
-	if( this->value != 1) abort();
-
-	sout | "Step 2" | endl;
-	this->value = 2;
-	signal( &cond );
-}
-
-void step3( global_t * mutex this ) {
-	if( this->value != 2) abort();
-
-	sout | "Step 3" | endl;
-	this->value = 3;
-	signal( &cond );
-}
-
-void main( Signalee* this ) {
-	step1( &global );
-	step3( &global );
-}
-
-void main( Signaler* this ) {
-	for(int i = 0; i < 10_000; i++) {
-		asm volatile ("" : : : "memory");
-	}
-
-	step2( &global );
-}
-
-int main(int argc, char* argv[]) {
-	assert( global.__mon.entry_queue.tail != NULL );
-	processor p;
-	{
-		Signalee a;
-		Signaler b;
-	}
-	if( global.value != 3) abort();
-}
Index: tools/vscode/uwaterloo.cforall-0.1.0/cforall.configuration.json
===================================================================
--- tools/vscode/uwaterloo.cforall-0.1.0/cforall.configuration.json	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ tools/vscode/uwaterloo.cforall-0.1.0/cforall.configuration.json	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,29 @@
+{
+	"comments": {
+		"lineComment": "//",
+		"blockComment": [ "/*", "*/" ]
+	},
+	// symbols used as brackets
+	"brackets": [
+		["{", "}"],
+		["[", "]"],
+		["(", ")"]
+	],
+	// symbols that are auto closed when typing
+	"autoClosingPairs": [
+		["{", "}"],
+		["[", "]"],
+		["(", ")"],
+		["\"", "\""],
+		["'", "'"]
+	],
+	// symbols that that can be used to surround a selection
+	"surroundingPairs": [
+		["{", "}"],
+		["[", "]"],
+		["(", ")"],
+		["\"", "\""],
+		["'", "'"],
+		["$", "$"]
+	]
+}
Index: tools/vscode/uwaterloo.cforall-0.1.0/images/icon.svg
===================================================================
--- tools/vscode/uwaterloo.cforall-0.1.0/images/icon.svg	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ tools/vscode/uwaterloo.cforall-0.1.0/images/icon.svg	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="25mm" height="25mm" viewBox="0 0 2500 2500" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs class="ClipPathGroup">
+  <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
+   <rect x="0" y="0" width="2500" height="2500"/>
+  </clipPath>
+ </defs>
+ <defs class="TextShapeIndex">
+  <g ooo:slide="id1" ooo:id-list="id3 id4 id5 id6"/>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+  <g id="bullet-char-template(57356)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+  </g>
+  <g id="bullet-char-template(57354)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+  </g>
+  <g id="bullet-char-template(10146)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+  </g>
+  <g id="bullet-char-template(10132)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+  </g>
+  <g id="bullet-char-template(10007)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+  </g>
+  <g id="bullet-char-template(10004)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+  </g>
+  <g id="bullet-char-template(9679)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+  </g>
+  <g id="bullet-char-template(8226)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+  </g>
+  <g id="bullet-char-template(8211)" transform="scale(0.00048828125,-0.00048828125)">
+   <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+  </g>
+ </defs>
+ <defs class="TextEmbeddedBitmaps"/>
+ <g>
+  <g id="id2" class="Master_Slide">
+   <g id="bg-id2" class="Background"/>
+   <g id="bo-id2" class="BackgroundObjects"/>
+  </g>
+ </g>
+ <g class="SlideGroup">
+  <g>
+   <g id="id1" class="Slide" clip-path="url(#presentation_clip_path)">
+    <g class="Page">
+     <g class="com.sun.star.drawing.ClosedBezierShape">
+      <g id="id3">
+       <rect class="BoundingBox" stroke="none" fill="none" x="256" y="501" width="919" height="1289"/>
+       <path fill="rgb(152,76,147)" stroke="none" d="M 1173,1722 L 1173,1722 C 1072,1768 978,1788 867,1788 856,1788 848,1788 837,1787 L 837,1787 C 827,1788 818,1788 808,1788 707,1788 621,1765 534,1715 487,1688 450,1659 412,1619 L 412,1619 C 384,1587 363,1558 341,1521 283,1419 256,1320 256,1203 256,1192 256,1182 257,1171 L 257,1171 C 256,1161 256,1152 256,1142 256,1017 285,910 347,802 372,759 397,724 431,687 L 431,687 C 473,643 514,611 566,580 661,526 753,501 862,501 869,501 875,502 883,502 L 883,502 C 890,502 897,502 904,502 1001,502 1082,516 1173,548 L 1173,817 1173,817 C 1168,814 1163,812 1158,808 1080,763 1003,743 912,743 909,743 907,743 904,743 899,743 895,743 891,743 827,743 773,757 718,789 686,807 662,826 637,853 619,874 606,893 592,917 553,984 535,1050 535,1128 535,1136 535,1143 535,1151 L 535,1151 C 535,1159 535,1165 535,1173 535,1249 552,1314 591,1381 603,1402 615,1419 631,1439 L 631,1439 C 655,1465 679,1484 710,1502 763,1532 814,1546 875,1546 880,1546 884,1546 889,1546 L 889,1546 C 891,1546 892,1546 894,1546 991,1546 1073,1524 1157,1475 1163,1472 1168,1469 1173,1466 L 1173,1722 Z"/>
+      </g>
+     </g>
+     <g class="com.sun.star.drawing.CustomShape">
+      <g id="id4">
+       <rect class="BoundingBox" stroke="none" fill="none" x="1281" y="520" width="540" height="1282"/>
+       <path fill="rgb(152,76,147)" stroke="none" d="M 1576,1800 L 1819,1800 1524,521 1282,521 1576,1800 Z M 1282,1800 L 1282,1800 Z M 1819,521 L 1819,521 Z"/>
+       <path fill="none" stroke="rgb(152,76,147)" d="M 1576,1800 L 1819,1800 1524,521 1282,521 1576,1800 Z"/>
+       <path fill="none" stroke="rgb(152,76,147)" d="M 1282,1800 L 1282,1800 Z"/>
+       <path fill="none" stroke="rgb(152,76,147)" d="M 1819,521 L 1819,521 Z"/>
+      </g>
+     </g>
+     <g class="com.sun.star.drawing.CustomShape">
+      <g id="id5">
+       <rect class="BoundingBox" stroke="none" fill="none" x="1489" y="838" width="527" height="167"/>
+       <path fill="rgb(152,76,147)" stroke="none" d="M 1752,1003 L 1490,1003 1490,839 2014,839 2014,1003 1752,1003 Z"/>
+       <path fill="none" stroke="rgb(152,76,147)" d="M 1752,1003 L 1490,1003 1490,839 2014,839 2014,1003 1752,1003 Z"/>
+      </g>
+     </g>
+     <g class="com.sun.star.drawing.CustomShape">
+      <g id="id6">
+       <rect class="BoundingBox" stroke="none" fill="none" x="1663" y="521" width="540" height="1282"/>
+       <path fill="rgb(152,76,147)" stroke="none" d="M 1958,522 L 2201,522 1906,1801 1664,1801 1958,522 Z M 1664,522 L 1664,522 Z M 2201,1801 L 2201,1801 Z"/>
+       <path fill="none" stroke="rgb(152,76,147)" d="M 1958,522 L 2201,522 1906,1801 1664,1801 1958,522 Z"/>
+       <path fill="none" stroke="rgb(152,76,147)" d="M 1664,522 L 1664,522 Z"/>
+       <path fill="none" stroke="rgb(152,76,147)" d="M 2201,1801 L 2201,1801 Z"/>
+      </g>
+     </g>
+    </g>
+   </g>
+  </g>
+ </g>
+</svg>
Index: tools/vscode/uwaterloo.cforall-0.1.0/package.json
===================================================================
--- tools/vscode/uwaterloo.cforall-0.1.0/package.json	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ tools/vscode/uwaterloo.cforall-0.1.0/package.json	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,41 @@
+{
+	"name": "cforall",
+	"version": "0.1.0",
+	"displayName": "Cforall Language Support",
+	"description": "Cforall - colorizer, grammar and snippets.",
+	"publisher": "uwaterloo",
+	"license": "MIT",
+	"engines": {
+		"vscode": "^1.5.0"
+	},
+	"icon": "images/icon.svg",
+	"categories": [
+		"Languages",
+		"Linters",
+		"Other"
+	],
+	"contributes": {
+		"languages": [
+			{
+				"id": "cforall",
+				"aliases": [
+					"C∀",
+					"Cforall",
+					"CForAll",
+					"cforall"
+				],
+				"extensions": [
+					".cf"
+				],
+				"configuration": "./cforall.configuration.json"
+			}
+		],
+		"grammars": [
+			{
+				"language": "cforall",
+				"scopeName": "source.cf",
+				"path": "./syntaxes/cfa.tmLanguage"
+			}
+		]
+	}
+}
Index: tools/vscode/uwaterloo.cforall-0.1.0/snippets/snippets.json
===================================================================
--- tools/vscode/uwaterloo.cforall-0.1.0/snippets/snippets.json	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ tools/vscode/uwaterloo.cforall-0.1.0/snippets/snippets.json	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,3 @@
+{
+	
+}
Index: tools/vscode/uwaterloo.cforall-0.1.0/syntaxes/cfa.tmLanguage
===================================================================
--- tools/vscode/uwaterloo.cforall-0.1.0/syntaxes/cfa.tmLanguage	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
+++ tools/vscode/uwaterloo.cforall-0.1.0/syntaxes/cfa.tmLanguage	(revision 6250a3124c81969f1b53ea4010c9c212d48ea9b0)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>fileTypes</key>
+	<array>
+		<string>c</string>
+		<string>cf</string>
+		<string>cfa</string>
+		<string>h</string>
+	</array>
+	<key>foldingStartMarker</key>
+	<string>/\*\*|\{\s*$</string>
+	<key>foldingStopMarker</key>
+	<string>\*\*/|^\s*\}</string>
+	<key>keyEquivalent</key>
+	<string>^~G</string>
+	<key>name</key>
+	<string>Cforall</string>
+	<key>patterns</key>
+	<array>
+		<dict>
+			<key>match</key>
+			<string>\b(forall)\b</string>
+			<key>name</key>
+			<string>keyword.control.cfa</string>
+		</dict>
+		<dict>
+			<key>match</key>
+			<string>\b(trait|dtype|otype|ftype|sized|volatile|extern|static|inline|coroutine|thread|thread_local|mutex|monitor)\b</string>
+			<key>name</key>
+			<string>storage.type.cfa</string>
+		</dict>
+		<dict>
+			<key>match</key>
+			<string>\b(this)\b</string>
+			<key>name</key>
+			<string>variable.language.cfa</string>
+		</dict>
+		<dict>
+			<key>include</key>
+			<string>source.c</string>
+		</dict>
+	</array>
+	<key>scopeName</key>
+	<string>source.cf</string>
+	<key>uuid</key>
+	<string>25066DC2-6B1D-11D9-9D5B-000D93589AF6</string>
+</dict>
+</plist>
