Index: .gitignore
===================================================================
--- .gitignore	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ .gitignore	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -54,2 +54,3 @@
 doc/user/pointer1.tex
 doc/user/pointer2.tex
+doc/user/EHMHierarchy.tex
Index: doc/LaTeXmacros/lstlang.sty
===================================================================
--- doc/LaTeXmacros/lstlang.sty	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ doc/LaTeXmacros/lstlang.sty	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -8,6 +8,6 @@
 %% Created On       : Sat May 13 16:34:42 2017
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Fri May 26 12:47:09 2017
-%% Update Count     : 8
+%% Last Modified On : Thu Jun 22 07:40:31 2017
+%% Update Count     : 10
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -116,4 +116,5 @@
 		_Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, 
 		resume, suspend, thread, _Thread_local, yield},
+	moredirectives={defined,include_next}%
 }
 
Index: doc/generic_types/mail
===================================================================
--- doc/generic_types/mail	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ doc/generic_types/mail	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -78,2 +78,273 @@
 
 - OOPSLA'17 Submissions
+
+
+
+From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
+Subject: [OOPSLA'17] Paper #20 "Generic and Tuple Types with Efficient..."
+To: Peter Buhr <pabuhr@uwaterloo.ca>
+Cc: jonathan.aldrich@cs.cmu.edu
+Reply-To: jonathan.aldrich@cs.cmu.edu
+Date: Wed,  7 Jun 2017 13:33:40 +0000 (UTC)
+
+Dear Peter Buhr,
+
+The author response period for OOPSLA has started, and will continue until
+the end of June 10th (Anywhere on Earth).  No email with a snapshot of your
+reviews will be sent: you can see the live version of reviews (including
+current updates) on the HotCRP system (links at the bottom).
+
+An author response should aim to:
+ -correct reviewers' mistakes or misunderstandings
+ -offer new information only when this addresses reviewers' concerns (e.g.,
+"I wonder if A might work better...";  "we tried that, but...")
+ -answer explicit questions by the reviewers. The key questions will be in a
+designated "Questions for Author Response" entry of a review.
+
+Please keep in mind that an author response is *not* a "rebuttal". You are
+not rebutting an opponent's arguments with your own, in front of an
+audience that weighs both sets of arguments. Instead, your audience is the
+same reviewers who offered the comments in the first place, and their
+subjective weighing of different factors is very unlikely to change.
+
+During author response, please keep in mind that the reviewers are still
+unaware of author identity. If you need to refer to author-identifying
+information during your response, the ideal course of action is to place it
+at an external location and include a URL, with an explicit warning (e.g.,
+"WARNING: following this link will reveal author identity").
+
+As with all external resources, your response should be self-contained,
+without consulting them. That is, the author-visible external URL is just
+evidence, but the claim that this evidence supports should be clear in the
+response text. For instance:
+"we have received public feedback from the developers of X that confirm the
+issue [supporting URL] (WARNING: following this link will reveal author
+identity)"
+
+Your paper's access information is below:
+
+       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+  Paper site: https://oopsla17.hotcrp.com/paper/20
+
+Use the link below to sign in to the site.
+
+https://oopsla17.hotcrp.com/?email=pabuhr%40uwaterloo.ca
+
+Please contact me <jonathan.aldrich@cs.cmu.edu> with any questions or
+concerns.
+
+Best Regards and wishes for a constructive response,
+
+Jonathan Aldrich
+
+
+
+From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
+Subject: [OOPSLA'17] Paper #20 "Generic and Tuple Types with Efficient..."
+To: Peter Buhr <pabuhr@uwaterloo.ca>
+Cc: jonathan.aldrich@cs.cmu.edu
+Reply-To: jonathan.aldrich@cs.cmu.edu
+Date: Tue, 20 Jun 2017 00:33:10 +0000 (UTC)
+
+Dear Peter Buhr,
+
+I regret to inform you that your submission to OOPSLA'17 listed below has not
+been selected for the second phase of the review process. I understand this is
+not welcome news but selection was very competitive: 157 of the 223 papers
+submitted did not advance to the second phase. For several of these, there was
+a clear impression that in the future they can evolve into some of the
+strongest results of our community.
+
+       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+  Paper site: https://oopsla17.hotcrp.com/paper/20
+  Login link: https://oopsla17.hotcrp.com/?email=pabuhr%40uwaterloo.ca
+
+Below you will find reviews, as well as author-visible comments--the latter may
+include further communication. I hope you will find the reviewers' feedback
+useful.
+
+Best Regards,
+
+- Jonathan Aldrich <jonathan.aldrich@cs.cmu.edu>, for OOPSLA 2017
+Submissions
+
+
+
+===========================================================================
+                           OOPSLA'17 Review #20A
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: C. Weak paper, though I will not fight
+                                        strongly against it
+                         Confidence: X. I am an expert in this area
+
+                         ===== Paper summary =====
+
+This presents an extension of the C programming language that tries to preserve the character of the existing language, while adding tuples and generics. Unlike C++ templates, generics preserve separate compilation. Types are represented at runtime, if needed, by size and alignment values, along with pointers to the code for any needed operators. A microbenchmark performance comparison is provided.
+
+                      ===== Comments for author =====
+
+This is an interesting extension to C, that may be of interest to some C programmers. It generally seems to be fairly well engineered, and mostly respects C's design goals.
+
+Unfortunately, there have been enough proposals for extended C dialects that this sort of design is tough to sell. And I don't think the evaluation really went far enough to make that case.
+
+The ideas in the paper don't appear to be fundamentally new. The idea of passing types as runtime objects has certainly been explored before. An additional ancient reference is http://dl.acm.org/citation.cfm?doid=13310.13330.
+
+There seems to be a new idea of minimally describing types using alignment and size attributes instead of (?) pointers to assignment operators and the like. But this scheme is not very well described. Notably, it is not clear how, say, a struct with atomic field or bit-fields would be described.
+
+I wasn't quite clear on the extent to which operator overloading is supported. The MAX example appears to me like it would be quite controversial among C programmers. 
+
+It is not obvious that type inference here always converges. An outline of the algorithm would be useful.
+
+Above all, this needs experience results from a more complete implementation.
+
+Details:
+
+Relying on TIOBE here seems a bit dubious. Since it counts web pages, and C isn't exactly new and hot, it may actually understate your case.
+
+The print example seems a little simplistic, since it's not clear how it handles formatting.
+
+"does not using the return type"
+
+              ===== Questions for authors’ response =====
+
+How are atomics, volatile, and bit-fields in structs handled?
+
+===========================================================================
+                           OOPSLA'17 Review #20B
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: D. Reject
+                         Confidence: X. I am an expert in this area
+
+                         ===== Paper summary =====
+
+The authors present an extension to C, adding universal polymorphism and tuples. These features are described in prose. There is an implementation, though this is not described in depth in the paper. There is a benchmark evaluation.
+
+                      ===== Comments for author =====
+
+The paper is well-written and the concepts explained well. It is nice to see work in the low-level/C space - I believe that it is an area that has not been well-served by the OOPSLA community. My concerns with the paper are that the contribution is rather small and the concepts are not well-evaluated; specifically this is a language design paper and there is no attempt to evaluate the actual language design.
+
+While it is reasonable to describe only a couple of features in a paper, I would then expect a detailed description of the implementation and/or a formalism with proven safety properties and a thorough evaluation of the design. For a paper which only describes the design of a language the bar is higher than two features - for example, a description of a 'large' language such as D or Rust, even then I would expect a stronger evaluation.
+
+## On the design of C-forall
+
+There are some interesting points in the design of generics, notably the otype/dtype distinction. The design seems reasonable and follows what I would expect from other languages. The design for tuples is more unusual - the usual design of simple anonymous records with anonymous fields is extended with a mix of 'spread'ing, variadics, and implicit conversions. Importantly, the authors neither justify nor evaluate this departure - that is a severe omission for this paper. Furthermore, the only in-depth description of the implementation in the paper concerns tuples, and it seems to me that this is only interesting because of the unusual design - further reason for justifying it.
+
+## Evaluation
+
+The paper evaluates the implementation of C-forall with (effectively) a single micro-benchmark. That benchmark seems to show that C-forall performs worse than C++ on every measure, but this is not really discussed.
+
+A better performance evaluation would consist of multiple tests, both micro-benchmarks and realistic code and would test C-forall compared to alternatives (D, Rust, Go, etc.) not just C/C++.
+
+However, performance is not the really interesting thing to test here. The authors propose a new language and while performance is an important consideration for systems languages, it is far from the most important. I would like to see the usability of the language tested with user studies of different kinds (various levels of skill-level and coding scenarios). The authors could also use case studies or programming idioms to compare programming in C-forall vs the alternatives (again, comparing with D, Rust, etc. is more interesting to me than C).
+
+Finally, in designing C-forall, the authors make several assumptions about why C programmers use C. These should be backed up either with evaluation or citation. Statements in the paper certainly do not reflect my experience discussing language design with C programmers, and I would like to see them verified.
+
+
+## Related work
+
+The related work section is broad and gives good descriptions of other languages. However, the comparisons between languages focus more on the high-level goals of the language. It would be more interesting to focus on the details of the languages - the comparisons between Cyclone, C++, Java, and C-forall generics are good, I would like to see more of this with D and Rust, which are the more modern alternatives to C-forall (for example, Rust's notion of Sized and ?Sized types seems similar to otypes/dtypes).
+
+The related work is really missing any discussion of why the C-forall design choices are better than other languages. To clarify, I mean the specific design of generics and tuples, c.f., the suitability of the language in general because of garbage collection or learning difficulties.
+
+===========================================================================
+                           OOPSLA'17 Review #20C
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: D. Reject
+                         Confidence: Z. I am not an expert; my evaluation
+                                        is that of an informed outsider
+
+                         ===== Paper summary =====
+
+The paper presents two language features of "Cforall": generics and tuples.
+
+                      ===== Comments for author =====
+
+The authors really need to talk about C++ as early as possible IMHO. That's the first thing that came to mind when reading the abstract: how is this different from C++?
+
+Comparison with C++:
+The main difference with C++ seems to be that Cforall favors separate compilation at the expense of runtime overhead while C++ systematically avoids any runtime overhead (at the expense of slow compilation times). C++ approach makes more sense IMHO. While it's true that people where using C for almost everything 30 years ago, that is just not true anymore. Most people writing C today are doing system programming, otherwise there would be using a higher level programming language (C#, Java etc ...).
+Now, when doing system programming, one needs very fine grain control over the resources: memory layout, etc ...
+It is pretty clear to me that the people writing that kind of code will favor generics that do not cost any overhead at runtime, otherwise they would be writing Java in the first place.
+The authors need to better justify the runtime overhead, or give escape hatches for those who don't want to pay that cost at runtime.
+They very often go back to the benefit of separate compilation, but that's not enough IMHO. Here is a proposal: why not have 2 modes, one called debug mode, used while developing the code, that would compile generics with a runtime overhead. Another, called production, that would unfold the world like C++ does?
+
+About Tuples:
+The section about tuples is too long. I would have spent more time explaining generics.
+
+Feedback:
+"This installation base"
+Unclear what you mean by that.
+
+"Prior projects ... but failed ..."
+Hummm ... What about C++.
+
+"... object-oriented or functional programming with garbage collection ..."
+You are really mixing apples and oranges here. Many C programmers have nothing agains object-oriented features, not even functional programming (C++ 11 adds
+a bunch of features proving my point), but it's clear that most of them feel very strongly against automated garbage collection.
+
+"In many cases, C++ is often ..."
+This sentence feels like it is coming out of nowhere.
+
+"... the polymorphic runtime-cost ..."
+Is there any way to avoid that overhead? It's true it will make the compiler faster, but there are cases where the user might not want to pay for
+the overhead at runtime. Is there a way to force the compiler to specialize the code?
+
+"... to write a type-safe Cforall wrapper malloc based ..."
+That cannot be true in general. Malloc produces a pointer (of any type), given an integer (the size).
+It looks like Cforall is assuming that the integer is the result of a call to sizeof (a good practice in C).
+However, if that's the case, it should be explained.
+
+"... allows variable overloading ..."
+How are conflict resolved? In other words, what happens when two variables could be used?
+
+"... reuses the generated structure declarations where appropriate."
+This is too vague.
+
+"... have multiple outcomes, some exceptional."
+Humm, I would say these two things are distinct. Let's just way that this way of presenting things is strange, I woulds ay that a function can either
+return one or multiple values or throw an exception. Not that some of the values returned are "exceptional".
+
+"The type-resolver ..."
+What's that? Type-checker? Type-inference?
+
+"... applies C conversions."
+Noooo! That's exactly what leads to very subtle bugs. Is there any way to stop those conversions from happening?
+
+"The minimal cost ..."
+In what regard? Runtime cost? How does the "resolver" know how expensive the conversions are?
+
+"z = 10 // mass assignments"
+That stuff is completely unreadable. Why not introduce a new operator?
+
+"... roughly equivalent time ..."
+Well, C++ looks faster to me.
+
+"... is restricted because the resolution does not using ..."
+Did you mean, does not use?
+
+"... D and go are garbage collected ..."
+Yes, but in D, the use of the GC is optional.
+
+"... while respecting the talent and skill of C programmers."
+Are you implying that other approaches are not?
+
+"On the surface, the project may appear as a rehash of similar mechanisms in C++."
+Absolutely.
+
+"... integration with C and its programmers ..."
+Bold claim. What makes you think you are integrated with programmers? Number of users?
+
+"... inline annotation at polymorphic function call sites to create a template-specialization ..."
+This should have been mentioned sooner. Plus conflating inlining and specialization is unfortunate.
+Does "inline" also inline the function? Or does it only specialize the code?
+If it also inline, that's a very unfortunate design. I might want to specialize the code, but without inlining ...
+How do I specialize a recursive function?
Index: doc/proposals/references.md
===================================================================
--- doc/proposals/references.md	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ doc/proposals/references.md	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -17,5 +17,5 @@
 derived rvalue types such as pointer types may include qualifiers; 
 `const int *` is a distinct type from `int *`, though the latter is safely 
-convertable to the former. 
+convertible to the former. 
 In general, any number of qualifiers can be safely added to the 
 pointed-to-type of a pointer type, e.g. `int *` converts safely to 
@@ -23,5 +23,5 @@
 `const volatile int *`.
 
-Since lvalues are precicely "addressable objects", in C, only lvalues can be 
+Since lvalues are precisely "addressable objects", in C, only lvalues can be 
 used as the operand of the `&` address-of operator. 
 Similarly, only modifiable lvalues may be used as the assigned-to 
@@ -147,10 +147,10 @@
 call "lvalue of type `T`" as `T&`. 
 There's also an obvious argument that lvalues of a (possibly-qualified) type 
-`T` should be convertable to references of type `T`, where `T` is also 
+`T` should be convertible to references of type `T`, where `T` is also 
 so-qualified (e.g. lvalue `int` to `int&`, lvalue `const char` to 
 `const char&`). 
 By similar arguments to pointer types, qualifiers should be addable to the 
 referred-to type of a reference (e.g. `int&` to `const int&`). 
-As a note, since pointer arithmetic is explictly not defined on `T&`, 
+As a note, since pointer arithmetic is explicitly not defined on `T&`, 
 `restrict T&` should be allowable and would have alias-analysis rules that 
 are actually comprehensible to mere mortals.
Index: doc/user/EHMHierarchy.fig
===================================================================
--- doc/user/EHMHierarchy.fig	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
+++ doc/user/EHMHierarchy.fig	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -0,0 +1,38 @@
+#FIG 3.2  Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter  
+85.00
+Single
+-2
+1200 2
+2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 90.00
+	 4950 1425 3975 1200
+2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 90.00
+	 3750 1875 4425 1650
+2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 90.00
+	 6000 1875 5475 1650
+2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 90.00
+	 1950 1425 3000 1200
+2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 90.00
+	 1350 1875 1800 1650
+2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 90.00
+	 2550 1875 2100 1650
+2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 90.00
+	 4950 1950 4950 1725
+4 1 0 100 0 0 12 0.0000 0 135 195 1950 1650 IO\001
+4 1 0 100 0 0 12 0.0000 0 135 870 4950 1650 Arithmetic\001
+4 1 0 100 0 0 12 0.0000 0 135 315 1350 2100 File\001
+4 1 0 100 0 0 12 0.0000 0 135 690 2550 2100 Network\001
+4 1 0 100 0 0 12 0.0000 0 180 1170 3750 2100 DivideByZero\001
+4 1 0 100 0 0 12 0.0000 0 135 750 4950 2100 Overflow\001
+4 1 0 100 0 0 12 0.0000 0 135 855 6000 2100 Underflow\001
+4 1 0 100 0 0 12 0.0000 0 180 840 3450 1200 Exception\001
Index: doc/user/Makefile
===================================================================
--- doc/user/Makefile	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ doc/user/Makefile	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -12,4 +12,5 @@
 
 FIGURES = ${addsuffix .tex, \
+EHMHierarchy \
 Cdecl \
 pointer1 \
Index: doc/user/user.tex
===================================================================
--- doc/user/user.tex	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ doc/user/user.tex	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -11,6 +11,6 @@
 %% Created On       : Wed Apr  6 14:53:29 2016
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Fri Jun 16 12:00:01 2017
-%% Update Count     : 2433
+%% Last Modified On : Sun Jul  2 09:49:56 2017
+%% Update Count     : 2503
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -25,8 +25,4 @@
 \usepackage{textcomp}
 \usepackage[latin1]{inputenc}
-% Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore
-% removes it as a variable-name character so keyworks in variables are highlighted
-\DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}
-
 
 \usepackage{fullpage,times,comment}
@@ -48,4 +44,10 @@
 \renewcommand{\UrlFont}{\small\sf}
 
+% Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore
+% removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR
+% AFTER HYPERREF.
+\renewcommand{\_}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
+\renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
+
 \setlength{\topmargin}{-0.45in}							% move running title into header
 \setlength{\headsep}{0.25in}
@@ -110,5 +112,5 @@
 \renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}}
 \pagenumbering{roman}
-%\linenumbers                                            % comment out to turn off line numbering
+\linenumbers                                            % comment out to turn off line numbering
 
 \maketitle
@@ -477,5 +479,5 @@
 #endif // ! otype
 
-#include_next <bfd.h>			§\C{// must have internal check for multiple expansion}§
+#®include_next® <bfd.h>			§\C{// must have internal check for multiple expansion}§
 
 #if defined( otype ) && defined( __CFA_BFD_H__ )	§\C{// reset only if set}§
@@ -487,1475 +489,4 @@
 \label{f:InterpositionHeaderFile}
 \end{figure}
-
-
-\section{Declarations}
-\label{s:Declarations}
-
-C declaration syntax is notoriously confusing and error prone.
-For example, many C programmers are confused by a declaration as simple as:
-\begin{quote2}
-\begin{tabular}{@{}ll@{}}
-\begin{cfa}
-int * x[5]
-\end{cfa}
-&
-\raisebox{-0.75\totalheight}{\input{Cdecl}}
-\end{tabular}
-\end{quote2}
-Is this an array of 5 pointers to integers or a \Index{pointer} to an array of 5 integers?
-The fact this declaration is unclear to many C programmers means there are \Index{productivity} and \Index{safety} issues even for basic programs.
-Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site.
-For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way:
-\begin{cfa}
-int ®(*®f®())[®5®]® {...};				§\C{definition}§
- ... ®(*®f®())[®3®]® += 1;				§\C{usage}§
-\end{cfa}
-Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
-While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
-
-\CFA provides its own type, variable and routine declarations, using a different syntax.
-The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type.
-In the following example, \R{red} is the base type and \B{blue} is qualifiers.
-The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type.
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-ß[5] *ß ®int® x1;
-ß* [5]ß ®int® x2;
-ß[* [5] int]ß f®( int p )®;
-\end{cfa}
-&
-\begin{cfa}
-®int® ß*ß x1 ß[5]ß;
-®int® ß(*ßx2ß)[5]ß;
-ßint (*ßf®( int p )®ß)[5]ß;
-\end{cfa}
-\end{tabular}
-\end{quote2}
-The only exception is \Index{bit field} specification, which always appear to the right of the base type.
-% Specifically, the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array or function return value, and parentheses ©()© are used to indicate a routine parameter.
-However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
-For instance, variables ©x© and ©y© of type \Index{pointer} to integer are defined in \CFA as follows:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-®*® int x, y;
-\end{cfa}
-&
-\begin{cfa}
-int ®*®x, ®*®y;
-\end{cfa}
-\end{tabular}
-\end{quote2}
-The downside of this semantics is the need to separate regular and \Index{pointer} declarations:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-®*® int x;
-int y;
-\end{cfa}
-&
-\begin{cfa}
-int ®*®x, y;
-
-\end{cfa}
-\end{tabular}
-\end{quote2}
-which is \Index{prescribing} a safety benefit.
-Other examples are:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}}	\\
-\begin{cfa}
-[ 5 ] int z;
-[ 5 ] * char w;
-* [ 5 ] double v;
-struct s {
-	int f0:3;
-	* int f1;
-	[ 5 ] * int f2;
-};
-\end{cfa}
-&
-\begin{cfa}
-int z[ 5 ];
-char * w[ 5 ];
-double (* v)[ 5 ];
-struct s {
-	int f0:3;
-	int * f1;
-	int * f2[ 5 ]
-};
-\end{cfa}
-&
-\begin{cfa}
-// array of 5 integers
-// array of 5 pointers to char
-// pointer to array of 5 doubles
-
-// common bit field syntax
-
-
-
-\end{cfa}
-\end{tabular}
-\end{quote2}
-
-All type qualifiers, \eg ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, \eg:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}}
-\multicolumn{1}{c@{\hspace{1em}}}{\textbf{\CFA}}	& \multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}}	\\
-\begin{cfa}
-const * const int x;
-const * [ 5 ] const int y;
-\end{cfa}
-&
-\begin{cfa}
-int const * const x;
-const int (* const y)[ 5 ]
-\end{cfa}
-&
-\begin{cfa}
-// const pointer to const integer
-// const pointer to array of 5 const integers
-\end{cfa}
-\end{tabular}
-\end{quote2}
-All declaration qualifiers, \eg ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
-The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} \eg:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}}	\\
-\begin{cfa}
-extern [ 5 ] int x;
-static * const int y;
-\end{cfa}
-&
-\begin{cfa}
-int extern x[ 5 ];
-const int static * y;
-\end{cfa}
-&
-\begin{cfa}
-// externally visible array of 5 integers
-// internally visible pointer to constant int
-\end{cfa}
-\end{tabular}
-\end{quote2}
-
-The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-y = (®* int®)x;
-i = sizeof(®[ 5 ] * int®);
-\end{cfa}
-&
-\begin{cfa}
-y = (®int *®)x;
-i = sizeof(®int * [ 5 ]®);
-\end{cfa}
-\end{tabular}
-\end{quote2}
-
-Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
-Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
-Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems.
-
-
-\section{Pointer/Reference}
-
-C provides a \newterm{pointer type};
-\CFA adds a \newterm{reference type}.
-These types may be derived from an object or routine type, called the \newterm{referenced type}.
-Objects of these types contain an \newterm{address}, which is normally a location in memory, but may also address memory-mapped registers in hardware devices.
-An integer constant expression with the value 0, or such an expression cast to type ©void *©, is called a \newterm{null-pointer constant}.\footnote{
-One way to conceptualize the null pointer is that no variable is placed at this address, so the null-pointer address can be used to denote an uninitialized pointer/reference object;
-\ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine.}
-An address is \newterm{sound}, if it points to a valid memory location in scope, \ie within the program's execution-environment and has not been freed.
-Dereferencing an \newterm{unsound} address, including the null pointer, is \Index{undefined}, often resulting in a \Index{memory fault}.
-
-A program \newterm{object} is a region of data storage in the execution environment, the contents of which can represent values.
-In most cases, objects are located in memory at an address, and the variable name for an object is an implicit address to the object generated by the compiler and automatically dereferenced, as in:
-\begin{quote2}
-\begin{tabular}{@{}ll@{\hspace{2em}}l@{}}
-\begin{cfa}
-int x;
-x = 3;
-int y;
-y = x;
-\end{cfa}
-&
-\raisebox{-0.45\totalheight}{\input{pointer1}}
-&
-\begin{cfa}
-int * ®const® x = (int *)100
-*x = 3;			// implicit dereference
-int * ®const® y = (int *)104;
-*y = *x;		// implicit dereference
-\end{cfa}
-\end{tabular}
-\end{quote2}
-where the right example is how the compiler logically interprets the variables in the left example.
-Since a variable name only points to one address during its lifetime, it is an \Index{immutable} \Index{pointer};
-hence, the implicit type of pointer variables ©x© and ©y© are constant pointers in the compiler interpretation.
-In general, variable addresses are stored in instructions instead of loaded from memory, and hence may not occupy storage.
-These approaches are contrasted in the following:
-\begin{quote2}
-\begin{tabular}{@{}l|l@{}}
-\multicolumn{1}{c|}{explicit variable address} & \multicolumn{1}{c}{implicit variable address} \\
-\hline
-\begin{cfa}
-lda		r1,100			// load address of x
-ld		 r2,(r1)		  // load value of x
-lda		r3,104			// load address of y
-st		 r2,(r3)		  // store x into y
-\end{cfa}
-&
-\begin{cfa}
-
-ld		r2,(100)		// load value of x
-
-st		r2,(104)		// store x into y
-\end{cfa}
-\end{tabular}
-\end{quote2}
-Finally, the immutable nature of a variable's address and the fact that there is no storage for the variable pointer means pointer assignment\index{pointer!assignment}\index{assignment!pointer} is impossible.
-Therefore, the expression ©x = y© has only one meaning, ©*x = *y©, \ie manipulate values, which is why explicitly writing the dereferences is unnecessary even though it occurs implicitly as part of \Index{instruction decoding}.
-
-A \Index{pointer}/\Index{reference} object is a generalization of an object variable-name, \ie a mutable address that can point to more than one memory location during its lifetime.
-(Similarly, an integer variable can contain multiple integer literals during its lifetime versus an integer constant representing a single literal during its lifetime, and like a variable name, may not occupy storage if the literal is embedded directly into instructions.)
-Hence, a pointer occupies memory to store its current address, and the pointer's value is loaded by dereferencing, \eg:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{2em}}l@{}}
-\begin{cfa}
-int x, y, ®*® p1, ®*® p2, ®**® p3;
-p1 = ®&®x;		 // p1 points to x
-p2 = p1;		 // p2 points to x
-p1 = ®&®y;		 // p1 points to y
-p3 = &p2;		// p3 points to p2
-\end{cfa}
-&
-\raisebox{-0.5\totalheight}{\input{pointer2.pstex_t}}
-\end{tabular}
-\end{quote2}
-
-Notice, an address has a \Index{duality}\index{address!duality}: a location in memory or the value at that location.
-In many cases, a compiler might be able to infer the best meaning for these two cases.
-For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage
-\begin{cfa}
-p2 = p1 + x;					§\C{// compiler infers *p2 = *p1 + x;}§
-\end{cfa}
-Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
-Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices. 
-
-Rather than inferring dereference, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality.
-In C, objects of pointer type always manipulate the pointer object's address:
-\begin{cfa}
-p1 = p2;						§\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
-p2 = p1 + x;					§\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
-\end{cfa}
-even though the assignment to ©p2© is likely incorrect, and the programmer probably meant:
-\begin{cfa}
-p1 = p2;						§\C{// pointer address assignment}§
-®*®p2 = ®*®p1 + x;				§\C{// pointed-to value assignment / operation}§
-\end{cfa}
-The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).
-
-However, in most other situations, the pointed-to value is requested more often than the pointer address.
-\begin{cfa}
-*p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15);
-\end{cfa}
-In this case, it is tedious to explicitly write the dereferencing, and error prone when pointer arithmetic is allowed.
-It is better to have the compiler generate the dereferencing and have no implicit pointer arithmetic:
-\begin{cfa}
-p2 = ((p1 + p2) * (p3 - p1)) / (p3 - 15);
-\end{cfa}
-
-To support this common case, a reference type is introduced in \CFA, denoted by ©&©, which is the opposite dereference semantics to a pointer type, making the value at the pointed-to location the implicit semantics for dereferencing (similar but not the same as \CC \Index{reference type}s).
-\begin{cfa}
-int x, y, ®&® r1, ®&® r2, ®&&® r3;
-®&®r1 = &x;						§\C{// r1 points to x}§
-®&®r2 = &r1;					§\C{// r2 points to x}§
-®&®r1 = &y;						§\C{// r1 points to y}§
-®&&®r3 = ®&®&r2;				§\C{// r3 points to r2}§
-r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§
-\end{cfa}
-Except for auto-dereferencing by the compiler, this reference example is the same as the previous pointer example.
-Hence, a reference behaves like the variable name for the current variable it is pointing-to.
-One way to conceptualize a reference is via a rewrite rule, where the compiler inserts a dereference operator before the reference variable for each reference qualifier in a declaration, so the previous example becomes:
-\begin{cfa}
-®*®r2 = ((®*®r1 + ®*®r2) ®*® (®**®r3 - ®*®r1)) / (®**®r3 - 15);
-\end{cfa}
-When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out.
-However, in C, the cancellation always yields a value (\Index{rvalue}).\footnote{
-The unary ©&© operator yields the address of its operand.
-If the operand has type ``type'', the result has type ``pointer to type''.
-If the operand is the result of a unary ©*© operator, neither that operator nor the ©&© operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue.~\cite[\S~6.5.3.2--3]{C11}}
-For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}):
-\begin{cfa}
-(&®*®)r1 = &x;					§\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
-\end{cfa}
-Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}):
-\begin{cfa}
-(&(&®*®)®*®)r3 = &(&®*®)r2;		§\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
-\end{cfa}
-Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth.
-
-Fundamentally, pointer and reference objects are functionally interchangeable because both contain addresses.
-\begin{cfa}
-int x, *p1 = &x, **p2 = &p1, ***p3 = &p2,
-		 &r1 = x,    &&r2 = r1,   &&&r3 = r2;
-***p3 = 3;						§\C{// change x}§
-r3 = 3;							§\C{// change x, ***r3}§
-**p3 = ...;						§\C{// change p1}§
-&r3 = ...;						§\C{// change r1, (\&*)**r3, 1 cancellation}§
-*p3 = ...;						§\C{// change p2}§
-&&r3 = ...;						§\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
-&&&r3 = p3;						§\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
-\end{cfa}
-Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types.
-Therefore, the choice between them is based solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of implicit dereferencing aid from the compiler.
-
-As for a pointer type, a reference type may have qualifiers:
-\begin{cfa}
-const int cx = 5;					§\C{// cannot change cx;}§
-const int & cr = cx;				§\C{// cannot change what cr points to}§
-®&®cr = &cx;						§\C{// can change cr}§
-cr = 7;								§\C{// error, cannot change cx}§
-int & const rc = x;					§\C{// must be initialized}§
-®&®rc = &x;							§\C{// error, cannot change rc}§
-const int & const crc = cx;			§\C{// must be initialized}§
-crc = 7;							§\C{// error, cannot change cx}§
-®&®crc = &cx;						§\C{// error, cannot change crc}§
-\end{cfa}
-Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}:
-\begin{cfa}
-int & const cr = *0;				§\C{// where 0 is the int * zero}§
-\end{cfa}
-Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management:
-\begin{cfa}
-int & const cr = *malloc();
-cr = 5;
-free( &cr );
-cr = 7;								§\C{// unsound pointer dereference}§
-\end{cfa}
-
-The position of the ©const© qualifier \emph{after} the pointer/reference qualifier causes confuse for C programmers.
-The ©const© qualifier cannot be moved before the pointer/reference qualifier for C style-declarations;
-\CFA-style declarations (see \VRef{s:Declarations}) attempt to address this issue:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-®const® * ®const® * const int ccp;
-®const® & ®const® & const int ccr;
-\end{cfa}
-&
-\begin{cfa}
-const int * ®const® * ®const® ccp;
-
-\end{cfa}
-\end{tabular}
-\end{quote2}
-where the \CFA declaration is read left-to-right.
-
-Finally, like pointers, references are usable and composable with other type operators and generators.
-\begin{cfa}
-int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§
-&ar[1] = &w;						§\C{// change reference array element}§
-typeof( ar[1] ) p;					§\C{// (gcc) is int, i.e., the type of referenced object}§
-typeof( &ar[1] ) q;					§\C{// (gcc) is int \&, i.e., the type of reference}§
-sizeof( ar[1] ) == sizeof( int );	§\C{// is true, i.e., the size of referenced object}§
-sizeof( &ar[1] ) == sizeof( int *)	§\C{// is true, i.e., the size of a reference}§
-\end{cfa}
-
-In contrast to \CFA reference types, \Index*[C++]{\CC{}}'s reference types are all ©const© references, preventing changes to the reference address, so only value assignment is possible, which eliminates half of the \Index{address duality}.
-Also, \CC does not allow \Index{array}s\index{array!reference} of reference\footnote{
-The reason for disallowing arrays of reference is unknown, but possibly comes from references being ethereal (like a textual macro), and hence, replaceable by the referant object.}
-\Index*{Java}'s reference types to objects (all Java objects are on the heap) are like C pointers, which always manipulate the address, and there is no (bit-wise) object assignment, so objects are explicitly cloned by shallow or deep copying, which eliminates half of the address duality.
-
-
-\subsection{Initialization}
-
-\Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
-There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
-Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
-In contrast, the left-hand side of assignment has an address that has a duality.
-Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
-\begin{cfa}
-int * p = &x;						§\C{// assign address of x}§
-®int * p = x;®						§\C{// assign value of x}§
-int & r = x;						§\C{// must have address of x}§
-\end{cfa}
-Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
-Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
-Note, this is strictly a convenience and safety feature for a programmer.
-Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
-Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
-Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
-\begin{cfa}
-int & f( int & r );					§\C{// reference parameter and return}§
-z = f( x ) + f( y );				§\C{// reference operator added, temporaries needed for call results}§
-\end{cfa}
-Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
-Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
-\begin{cfa}
-int temp1 = f( x ), temp2 = f( y );
-z = temp1 + temp2;
-\end{cfa}
-This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
-otherwise references have the same syntactic  burden as pointers in these contexts.
-
-When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
-\begin{cfa}
-void f( ®const® int & cr );
-void g( ®const® int * cp );
-f( 3 );			  g( ®&®3 );
-f( x + y );		g( ®&®(x + y) );
-\end{cfa}
-Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
-The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
-Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
-
-\CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
-If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
-\begin{cfa}
-void f( int & r );
-void g( int * p );
-f( 3 );			  g( ®&®3 );		§\C{// compiler implicit generates temporaries}§
-f( x + y );		g( ®&®(x + y) );	§\C{// compiler implicit generates temporaries}§
-\end{cfa}
-Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
-This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
-The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
-
-%\CFA attempts to handle pointers and references in a uniform, symmetric manner.
-Finally, C handles \Index{routine object}s in an inconsistent way.
-A routine object is both a pointer and a reference (\Index{particle and wave}).
-\begin{cfa}
-void f( int i );
-void (*fp)( int );					§\C{// routine pointer}§
-fp = f;								§\C{// reference initialization}§
-fp = &f;							§\C{// pointer initialization}§
-fp = *f;							§\C{// reference initialization}§
-fp(3);								§\C{// reference invocation}§
-(*fp)(3);							§\C{// pointer invocation}§
-\end{cfa}
-While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
-Instead, a routine object should be referenced by a ©const© reference:
-\begin{cfa}
-®const® void (®&® fr)( int ) = f;	§\C{// routine reference}§
-fr = ...							§\C{// error, cannot change code}§
-&fr = ...;							§\C{// changing routine reference}§
-fr( 3 );							§\C{// reference call to f}§
-(*fr)(3);							§\C{// error, incorrect type}§
-\end{cfa}
-because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
-Dynamic code rewriting is possible but only in special circumstances.}
-\CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
-
-
-\subsection{Address-of Semantics}
-
-In C, ©&E© is an rvalue for any expression ©E©.
-\CFA extends the ©&© (address-of) operator as follows:
-\begin{itemize}
-\item
-if ©R© is an \Index{rvalue} of type ©T &$_1$...&$_r$© where $r \ge 1$ references (©&© symbols) than ©&R© has type ©T ®*®&$_{\color{red}2}$...&$_{\color{red}r}$©, \ie ©T© pointer with $r-1$ references (©&© symbols).
-
-\item
-if ©L© is an \Index{lvalue} of type ©T &$_1$...&$_l$© where $l \ge 0$ references (©&© symbols) then ©&L© has type ©T ®*®&$_{\color{red}1}$...&$_{\color{red}l}$©, \ie ©T© pointer with $l$ references (©&© symbols).
-\end{itemize}
-The following example shows the first rule applied to different \Index{rvalue} contexts:
-\begin{cfa}
-int x, * px, ** ppx, *** pppx, **** ppppx;
-int & rx = x, && rrx = rx, &&& rrrx = rrx ;
-x = rrrx;		// rrrx is an lvalue with type int &&& (equivalent to x)
-px = &rrrx;		// starting from rrrx, &rrrx is an rvalue with type int *&&& (&x)
-ppx = &&rrrx;	// starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx)
-pppx = &&&rrrx;	// starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx)
-ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx)
-\end{cfa}
-The following example shows the second rule applied to different \Index{lvalue} contexts:
-\begin{cfa}
-int x, * px, ** ppx, *** pppx;
-int & rx = x, && rrx = rx, &&& rrrx = rrx ;
-rrrx = 2;		// rrrx is an lvalue with type int &&& (equivalent to x)
-&rrrx = px;		// starting from rrrx, &rrrx is an rvalue with type int *&&& (rx)
-&&rrrx = ppx;	// starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx)
-&&&rrrx = pppx;	// starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx)
-\end{cfa}
-
-
-\subsection{Conversions}
-
-C provides a basic implicit conversion to simplify variable usage:
-\begin{enumerate}
-\setcounter{enumi}{-1}
-\item
-lvalue to rvalue conversion: ©cv T© converts to ©T©, which allows implicit variable dereferencing.
-\begin{cfa}
-int x;
-x + 1;			// lvalue variable (int) converts to rvalue for expression
-\end{cfa}
-An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped.
-\end{enumerate}
-\CFA provides three new implicit conversion for reference types to simplify reference usage.
-\begin{enumerate}
-\item
-reference to rvalue conversion: ©cv T &© converts to ©T©, which allows implicit reference dereferencing.
-\begin{cfa}
-int x, &r = x, f( int p );
-x = ®r® + f( ®r® );  // lvalue reference converts to rvalue
-\end{cfa}
-An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped.
-
-\item
-lvalue to reference conversion: \lstinline[deletekeywords={lvalue}]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references.
-\begin{cfa}
-int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &)
-f( ®x® );		// lvalue variable (int) convert to reference (int &)
-\end{cfa}
-Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost.
-Conversion can expand a type, where ©cv1© $>$ ©cv2©, \eg passing a ©const volatile int© to an ©int &©, which has high cost (\Index{warning});
-furthermore, if ©cv1© has ©const© but not ©cv2©, a temporary variable is created to preserve the immutable lvalue.
-
-\item
-rvalue to reference conversion: ©T© converts to ©cv T &©, which allows binding references to temporaries.
-\begin{cfa}
-int x, & f( int & p );
-f( ®x + 3® );	// rvalue parameter (int) implicitly converts to lvalue temporary reference (int &)
-®&f®(...) = &x;	// rvalue result (int &) implicitly converts to lvalue temporary reference (int &)
-\end{cfa}
-In both case, modifications to the temporary are inaccessible (\Index{warning}).
-Conversion expands the temporary-type with ©cv©, which is low cost since the temporary is inaccessible.
-\end{enumerate}
-
-
-\begin{comment}
-From: Richard Bilson <rcbilson@gmail.com>
-Date: Wed, 13 Jul 2016 01:58:58 +0000
-Subject: Re: pointers / references
-To: "Peter A. Buhr" <pabuhr@plg2.cs.uwaterloo.ca>
-
-As a general comment I would say that I found the section confusing, as you move back and forth
-between various real and imagined programming languages. If it were me I would rewrite into two
-subsections, one that specifies precisely the syntax and semantics of reference variables and
-another that provides the rationale.
-
-I don't see any obvious problems with the syntax or semantics so far as I understand them. It's not
-obvious that the description you're giving is complete, but I'm sure you'll find the special cases
-as you do the implementation.
-
-My big gripes are mostly that you're not being as precise as you need to be in your terminology, and
-that you say a few things that aren't actually true even though I generally know what you mean.
-
-20 C provides a pointer type; CFA adds a reference type. Both types contain an address, which is normally a
-21 location in memory.
-
-An address is not a location in memory; an address refers to a location in memory. Furthermore it
-seems weird to me to say that a type "contains" an address; rather, objects of that type do.
-
-21 Special addresses are used to denote certain states or access co-processor memory. By
-22 convention, no variable is placed at address 0, so addresses like 0, 1, 2, 3 are often used to denote no-value
-23 or other special states.
-
-This isn't standard C at all. There has to be one null pointer representation, but it doesn't have
-to be a literal zero representation and there doesn't have to be more than one such representation.
-
-23 Often dereferencing a special state causes a memory fault, so checking is necessary
-24 during execution.
-
-I don't see the connection between the two clauses here. I feel like if a bad pointer will not cause
-a memory fault then I need to do more checking, not less.
-
-24 If the programming language assigns addresses, a program's execution is sound, \ie all
-25 addresses are to valid memory locations.
-
-You haven't said what it means to "assign" an address, but if I use my intuitive understanding of
-the term I don't see how this can be true unless you're assuming automatic storage management.
-
-1 Program variables are implicit pointers to memory locations generated by the compiler and automatically
-2 dereferenced, as in:
-
-There is no reason why a variable needs to have a location in memory, and indeed in a typical
-program many variables will not. In standard terminology an object identifier refers to data in the
-execution environment, but not necessarily in memory.
-
-13 A pointer/reference is a generalization of a variable name, \ie a mutable address that can point to more
-14 than one memory location during its lifetime.
-
-I feel like you're off the reservation here. In my world there are objects of pointer type, which
-seem to be what you're describing here, but also pointer values, which can be stored in an object of
-pointer type but don't necessarily have to be. For example, how would you describe the value denoted
-by "&main" in a C program? I would call it a (function) pointer, but that doesn't satisfy your
-definition.
-
-16 not occupy storage as the literal is embedded directly into instructions.) Hence, a pointer occupies memory
-17 to store its current address, and the pointer's value is loaded by dereferencing, e.g.:
-
-As with my general objection regarding your definition of variables, there is no reason why a
-pointer variable (object of pointer type) needs to occupy memory.
-
-21 p2 = p1 + x; // compiler infers *p2 = *p1 + x;
-
-What language are we in now?
-
-24 pointer usage. However, in C, the following cases are ambiguous, especially with pointer arithmetic:
-25 p1 = p2; // p1 = p2 or *p1 = *p2
-
-This isn't ambiguous. it's defined to be the first option.
-
-26 p1 = p1 + 1; // p1 = p1 + 1 or *p1 = *p1 + 1
-
-Again, this statement is not ambiguous.
-
-13 example. Hence, a reference behaves like the variable name for the current variable it is pointing-to. The
-14 simplest way to understand a reference is to imagine the compiler inserting a dereference operator before
-15 the reference variable for each reference qualifier in a declaration, e.g.:
-
-It's hard for me to understand who the audience for this part is. I think a practical programmer is
-likely to be satisfied with "a reference behaves like the variable name for the current variable it
-is pointing-to," maybe with some examples. Your "simplest way" doesn't strike me as simpler than
-that. It feels like you're trying to provide a more precise definition for the semantics of
-references, but it isn't actually precise enough to be a formal specification. If you want to
-express the semantics of references using rewrite rules that's a great way to do it, but lay the
-rules out clearly, and when you're showing an example of rewriting keep your
-references/pointers/values separate (right now, you use \eg "r3" to mean a reference, a pointer,
-and a value).
-
-24 Cancellation works to arbitrary depth, and pointer and reference values are interchangeable because both
-25 contain addresses.
-
-Except they're not interchangeable, because they have different and incompatible types.
-
-40 Interestingly, C++ deals with the address duality by making the pointed-to value the default, and prevent-
-41 ing changes to the reference address, which eliminates half of the duality. Java deals with the address duality
-42 by making address assignment the default and requiring field assignment (direct or indirect via methods),
-43 \ie there is no builtin bit-wise or method-wise assignment, which eliminates half of the duality.
-
-I can follow this but I think that's mostly because I already understand what you're trying to
-say. I don't think I've ever heard the term "method-wise assignment" and I don't see you defining
-it. Furthermore Java does have value assignment of basic (non-class) types, so your summary here
-feels incomplete. (If it were me I'd drop this paragraph rather than try to save it.)
-
-11 Hence, for type & const, there is no pointer assignment, so &rc = &x is disallowed, and the address value
-12 cannot be 0 unless an arbitrary pointer is assigned to the reference.
-
-Given the pains you've taken to motivate every little bit of the semantics up until now, this last
-clause ("the address value cannot be 0") comes out of the blue. It seems like you could have
-perfectly reasonable semantics that allowed the initialization of null references.
-
-12 In effect, the compiler is managing the
-13 addresses for type & const not the programmer, and by a programming discipline of only using references
-14 with references, address errors can be prevented.
-
-Again, is this assuming automatic storage management?
-
-18 rary binding. For reference initialization (like pointer), the initializing value must be an address (lvalue) not
-19 a value (rvalue).
-
-This sentence appears to suggest that an address and an lvalue are the same thing.
-
-20 int * p = &x; // both &x and x are possible interpretations
-
-Are you saying that we should be considering "x" as a possible interpretation of the initializer
-"&x"? It seems to me that this expression has only one legitimate interpretation in context.
-
-21 int & r = x; // x unlikely interpretation, because of auto-dereferencing
-
-You mean, we can initialize a reference using an integer value? Surely we would need some sort of
-cast to induce that interpretation, no?
-
-22 Hence, the compiler implicitly inserts a reference operator, &, before the initialization expression.
-
-But then the expression would have pointer type, which wouldn't be compatible with the type of r.
-
-22 Similarly,
-23 when a reference is used for a parameter/return type, the call-site argument does not require a reference
-24 operator.
-
-Furthermore, it would not be correct to use a reference operator.
-
-45 The implicit conversion allows
-1 seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
-2 While C' attempts to handle pointers and references in a uniform, symmetric manner, C handles routine
-3 variables in an inconsistent way: a routine variable is both a pointer and a reference (particle and wave).
-
-After all this talk of how expressions can have both pointer and value interpretations, you're
-disparaging C because it has expressions that have both pointer and value interpretations?
-
-On Sat, Jul 9, 2016 at 4:18 PM Peter A. Buhr <pabuhr@plg.uwaterloo.ca> wrote:
-> Aaron discovered a few places where "&"s are missing and where there are too many "&", which are
-> corrected in the attached updated. None of the text has changed, if you have started reading
-> already.
-\end{comment}
-
-
-\section{Routine Definition}
-
-\CFA also supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
-The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
-\begin{cfa}
-®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) {
-	§\emph{routine body}§
-}
-\end{cfa}
-where routine ©f© has three output (return values) and three input parameters.
-Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type specifications.
-
-In detail, the brackets, ©[]©, enclose the result type, where each return value is named and that name is a local variable of the particular return type.\footnote{
-\Index*{Michael Tiemann}, with help from \Index*{Doug Lea}, provided named return values in g++, circa 1989.}
-The value of each local return variable is automatically returned at routine termination.
-Declaration qualifiers can only appear at the start of a routine definition, \eg:
-\begin{cfa}
-®extern® [ int x ] g( int y ) {§\,§}
-\end{cfa}
-Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified;
-in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
-\begin{cfa}
-[§\,§] g();							§\C{// no input or output parameters}§
-[ void ] g( void );					§\C{// no input or output parameters}§
-\end{cfa}
-
-Routine f is called as follows:
-\begin{cfa}
-[ i, j, ch ] = f( 3, 'a', ch );
-\end{cfa}
-The list of return values from f and the grouping on the left-hand side of the assignment is called a \newterm{return list} and discussed in Section 12.
-
-\CFA style declarations cannot be used to declare parameters for K\&R style routine definitions because of the following ambiguity:
-\begin{cfa}
-int (*f(x))[ 5 ] int x; {}
-\end{cfa}
-The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter x of type array of 5 integers.
-Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string.
-As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity:
-\begin{cfa}
-typedef int foo;
-int f( int (* foo) );				§\C{// foo is redefined as a parameter name}§
-\end{cfa}
-The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
-The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name.
-The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.
-
-C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
-\begin{cfa}
-[ int ] f( * int, int * );			§\C{// returns an integer, accepts 2 pointers to integers}§
-[ * int, int * ] f( int );			§\C{// returns 2 pointers to integers, accepts an integer}§
-\end{cfa}
-The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
-\begin{cfa}
-#define ptoa( n, d ) int (*n)[ d ]
-int f( ptoa( p, 5 ) ) ...			§\C{// expands to int f( int (*p)[ 5 ] )}§
-[ int ] f( ptoa( p, 5 ) ) ...		§\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
-\end{cfa}
-Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
-
-
-\subsection{Named Return Values}
-
-\Index{Named return values} handle the case where it is necessary to define a local variable whose value is then returned in a ©return© statement, as in:
-\begin{cfa}
-int f() {
-	int x;
-	... x = 0; ... x = y; ...
-	return x;
-}
-\end{cfa}
-Because the value in the return variable is automatically returned when a \CFA routine terminates, the ©return© statement \emph{does not} contain an expression, as in:
-\newline
-\begin{minipage}{\linewidth}
-\begin{cfa}
-®[ int x, int y ]® f() {
-	int z;
-	... x = 0; ... y = z; ...
-	®return;®							§\C{// implicitly return x, y}§
-}
-\end{cfa}
-\end{minipage}
-\newline
-When the return is encountered, the current values of ©x© and ©y© are returned to the calling routine.
-As well, ``falling off the end'' of a routine without a ©return© statement is permitted, as in:
-\begin{cfa}
-[ int x, int y ] f() {
-	...
-}										§\C{// implicitly return x, y}§
-\end{cfa}
-In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
-
-Named return values may be used in conjunction with named parameter values;
-specifically, a return and parameter can have the same name.
-\begin{cfa}
-[ int x, int y ] f( int, x, int y ) {
-	...
-}										§\C{// implicitly return x, y}§
-\end{cfa}
-This notation allows the compiler to eliminate temporary variables in nested routine calls.
-\begin{cfa}
-[ int x, int y ] f( int, x, int y );	§\C{// prototype declaration}§
-int a, b;
-[a, b] = f( f( f( a, b ) ) );
-\end{cfa}
-While the compiler normally ignores parameters names in prototype declarations, here they are used to eliminate temporary return-values by inferring that the results of each call are the inputs of the next call, and ultimately, the left-hand side of the assignment.
-Hence, even without the body of routine ©f© (separate compilation), it is possible to perform a global optimization across routine calls.
-The compiler warns about naming inconsistencies between routine prototype and definition in this case, and behaviour is \Index{undefined} if the programmer is inconsistent.
-
-
-\subsection{Routine Prototype}
-
-The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
-as well, parameter names are optional, \eg:
-\begin{cfa}
-[ int x ] f ();							§\C{// returning int with no parameters}§
-[ * int ] g (int y);					§\C{// returning pointer to int with int parameter}§
-[ ] h ( int, char );					§\C{// returning no result with int and char parameters}§
-[ * int, int ] j ( int );				§\C{// returning pointer to int and int, with int parameter}§
-\end{cfa}
-This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
-It is possible to declare multiple routine-prototypes in a single declaration, but the entire type specification is distributed across \emph{all} routine names in the declaration list (see~\VRef{s:Declarations}), \eg:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-[ int ] f( int ), g;
-\end{cfa}
-&
-\begin{cfa}
-int f( int ), g( int );
-\end{cfa}
-\end{tabular}
-\end{quote2}
-Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
-\begin{cfa}
-extern [ int ] f ( int );
-static [ int ] g ( int );
-\end{cfa}
-
-
-\section{Routine Pointers}
-
-The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
-\begin{cfa}
-* [ int x ] () fp;						§\C{// pointer to routine returning int with no parameters}§
-* [ * int ] (int y) gp;					§\C{// pointer to routine returning pointer to int with int parameter}§
-* [ ] (int,char) hp;					§\C{// pointer to routine returning no result with int and char parameters}§
-* [ * int,int ] ( int ) jp;				§\C{// pointer to routine returning pointer to int and int, with int parameter}§
-\end{cfa}
-While parameter names are optional, \emph{a routine name cannot be specified};
-for example, the following is incorrect:
-\begin{cfa}
-* [ int x ] f () fp;					§\C{// routine name "f" is not allowed}§
-\end{cfa}
-
-
-\section{Named and Default Arguments}
-
-Named\index{named arguments}\index{arguments!named} and default\index{default arguments}\index{arguments!default} arguments~\cite{Hardgrave76}\footnote{
-Francez~\cite{Francez77} proposed a further extension to the named-parameter passing style, which specifies what type of communication (by value, by reference, by name) the argument is passed to the routine.}
-are two mechanisms to simplify routine call.
-Both mechanisms are discussed with respect to \CFA.
-\begin{description}
-\item[Named (or Keyword) Arguments:]
-provide the ability to specify an argument to a routine call using the parameter name rather than the position of the parameter.
-For example, given the routine:
-\begin{cfa}
-void p( int x, int y, int z ) {...}
-\end{cfa}
-a positional call is:
-\begin{cfa}
-p( 4, 7, 3 );
-\end{cfa}
-whereas a named (keyword) call may be:
-\begin{cfa}
-p( z : 3, x : 4, y : 7 ); 	§\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
-\end{cfa}
-Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
-The compiler rewrites a named call into a positional call.
-The advantages of named parameters are:
-\begin{itemize}
-\item
-Remembering the names of the parameters may be easier than the order in the routine definition.
-\item
-Parameter names provide documentation at the call site (assuming the names are descriptive).
-\item
-Changes can be made to the order or number of parameters without affecting the call (although the call must still be recompiled).
-\end{itemize}
-
-Unfortunately, named arguments do not work in C-style programming-languages because a routine prototype is not required to specify parameter names, nor do the names in the prototype have to match with the actual definition.
-For example, the following routine prototypes and definition are all valid.
-\begin{cfa}
-void p( int, int, int );			§\C{// equivalent prototypes}§
-void p( int x, int y, int z );
-void p( int y, int x, int z );
-void p( int z, int y, int x );
-void p( int q, int r, int s ) {}	§\C{// match with this definition}§
-\end{cfa}
-Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming.
-Alternatively, prototype definitions can be eliminated by using a two-pass compilation, and implicitly creating header files for exports.
-The former is easy to do, while the latter is more complex.
-
-Furthermore, named arguments do not work well in a \CFA-style programming-languages because they potentially introduces a new criteria for type matching.
-For example, it is technically possible to disambiguate between these two overloaded definitions of ©f© based on named arguments at the call site:
-\begin{cfa}
-int f( int i, int j );
-int f( int x, double y );
-
-f( j : 3, i : 4 );				§\C{// 1st f}§
-f( x : 7, y : 8.1 );			§\C{// 2nd f}§
-f( 4, 5 ); 						§\C{// ambiguous call}§
-\end{cfa}
-However, named arguments compound routine resolution in conjunction with conversions:
-\begin{cfa}
-f( i : 3, 5.7 );				§\C{// ambiguous call ?}§
-\end{cfa}
-Depending on the cost associated with named arguments, this call could be resolvable or ambiguous.
-Adding named argument into the routine resolution algorithm does not seem worth the complexity.
-Therefore, \CFA does \emph{not} attempt to support named arguments.
-
-\item[Default Arguments]
-provide the ability to associate a default value with a parameter so it can be optionally specified in the argument list.
-For example, given the routine:
-\begin{cfa}
-void p( int x = 1, int y = 2, int z = 3 ) {...}
-\end{cfa}
-the allowable positional calls are:
-\begin{cfa}
-p();							§\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
-p( 4 );							§\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
-p( 4, 4 );						§\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
-p( 4, 4, 4 );					§\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
-// empty arguments
-p(  , 4, 4 );					§\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
-p( 4,  , 4 );					§\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
-p( 4, 4,   );					§\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
-p( 4,  ,   );					§\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
-p(  , 4,   );					§\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
-p(  ,  , 4 );					§\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
-p(  ,  ,   );					§\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
-\end{cfa}
-Here the missing arguments are inserted from the default values in the parameter list.
-The compiler rewrites missing default values into explicit positional arguments.
-The advantages of default values are:
-\begin{itemize}
-\item
-Routines with a large number of parameters are often very generalized, giving a programmer a number of different options on how a computation is performed.
-For many of these kinds of routines, there are standard or default settings that work for the majority of computations.
-Without default values for parameters, a programmer is forced to specify these common values all the time, resulting in long argument lists that are error prone.
-\item
-When a routine's interface is augmented with new parameters, it extends the interface providing generalizability\footnote{
-``It should be possible for the implementor of an abstraction to increase its generality.
-So long as the modified abstraction is a generalization of the original, existing uses of the abstraction will not require change.
-It might be possible to modify an abstraction in a manner which is not a generalization without affecting existing uses, but, without inspecting the modules in which the uses occur, this possibility cannot be determined.
-This criterion precludes the addition of parameters, unless these parameters have default or inferred values that are valid for all possible existing applications.''~\cite[p.~128]{Cormack90}}
-(somewhat like the generalization provided by inheritance for classes).
-That is, all existing calls are still valid, although the call must still be recompiled.
-\end{itemize}
-The only disadvantage of default arguments is that unintentional omission of an argument may not result in a compiler-time error.
-Instead, a default value is used, which may not be the programmer's intent.
-
-Default values may only appear in a prototype versus definition context:
-\begin{cfa}
-void p( int x, int y = 2, int z = 3 );		§\C{// prototype: allowed}§
-void p( int, int = 2, int = 3 );			§\C{// prototype: allowed}§
-void p( int x, int y = 2, int z = 3 ) {}	§\C{// definition: not allowed}§
-\end{cfa}
-The reason for this restriction is to allow separate compilation.
-Multiple prototypes with different default values is an error.
-\end{description}
-
-Ellipse (``...'') arguments present problems when used with default arguments.
-The conflict occurs because both named and ellipse arguments must appear after positional arguments, giving two possibilities:
-\begin{cfa}
-p( /* positional */, ... , /* named */ );
-p( /* positional */, /* named */, ... );
-\end{cfa}
-While it is possible to implement both approaches, the first possibly is more complex than the second, \eg:
-\begin{cfa}
-p( int x, int y, int z, ... );
-p( 1, 4, 5, 6, z : 3, y : 2 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
-p( 1, z : 3, y : 2, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
-\end{cfa}
-In the first call, it is necessary for the programmer to conceptually rewrite the call, changing named arguments into positional, before knowing where the ellipse arguments begin.
-Hence, this approach seems significantly more difficult, and hence, confusing and error prone.
-In the second call, the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
-
-The problem is exacerbated with default arguments, \eg:
-\begin{cfa}
-void p( int x, int y = 2, int z = 3... );
-p( 1, 4, 5, 6, z : 3 );		§\C{// assume p( /* positional */, ... , /* named */ );}§
-p( 1, z : 3, 4, 5, 6 );		§\C{// assume p( /* positional */, /* named */, ... );}§
-\end{cfa}
-The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments;
-therefore, argument 5 subsequently conflicts with the named argument z : 3.
-In the second call, the default value for y is implicitly inserted after argument 1 and the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
-For these reasons, \CFA requires named arguments before ellipse arguments.
-Finally, while ellipse arguments are needed for a small set of existing C routines, like printf, the extended \CFA type system largely eliminates the need for ellipse arguments (see Section 24), making much of this discussion moot.
-
-Default arguments and overloading (see Section 24) are complementary.
-While in theory default arguments can be simulated with overloading, as in:
-\begin{quote2}
-\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{default arguments}}	& \multicolumn{1}{c}{\textbf{overloading}}	\\
-\begin{cfa}
-void p( int x, int y = 2, int z = 3 ) {...}
-
-
-\end{cfa}
-&
-\begin{cfa}
-void p( int x, int y, int z ) {...}
-void p( int x ) { p( x, 2, 3 ); }
-void p( int x, int y ) { p( x, y, 3 ); }
-\end{cfa}
-\end{tabular}
-\end{quote2}
-the number of required overloaded routines is linear in the number of default values, which is unacceptable growth.
-In general, overloading should only be used over default arguments if the body of the routine is significantly different.
-Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
-\begin{cfa}
-p( 1, /* default */, 5 );		§\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
-\end{cfa}
-
-Given the \CFA restrictions above, both named and default arguments are backwards compatible.
-\Index*[C++]{\CC{}} only supports default arguments;
-\Index*{Ada} supports both named and default arguments.
-
-
-\section{Unnamed Structure Fields}
-
-C requires each field of a structure to have a name, except for a bit field associated with a basic type, \eg:
-\begin{cfa}
-struct {
-	int f1;					§\C{// named field}§
-	int f2 : 4;				§\C{// named field with bit field size}§
-	int : 3;				§\C{// unnamed field for basic type with bit field size}§
-	int ;					§\C{// disallowed, unnamed field}§
-	int *;					§\C{// disallowed, unnamed field}§
-	int (*)( int );			§\C{// disallowed, unnamed field}§
-};
-\end{cfa}
-This requirement is relaxed by making the field name optional for all field declarations; therefore, all the field declarations in the example are allowed.
-As for unnamed bit fields, an unnamed field is used for padding a structure to a particular size.
-A list of unnamed fields is also supported, \eg:
-\begin{cfa}
-struct {
-	int , , ;				§\C{// 3 unnamed fields}§
-}
-\end{cfa}
-
-
-\section{Nesting}
-
-Nesting of types and routines is useful for controlling name visibility (\newterm{name hiding}).
-
-
-\subsection{Type Nesting}
-
-\CFA allows \Index{type nesting}, and type qualification of the nested types (see \VRef[Figure]{f:TypeNestingQualification}), where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
-\begin{figure}
-\centering
-\begin{tabular}{@{}l@{\hspace{3em}}l|l@{}}
-\multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}}	& \multicolumn{1}{c}{\textbf{C Implicit Hoisting}}	& \multicolumn{1}{|c}{\textbf{\CFA}}	\\
-\hline
-\begin{cfa}
-struct S {
-	enum C { R, G, B };
-	struct T {
-		union U { int i, j; };
-		enum C c;
-		short int i, j;
-	};
-	struct T t;
-} s;
-
-int fred() {
-	s.t.c = R;
-	struct T t = { R, 1, 2 };
-	enum C c;
-	union U u;
-}
-\end{cfa}
-&
-\begin{cfa}
-enum C { R, G, B };
-union U { int i, j; };
-struct T {
-	enum C c;
-	short int i, j;
-};
-struct S {
-	struct T t;
-} s;
-	
-
-
-
-
-
-
-\end{cfa}
-&
-\begin{cfa}
-struct S {
-	enum C { R, G, B };
-	struct T {
-		union U { int i, j; };
-		enum C c;
-		short int i, j;
-	};
-	struct T t;
-} s;
-
-int fred() {
-	s.t.c = ®S.®R;	// type qualification
-	struct ®S.®T t = { ®S.®R, 1, 2 };
-	enum ®S.®C c;
-	union ®S.T.®U u;
-}
-\end{cfa}
-\end{tabular}
-\caption{Type Nesting / Qualification}
-\label{f:TypeNestingQualification}
-\end{figure}
-In the left example in C, types ©C©, ©U© and ©T© are implicitly hoisted outside of type ©S© into the containing block scope.
-In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``©.©'' for type qualification, as does \Index*{Java}, rather than the \CC type-selection operator ``©::©''.
-
-
-\subsection{Routine Nesting}
-
-While \CFA does not provide object programming by putting routines into structures, it does rely heavily on locally nested routines to redefine operations at or close to a call site.
-For example, the C quick-sort is wrapped into the following polymorphic \CFA routine:
-\begin{cfa}
-forall( otype T | { int ?<?( T, T ); } )
-void qsort( const T * arr, size_t dimension );
-\end{cfa}
-which can be used to sort in ascending and descending order by locally redefining the less-than operator into greater-than.
-\begin{cfa}
-const unsigned int size = 5;
-int ia[size];
-...						§\C{// assign values to array ia}§
-qsort( ia, size );		§\C{// sort ascending order using builtin ?<?}§
-{
-	®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§
-	qsort( ia, size );	§\C{// sort descending order by local redefinition}§
-}
-\end{cfa}
-
-Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks;
-the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program.
-The following program in undefined in \CFA (and Indexc{gcc})
-\begin{cfa}
-[* [int]( int )] foo() {		§\C{// int (*foo())( int )}§
-	int ®i® = 7;
-	int bar( int p ) {
-		®i® += 1;				§\C{// dependent on local variable}§
-		sout | ®i® | endl;
-	}
-	return bar;					§\C{// undefined because of local dependence}§
-}
-int main() {
-	* [int]( int ) fp = foo();	§\C{// int (*fp)( int )}§
-	sout | fp( 3 ) | endl;
-}
-\end{cfa}
-because 
-
-Currently, there are no \Index{lambda} expressions, \ie unnamed routines because routine names are very important to properly select the correct routine.
-
-
-\section{Tuples}
-
-In C and \CFA, lists of elements appear in several contexts, such as the parameter list for a routine call.
-(More contexts are added shortly.)
-A list of such elements is called a \newterm{lexical list}.
-The general syntax of a lexical list is:
-\begin{cfa}
-[ §\emph{exprlist}§ ]
-\end{cfa}
-where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas.
-The brackets, ©[]©, allow differentiating between lexical lists and expressions containing the C comma operator.
-The following are examples of lexical lists:
-\begin{cfa}
-[ x, y, z ]
-[ 2 ]
-[ v+w, x*y, 3.14159, f() ]
-\end{cfa}
-Tuples are permitted to contain sub-tuples (\ie nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple.
-Note, a tuple is not a record (structure);
-a record denotes a single value with substructure, whereas a tuple is multiple values with no substructure (see flattening coercion in Section 12.1).
-In essence, tuples are largely a compile time phenomenon, having little or no runtime presence.
-
-Tuples can be organized into compile-time tuple variables;
-these variables are of \newterm{tuple type}.
-Tuple variables and types can be used anywhere lists of conventional variables and types can be used.
-The general syntax of a tuple type is:
-\begin{cfa}
-[ §\emph{typelist}§ ]
-\end{cfa}
-where ©$\emph{typelist}$© is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications.
-Examples of tuple types include:
-\begin{cfa}
-[ unsigned int, char ]
-[ double, double, double ]
-[ * int, int * ]		§\C{// mix of CFA and ANSI}§
-[ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ]
-\end{cfa}
-Like tuples, tuple types may be nested, such as ©[ [ int, int ], int ]©, which is a 2-element tuple type whose first element is itself a tuple type.
-
-Examples of declarations using tuple types are:
-\begin{cfa}
-[ int, int ] x;			§\C{// 2 element tuple, each element of type int}§
-* [ char, char ] y;		§\C{// pointer to a 2 element tuple}§
-[ [ int, int ] ] z ([ int, int ]);
-\end{cfa}
-The last example declares an external routine that expects a 2 element tuple as an input parameter and returns a 2 element tuple as its result.
-
-As mentioned, tuples can appear in contexts requiring a list of value, such as an argument list of a routine call.
-In unambiguous situations, the tuple brackets may be omitted, \eg a tuple that appears as an argument may have its
-square brackets omitted for convenience; therefore, the following routine invocations are equivalent:
-\begin{cfa}
-f( [ 1, x+2, fred() ] );
-f( 1, x+2, fred() );
-\end{cfa}
-Also, a tuple or a tuple variable may be used to supply all or part of an argument list for a routine expecting multiple input parameters or for a routine expecting a tuple as an input parameter.
-For example, the following are all legal:
-\begin{cfa}
-[ int, int ] w1;
-[ int, int, int ] w2;
-[ void ] f (int, int, int); /* three input parameters of type int */
-[ void ] g ([ int, int, int ]); /* 3 element tuple as input */
-f( [ 1, 2, 3 ] );
-f( w1, 3 );
-f( 1, w1 );
-f( w2 );
-g( [ 1, 2, 3 ] );
-g( w1, 3 );
-g( 1, w1 );
-g( w2 );
-\end{cfa}
-Note, in all cases 3 arguments are supplied even though the syntax may appear to supply less than 3. As mentioned, a
-tuple does not have structure like a record; a tuple is simply converted into a list of components.
-\begin{rationale}
-The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; \ie a statement such as ©g( f() )© is not supported.
-Using a temporary variable to store the  results of the inner routine and then passing this variable to the outer routine works, however.
-\end{rationale}
-
-A tuple can contain a C comma expression, provided the expression containing the comma operator is enclosed in parentheses.
-For instance, the following tuples are equivalent:
-\begin{cfa}
-[ 1, 3, 5 ]
-[ 1, (2, 3), 5 ]
-\end{cfa}
-The second element of the second tuple is the expression (2, 3), which yields the result 3.
-This requirement is the same as for comma expressions in argument lists.
-
-Type qualifiers, \ie const and volatile, may modify a tuple type.
-The meaning is the same as for a type qualifier modifying an aggregate type [Int99, x 6.5.2.3(7),x 6.7.3(11)], \ie the qualifier is distributed across all of the types in the tuple, \eg:
-\begin{cfa}
-const volatile [ int, float, const int ] x;
-\end{cfa}
-is equivalent to:
-\begin{cfa}
-[ const volatile int, const volatile float, const volatile int ] x;
-\end{cfa}
-Declaration qualifiers can only appear at the start of a \CFA tuple declaration4, \eg:
-\begin{cfa}
-extern [ int, int ] w1;
-static [ int, int, int ] w2;
-\end{cfa}
-\begin{rationale}
-Unfortunately, C's syntax for subscripts precluded treating them as tuples.
-The C subscript list has the form ©[i][j]...© and not ©[i, j, ...]©.
-Therefore, there is no syntactic way for a routine returning multiple values to specify the different subscript values, \eg ©f[g()]© always means a single subscript value because there is only one set of brackets.
-Fixing this requires a major change to C because the syntactic form ©M[i, j, k]© already has a particular meaning: ©i, j, k© is a comma expression.
-\end{rationale}
-
-
-\subsection{Tuple Coercions}
-
-There are four coercions that can be performed on tuples and tuple variables: closing, opening, flattening and structuring.
-In addition, the coercion of dereferencing can be performed on a tuple variable to yield its value(s), as for other variables.
-A \newterm{closing coercion} takes a set of values and converts it into a tuple value, which is a contiguous set of values, as in:
-\begin{cfa}
-[ int, int, int, int ] w;
-w = [ 1, 2, 3, 4 ];
-\end{cfa}
-First the right-hand tuple is closed into a tuple value and then the tuple value is assigned.
-
-An \newterm{opening coercion} is the opposite of closing; a tuple value is converted into a tuple of values, as in:
-\begin{cfa}
-[ a, b, c, d ] = w
-\end{cfa}
-©w© is implicitly opened to yield a tuple of four values, which are then assigned individually.
-
-A \newterm{flattening coercion} coerces a nested tuple, \ie a tuple with one or more components, which are themselves tuples, into a flattened tuple, which is a tuple whose components are not tuples, as in:
-\begin{cfa}
-[ a, b, c, d ] = [ 1, [ 2, 3 ], 4 ];
-\end{cfa}
-First the right-hand tuple is flattened and then the values are assigned individually.
-Flattening is also performed on tuple types.
-For example, the type ©[ int, [ int, int ], int ]© can be coerced, using flattening, into the type ©[ int, int, int, int ]©.
-
-A \newterm{structuring coercion} is the opposite of flattening;
-a tuple is structured into a more complex nested tuple.
-For example, structuring the tuple ©[ 1, 2, 3, 4 ]© into the tuple ©[ 1, [ 2, 3 ], 4 ]© or the tuple type ©[ int, int, int, int ]© into the tuple type ©[ int, [ int, int ], int ]©.
-In the following example, the last assignment illustrates all the tuple coercions:
-\begin{cfa}
-[ int, int, int, int ] w = [ 1, 2, 3, 4 ];
-int x = 5;
-[ x, w ] = [ w, x ];		§\C{// all four tuple coercions}§
-\end{cfa}
-Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values;
-therefore, the right-hand tuple is now the tuple ©[ [ 1, 2, 3, 4 ], 5 ]©.
-This tuple is then flattened, yielding ©[ 1, 2, 3, 4, 5 ]©, which is structured into ©[ 1, [ 2, 3, 4, 5 ] ]© to match the tuple type of the left-hand side.
-The tuple ©[ 2, 3, 4, 5 ]© is then closed to create a tuple value.
-Finally, ©x© is assigned ©1© and ©w© is assigned the tuple value using multiple assignment (see Section 14).
-\begin{rationale}
-A possible additional language extension is to use the structuring coercion for tuples to initialize a complex record with a tuple.
-\end{rationale}
-
-
-\section{Mass Assignment}
-
-\CFA permits assignment to several variables at once using mass assignment~\cite{CLU}.
-Mass assignment has the following form:
-\begin{cfa}
-[ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = §\emph{expr}§;
-\end{cfa}
-\index{lvalue}
-The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement.
-©$\emph{expr}$© is any standard arithmetic expression.
-Clearly, the types of the entities being assigned must be type compatible with the value of the expression.
-
-Mass assignment has parallel semantics, \eg the statement:
-\begin{cfa}
-[ x, y, z ] = 1.5;
-\end{cfa}
-is equivalent to:
-\begin{cfa}
-x = 1.5; y = 1.5; z = 1.5;
-\end{cfa}
-This semantics is not the same as the following in C:
-\begin{cfa}
-x = y = z = 1.5;
-\end{cfa}
-as conversions between intermediate assignments may lose information.
-A more complex example is:
-\begin{cfa}
-[ i, y[i], z ] = a + b;
-\end{cfa}
-which is equivalent to:
-\begin{cfa}
-t = a + b;
-a1 = &i; a2 = &y[i]; a3 = &z;
-*a1 = t; *a2 = t; *a3 = t;
-\end{cfa}
-The temporary ©t© is necessary to store the value of the expression to eliminate conversion issues.
-The temporaries for the addresses are needed so that locations on the left-hand side do not change as the values are assigned.
-In this case, ©y[i]© uses the previous value of ©i© and not the new value set at the beginning of the mass assignment.
-
-
-\section{Multiple Assignment}
-
-\CFA also supports the assignment of several values at once, known as multiple assignment~\cite{CLU,Galletly96}.
-Multiple assignment has the following form:
-\begin{cfa}
-[ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§ ];
-\end{cfa}
-\index{lvalue}
-The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
-Each \emph{expr} appearing on the right-hand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment.
-An example of multiple assignment is:
-\begin{cfa}
-[ x, y, z ] = [ 1, 2, 3 ];
-\end{cfa}
-Here, the values ©1©, ©2© and ©3© are assigned, respectively, to the variables ©x©, ©y© and ©z©.
- A more complex example is:
-\begin{cfa}
-[ i, y[ i ], z ] = [ 1, i, a + b ];
-\end{cfa}
-Here, the values ©1©, ©i© and ©a + b© are assigned to the variables ©i©, ©y[i]© and ©z©, respectively.
- Note, the parallel semantics of
-multiple assignment ensures:
-\begin{cfa}
-[ x, y ] = [ y, x ];
-\end{cfa}
-correctly interchanges (swaps) the values stored in ©x© and ©y©.
-The following cases are errors:
-\begin{cfa}
-[ a, b, c ] = [ 1, 2, 3, 4 ];
-[ a, b, c ] = [ 1, 2 ];
-\end{cfa}
-because the number of entities in the left-hand tuple is unequal with the right-hand tuple.
-
-As for all tuple contexts in C, side effects should not be used because C does not define an ordering for the evaluation of the elements of a tuple;
-both these examples produce indeterminate results:
-\begin{cfa}
-f( x++, x++ );				§\C{// C routine call with side effects in arguments}§
-[ v1, v2 ] = [ x++, x++ ];	§\C{// side effects in righthand side of multiple assignment}§
-\end{cfa}
-
-
-\section{Cascade Assignment}
-
-As in C, \CFA mass and multiple assignments can be cascaded, producing cascade assignment.
-Cascade assignment has the following form:
-\begin{cfa}
-§\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§;
-\end{cfa}
-and it has the same parallel semantics as for mass and multiple assignment.
-Some examples of cascade assignment are:
-\begin{cfa}
-x1 = y1 = x2 = y2 = 0;
-[ x1, y1 ] = [ x2, y2 ] = [ x3, y3 ];
-[ x1, y1 ] = [ x2, y2 ] = 0;
-[ x1, y1 ] = z = 0;
-\end{cfa}
-As in C, the rightmost assignment is performed first, \ie assignment parses right to left.
-
-
-\section{Field Tuples}
-
-Tuples may be used to select multiple fields of a record by field name.
-Its general form is:
-\begin{cfa}
-§\emph{expr}§ . [ §\emph{fieldlist}§ ]
-§\emph{expr}§ -> [ §\emph{fieldlist}§ ]
-\end{cfa}
-\emph{expr} is any expression yielding a value of type record, \eg ©struct©, ©union©.
-Each element of \emph{ fieldlist} is an element of the record specified by \emph{expr}.
-A record-field tuple may be used anywhere a tuple can be used. An example of the use of a record-field tuple is
-the following:
-\begin{cfa}
-struct s {
-	int f1, f2;
-	char f3;
-	double f4;
-} v;
-v.[ f3, f1, f2 ] = ['x', 11, 17 ];	§\C{// equivalent to v.f3 = 'x', v.f1 = 11, v.f2 = 17}§
-f( v.[ f3, f1, f2 ] );				§\C{// equivalent to f( v.f3, v.f1, v.f2 )}§
-\end{cfa}
-Note, the fields appearing in a record-field tuple may be specified in any order;
-also, it is unnecessary to specify all the fields of a struct in a multiple record-field tuple.
-
-If a field of a ©struct© is itself another ©struct©, multiple fields of this subrecord can be specified using a nested record-field tuple, as in the following example:
-\begin{cfa}
-struct inner {
-	int f2, f3;
-};
-struct outer {
-	int f1;
-	struct inner i;
-	double f4;
-} o;
-
-o.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
-\end{cfa}
 
 
@@ -2249,5 +780,5 @@
 still works.
 Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments.
-Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, e.g.:
+Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg:
 \begin{cfa}
 ®choose® ( i ) {
@@ -2397,4 +928,1504 @@
 
 
+\subsection{Exception Hierarchy}
+
+An exception type can be derived from another exception type, just like deriving a subclass from a class, providing a kind of polymorphism among exception types.
+The exception-type hierarchy that is created is used to organize exception types, similar to a class hierarchy in object-oriented languages, \eg:
+\begin{center}
+\input{EHMHierarchy}
+\end{center}
+A programmer can then choose to handle an exception at different degrees of specificity along the hierarchy;
+derived exception-types support a more flexible programming style.
+For example, higher-level code should catch general exceptions to reduce coupling to the specific implementation at the lower levels;
+unnecessary coupling may force changes in higher-level code when low-level code changes.
+A consequence of derived exception-types is that multiple exceptions may match, \eg:
+\begin{cfa}
+catch( Arithmetic )
+\end{cfa}
+matches all three derived exception-types: ©DivideByZero©, ©Overflow©, and ©Underflow©.
+Because the propagation mechanisms perform a simple linear search of the handler clause for a guarded block, and selects the first matching handler, the order of catch clauses in the handler clause becomes important, \eg:
+\begin{cfa}
+try {
+	...
+} catch( Overflow ) {	// must appear first
+	// handle overflow
+} catch( Arithmetic )
+	// handle other arithmetic issues
+}
+\end{cfa}
+\newterm{Multiple derivation} among exception is not supported.
+
+
+\section{Declarations}
+\label{s:Declarations}
+
+C declaration syntax is notoriously confusing and error prone.
+For example, many C programmers are confused by a declaration as simple as:
+\begin{quote2}
+\begin{tabular}{@{}ll@{}}
+\begin{cfa}
+int * x[5]
+\end{cfa}
+&
+\raisebox{-0.75\totalheight}{\input{Cdecl}}
+\end{tabular}
+\end{quote2}
+Is this an array of 5 pointers to integers or a \Index{pointer} to an array of 5 integers?
+The fact this declaration is unclear to many C programmers means there are \Index{productivity} and \Index{safety} issues even for basic programs.
+Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site.
+For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way:
+\begin{cfa}
+int ®(*®f®())[®5®]® {...};				§\C{definition}§
+ ... ®(*®f®())[®3®]® += 1;				§\C{usage}§
+\end{cfa}
+Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
+While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
+
+\CFA provides its own type, variable and routine declarations, using a different syntax.
+The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type.
+In the following example, \R{red} is the base type and \B{blue} is qualifiers.
+The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type.
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+ß[5] *ß ®int® x1;
+ß* [5]ß ®int® x2;
+ß[* [5] int]ß f®( int p )®;
+\end{cfa}
+&
+\begin{cfa}
+®int® ß*ß x1 ß[5]ß;
+®int® ß(*ßx2ß)[5]ß;
+ßint (*ßf®( int p )®ß)[5]ß;
+\end{cfa}
+\end{tabular}
+\end{quote2}
+The only exception is \Index{bit field} specification, which always appear to the right of the base type.
+% Specifically, the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array or function return value, and parentheses ©()© are used to indicate a routine parameter.
+However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
+For instance, variables ©x© and ©y© of type \Index{pointer} to integer are defined in \CFA as follows:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+®*® int x, y;
+\end{cfa}
+&
+\begin{cfa}
+int ®*®x, ®*®y;
+\end{cfa}
+\end{tabular}
+\end{quote2}
+The downside of this semantics is the need to separate regular and \Index{pointer} declarations:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+®*® int x;
+int y;
+\end{cfa}
+&
+\begin{cfa}
+int ®*®x, y;
+
+\end{cfa}
+\end{tabular}
+\end{quote2}
+which is \Index{prescribing} a safety benefit.
+Other examples are:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}}	\\
+\begin{cfa}
+[ 5 ] int z;
+[ 5 ] * char w;
+* [ 5 ] double v;
+struct s {
+	int f0:3;
+	* int f1;
+	[ 5 ] * int f2;
+};
+\end{cfa}
+&
+\begin{cfa}
+int z[ 5 ];
+char * w[ 5 ];
+double (* v)[ 5 ];
+struct s {
+	int f0:3;
+	int * f1;
+	int * f2[ 5 ]
+};
+\end{cfa}
+&
+\begin{cfa}
+// array of 5 integers
+// array of 5 pointers to char
+// pointer to array of 5 doubles
+
+// common bit field syntax
+
+
+
+\end{cfa}
+\end{tabular}
+\end{quote2}
+
+All type qualifiers, \eg ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, \eg:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}}
+\multicolumn{1}{c@{\hspace{1em}}}{\textbf{\CFA}}	& \multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}}	\\
+\begin{cfa}
+const * const int x;
+const * [ 5 ] const int y;
+\end{cfa}
+&
+\begin{cfa}
+int const * const x;
+const int (* const y)[ 5 ]
+\end{cfa}
+&
+\begin{cfa}
+// const pointer to const integer
+// const pointer to array of 5 const integers
+\end{cfa}
+\end{tabular}
+\end{quote2}
+All declaration qualifiers, \eg ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
+The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} \eg:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}}	\\
+\begin{cfa}
+extern [ 5 ] int x;
+static * const int y;
+\end{cfa}
+&
+\begin{cfa}
+int extern x[ 5 ];
+const int static * y;
+\end{cfa}
+&
+\begin{cfa}
+// externally visible array of 5 integers
+// internally visible pointer to constant int
+\end{cfa}
+\end{tabular}
+\end{quote2}
+
+The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+y = (®* int®)x;
+i = sizeof(®[ 5 ] * int®);
+\end{cfa}
+&
+\begin{cfa}
+y = (®int *®)x;
+i = sizeof(®int * [ 5 ]®);
+\end{cfa}
+\end{tabular}
+\end{quote2}
+
+Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
+Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
+Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems.
+
+
+\section{Pointer/Reference}
+
+C provides a \newterm{pointer type};
+\CFA adds a \newterm{reference type}.
+These types may be derived from an object or routine type, called the \newterm{referenced type}.
+Objects of these types contain an \newterm{address}, which is normally a location in memory, but may also address memory-mapped registers in hardware devices.
+An integer constant expression with the value 0, or such an expression cast to type ©void *©, is called a \newterm{null-pointer constant}.\footnote{
+One way to conceptualize the null pointer is that no variable is placed at this address, so the null-pointer address can be used to denote an uninitialized pointer/reference object;
+\ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine.}
+An address is \newterm{sound}, if it points to a valid memory location in scope, \ie within the program's execution-environment and has not been freed.
+Dereferencing an \newterm{unsound} address, including the null pointer, is \Index{undefined}, often resulting in a \Index{memory fault}.
+
+A program \newterm{object} is a region of data storage in the execution environment, the contents of which can represent values.
+In most cases, objects are located in memory at an address, and the variable name for an object is an implicit address to the object generated by the compiler and automatically dereferenced, as in:
+\begin{quote2}
+\begin{tabular}{@{}ll@{\hspace{2em}}l@{}}
+\begin{cfa}
+int x;
+x = 3;
+int y;
+y = x;
+\end{cfa}
+&
+\raisebox{-0.45\totalheight}{\input{pointer1}}
+&
+\begin{cfa}
+int * ®const® x = (int *)100
+*x = 3;			// implicit dereference
+int * ®const® y = (int *)104;
+*y = *x;		// implicit dereference
+\end{cfa}
+\end{tabular}
+\end{quote2}
+where the right example is how the compiler logically interprets the variables in the left example.
+Since a variable name only points to one address during its lifetime, it is an \Index{immutable} \Index{pointer};
+hence, the implicit type of pointer variables ©x© and ©y© are constant pointers in the compiler interpretation.
+In general, variable addresses are stored in instructions instead of loaded from memory, and hence may not occupy storage.
+These approaches are contrasted in the following:
+\begin{quote2}
+\begin{tabular}{@{}l|l@{}}
+\multicolumn{1}{c|}{explicit variable address} & \multicolumn{1}{c}{implicit variable address} \\
+\hline
+\begin{cfa}
+lda		r1,100			// load address of x
+ld		 r2,(r1)		  // load value of x
+lda		r3,104			// load address of y
+st		 r2,(r3)		  // store x into y
+\end{cfa}
+&
+\begin{cfa}
+
+ld		r2,(100)		// load value of x
+
+st		r2,(104)		// store x into y
+\end{cfa}
+\end{tabular}
+\end{quote2}
+Finally, the immutable nature of a variable's address and the fact that there is no storage for the variable pointer means pointer assignment\index{pointer!assignment}\index{assignment!pointer} is impossible.
+Therefore, the expression ©x = y© has only one meaning, ©*x = *y©, \ie manipulate values, which is why explicitly writing the dereferences is unnecessary even though it occurs implicitly as part of \Index{instruction decoding}.
+
+A \Index{pointer}/\Index{reference} object is a generalization of an object variable-name, \ie a mutable address that can point to more than one memory location during its lifetime.
+(Similarly, an integer variable can contain multiple integer literals during its lifetime versus an integer constant representing a single literal during its lifetime, and like a variable name, may not occupy storage if the literal is embedded directly into instructions.)
+Hence, a pointer occupies memory to store its current address, and the pointer's value is loaded by dereferencing, \eg:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{2em}}l@{}}
+\begin{cfa}
+int x, y, ®*® p1, ®*® p2, ®**® p3;
+p1 = ®&®x;		 // p1 points to x
+p2 = p1;		 // p2 points to x
+p1 = ®&®y;		 // p1 points to y
+p3 = &p2;		// p3 points to p2
+\end{cfa}
+&
+\raisebox{-0.5\totalheight}{\input{pointer2.pstex_t}}
+\end{tabular}
+\end{quote2}
+
+Notice, an address has a \Index{duality}\index{address!duality}: a location in memory or the value at that location.
+In many cases, a compiler might be able to infer the best meaning for these two cases.
+For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage
+\begin{cfa}
+p2 = p1 + x;					§\C{// compiler infers *p2 = *p1 + x;}§
+\end{cfa}
+Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
+Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices. 
+
+Rather than inferring dereference, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality.
+In C, objects of pointer type always manipulate the pointer object's address:
+\begin{cfa}
+p1 = p2;						§\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
+p2 = p1 + x;					§\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
+\end{cfa}
+even though the assignment to ©p2© is likely incorrect, and the programmer probably meant:
+\begin{cfa}
+p1 = p2;						§\C{// pointer address assignment}§
+®*®p2 = ®*®p1 + x;				§\C{// pointed-to value assignment / operation}§
+\end{cfa}
+The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).
+
+However, in most other situations, the pointed-to value is requested more often than the pointer address.
+\begin{cfa}
+*p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15);
+\end{cfa}
+In this case, it is tedious to explicitly write the dereferencing, and error prone when pointer arithmetic is allowed.
+It is better to have the compiler generate the dereferencing and have no implicit pointer arithmetic:
+\begin{cfa}
+p2 = ((p1 + p2) * (p3 - p1)) / (p3 - 15);
+\end{cfa}
+
+To support this common case, a reference type is introduced in \CFA, denoted by ©&©, which is the opposite dereference semantics to a pointer type, making the value at the pointed-to location the implicit semantics for dereferencing (similar but not the same as \CC \Index{reference type}s).
+\begin{cfa}
+int x, y, ®&® r1, ®&® r2, ®&&® r3;
+®&®r1 = &x;						§\C{// r1 points to x}§
+®&®r2 = &r1;					§\C{// r2 points to x}§
+®&®r1 = &y;						§\C{// r1 points to y}§
+®&&®r3 = ®&®&r2;				§\C{// r3 points to r2}§
+r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§
+\end{cfa}
+Except for auto-dereferencing by the compiler, this reference example is the same as the previous pointer example.
+Hence, a reference behaves like the variable name for the current variable it is pointing-to.
+One way to conceptualize a reference is via a rewrite rule, where the compiler inserts a dereference operator before the reference variable for each reference qualifier in a declaration, so the previous example becomes:
+\begin{cfa}
+®*®r2 = ((®*®r1 + ®*®r2) ®*® (®**®r3 - ®*®r1)) / (®**®r3 - 15);
+\end{cfa}
+When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out.
+However, in C, the cancellation always yields a value (\Index{rvalue}).\footnote{
+The unary ©&© operator yields the address of its operand.
+If the operand has type ``type'', the result has type ``pointer to type''.
+If the operand is the result of a unary ©*© operator, neither that operator nor the ©&© operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue.~\cite[\S~6.5.3.2--3]{C11}}
+For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}):
+\begin{cfa}
+(&®*®)r1 = &x;					§\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
+\end{cfa}
+Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}):
+\begin{cfa}
+(&(&®*®)®*®)r3 = &(&®*®)r2;		§\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
+\end{cfa}
+Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth.
+
+Fundamentally, pointer and reference objects are functionally interchangeable because both contain addresses.
+\begin{cfa}
+int x, *p1 = &x, **p2 = &p1, ***p3 = &p2,
+		 &r1 = x,    &&r2 = r1,   &&&r3 = r2;
+***p3 = 3;						§\C{// change x}§
+r3 = 3;							§\C{// change x, ***r3}§
+**p3 = ...;						§\C{// change p1}§
+&r3 = ...;						§\C{// change r1, (\&*)**r3, 1 cancellation}§
+*p3 = ...;						§\C{// change p2}§
+&&r3 = ...;						§\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
+&&&r3 = p3;						§\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
+\end{cfa}
+Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types.
+Therefore, the choice between them is based solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of implicit dereferencing aid from the compiler.
+
+As for a pointer type, a reference type may have qualifiers:
+\begin{cfa}
+const int cx = 5;					§\C{// cannot change cx;}§
+const int & cr = cx;				§\C{// cannot change what cr points to}§
+®&®cr = &cx;						§\C{// can change cr}§
+cr = 7;								§\C{// error, cannot change cx}§
+int & const rc = x;					§\C{// must be initialized}§
+®&®rc = &x;							§\C{// error, cannot change rc}§
+const int & const crc = cx;			§\C{// must be initialized}§
+crc = 7;							§\C{// error, cannot change cx}§
+®&®crc = &cx;						§\C{// error, cannot change crc}§
+\end{cfa}
+Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}:
+\begin{cfa}
+int & const cr = *0;				§\C{// where 0 is the int * zero}§
+\end{cfa}
+Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management:
+\begin{cfa}
+int & const cr = *malloc();
+cr = 5;
+free( &cr );
+cr = 7;								§\C{// unsound pointer dereference}§
+\end{cfa}
+
+The position of the ©const© qualifier \emph{after} the pointer/reference qualifier causes confuse for C programmers.
+The ©const© qualifier cannot be moved before the pointer/reference qualifier for C style-declarations;
+\CFA-style declarations (see \VRef{s:Declarations}) attempt to address this issue:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+®const® * ®const® * const int ccp;
+®const® & ®const® & const int ccr;
+\end{cfa}
+&
+\begin{cfa}
+const int * ®const® * ®const® ccp;
+
+\end{cfa}
+\end{tabular}
+\end{quote2}
+where the \CFA declaration is read left-to-right.
+
+Finally, like pointers, references are usable and composable with other type operators and generators.
+\begin{cfa}
+int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§
+&ar[1] = &w;						§\C{// change reference array element}§
+typeof( ar[1] ) p;					§\C{// (gcc) is int, i.e., the type of referenced object}§
+typeof( &ar[1] ) q;					§\C{// (gcc) is int \&, i.e., the type of reference}§
+sizeof( ar[1] ) == sizeof( int );	§\C{// is true, i.e., the size of referenced object}§
+sizeof( &ar[1] ) == sizeof( int *)	§\C{// is true, i.e., the size of a reference}§
+\end{cfa}
+
+In contrast to \CFA reference types, \Index*[C++]{\CC{}}'s reference types are all ©const© references, preventing changes to the reference address, so only value assignment is possible, which eliminates half of the \Index{address duality}.
+Also, \CC does not allow \Index{array}s\index{array!reference} of reference\footnote{
+The reason for disallowing arrays of reference is unknown, but possibly comes from references being ethereal (like a textual macro), and hence, replaceable by the referant object.}
+\Index*{Java}'s reference types to objects (all Java objects are on the heap) are like C pointers, which always manipulate the address, and there is no (bit-wise) object assignment, so objects are explicitly cloned by shallow or deep copying, which eliminates half of the address duality.
+
+
+\subsection{Initialization}
+
+\Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
+There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
+Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
+In contrast, the left-hand side of assignment has an address that has a duality.
+Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
+\begin{cfa}
+int * p = &x;						§\C{// assign address of x}§
+®int * p = x;®						§\C{// assign value of x}§
+int & r = x;						§\C{// must have address of x}§
+\end{cfa}
+Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
+Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
+Note, this is strictly a convenience and safety feature for a programmer.
+Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
+Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
+Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
+\begin{cfa}
+int & f( int & r );					§\C{// reference parameter and return}§
+z = f( x ) + f( y );				§\C{// reference operator added, temporaries needed for call results}§
+\end{cfa}
+Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
+Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
+\begin{cfa}
+int temp1 = f( x ), temp2 = f( y );
+z = temp1 + temp2;
+\end{cfa}
+This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
+otherwise references have the same syntactic  burden as pointers in these contexts.
+
+When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
+\begin{cfa}
+void f( ®const® int & cr );
+void g( ®const® int * cp );
+f( 3 );			  g( ®&®3 );
+f( x + y );		g( ®&®(x + y) );
+\end{cfa}
+Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
+The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
+Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
+
+\CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
+If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
+\begin{cfa}
+void f( int & r );
+void g( int * p );
+f( 3 );			  g( ®&®3 );		§\C{// compiler implicit generates temporaries}§
+f( x + y );		g( ®&®(x + y) );	§\C{// compiler implicit generates temporaries}§
+\end{cfa}
+Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
+This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
+The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
+
+%\CFA attempts to handle pointers and references in a uniform, symmetric manner.
+Finally, C handles \Index{routine object}s in an inconsistent way.
+A routine object is both a pointer and a reference (\Index{particle and wave}).
+\begin{cfa}
+void f( int i );
+void (*fp)( int );					§\C{// routine pointer}§
+fp = f;								§\C{// reference initialization}§
+fp = &f;							§\C{// pointer initialization}§
+fp = *f;							§\C{// reference initialization}§
+fp(3);								§\C{// reference invocation}§
+(*fp)(3);							§\C{// pointer invocation}§
+\end{cfa}
+While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
+Instead, a routine object should be referenced by a ©const© reference:
+\begin{cfa}
+®const® void (®&® fr)( int ) = f;	§\C{// routine reference}§
+fr = ...							§\C{// error, cannot change code}§
+&fr = ...;							§\C{// changing routine reference}§
+fr( 3 );							§\C{// reference call to f}§
+(*fr)(3);							§\C{// error, incorrect type}§
+\end{cfa}
+because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
+Dynamic code rewriting is possible but only in special circumstances.}
+\CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
+
+
+\subsection{Address-of Semantics}
+
+In C, ©&E© is an rvalue for any expression ©E©.
+\CFA extends the ©&© (address-of) operator as follows:
+\begin{itemize}
+\item
+if ©R© is an \Index{rvalue} of type ©T &$_1$...&$_r$© where $r \ge 1$ references (©&© symbols) than ©&R© has type ©T ®*®&$_{\color{red}2}$...&$_{\color{red}r}$©, \ie ©T© pointer with $r-1$ references (©&© symbols).
+
+\item
+if ©L© is an \Index{lvalue} of type ©T &$_1$...&$_l$© where $l \ge 0$ references (©&© symbols) then ©&L© has type ©T ®*®&$_{\color{red}1}$...&$_{\color{red}l}$©, \ie ©T© pointer with $l$ references (©&© symbols).
+\end{itemize}
+The following example shows the first rule applied to different \Index{rvalue} contexts:
+\begin{cfa}
+int x, * px, ** ppx, *** pppx, **** ppppx;
+int & rx = x, && rrx = rx, &&& rrrx = rrx ;
+x = rrrx;		// rrrx is an lvalue with type int &&& (equivalent to x)
+px = &rrrx;		// starting from rrrx, &rrrx is an rvalue with type int *&&& (&x)
+ppx = &&rrrx;	// starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx)
+pppx = &&&rrrx;	// starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx)
+ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx)
+\end{cfa}
+The following example shows the second rule applied to different \Index{lvalue} contexts:
+\begin{cfa}
+int x, * px, ** ppx, *** pppx;
+int & rx = x, && rrx = rx, &&& rrrx = rrx ;
+rrrx = 2;		// rrrx is an lvalue with type int &&& (equivalent to x)
+&rrrx = px;		// starting from rrrx, &rrrx is an rvalue with type int *&&& (rx)
+&&rrrx = ppx;	// starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx)
+&&&rrrx = pppx;	// starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx)
+\end{cfa}
+
+
+\subsection{Conversions}
+
+C provides a basic implicit conversion to simplify variable usage:
+\begin{enumerate}
+\setcounter{enumi}{-1}
+\item
+lvalue to rvalue conversion: ©cv T© converts to ©T©, which allows implicit variable dereferencing.
+\begin{cfa}
+int x;
+x + 1;			// lvalue variable (int) converts to rvalue for expression
+\end{cfa}
+An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped.
+\end{enumerate}
+\CFA provides three new implicit conversion for reference types to simplify reference usage.
+\begin{enumerate}
+\item
+reference to rvalue conversion: ©cv T &© converts to ©T©, which allows implicit reference dereferencing.
+\begin{cfa}
+int x, &r = x, f( int p );
+x = ®r® + f( ®r® );  // lvalue reference converts to rvalue
+\end{cfa}
+An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped.
+
+\item
+lvalue to reference conversion: \lstinline[deletekeywords={lvalue}]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references.
+\begin{cfa}
+int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &)
+f( ®x® );		// lvalue variable (int) convert to reference (int &)
+\end{cfa}
+Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost.
+Conversion can expand a type, where ©cv1© $>$ ©cv2©, \eg passing a ©const volatile int© to an ©int &©, which has high cost (\Index{warning});
+furthermore, if ©cv1© has ©const© but not ©cv2©, a temporary variable is created to preserve the immutable lvalue.
+
+\item
+rvalue to reference conversion: ©T© converts to ©cv T &©, which allows binding references to temporaries.
+\begin{cfa}
+int x, & f( int & p );
+f( ®x + 3® );	// rvalue parameter (int) implicitly converts to lvalue temporary reference (int &)
+®&f®(...) = &x;	// rvalue result (int &) implicitly converts to lvalue temporary reference (int &)
+\end{cfa}
+In both case, modifications to the temporary are inaccessible (\Index{warning}).
+Conversion expands the temporary-type with ©cv©, which is low cost since the temporary is inaccessible.
+\end{enumerate}
+
+
+\begin{comment}
+From: Richard Bilson <rcbilson@gmail.com>
+Date: Wed, 13 Jul 2016 01:58:58 +0000
+Subject: Re: pointers / references
+To: "Peter A. Buhr" <pabuhr@plg2.cs.uwaterloo.ca>
+
+As a general comment I would say that I found the section confusing, as you move back and forth
+between various real and imagined programming languages. If it were me I would rewrite into two
+subsections, one that specifies precisely the syntax and semantics of reference variables and
+another that provides the rationale.
+
+I don't see any obvious problems with the syntax or semantics so far as I understand them. It's not
+obvious that the description you're giving is complete, but I'm sure you'll find the special cases
+as you do the implementation.
+
+My big gripes are mostly that you're not being as precise as you need to be in your terminology, and
+that you say a few things that aren't actually true even though I generally know what you mean.
+
+20 C provides a pointer type; CFA adds a reference type. Both types contain an address, which is normally a
+21 location in memory.
+
+An address is not a location in memory; an address refers to a location in memory. Furthermore it
+seems weird to me to say that a type "contains" an address; rather, objects of that type do.
+
+21 Special addresses are used to denote certain states or access co-processor memory. By
+22 convention, no variable is placed at address 0, so addresses like 0, 1, 2, 3 are often used to denote no-value
+23 or other special states.
+
+This isn't standard C at all. There has to be one null pointer representation, but it doesn't have
+to be a literal zero representation and there doesn't have to be more than one such representation.
+
+23 Often dereferencing a special state causes a memory fault, so checking is necessary
+24 during execution.
+
+I don't see the connection between the two clauses here. I feel like if a bad pointer will not cause
+a memory fault then I need to do more checking, not less.
+
+24 If the programming language assigns addresses, a program's execution is sound, \ie all
+25 addresses are to valid memory locations.
+
+You haven't said what it means to "assign" an address, but if I use my intuitive understanding of
+the term I don't see how this can be true unless you're assuming automatic storage management.
+
+1 Program variables are implicit pointers to memory locations generated by the compiler and automatically
+2 dereferenced, as in:
+
+There is no reason why a variable needs to have a location in memory, and indeed in a typical
+program many variables will not. In standard terminology an object identifier refers to data in the
+execution environment, but not necessarily in memory.
+
+13 A pointer/reference is a generalization of a variable name, \ie a mutable address that can point to more
+14 than one memory location during its lifetime.
+
+I feel like you're off the reservation here. In my world there are objects of pointer type, which
+seem to be what you're describing here, but also pointer values, which can be stored in an object of
+pointer type but don't necessarily have to be. For example, how would you describe the value denoted
+by "&main" in a C program? I would call it a (function) pointer, but that doesn't satisfy your
+definition.
+
+16 not occupy storage as the literal is embedded directly into instructions.) Hence, a pointer occupies memory
+17 to store its current address, and the pointer's value is loaded by dereferencing, \eg:
+
+As with my general objection regarding your definition of variables, there is no reason why a
+pointer variable (object of pointer type) needs to occupy memory.
+
+21 p2 = p1 + x; // compiler infers *p2 = *p1 + x;
+
+What language are we in now?
+
+24 pointer usage. However, in C, the following cases are ambiguous, especially with pointer arithmetic:
+25 p1 = p2; // p1 = p2 or *p1 = *p2
+
+This isn't ambiguous. it's defined to be the first option.
+
+26 p1 = p1 + 1; // p1 = p1 + 1 or *p1 = *p1 + 1
+
+Again, this statement is not ambiguous.
+
+13 example. Hence, a reference behaves like the variable name for the current variable it is pointing-to. The
+14 simplest way to understand a reference is to imagine the compiler inserting a dereference operator before
+15 the reference variable for each reference qualifier in a declaration, \eg:
+
+It's hard for me to understand who the audience for this part is. I think a practical programmer is
+likely to be satisfied with "a reference behaves like the variable name for the current variable it
+is pointing-to," maybe with some examples. Your "simplest way" doesn't strike me as simpler than
+that. It feels like you're trying to provide a more precise definition for the semantics of
+references, but it isn't actually precise enough to be a formal specification. If you want to
+express the semantics of references using rewrite rules that's a great way to do it, but lay the
+rules out clearly, and when you're showing an example of rewriting keep your
+references/pointers/values separate (right now, you use \eg "r3" to mean a reference, a pointer,
+and a value).
+
+24 Cancellation works to arbitrary depth, and pointer and reference values are interchangeable because both
+25 contain addresses.
+
+Except they're not interchangeable, because they have different and incompatible types.
+
+40 Interestingly, C++ deals with the address duality by making the pointed-to value the default, and prevent-
+41 ing changes to the reference address, which eliminates half of the duality. Java deals with the address duality
+42 by making address assignment the default and requiring field assignment (direct or indirect via methods),
+43 \ie there is no builtin bit-wise or method-wise assignment, which eliminates half of the duality.
+
+I can follow this but I think that's mostly because I already understand what you're trying to
+say. I don't think I've ever heard the term "method-wise assignment" and I don't see you defining
+it. Furthermore Java does have value assignment of basic (non-class) types, so your summary here
+feels incomplete. (If it were me I'd drop this paragraph rather than try to save it.)
+
+11 Hence, for type & const, there is no pointer assignment, so &rc = &x is disallowed, and the address value
+12 cannot be 0 unless an arbitrary pointer is assigned to the reference.
+
+Given the pains you've taken to motivate every little bit of the semantics up until now, this last
+clause ("the address value cannot be 0") comes out of the blue. It seems like you could have
+perfectly reasonable semantics that allowed the initialization of null references.
+
+12 In effect, the compiler is managing the
+13 addresses for type & const not the programmer, and by a programming discipline of only using references
+14 with references, address errors can be prevented.
+
+Again, is this assuming automatic storage management?
+
+18 rary binding. For reference initialization (like pointer), the initializing value must be an address (lvalue) not
+19 a value (rvalue).
+
+This sentence appears to suggest that an address and an lvalue are the same thing.
+
+20 int * p = &x; // both &x and x are possible interpretations
+
+Are you saying that we should be considering "x" as a possible interpretation of the initializer
+"&x"? It seems to me that this expression has only one legitimate interpretation in context.
+
+21 int & r = x; // x unlikely interpretation, because of auto-dereferencing
+
+You mean, we can initialize a reference using an integer value? Surely we would need some sort of
+cast to induce that interpretation, no?
+
+22 Hence, the compiler implicitly inserts a reference operator, &, before the initialization expression.
+
+But then the expression would have pointer type, which wouldn't be compatible with the type of r.
+
+22 Similarly,
+23 when a reference is used for a parameter/return type, the call-site argument does not require a reference
+24 operator.
+
+Furthermore, it would not be correct to use a reference operator.
+
+45 The implicit conversion allows
+1 seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
+2 While C' attempts to handle pointers and references in a uniform, symmetric manner, C handles routine
+3 variables in an inconsistent way: a routine variable is both a pointer and a reference (particle and wave).
+
+After all this talk of how expressions can have both pointer and value interpretations, you're
+disparaging C because it has expressions that have both pointer and value interpretations?
+
+On Sat, Jul 9, 2016 at 4:18 PM Peter A. Buhr <pabuhr@plg.uwaterloo.ca> wrote:
+> Aaron discovered a few places where "&"s are missing and where there are too many "&", which are
+> corrected in the attached updated. None of the text has changed, if you have started reading
+> already.
+\end{comment}
+
+
+\section{Routine Definition}
+
+\CFA also supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
+The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
+\begin{cfa}
+®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) {
+	§\emph{routine body}§
+}
+\end{cfa}
+where routine ©f© has three output (return values) and three input parameters.
+Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type specifications.
+
+In detail, the brackets, ©[]©, enclose the result type, where each return value is named and that name is a local variable of the particular return type.\footnote{
+\Index*{Michael Tiemann}, with help from \Index*{Doug Lea}, provided named return values in g++, circa 1989.}
+The value of each local return variable is automatically returned at routine termination.
+Declaration qualifiers can only appear at the start of a routine definition, \eg:
+\begin{cfa}
+®extern® [ int x ] g( int y ) {§\,§}
+\end{cfa}
+Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified;
+in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
+\begin{cfa}
+[§\,§] g();							§\C{// no input or output parameters}§
+[ void ] g( void );					§\C{// no input or output parameters}§
+\end{cfa}
+
+Routine f is called as follows:
+\begin{cfa}
+[ i, j, ch ] = f( 3, 'a', ch );
+\end{cfa}
+The list of return values from f and the grouping on the left-hand side of the assignment is called a \newterm{return list} and discussed in Section 12.
+
+\CFA style declarations cannot be used to declare parameters for K\&R style routine definitions because of the following ambiguity:
+\begin{cfa}
+int (*f(x))[ 5 ] int x; {}
+\end{cfa}
+The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter x of type array of 5 integers.
+Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string.
+As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity:
+\begin{cfa}
+typedef int foo;
+int f( int (* foo) );				§\C{// foo is redefined as a parameter name}§
+\end{cfa}
+The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
+The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name.
+The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.
+
+C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
+\begin{cfa}
+[ int ] f( * int, int * );			§\C{// returns an integer, accepts 2 pointers to integers}§
+[ * int, int * ] f( int );			§\C{// returns 2 pointers to integers, accepts an integer}§
+\end{cfa}
+The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
+\begin{cfa}
+#define ptoa( n, d ) int (*n)[ d ]
+int f( ptoa( p, 5 ) ) ...			§\C{// expands to int f( int (*p)[ 5 ] )}§
+[ int ] f( ptoa( p, 5 ) ) ...		§\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
+\end{cfa}
+Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
+
+
+\subsection{Named Return Values}
+
+\Index{Named return values} handle the case where it is necessary to define a local variable whose value is then returned in a ©return© statement, as in:
+\begin{cfa}
+int f() {
+	int x;
+	... x = 0; ... x = y; ...
+	return x;
+}
+\end{cfa}
+Because the value in the return variable is automatically returned when a \CFA routine terminates, the ©return© statement \emph{does not} contain an expression, as in:
+\newline
+\begin{minipage}{\linewidth}
+\begin{cfa}
+®[ int x, int y ]® f() {
+	int z;
+	... x = 0; ... y = z; ...
+	®return;®							§\C{// implicitly return x, y}§
+}
+\end{cfa}
+\end{minipage}
+\newline
+When the return is encountered, the current values of ©x© and ©y© are returned to the calling routine.
+As well, ``falling off the end'' of a routine without a ©return© statement is permitted, as in:
+\begin{cfa}
+[ int x, int y ] f() {
+	...
+}										§\C{// implicitly return x, y}§
+\end{cfa}
+In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
+
+Named return values may be used in conjunction with named parameter values;
+specifically, a return and parameter can have the same name.
+\begin{cfa}
+[ int x, int y ] f( int, x, int y ) {
+	...
+}										§\C{// implicitly return x, y}§
+\end{cfa}
+This notation allows the compiler to eliminate temporary variables in nested routine calls.
+\begin{cfa}
+[ int x, int y ] f( int, x, int y );	§\C{// prototype declaration}§
+int a, b;
+[a, b] = f( f( f( a, b ) ) );
+\end{cfa}
+While the compiler normally ignores parameters names in prototype declarations, here they are used to eliminate temporary return-values by inferring that the results of each call are the inputs of the next call, and ultimately, the left-hand side of the assignment.
+Hence, even without the body of routine ©f© (separate compilation), it is possible to perform a global optimization across routine calls.
+The compiler warns about naming inconsistencies between routine prototype and definition in this case, and behaviour is \Index{undefined} if the programmer is inconsistent.
+
+
+\subsection{Routine Prototype}
+
+The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
+as well, parameter names are optional, \eg:
+\begin{cfa}
+[ int x ] f ();							§\C{// returning int with no parameters}§
+[ * int ] g (int y);					§\C{// returning pointer to int with int parameter}§
+[ ] h ( int, char );					§\C{// returning no result with int and char parameters}§
+[ * int, int ] j ( int );				§\C{// returning pointer to int and int, with int parameter}§
+\end{cfa}
+This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
+It is possible to declare multiple routine-prototypes in a single declaration, but the entire type specification is distributed across \emph{all} routine names in the declaration list (see~\VRef{s:Declarations}), \eg:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+[ int ] f( int ), g;
+\end{cfa}
+&
+\begin{cfa}
+int f( int ), g( int );
+\end{cfa}
+\end{tabular}
+\end{quote2}
+Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
+\begin{cfa}
+extern [ int ] f ( int );
+static [ int ] g ( int );
+\end{cfa}
+
+
+\section{Routine Pointers}
+
+The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
+\begin{cfa}
+* [ int x ] () fp;						§\C{// pointer to routine returning int with no parameters}§
+* [ * int ] (int y) gp;					§\C{// pointer to routine returning pointer to int with int parameter}§
+* [ ] (int,char) hp;					§\C{// pointer to routine returning no result with int and char parameters}§
+* [ * int,int ] ( int ) jp;				§\C{// pointer to routine returning pointer to int and int, with int parameter}§
+\end{cfa}
+While parameter names are optional, \emph{a routine name cannot be specified};
+for example, the following is incorrect:
+\begin{cfa}
+* [ int x ] f () fp;					§\C{// routine name "f" is not allowed}§
+\end{cfa}
+
+
+\section{Named and Default Arguments}
+
+Named\index{named arguments}\index{arguments!named} and default\index{default arguments}\index{arguments!default} arguments~\cite{Hardgrave76}\footnote{
+Francez~\cite{Francez77} proposed a further extension to the named-parameter passing style, which specifies what type of communication (by value, by reference, by name) the argument is passed to the routine.}
+are two mechanisms to simplify routine call.
+Both mechanisms are discussed with respect to \CFA.
+\begin{description}
+\item[Named (or Keyword) Arguments:]
+provide the ability to specify an argument to a routine call using the parameter name rather than the position of the parameter.
+For example, given the routine:
+\begin{cfa}
+void p( int x, int y, int z ) {...}
+\end{cfa}
+a positional call is:
+\begin{cfa}
+p( 4, 7, 3 );
+\end{cfa}
+whereas a named (keyword) call may be:
+\begin{cfa}
+p( z : 3, x : 4, y : 7 ); 	§\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
+\end{cfa}
+Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
+The compiler rewrites a named call into a positional call.
+The advantages of named parameters are:
+\begin{itemize}
+\item
+Remembering the names of the parameters may be easier than the order in the routine definition.
+\item
+Parameter names provide documentation at the call site (assuming the names are descriptive).
+\item
+Changes can be made to the order or number of parameters without affecting the call (although the call must still be recompiled).
+\end{itemize}
+
+Unfortunately, named arguments do not work in C-style programming-languages because a routine prototype is not required to specify parameter names, nor do the names in the prototype have to match with the actual definition.
+For example, the following routine prototypes and definition are all valid.
+\begin{cfa}
+void p( int, int, int );			§\C{// equivalent prototypes}§
+void p( int x, int y, int z );
+void p( int y, int x, int z );
+void p( int z, int y, int x );
+void p( int q, int r, int s ) {}	§\C{// match with this definition}§
+\end{cfa}
+Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming.
+Alternatively, prototype definitions can be eliminated by using a two-pass compilation, and implicitly creating header files for exports.
+The former is easy to do, while the latter is more complex.
+
+Furthermore, named arguments do not work well in a \CFA-style programming-languages because they potentially introduces a new criteria for type matching.
+For example, it is technically possible to disambiguate between these two overloaded definitions of ©f© based on named arguments at the call site:
+\begin{cfa}
+int f( int i, int j );
+int f( int x, double y );
+
+f( j : 3, i : 4 );				§\C{// 1st f}§
+f( x : 7, y : 8.1 );			§\C{// 2nd f}§
+f( 4, 5 ); 						§\C{// ambiguous call}§
+\end{cfa}
+However, named arguments compound routine resolution in conjunction with conversions:
+\begin{cfa}
+f( i : 3, 5.7 );				§\C{// ambiguous call ?}§
+\end{cfa}
+Depending on the cost associated with named arguments, this call could be resolvable or ambiguous.
+Adding named argument into the routine resolution algorithm does not seem worth the complexity.
+Therefore, \CFA does \emph{not} attempt to support named arguments.
+
+\item[Default Arguments]
+provide the ability to associate a default value with a parameter so it can be optionally specified in the argument list.
+For example, given the routine:
+\begin{cfa}
+void p( int x = 1, int y = 2, int z = 3 ) {...}
+\end{cfa}
+the allowable positional calls are:
+\begin{cfa}
+p();							§\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
+p( 4 );							§\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
+p( 4, 4 );						§\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
+p( 4, 4, 4 );					§\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
+// empty arguments
+p(  , 4, 4 );					§\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
+p( 4,  , 4 );					§\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
+p( 4, 4,   );					§\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
+p( 4,  ,   );					§\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
+p(  , 4,   );					§\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
+p(  ,  , 4 );					§\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
+p(  ,  ,   );					§\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
+\end{cfa}
+Here the missing arguments are inserted from the default values in the parameter list.
+The compiler rewrites missing default values into explicit positional arguments.
+The advantages of default values are:
+\begin{itemize}
+\item
+Routines with a large number of parameters are often very generalized, giving a programmer a number of different options on how a computation is performed.
+For many of these kinds of routines, there are standard or default settings that work for the majority of computations.
+Without default values for parameters, a programmer is forced to specify these common values all the time, resulting in long argument lists that are error prone.
+\item
+When a routine's interface is augmented with new parameters, it extends the interface providing generalizability\footnote{
+``It should be possible for the implementor of an abstraction to increase its generality.
+So long as the modified abstraction is a generalization of the original, existing uses of the abstraction will not require change.
+It might be possible to modify an abstraction in a manner which is not a generalization without affecting existing uses, but, without inspecting the modules in which the uses occur, this possibility cannot be determined.
+This criterion precludes the addition of parameters, unless these parameters have default or inferred values that are valid for all possible existing applications.''~\cite[p.~128]{Cormack90}}
+(somewhat like the generalization provided by inheritance for classes).
+That is, all existing calls are still valid, although the call must still be recompiled.
+\end{itemize}
+The only disadvantage of default arguments is that unintentional omission of an argument may not result in a compiler-time error.
+Instead, a default value is used, which may not be the programmer's intent.
+
+Default values may only appear in a prototype versus definition context:
+\begin{cfa}
+void p( int x, int y = 2, int z = 3 );		§\C{// prototype: allowed}§
+void p( int, int = 2, int = 3 );			§\C{// prototype: allowed}§
+void p( int x, int y = 2, int z = 3 ) {}	§\C{// definition: not allowed}§
+\end{cfa}
+The reason for this restriction is to allow separate compilation.
+Multiple prototypes with different default values is an error.
+\end{description}
+
+Ellipse (``...'') arguments present problems when used with default arguments.
+The conflict occurs because both named and ellipse arguments must appear after positional arguments, giving two possibilities:
+\begin{cfa}
+p( /* positional */, ... , /* named */ );
+p( /* positional */, /* named */, ... );
+\end{cfa}
+While it is possible to implement both approaches, the first possibly is more complex than the second, \eg:
+\begin{cfa}
+p( int x, int y, int z, ... );
+p( 1, 4, 5, 6, z : 3, y : 2 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
+p( 1, z : 3, y : 2, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
+\end{cfa}
+In the first call, it is necessary for the programmer to conceptually rewrite the call, changing named arguments into positional, before knowing where the ellipse arguments begin.
+Hence, this approach seems significantly more difficult, and hence, confusing and error prone.
+In the second call, the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
+
+The problem is exacerbated with default arguments, \eg:
+\begin{cfa}
+void p( int x, int y = 2, int z = 3... );
+p( 1, 4, 5, 6, z : 3 );		§\C{// assume p( /* positional */, ... , /* named */ );}§
+p( 1, z : 3, 4, 5, 6 );		§\C{// assume p( /* positional */, /* named */, ... );}§
+\end{cfa}
+The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments;
+therefore, argument 5 subsequently conflicts with the named argument z : 3.
+In the second call, the default value for y is implicitly inserted after argument 1 and the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
+For these reasons, \CFA requires named arguments before ellipse arguments.
+Finally, while ellipse arguments are needed for a small set of existing C routines, like printf, the extended \CFA type system largely eliminates the need for ellipse arguments (see Section 24), making much of this discussion moot.
+
+Default arguments and overloading (see Section 24) are complementary.
+While in theory default arguments can be simulated with overloading, as in:
+\begin{quote2}
+\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{default arguments}}	& \multicolumn{1}{c}{\textbf{overloading}}	\\
+\begin{cfa}
+void p( int x, int y = 2, int z = 3 ) {...}
+
+
+\end{cfa}
+&
+\begin{cfa}
+void p( int x, int y, int z ) {...}
+void p( int x ) { p( x, 2, 3 ); }
+void p( int x, int y ) { p( x, y, 3 ); }
+\end{cfa}
+\end{tabular}
+\end{quote2}
+the number of required overloaded routines is linear in the number of default values, which is unacceptable growth.
+In general, overloading should only be used over default arguments if the body of the routine is significantly different.
+Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
+\begin{cfa}
+p( 1, /* default */, 5 );		§\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
+\end{cfa}
+
+Given the \CFA restrictions above, both named and default arguments are backwards compatible.
+\Index*[C++]{\CC{}} only supports default arguments;
+\Index*{Ada} supports both named and default arguments.
+
+
+\section{Unnamed Structure Fields}
+
+C requires each field of a structure to have a name, except for a bit field associated with a basic type, \eg:
+\begin{cfa}
+struct {
+	int f1;					§\C{// named field}§
+	int f2 : 4;				§\C{// named field with bit field size}§
+	int : 3;				§\C{// unnamed field for basic type with bit field size}§
+	int ;					§\C{// disallowed, unnamed field}§
+	int *;					§\C{// disallowed, unnamed field}§
+	int (*)( int );			§\C{// disallowed, unnamed field}§
+};
+\end{cfa}
+This requirement is relaxed by making the field name optional for all field declarations; therefore, all the field declarations in the example are allowed.
+As for unnamed bit fields, an unnamed field is used for padding a structure to a particular size.
+A list of unnamed fields is also supported, \eg:
+\begin{cfa}
+struct {
+	int , , ;				§\C{// 3 unnamed fields}§
+}
+\end{cfa}
+
+
+\section{Nesting}
+
+Nesting of types and routines is useful for controlling name visibility (\newterm{name hiding}).
+
+
+\subsection{Type Nesting}
+
+\CFA allows \Index{type nesting}, and type qualification of the nested types (see \VRef[Figure]{f:TypeNestingQualification}), where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
+\begin{figure}
+\centering
+\begin{tabular}{@{}l@{\hspace{3em}}l|l@{}}
+\multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}}	& \multicolumn{1}{c}{\textbf{C Implicit Hoisting}}	& \multicolumn{1}{|c}{\textbf{\CFA}}	\\
+\hline
+\begin{cfa}
+struct S {
+	enum C { R, G, B };
+	struct T {
+		union U { int i, j; };
+		enum C c;
+		short int i, j;
+	};
+	struct T t;
+} s;
+
+int fred() {
+	s.t.c = R;
+	struct T t = { R, 1, 2 };
+	enum C c;
+	union U u;
+}
+\end{cfa}
+&
+\begin{cfa}
+enum C { R, G, B };
+union U { int i, j; };
+struct T {
+	enum C c;
+	short int i, j;
+};
+struct S {
+	struct T t;
+} s;
+	
+
+
+
+
+
+
+\end{cfa}
+&
+\begin{cfa}
+struct S {
+	enum C { R, G, B };
+	struct T {
+		union U { int i, j; };
+		enum C c;
+		short int i, j;
+	};
+	struct T t;
+} s;
+
+int fred() {
+	s.t.c = ®S.®R;	// type qualification
+	struct ®S.®T t = { ®S.®R, 1, 2 };
+	enum ®S.®C c;
+	union ®S.T.®U u;
+}
+\end{cfa}
+\end{tabular}
+\caption{Type Nesting / Qualification}
+\label{f:TypeNestingQualification}
+\end{figure}
+In the left example in C, types ©C©, ©U© and ©T© are implicitly hoisted outside of type ©S© into the containing block scope.
+In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``©.©'' for type qualification, as does \Index*{Java}, rather than the \CC type-selection operator ``©::©''.
+
+
+\subsection{Routine Nesting}
+
+While \CFA does not provide object programming by putting routines into structures, it does rely heavily on locally nested routines to redefine operations at or close to a call site.
+For example, the C quick-sort is wrapped into the following polymorphic \CFA routine:
+\begin{cfa}
+forall( otype T | { int ?<?( T, T ); } )
+void qsort( const T * arr, size_t dimension );
+\end{cfa}
+which can be used to sort in ascending and descending order by locally redefining the less-than operator into greater-than.
+\begin{cfa}
+const unsigned int size = 5;
+int ia[size];
+...						§\C{// assign values to array ia}§
+qsort( ia, size );		§\C{// sort ascending order using builtin ?<?}§
+{
+	®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§
+	qsort( ia, size );	§\C{// sort descending order by local redefinition}§
+}
+\end{cfa}
+
+Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks;
+the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program.
+The following program in undefined in \CFA (and Indexc{gcc})
+\begin{cfa}
+[* [int]( int )] foo() {		§\C{// int (*foo())( int )}§
+	int ®i® = 7;
+	int bar( int p ) {
+		®i® += 1;				§\C{// dependent on local variable}§
+		sout | ®i® | endl;
+	}
+	return bar;					§\C{// undefined because of local dependence}§
+}
+int main() {
+	* [int]( int ) fp = foo();	§\C{// int (*fp)( int )}§
+	sout | fp( 3 ) | endl;
+}
+\end{cfa}
+because 
+
+Currently, there are no \Index{lambda} expressions, \ie unnamed routines because routine names are very important to properly select the correct routine.
+
+
+\section{Tuples}
+
+In C and \CFA, lists of elements appear in several contexts, such as the parameter list for a routine call.
+(More contexts are added shortly.)
+A list of such elements is called a \newterm{lexical list}.
+The general syntax of a lexical list is:
+\begin{cfa}
+[ §\emph{exprlist}§ ]
+\end{cfa}
+where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas.
+The brackets, ©[]©, allow differentiating between lexical lists and expressions containing the C comma operator.
+The following are examples of lexical lists:
+\begin{cfa}
+[ x, y, z ]
+[ 2 ]
+[ v+w, x*y, 3.14159, f() ]
+\end{cfa}
+Tuples are permitted to contain sub-tuples (\ie nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple.
+Note, a tuple is not a record (structure);
+a record denotes a single value with substructure, whereas a tuple is multiple values with no substructure (see flattening coercion in Section 12.1).
+In essence, tuples are largely a compile time phenomenon, having little or no runtime presence.
+
+Tuples can be organized into compile-time tuple variables;
+these variables are of \newterm{tuple type}.
+Tuple variables and types can be used anywhere lists of conventional variables and types can be used.
+The general syntax of a tuple type is:
+\begin{cfa}
+[ §\emph{typelist}§ ]
+\end{cfa}
+where ©$\emph{typelist}$© is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications.
+Examples of tuple types include:
+\begin{cfa}
+[ unsigned int, char ]
+[ double, double, double ]
+[ * int, int * ]		§\C{// mix of CFA and ANSI}§
+[ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ]
+\end{cfa}
+Like tuples, tuple types may be nested, such as ©[ [ int, int ], int ]©, which is a 2-element tuple type whose first element is itself a tuple type.
+
+Examples of declarations using tuple types are:
+\begin{cfa}
+[ int, int ] x;			§\C{// 2 element tuple, each element of type int}§
+* [ char, char ] y;		§\C{// pointer to a 2 element tuple}§
+[ [ int, int ] ] z ([ int, int ]);
+\end{cfa}
+The last example declares an external routine that expects a 2 element tuple as an input parameter and returns a 2 element tuple as its result.
+
+As mentioned, tuples can appear in contexts requiring a list of value, such as an argument list of a routine call.
+In unambiguous situations, the tuple brackets may be omitted, \eg a tuple that appears as an argument may have its
+square brackets omitted for convenience; therefore, the following routine invocations are equivalent:
+\begin{cfa}
+f( [ 1, x+2, fred() ] );
+f( 1, x+2, fred() );
+\end{cfa}
+Also, a tuple or a tuple variable may be used to supply all or part of an argument list for a routine expecting multiple input parameters or for a routine expecting a tuple as an input parameter.
+For example, the following are all legal:
+\begin{cfa}
+[ int, int ] w1;
+[ int, int, int ] w2;
+[ void ] f (int, int, int); /* three input parameters of type int */
+[ void ] g ([ int, int, int ]); /* 3 element tuple as input */
+f( [ 1, 2, 3 ] );
+f( w1, 3 );
+f( 1, w1 );
+f( w2 );
+g( [ 1, 2, 3 ] );
+g( w1, 3 );
+g( 1, w1 );
+g( w2 );
+\end{cfa}
+Note, in all cases 3 arguments are supplied even though the syntax may appear to supply less than 3. As mentioned, a
+tuple does not have structure like a record; a tuple is simply converted into a list of components.
+\begin{rationale}
+The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; \ie a statement such as ©g( f() )© is not supported.
+Using a temporary variable to store the  results of the inner routine and then passing this variable to the outer routine works, however.
+\end{rationale}
+
+A tuple can contain a C comma expression, provided the expression containing the comma operator is enclosed in parentheses.
+For instance, the following tuples are equivalent:
+\begin{cfa}
+[ 1, 3, 5 ]
+[ 1, (2, 3), 5 ]
+\end{cfa}
+The second element of the second tuple is the expression (2, 3), which yields the result 3.
+This requirement is the same as for comma expressions in argument lists.
+
+Type qualifiers, \ie const and volatile, may modify a tuple type.
+The meaning is the same as for a type qualifier modifying an aggregate type [Int99, x 6.5.2.3(7),x 6.7.3(11)], \ie the qualifier is distributed across all of the types in the tuple, \eg:
+\begin{cfa}
+const volatile [ int, float, const int ] x;
+\end{cfa}
+is equivalent to:
+\begin{cfa}
+[ const volatile int, const volatile float, const volatile int ] x;
+\end{cfa}
+Declaration qualifiers can only appear at the start of a \CFA tuple declaration4, \eg:
+\begin{cfa}
+extern [ int, int ] w1;
+static [ int, int, int ] w2;
+\end{cfa}
+\begin{rationale}
+Unfortunately, C's syntax for subscripts precluded treating them as tuples.
+The C subscript list has the form ©[i][j]...© and not ©[i, j, ...]©.
+Therefore, there is no syntactic way for a routine returning multiple values to specify the different subscript values, \eg ©f[g()]© always means a single subscript value because there is only one set of brackets.
+Fixing this requires a major change to C because the syntactic form ©M[i, j, k]© already has a particular meaning: ©i, j, k© is a comma expression.
+\end{rationale}
+
+
+\subsection{Tuple Coercions}
+
+There are four coercions that can be performed on tuples and tuple variables: closing, opening, flattening and structuring.
+In addition, the coercion of dereferencing can be performed on a tuple variable to yield its value(s), as for other variables.
+A \newterm{closing coercion} takes a set of values and converts it into a tuple value, which is a contiguous set of values, as in:
+\begin{cfa}
+[ int, int, int, int ] w;
+w = [ 1, 2, 3, 4 ];
+\end{cfa}
+First the right-hand tuple is closed into a tuple value and then the tuple value is assigned.
+
+An \newterm{opening coercion} is the opposite of closing; a tuple value is converted into a tuple of values, as in:
+\begin{cfa}
+[ a, b, c, d ] = w
+\end{cfa}
+©w© is implicitly opened to yield a tuple of four values, which are then assigned individually.
+
+A \newterm{flattening coercion} coerces a nested tuple, \ie a tuple with one or more components, which are themselves tuples, into a flattened tuple, which is a tuple whose components are not tuples, as in:
+\begin{cfa}
+[ a, b, c, d ] = [ 1, [ 2, 3 ], 4 ];
+\end{cfa}
+First the right-hand tuple is flattened and then the values are assigned individually.
+Flattening is also performed on tuple types.
+For example, the type ©[ int, [ int, int ], int ]© can be coerced, using flattening, into the type ©[ int, int, int, int ]©.
+
+A \newterm{structuring coercion} is the opposite of flattening;
+a tuple is structured into a more complex nested tuple.
+For example, structuring the tuple ©[ 1, 2, 3, 4 ]© into the tuple ©[ 1, [ 2, 3 ], 4 ]© or the tuple type ©[ int, int, int, int ]© into the tuple type ©[ int, [ int, int ], int ]©.
+In the following example, the last assignment illustrates all the tuple coercions:
+\begin{cfa}
+[ int, int, int, int ] w = [ 1, 2, 3, 4 ];
+int x = 5;
+[ x, w ] = [ w, x ];		§\C{// all four tuple coercions}§
+\end{cfa}
+Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values;
+therefore, the right-hand tuple is now the tuple ©[ [ 1, 2, 3, 4 ], 5 ]©.
+This tuple is then flattened, yielding ©[ 1, 2, 3, 4, 5 ]©, which is structured into ©[ 1, [ 2, 3, 4, 5 ] ]© to match the tuple type of the left-hand side.
+The tuple ©[ 2, 3, 4, 5 ]© is then closed to create a tuple value.
+Finally, ©x© is assigned ©1© and ©w© is assigned the tuple value using multiple assignment (see Section 14).
+\begin{rationale}
+A possible additional language extension is to use the structuring coercion for tuples to initialize a complex record with a tuple.
+\end{rationale}
+
+
+\section{Mass Assignment}
+
+\CFA permits assignment to several variables at once using mass assignment~\cite{CLU}.
+Mass assignment has the following form:
+\begin{cfa}
+[ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = §\emph{expr}§;
+\end{cfa}
+\index{lvalue}
+The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement.
+©$\emph{expr}$© is any standard arithmetic expression.
+Clearly, the types of the entities being assigned must be type compatible with the value of the expression.
+
+Mass assignment has parallel semantics, \eg the statement:
+\begin{cfa}
+[ x, y, z ] = 1.5;
+\end{cfa}
+is equivalent to:
+\begin{cfa}
+x = 1.5; y = 1.5; z = 1.5;
+\end{cfa}
+This semantics is not the same as the following in C:
+\begin{cfa}
+x = y = z = 1.5;
+\end{cfa}
+as conversions between intermediate assignments may lose information.
+A more complex example is:
+\begin{cfa}
+[ i, y[i], z ] = a + b;
+\end{cfa}
+which is equivalent to:
+\begin{cfa}
+t = a + b;
+a1 = &i; a2 = &y[i]; a3 = &z;
+*a1 = t; *a2 = t; *a3 = t;
+\end{cfa}
+The temporary ©t© is necessary to store the value of the expression to eliminate conversion issues.
+The temporaries for the addresses are needed so that locations on the left-hand side do not change as the values are assigned.
+In this case, ©y[i]© uses the previous value of ©i© and not the new value set at the beginning of the mass assignment.
+
+
+\section{Multiple Assignment}
+
+\CFA also supports the assignment of several values at once, known as multiple assignment~\cite{CLU,Galletly96}.
+Multiple assignment has the following form:
+\begin{cfa}
+[ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§ ];
+\end{cfa}
+\index{lvalue}
+The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
+Each \emph{expr} appearing on the right-hand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment.
+An example of multiple assignment is:
+\begin{cfa}
+[ x, y, z ] = [ 1, 2, 3 ];
+\end{cfa}
+Here, the values ©1©, ©2© and ©3© are assigned, respectively, to the variables ©x©, ©y© and ©z©.
+ A more complex example is:
+\begin{cfa}
+[ i, y[ i ], z ] = [ 1, i, a + b ];
+\end{cfa}
+Here, the values ©1©, ©i© and ©a + b© are assigned to the variables ©i©, ©y[i]© and ©z©, respectively.
+ Note, the parallel semantics of
+multiple assignment ensures:
+\begin{cfa}
+[ x, y ] = [ y, x ];
+\end{cfa}
+correctly interchanges (swaps) the values stored in ©x© and ©y©.
+The following cases are errors:
+\begin{cfa}
+[ a, b, c ] = [ 1, 2, 3, 4 ];
+[ a, b, c ] = [ 1, 2 ];
+\end{cfa}
+because the number of entities in the left-hand tuple is unequal with the right-hand tuple.
+
+As for all tuple contexts in C, side effects should not be used because C does not define an ordering for the evaluation of the elements of a tuple;
+both these examples produce indeterminate results:
+\begin{cfa}
+f( x++, x++ );				§\C{// C routine call with side effects in arguments}§
+[ v1, v2 ] = [ x++, x++ ];	§\C{// side effects in righthand side of multiple assignment}§
+\end{cfa}
+
+
+\section{Cascade Assignment}
+
+As in C, \CFA mass and multiple assignments can be cascaded, producing cascade assignment.
+Cascade assignment has the following form:
+\begin{cfa}
+§\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§;
+\end{cfa}
+and it has the same parallel semantics as for mass and multiple assignment.
+Some examples of cascade assignment are:
+\begin{cfa}
+x1 = y1 = x2 = y2 = 0;
+[ x1, y1 ] = [ x2, y2 ] = [ x3, y3 ];
+[ x1, y1 ] = [ x2, y2 ] = 0;
+[ x1, y1 ] = z = 0;
+\end{cfa}
+As in C, the rightmost assignment is performed first, \ie assignment parses right to left.
+
+
+\section{Field Tuples}
+
+Tuples may be used to select multiple fields of a record by field name.
+Its general form is:
+\begin{cfa}
+§\emph{expr}§ . [ §\emph{fieldlist}§ ]
+§\emph{expr}§ -> [ §\emph{fieldlist}§ ]
+\end{cfa}
+\emph{expr} is any expression yielding a value of type record, \eg ©struct©, ©union©.
+Each element of \emph{ fieldlist} is an element of the record specified by \emph{expr}.
+A record-field tuple may be used anywhere a tuple can be used. An example of the use of a record-field tuple is
+the following:
+\begin{cfa}
+struct s {
+	int f1, f2;
+	char f3;
+	double f4;
+} v;
+v.[ f3, f1, f2 ] = ['x', 11, 17 ];	§\C{// equivalent to v.f3 = 'x', v.f1 = 11, v.f2 = 17}§
+f( v.[ f3, f1, f2 ] );				§\C{// equivalent to f( v.f3, v.f1, v.f2 )}§
+\end{cfa}
+Note, the fields appearing in a record-field tuple may be specified in any order;
+also, it is unnecessary to specify all the fields of a struct in a multiple record-field tuple.
+
+If a field of a ©struct© is itself another ©struct©, multiple fields of this subrecord can be specified using a nested record-field tuple, as in the following example:
+\begin{cfa}
+struct inner {
+	int f2, f3;
+};
+struct outer {
+	int f1;
+	struct inner i;
+	double f4;
+} o;
+
+o.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
+\end{cfa}
+
+
 \section{I/O Library}
 \label{s:IOLibrary}
@@ -2402,4 +2433,5 @@
 
 The goal of \CFA I/O is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
+The approach combines ideas from \CC and Python.
 The \CFA header file for the I/O library is \Indexc{fstream}.
 
@@ -2419,5 +2451,5 @@
 \\
 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
-1 2 3
+1® ®2® ®3
 \end{cfa}
 &
@@ -2427,14 +2459,14 @@
 \end{tabular}
 \end{quote2}
-The \CFA form has half as many characters as the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
-A tuple prints all the tuple's values, each separated by ©", "©.
+The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
+Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''.
 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
-[int, int] t1 = [1, 2], t2 = [3, 4];
+[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
 sout | t1 | t2 | endl;					§\C{// print tuples}§
 \end{cfa}
 \begin{cfa}[mathescape=off,showspaces=true,belowskip=0pt]
-1, 2, 3, 4
-\end{cfa}
-\CFA uses the logical-or operator for I/O because it is the lowest-priority overloadable operator, other than assignment.
+1®, ®2®, ®3 3®, ®4®, ®5
+\end{cfa}
+Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment.
 Therefore, fewer output expressions require parenthesis.
 \begin{quote2}
@@ -2458,8 +2490,10 @@
 \end{tabular}
 \end{quote2}
-Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output.
-
-
-The implicit separator\index{I/O!separator} character (space/blank) is a separator not a terminator.
+There is a weak similarity between the \CFA logical-or operator and the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output.
+
+
+\subsection{Implicit Separator}
+
+The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator.
 The rules for implicitly adding the separator are:
 \begin{enumerate}
@@ -2533,4 +2567,7 @@
 \end{enumerate}
 
+
+\subsection{Manipulator}
+
 The following routines and \CC-style \Index{manipulator}s control implicit seperation.
 \begin{enumerate}
@@ -2544,5 +2581,5 @@
 %$
 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
-1, $2, $3 ®", $"®
+1®, $®2®, $®3 ®", $"®
 \end{cfa}
 %$
@@ -2552,41 +2589,5 @@
 \end{cfa}
 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
-1 2 3 ®" "®
-\end{cfa}
-
-\item
-Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
-\begin{cfa}[mathescape=off,belowskip=0pt]
-sout | sepOn | 1 | 2 | 3 | sepOn | endl;	§\C{// separator at start of line}§
-\end{cfa}
-\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
- 1 2 3
-\end{cfa}
-\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
-sout | 1 | sepOff | 2 | 3 | endl;			§\C{// locally turn off implicit separator}§
-\end{cfa}
-\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
-12 3
-\end{cfa}
-
-\item
-Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted.
-\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
-sout | sepDisable | 1 | 2 | 3 | endl;		§\C{// globally turn off implicit separation}§
-\end{cfa}
-\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
-123
-\end{cfa}
-\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
-sout | 1 | sepOn | 2 | 3 | endl;			§\C{// locally turn on implicit separator}§
-\end{cfa}
-\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
-1 23
-\end{cfa}
-\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
-sout | sepEnable | 1 | 2 | 3 | endl;		§\C{// globally turn on implicit separation}§
-\end{cfa}
-\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
-1 2 3
+1® ®2® ®3 ®" "®
 \end{cfa}
 
@@ -2610,5 +2611,18 @@
 
 \item
-The tuple separator can also be turned on and off.
+Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
+\begin{cfa}[mathescape=off,belowskip=0pt]
+sout | sepOn | 1 | 2 | 3 | sepOn | endl;	§\C{// separator at start/end of line}§
+\end{cfa}
+\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
+® ®1 2 3® ®
+\end{cfa}
+\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
+sout | 1 | sepOff | 2 | 3 | endl;			§\C{// locally turn off implicit separator}§
+\end{cfa}
+\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
+12 3
+\end{cfa}
+The tuple separator also responses to being turned on and off.
 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
 sout | sepOn | t1 | sepOff | t2 | endl;		§\C{// locally turn on/off implicit separation}§
@@ -2618,4 +2632,25 @@
 \end{cfa}
 Notice a tuple seperator starts the line because the next item is a tuple.
+
+\item
+Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted.
+\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
+sout | sepDisable | 1 | 2 | 3 | endl;		§\C{// globally turn off implicit separation}§
+\end{cfa}
+\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
+123
+\end{cfa}
+\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
+sout | 1 | ®sepOn® | 2 | 3 | endl;			§\C{// locally turn on implicit separator}§
+\end{cfa}
+\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
+1® ®23
+\end{cfa}
+\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
+sout | sepEnable | 1 | 2 | 3 | endl;		§\C{// globally turn on implicit separation}§
+\end{cfa}
+\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
+1 2 3
+\end{cfa}
 \end{enumerate}
 
@@ -2626,6 +2661,6 @@
 	int x = 1, y = 2, z = 3;
 	sout | x | y | z | endl;
-	[int, int] t1 = [1, 2], t2 = [3, 4];
-	sout | t1 | t2 | endl;						// print tuple
+	[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
+	sout | t1 | t2 | endl;						// print tuples
 	sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
 	sout | 1 | 2 | 3 | endl;
@@ -5189,5 +5224,5 @@
 
 
-\section{\protect\CFA Keywords}
+\section{\CFA Keywords}
 \label{s:CFAKeywords}
 
@@ -5487,5 +5522,5 @@
 For an increase in storage size, new storage after the copied data may be filled.
 \item[alignment]
-an allocation starts on a specified memory boundary, e.g., an address multiple of 64 or 128 for cache-line purposes.
+an allocation starts on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes.
 \item[array]
 the allocation size is scaled to the specified number of array elements.
Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/CodeGen/CodeGenerator.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -288,16 +288,16 @@
 	}
 
-	void CodeGenerator::printDesignators( std::list< Expression * > & designators ) {
-		typedef std::list< Expression * > DesignatorList;
+	void CodeGenerator::visit( Designation * designation ) {
+		std::list< Expression * > designators = designation->get_designators();
 		if ( designators.size() == 0 ) return;
-		for ( DesignatorList::iterator iter = designators.begin(); iter != designators.end(); ++iter ) {
-			if ( dynamic_cast< NameExpr * >( *iter ) ) {
-				// if expression is a name, then initializing aggregate member
+		for ( Expression * des : designators ) {
+			if ( dynamic_cast< NameExpr * >( des ) || dynamic_cast< VariableExpr * >( des ) ) {
+				// if expression is a NameExpr or VariableExpr, then initializing aggregate member
 				output << ".";
-				(*iter)->accept( *this );
+				des->accept( *this );
 			} else {
-				// if not a simple name, it has to be a constant expression, i.e. an array designator
+				// otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt
 				output << "[";
-				(*iter)->accept( *this );
+				des->accept( *this );
 				output << "]";
 			} // if
@@ -307,13 +307,24 @@
 
 	void CodeGenerator::visit( SingleInit * init ) {
-		printDesignators( init->get_designators() );
 		init->get_value()->accept( *this );
 	}
 
 	void CodeGenerator::visit( ListInit * init ) {
-		printDesignators( init->get_designators() );
+		auto initBegin = init->begin();
+		auto initEnd = init->end();
+		auto desigBegin = init->get_designations().begin();
+		auto desigEnd = init->get_designations().end();
+
 		output << "{ ";
-		genCommaList( init->begin(), init->end() );
+		for ( ; initBegin != initEnd && desigBegin != desigEnd; ) {
+			(*desigBegin)->accept( *this );
+			(*initBegin)->accept( *this );
+			++initBegin, ++desigBegin;
+			if ( initBegin != initEnd ) {
+				output << ", ";
+			}
+		}
 		output << " }";
+		assertf( initBegin == initEnd && desigBegin == desigEnd, "Initializers and designators not the same length. %s", toString( init ).c_str() );
 	}
 
@@ -716,6 +727,9 @@
 
 	void CodeGenerator::visit( TypeExpr * typeExpr ) {
-		assertf( ! genC, "TypeExpr should not reach code generation." );
-		output<< genType( typeExpr->get_type(), "", pretty, genC );
+		// if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
+		// assertf( ! genC, "TypeExpr should not reach code generation." );
+		if ( ! genC ) {
+			output<< genType( typeExpr->get_type(), "", pretty, genC );
+		}
 	}
 
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/CodeGen/CodeGenerator.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -47,4 +47,5 @@
 
 		//*** Initializer
+		virtual void visit( Designation * );
 		virtual void visit( SingleInit * );
 		virtual void visit( ListInit * );
@@ -137,5 +138,4 @@
 		bool lineMarks = false;
 
-		void printDesignators( std::list< Expression * > & );
 		void handleStorageClass( DeclarationWithType *decl );
 		void handleAggregate( AggregateDecl *aggDecl, const std::string & kind );
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Common/PassVisitor.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -12,4 +12,5 @@
 #include "SynTree/Expression.h"
 #include "SynTree/Constant.h"
+#include "SynTree/TypeSubstitution.h"
 
 #include "PassVisitor.proto.h"
@@ -26,5 +27,5 @@
 //                          stmtsToAddBefore or stmtsToAddAfter respectively.
 // | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children to false in pre{visit,mutate} to skip visiting children
-// | WithScopes           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
+// | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
 //                          will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates.
 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -32,5 +33,4 @@
 class PassVisitor final : public Visitor, public Mutator {
 public:
-	PassVisitor() = default;
 
 	template< typename... Args >
@@ -257,15 +257,4 @@
 
 	void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); }
-
-	guard_value_impl init_guard() {
-		guard_value_impl guard;
-		auto at_cleanup = at_cleanup_impl(pass, 0);
-		if( at_cleanup ) {
-			*at_cleanup = [&guard]( cleanup_func_t && func, void* val ) {
-				guard.push( std::move( func ), val );
-			};
-		}
-		return guard;
-	}
 };
 
@@ -283,5 +272,5 @@
 
 public:
-	TypeSubstitution * env;
+	TypeSubstitution * env = nullptr;
 };
 
@@ -295,4 +284,15 @@
 	std::list< Statement* > stmtsToAddAfter;
 };
+
+class WithDeclsToAdd {
+protected:
+	WithDeclsToAdd() = default;
+	~WithDeclsToAdd() = default;
+
+public:
+	std::list< Declaration* > declsToAddBefore;
+	std::list< Declaration* > declsToAddAfter;
+};
+
 class WithShortCircuiting {
 protected:
@@ -304,8 +304,8 @@
 };
 
-class WithScopes {
-protected:
-	WithScopes() = default;
-	~WithScopes() = default;
+class WithGuards {
+protected:
+	WithGuards() = default;
+	~WithGuards() = default;
 
 public:
@@ -318,4 +318,17 @@
 		}, static_cast< void * >( & val ) );
 	}
+
+	template< typename T >
+	void GuardScope( T& val ) {
+		val.beginScope();
+		at_cleanup( []( void * val ) {
+			static_cast< T * >( val )->endScope();
+		}, static_cast< void * >( & val ) );
+	}
+
+	template< typename Func >
+	void GuardAction( Func func ) {
+		at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr );
+	}
 };
 
@@ -323,9 +336,9 @@
 class WithVisitorRef {
 protected:
-	WithVisitorRef() = default;
-	~WithVisitorRef() = default;
-
-public:
-	PassVisitor<pass_type> * const visitor;
+	WithVisitorRef() {}
+	~WithVisitorRef() {}
+
+public:
+	PassVisitor<pass_type> * const visitor = nullptr;
 };
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Common/PassVisitor.impl.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -3,5 +3,5 @@
 #define VISIT_START( node )                     \
 	__attribute__((unused))                   \
-	const auto & guard = init_guard();        \
+	guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
 	bool visit_children = true;               \
 	set_visit_children( visit_children );	\
@@ -15,5 +15,5 @@
 #define MUTATE_START( node )                    \
 	__attribute__((unused))                   \
-	const auto & guard = init_guard();        \
+	guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
 	bool visit_children = true;               \
 	set_visit_children( visit_children );	\
@@ -68,5 +68,5 @@
 	for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
 		// splice in new declarations after previous decl
-		if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }	
+		if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
 
 		if ( i == decls.end() ) break;
@@ -88,5 +88,5 @@
 	for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
 		// splice in new declarations after previous decl
-		if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }	
+		if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
 
 		if ( i == decls.end() ) break;
@@ -104,4 +104,10 @@
 void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
 	SemanticError errors;
+
+	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
+	ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
+	ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
+	ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
+	ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
 
 	StmtList_t* beforeStmts = get_beforeStmts();
@@ -181,5 +187,5 @@
 Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
 	return handleStatement( stmt, [this]( Statement * stmt ) {
-		maybeAccept( stmt, *this ); 
+		maybeAccept( stmt, *this );
 		return stmt;
 	});
@@ -212,5 +218,5 @@
 		expr->accept( *this );
 		return expr;
-	});		
+	});
 }
 
@@ -565,4 +571,7 @@
 	VISIT_START( node );
 
+	// maybeAccept( node->get_env(), *this );
+	maybeAccept( node->get_result(), *this );
+
 	for ( auto expr : node->get_args() ) {
 		visitExpression( expr );
@@ -575,4 +584,7 @@
 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
 	MUTATE_START( node );
+
+	node->set_env( maybeMutate( node->get_env(), *this ) );
+	node->set_result( maybeMutate( node->get_result(), *this ) );
 
 	for ( auto& expr : node->get_args() ) {
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Common/PassVisitor.proto.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -5,8 +5,15 @@
 
 typedef std::function<void( void * )> cleanup_func_t;
+typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
 
 class guard_value_impl {
 public:
-	guard_value_impl() = default;
+	guard_value_impl( at_cleanup_t * at_cleanup ) {
+		if( at_cleanup ) {
+			*at_cleanup = [this]( cleanup_func_t && func, void* val ) {
+				push( std::move( func ), val );
+			};
+		}
+	}
 
 	~guard_value_impl() {
@@ -33,5 +40,4 @@
 };
 
-typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
 
 class bool_ref {
@@ -56,5 +62,5 @@
 // Deep magic (a.k.a template meta programming) to make the templated visitor work
 // Basically the goal is to make 2 previsit_impl
-// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 
+// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
 //     'pass.previsit( node )' that compiles will be used for that node for that type
 //     This requires that this option only compile for passes that actually define an appropriate visit.
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Common/utility.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -305,5 +305,5 @@
 // for ( val : group_iterate( container1, container2, ... ) ) {}
 // syntax to have a for each that iterates multiple containers of the same length
-// TODO: update to use variadic arguments
+// TODO: update to use variadic arguments, perfect forwarding
 
 template< typename T1, typename T2 >
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,12 +10,17 @@
 // Created On       : Wed Jun 14 16:49:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Jun 22 15:57:00 2017
-// Update Count     : 0
+// Last Modified On : Fri Jun 30 13:30:00 2017
+// Update Count     : 1
 //
 
 #include "ExceptTranslate.h"
 #include "Common/PassVisitor.h"
-
-namespace ControlFlow {
+#include "SynTree/Statement.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Type.h"
+#include "SynTree/Attribute.h"
+
+namespace ControlStruct {
 
 	// This (large) section could probably be moved out of the class
@@ -24,6 +29,6 @@
 	// Type(Qualifiers &, false, std::list<Attribute *> &)
 
-	// void (*function)()
-	static FunctionType void_func_t(Type::Qualifiers(), false);
+	// void (*function)();
+	static FunctionType try_func_t(Type::Qualifiers(), false);
 	// void (*function)(int, exception);
 	static FunctionType catch_func_t(Type::Qualifiers(), false);
@@ -32,28 +37,33 @@
 	// bool (*function)(exception);
 	static FunctionType handle_func_t(Type::Qualifiers(), false);
+	// void (*function)(__attribute__((unused)) void *);
+	static FunctionType finally_func_t(Type::Qualifiers(), false);
 
 	static void init_func_types() {
-		static init_complete = false;
+		static bool init_complete = false;
 		if (init_complete) {
 			return;
 		}
 		ObjectDecl index_obj(
-			"index_t",
+			"__handler_index",
 			Type::StorageClasses(),
 			LinkageSpec::Cforall,
 			/*bitfieldWidth*/ NULL,
-			new BasicType(emptyQualifiers, BasicType::UnsignedInt),
+			new BasicType( emptyQualifiers, BasicType::SignedInt ),
 			/*init*/ NULL
-		);
+			);
 		ObjectDecl exception_obj(
-			"exception_t",
+			"__exception_inst",
 			Type::StorageClasses(),
 			LinkageSpec::Cforall,
 			/*bitfieldWidth*/ NULL,
-			new BasicType(emptyQualifiers, BasicType::UnsignedInt),
+			new PointerType(
+				emptyQualifiers,
+				new BasicType( emptyQualifiers, BasicType::SignedInt )
+				),
 			/*init*/ NULL
-		);
+			);
 		ObjectDecl bool_obj(
-			"bool_t",
+			"__ret_bool",
 			Type::StorageClasses(),
 			LinkageSpec::Cforall,
@@ -61,12 +71,27 @@
 			new BasicType(emptyQualifiers, BasicType::Bool),
 			/*init*/ NULL
-		);
-
-		catch_func_t.get_parameters().push_back(index_obj.clone());
-		catch_func_t.get_parameters().push_back(exception_obj.clone());
-		match_func_t.get_returnVals().push_back(index_obj.clone());
-		match_func_t.get_parameters().push_back(exception_obj.clone());
-		handle_func_t.get_returnVals().push_back(bool_obj.clone());
-		handle_func_t.get_parameters().push_back(exception_obj.clone());
+			);
+		ObjectDecl voidptr_obj(
+			"__hook",
+			Type::StorageClasses(),
+			LinkageSpec::Cforall,
+			NULL,
+			new PointerType(
+				emptyQualifiers,
+				new VoidType(
+					emptyQualifiers
+					),
+				std::list<Attribute *>{new Attribute("unused")}
+				),
+			NULL
+			);
+
+		catch_func_t.get_parameters().push_back( index_obj.clone() );
+		catch_func_t.get_parameters().push_back( exception_obj.clone() );
+		match_func_t.get_returnVals().push_back( index_obj.clone() );
+		match_func_t.get_parameters().push_back( exception_obj.clone() );
+		handle_func_t.get_returnVals().push_back( bool_obj.clone() );
+		handle_func_t.get_parameters().push_back( exception_obj.clone() );
+		finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
 
 		init_complete = true;
@@ -78,9 +103,9 @@
 
 	void split( CatchList& allHandlers, CatchList& terHandlers,
-	            CatchList& resHandlers ) {
+				CatchList& resHandlers ) {
 		while ( !allHandlers.empty() ) {
-			Statement * stmt = allHandlers.front();
+			CatchStmt * stmt = allHandlers.front();
 			allHandlers.pop_front();
-			if (CaseStmt::Terminate == stmt->get_kind()) {
+			if (CatchStmt::Terminate == stmt->get_kind()) {
 				terHandlers.push_back(stmt);
 			} else {
@@ -92,5 +117,5 @@
 	template<typename T>
 	void free_all( std::list<T *> &list ) {
-		std::list<T *>::iterator it;
+		typename std::list<T *>::iterator it;
 		for ( it = list.begin() ; it != list.end() ; ++it ) {
 			delete *it;
@@ -100,27 +125,44 @@
 
 	void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
-		block->push_back(new DeclStmt(no_labels, item));
-	}
-
-	Expression * nameOf( FunctionDecl * function ) {
-		return new VariableExpr( function );
+		block->push_back(new DeclStmt(noLabels, item));
+	}
+
+	Expression * nameOf( DeclarationWithType * decl ) {
+		return new VariableExpr( decl );
 	}
 
 	// ThrowStmt Mutation Helpers
 
-	Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
-		// __throw_terminate( EXPR );
-		ApplicationExpr * call = new ApplicationExpr( /* ... */ );
-		call->get_args.push_back( throwStmt->get_expr() );
-		Statement * result = new ExprStmt( throwStmt->get_labels(), call );
+	Statement * create_given_throw(
+			const char * throwFunc, ThrowStmt * throwStmt ) {
+		// { int NAME = EXPR; throwFunc( &NAME ); }
+		CompoundStmt * result = new CompoundStmt( noLabels );
+		ObjectDecl * local = new ObjectDecl(
+			"__local_exception_copy",
+			Type::StorageClasses(),
+			LinkageSpec::Cforall,
+			NULL,
+			new BasicType( emptyQualifiers, BasicType::SignedInt ),
+			new SingleInit( throwStmt->get_expr() )
+			);
+		appendDeclStmt( result, local );
+		UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
+		call->get_args().push_back( new AddressExpr( nameOf( local ) ) );
+		result->push_back( new ExprStmt( throwStmt->get_labels(), call ) );
 		throwStmt->set_expr( nullptr );
 		delete throwStmt;
 		return result;
 	}
+
+	Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
+		// { int NAME = EXPR; __throw_terminate( &NAME ); }
+		return create_given_throw( "__cfaehm__throw_termination", throwStmt );
+	}
 	Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
 		// __rethrow_terminate();
+		assert( nullptr == throwStmt->get_expr() );
 		Statement * result = new ExprStmt(
 			throwStmt->get_labels(),
-			new ApplicationExpr( /* ... */ );
+			new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) )
 			);
 		delete throwStmt;
@@ -129,10 +171,5 @@
 	Statement * create_resume_throw( ThrowStmt *throwStmt ) {
 		// __throw_resume( EXPR );
-		ApplicationExpr * call = new ApplicationExpr( /* ... */ );
-		call->get_args.push_back( throwStmt->get_expr() );
-		Statement * result = new ExprStmt( throwStmt->get_labels(), call );
-		throwStmt->set_expr( nullptr );
-		delete throwStmt;
-		return result;
+		return create_given_throw( "__cfaehm__throw_resumption", throwStmt );
 	}
 	Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
@@ -140,12 +177,5 @@
 		Statement * result = new ReturnStmt(
 			throwStmt->get_labels(),
-			new ConstantExpr(
-				Constant(
-					new BasicType(
-						Type::Qualifiers(),
-						BasicType::Bool
-						),
-					"0")
-				)
+			new ConstantExpr( Constant::from_bool( false ) )
 			);
 		delete throwStmt;
@@ -160,14 +190,16 @@
 		return block;
 	}
-	FunctionDecl * create_try_wrapper( TryStmt *tryStmt ) {
-		CompoundStmt * body = base_try->get_block();
-		base_try->set_block(nullptr);
-
-		return new FunctionDecl("try", Type::StorageClasses(),
-			LinkageSpec::Cforall, void_func_t, body);
+	FunctionDecl * create_try_wrapper( CompoundStmt *body ) {
+
+		return new FunctionDecl( "try", Type::StorageClasses(),
+			LinkageSpec::Cforall, try_func_t.clone(), body );
 	}
 
 	FunctionDecl * create_terminate_catch( CatchList &handlers ) {
 		std::list<CaseStmt *> handler_wrappers;
+
+		FunctionType *func_type = catch_func_t.clone();
+		DeclarationWithType * index_obj = func_type->get_parameters().front();
+	//	DeclarationWithType * except_obj = func_type->get_parameters().back();
 
 		// Index 1..{number of handlers}
@@ -178,26 +210,33 @@
 			CatchStmt * handler = *it;
 
-			std::list<Statement *> core;
-			if ( /*the exception is named*/ ) {
-				ObjectDecl * local_except = /* Dynamic case, same */;
-				core->push_back( new DeclStmt( noLabel, local_except ) );
-			}
-			// Append the provided statement to the handler.
-			core->push_back( cur_handler->get_body() );
-			// Append return onto the inner block? case stmt list?
-			CaseStmt * wrapper = new CaseStmt(
+			// INTEGERconstant Version
+			// case `index`:
+			// {
+			//     `handler.body`
+			// }
+			// return;
+			std::list<Statement *> caseBody;
+			caseBody.push_back( handler->get_body() );
+			handler->set_body( nullptr );
+			caseBody.push_back( new ReturnStmt( noLabels, nullptr ) );
+
+			handler_wrappers.push_back( new CaseStmt(
 				noLabels,
 				new ConstantExpr( Constant::from_int( index ) ),
-				core
-				);
-			handler_wrappers.push_back(wrapper);
+				caseBody
+				) );
 		}
 		// TODO: Some sort of meaningful error on default perhaps?
+
+		std::list<Statement*> stmt_handlers;
+		while ( !handler_wrappers.empty() ) {
+			stmt_handlers.push_back( handler_wrappers.front() );
+			handler_wrappers.pop_front();
+		}
 
 		SwitchStmt * handler_lookup = new SwitchStmt(
 			noLabels,
-			/*parameter 0: index*/,
-			handler_wrappers,
-			false
+			nameOf( index_obj ),
+			stmt_handlers
 			);
 		CompoundStmt * body = new CompoundStmt( noLabels );
@@ -205,21 +244,39 @@
 
 		return new FunctionDecl("catch", Type::StorageClasses(),
-			LinkageSpec::Cforall, catch_func_t, body);
+			LinkageSpec::Cforall, func_type, body);
 	}
 
 	// Create a single check from a moddified handler.
-	CompoundStmt *create_single_matcher( CatchStmt * modded_handler ) {
-		CompoundStmt * block = new CompoundStmt( noLables );
-
-		appendDeclStmt( block, modded_handler->get_decl() );
-
-		// TODO: This is not the actual check.
-		LogicalExpr * cond = new ConstantExpr( Constant::from_bool( false ) );
+	// except_obj is referenced, modded_handler will be freed.
+	CompoundStmt *create_single_matcher(
+			DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
+		CompoundStmt * block = new CompoundStmt( noLabels );
+
+		// INTEGERconstant Version
+		assert( nullptr == modded_handler->get_decl() );
+		ConstantExpr * number =
+			dynamic_cast<ConstantExpr*>( modded_handler->get_cond() );
+		assert( number );
+		modded_handler->set_cond( nullptr );
+
+		Expression * cond;
+		{
+			std::list<Expression *> args;
+			args.push_back( number );
+
+			std::list<Expression *> rhs_args;
+			rhs_args.push_back( nameOf( except_obj ) );
+			Expression * rhs = new UntypedExpr(
+				new NameExpr( "*?" ), rhs_args );
+			args.push_back( rhs );
+
+			cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args );
+		}
 
 		if ( modded_handler->get_cond() ) {
-			cond = new LogicalExpr( cond, modded_handler->get_cond() )q
+			cond = new LogicalExpr( cond, modded_handler->get_cond() );
 		}
 		block->push_back( new IfStmt( noLabels,
-			cond, modded_handler->get_body() );
+			cond, modded_handler->get_body(), nullptr ) );
 
 		modded_handler->set_decl( nullptr );
@@ -232,4 +289,7 @@
 	FunctionDecl * create_terminate_match( CatchList &handlers ) {
 		CompoundStmt * body = new CompoundStmt( noLabels );
+
+		FunctionType * func_type = match_func_t.clone();
+		DeclarationWithType * except_obj = func_type->get_parameters().back();
 
 		// Index 1..{number of handlers}
@@ -240,32 +300,45 @@
 			CatchStmt * handler = *it;
 
-			// body should have been taken by create_terminate_catch.
-			// assert( nullptr == handler->get_body() );
+			// Body should have been taken by create_terminate_catch.
+			assert( nullptr == handler->get_body() );
+
+			// Create new body.
 			handler->set_body( new ReturnStmt( noLabels,
 				new ConstantExpr( Constant::from_int( index ) ) ) );
 
-			body->push_back( create_single_matcher( handler ) );
-		}
+			// Create the handler.
+			body->push_back( create_single_matcher( except_obj, handler ) );
+			*it = nullptr;
+		}
+
+		body->push_back( new ReturnStmt( noLabels, new ConstantExpr(
+			Constant::from_int( 0 ) ) ) );
 
 		return new FunctionDecl("match", Type::StorageClasses(),
-			LinkageSpec::Cforall, match_func_t, body);
-	}
-
-	Statement * create_terminate_caller(
+			LinkageSpec::Cforall, func_type, body);
+	}
+
+	CompoundStmt * create_terminate_caller(
 			FunctionDecl * try_wrapper,
 			FunctionDecl * terminate_catch,
 			FunctionDecl * terminate_match) {
 
-		ApplicationExpr * caller = new ApplicationExpr( /* ... */ );
-		std::list<Expression *>& args = caller.get_args();
+		UntypedExpr * caller = new UntypedExpr( new NameExpr(
+			"__cfaehm__try_terminate" ) );
+		std::list<Expression *>& args = caller->get_args();
 		args.push_back( nameOf( try_wrapper ) );
 		args.push_back( nameOf( terminate_catch ) );
 		args.push_back( nameOf( terminate_match ) );
 
-		return new ExprStmt( noLabels, caller );
+		CompoundStmt * callStmt = new CompoundStmt( noLabels );
+		callStmt->push_back( new ExprStmt( noLabels, caller ) );
+		return callStmt;
 	}
 
 	FunctionDecl * create_resume_handler( CatchList &handlers ) {
-		CompoundStmt * body = new CompountStmt( noLabels );
+		CompoundStmt * body = new CompoundStmt( noLabels );
+
+		FunctionType * func_type = match_func_t.clone();
+		DeclarationWithType * except_obj = func_type->get_parameters().back();
 
 		CatchList::iterator it;
@@ -280,52 +353,58 @@
 				handling_code->push_back( handler->get_body() );
 			}
-			handling_code->push_back( new ReturnStmt( noLabel,
+			handling_code->push_back( new ReturnStmt( noLabels,
 				new ConstantExpr( Constant::from_bool( false ) ) ) );
 			handler->set_body( handling_code );
 
 			// Create the handler.
-			body->push_back( create_single_matcher( handler ) );
+			body->push_back( create_single_matcher( except_obj, handler ) );
+			*it = nullptr;
 		}
 
 		return new FunctionDecl("handle", Type::StorageClasses(),
-			LinkageSpec::Cforall, handle_func_t, body);
-	}
-
-	Statement * create_resume_wrapper(
+			LinkageSpec::Cforall, func_type, body);
+	}
+
+	CompoundStmt * create_resume_wrapper(
+			StructDecl * node_decl,
 			Statement * wraps,
 			FunctionDecl * resume_handler ) {
 		CompoundStmt * body = new CompoundStmt( noLabels );
 
-		// struct node = {current top resume handler, call to resume_handler};
-		// __attribute__((cleanup( ... )));
-		// set top resume handler to node.
-		// The wrapped statement.
-
-		ListInit * node_init;
-		{
-			std::list<Initializer*> field_inits;
-			field_inits.push_back( new SingleInit( /* ... */ ) );
-			field_inits.push_back( new SingleInit( nameOf( resume_handler ) ) );
-			node_init = new ListInit( field_inits );
-		}
+		// struct __try_resume_node __resume_node
+		//  	__attribute__((cleanup( __cfaehm__try_resume_cleanup )));
+		// ** unwinding of the stack here could cause problems **
+		// ** however I don't think that can happen currently **
+		// __cfaehm__try_resume_setup( &__resume_node, resume_handler );
 
 		std::list< Attribute * > attributes;
 		{
 			std::list< Expression * > attr_params;
-			attr_params.push_back( nameOf( /* ... deconstructor ... */ ) );
-			attrributes.push_back( new Attribute( "cleanup", attr_params ) );
-		}
-
-		appendDeclStmt( body,
-		/**/ ObjectDecl(
-			"resume_node",
+			attr_params.push_back( new NameExpr(
+				"__cfaehm__try_resume_cleanup" ) );
+			attributes.push_back( new Attribute( "cleanup", attr_params ) );
+		}
+
+		ObjectDecl * obj = new ObjectDecl(
+			"__resume_node",
 			Type::StorageClasses(),
 			LinkageSpec::Cforall,
 			nullptr,
-			/* Type* = resume_node */,
-			node_init,
+			new StructInstType(
+				Type::Qualifiers(),
+				node_decl
+				),
+			nullptr,
 			attributes
-			)
-		);
+			);
+		appendDeclStmt( body, obj );
+
+		UntypedExpr *setup = new UntypedExpr( new NameExpr(
+			"__cfaehm__try_resume_setup" ) );
+		setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) );
+		setup->get_args().push_back( nameOf( resume_handler ) );
+
+		body->push_back( new ExprStmt( noLabels, setup ) );
+
 		body->push_back( wraps );
 		return body;
@@ -333,13 +412,18 @@
 
 	FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
-		CompoundStmt * body = tryStmt->get_finally();
+		FinallyStmt * finally = tryStmt->get_finally();
+		CompoundStmt * body = finally->get_block();
+		finally->set_block( nullptr );
+		delete finally;
 		tryStmt->set_finally( nullptr );
 
 		return new FunctionDecl("finally", Type::StorageClasses(),
-			LinkageSpec::Cforall, void_func_t, body);
-	}
-
-	ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) {
-		// struct _cleanup_hook NAME __attribute__((cleanup( ... )));
+			LinkageSpec::Cforall, finally_func_t.clone(), body);
+	}
+
+	ObjectDecl * create_finally_hook(
+			StructDecl * hook_decl, FunctionDecl * finally_wrapper ) {
+		// struct __cfaehm__cleanup_hook __finally_hook
+		//   	__attribute__((cleanup( finally_wrapper )));
 
 		// Make Cleanup Attribute.
@@ -348,13 +432,16 @@
 			std::list< Expression * > attr_params;
 			attr_params.push_back( nameOf( finally_wrapper ) );
-			attrributes.push_back( new Attribute( "cleanup", attr_params ) );
-		}
-
-		return ObjectDecl( /* ... */
-			const std::string &name "finally_hook",
+			attributes.push_back( new Attribute( "cleanup", attr_params ) );
+		}
+
+		return new ObjectDecl(
+			"__finally_hook",
 			Type::StorageClasses(),
 			LinkageSpec::Cforall,
 			nullptr,
-			/* ... Type * ... */,
+			new StructInstType(
+				emptyQualifiers,
+				hook_decl
+				),
 			nullptr,
 			attributes
@@ -363,5 +450,5 @@
 
 
-	class ExceptionMutatorCore : public WithScoping {
+	class ExceptionMutatorCore : public WithGuards {
 		enum Context { NoHandler, TerHandler, ResHandler };
 
@@ -370,5 +457,5 @@
 		// loop, switch or the goto stays within the function.
 
-		Context curContext;
+		Context cur_context;
 
 		// We might not need this, but a unique base for each try block's
@@ -377,11 +464,15 @@
 		//unsigned int try_count = 0;
 
+		StructDecl *node_decl;
+		StructDecl *hook_decl;
 
 	public:
 		ExceptionMutatorCore() :
-			curContext(NoHandler)
+			cur_context(NoHandler),
+			node_decl(nullptr), hook_decl(nullptr)
 		{}
 
-		void premutate( CatchStmt *tryStmt );
+		void premutate( CatchStmt *catchStmt );
+		void premutate( StructDecl *structDecl );
 		Statement * postmutate( ThrowStmt *throwStmt );
 		Statement * postmutate( TryStmt *tryStmt );
@@ -393,9 +484,9 @@
 			if ( throwStmt->get_expr() ) {
 				return create_terminate_throw( throwStmt );
-			} else if ( TerHandler == curContext ) {
+			} else if ( TerHandler == cur_context ) {
 				return create_terminate_rethrow( throwStmt );
 			} else {
 				assertf(false, "Invalid throw in %s at %i\n",
-					throwStmt->location.filename,
+					throwStmt->location.filename.c_str(),
 					throwStmt->location.linenumber);
 				return nullptr;
@@ -404,9 +495,9 @@
 			if ( throwStmt->get_expr() ) {
 				return create_resume_throw( throwStmt );
-			} else if ( ResHandler == curContext ) {
+			} else if ( ResHandler == cur_context ) {
 				return create_resume_rethrow( throwStmt );
 			} else {
 				assertf(false, "Invalid throwResume in %s at %i\n",
-					throwStmt->location.filename,
+					throwStmt->location.filename.c_str(),
 					throwStmt->location.linenumber);
 				return nullptr;
@@ -416,8 +507,11 @@
 
 	Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
+		assert( node_decl );
+		assert( hook_decl );
+
 		// Generate a prefix for the function names?
 
-		CompoundStmt * block = new CompoundStmt();
-		Statement * inner = take_try_block( tryStmt );
+		CompoundStmt * block = new CompoundStmt( noLabels );
+		CompoundStmt * inner = take_try_block( tryStmt );
 
 		if ( tryStmt->get_finally() ) {
@@ -427,13 +521,14 @@
 			appendDeclStmt( block, finally_block );
 			// Create and add the finally cleanup hook.
-			appendDeclStmt( block, create_finally_hook( finally_block ) );
-		}
-
-		StatementList termination_handlers;
-		StatementList resumption_handlers;
-		split( tryStmt->get_handlers(),
-		       termination_handlers, resumption_handlers );
-
-		if ( resumeption_handlers.size() ) {
+			appendDeclStmt( block,
+				create_finally_hook( hook_decl, finally_block ) );
+		}
+
+		CatchList termination_handlers;
+		CatchList resumption_handlers;
+		split( tryStmt->get_catchers(),
+			   termination_handlers, resumption_handlers );
+
+		if ( resumption_handlers.size() ) {
 			// Define the helper function.
 			FunctionDecl * resume_handler =
@@ -441,5 +536,5 @@
 			appendDeclStmt( block, resume_handler );
 			// Prepare hooks
-			inner = create_resume_wrapper( inner, resume_handler );
+			inner = create_resume_wrapper( node_decl, inner, resume_handler );
 		}
 
@@ -462,6 +557,6 @@
 		block->push_back( inner );
 
-		free_all( termination_handlers );
-		free_all( resumption_handlers );
+		//free_all( termination_handlers );
+		//free_all( resumption_handlers );
 
 		return block;
@@ -469,16 +564,32 @@
 
 	void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
-		GuardValue( curContext );
-		if ( CatchStmt::Termination == catchStmt->get_kind() ) {
-			curContext = TerHandler;
+		GuardValue( cur_context );
+		if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
+			cur_context = TerHandler;
 		} else {
-			curContext = ResHandler;
-		}
-	}
-
-    void translateEHM( std::list< Declaration *> & translationUnit ) {
+			cur_context = ResHandler;
+		}
+	}
+
+	void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
+		if ( !structDecl->has_body() ) {
+			// Skip children?
+			return;
+		} else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
+			assert( nullptr == node_decl );
+			node_decl = structDecl;
+		} else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
+			assert( nullptr == hook_decl );
+			hook_decl = structDecl;
+		}
+		// Later we might get the exception type as well.
+	}
+
+	void translateEHM( std::list< Declaration *> & translationUnit ) {
+		init_func_types();
+
 		PassVisitor<ExceptionMutatorCore> translator;
 		for ( Declaration * decl : translationUnit ) {
-			decl->mutate( translator );
+			decl->acceptMutator( translator );
 		}
 	}
Index: src/ControlStruct/ExceptTranslate.h
===================================================================
--- src/ControlStruct/ExceptTranslate.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ControlStruct/ExceptTranslate.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,6 +10,6 @@
 // Created On       : Tus Jun 06 10:13:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Jun 22 15:57:00 2017
-// Update Count     : 0
+// Last Modified On : Fri Jun 30 10:20:00 2017
+// Update Count     : 2
 //
 
@@ -17,5 +17,8 @@
 #define EXCEPT_TRANSLATE_H
 
-namespace ControlFlow {
+#include <list>
+#include "SynTree/SynTree.h"
+
+namespace ControlStruct {
 	void translateEHM( std::list< Declaration *> & translationUnit );
 	/* Converts exception handling structures into their underlying C code.
Index: src/ControlStruct/module.mk
===================================================================
--- src/ControlStruct/module.mk	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ControlStruct/module.mk	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,13 +10,13 @@
 ## Author           : Richard C. Bilson
 ## Created On       : Mon Jun  1 17:49:17 2015
-## Last Modified By : Peter A. Buhr
-## Last Modified On : Thu Aug  4 11:38:06 2016
-## Update Count     : 3
+## Last Modified By : Andrew Beach
+## Last Modified On : Wed Jun 28 16:15:00 2017
+## Update Count     : 4
 ###############################################################################
 
 SRC +=  ControlStruct/LabelGenerator.cc \
 	ControlStruct/LabelFixer.cc \
-        ControlStruct/MLEMutator.cc \
+	ControlStruct/MLEMutator.cc \
 	ControlStruct/Mutate.cc \
-	ControlStruct/ForExprMutator.cc
-
+	ControlStruct/ForExprMutator.cc \
+	ControlStruct/ExceptTranslate.cc
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/GenPoly/Box.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -504,4 +504,5 @@
 		DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
 			if ( functionDecl->get_statements() ) {		// empty routine body ?
+				// std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
 				doBeginScope();
 				scopeTyVars.beginScope();
@@ -548,4 +549,5 @@
 				retval = oldRetval;
 				doEndScope();
+				// std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
 			} // if
 			return functionDecl;
@@ -1116,5 +1118,5 @@
 
 		Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
-			// std::cerr << "mutate appExpr: ";
+			// std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
 			// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
 			// 	std::cerr << i->first << " ";
@@ -1141,8 +1143,17 @@
 			ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
 
+			// std::cerr << function << std::endl;
+			// std::cerr << "scopeTyVars: ";
+			// printTyVarMap( std::cerr, scopeTyVars );
+			// std::cerr << "exprTyVars: ";
+			// printTyVarMap( std::cerr, exprTyVars );
+			// std::cerr << "env: " << *env << std::endl;
+			// std::cerr << needsAdapter( function, scopeTyVars ) << ! needsAdapter( function, exprTyVars) << std::endl;
+
 			// NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr
 			// passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int))
 			// concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome.
 			if ( dynRetType ) {
+				// std::cerr << "dynRetType: " << dynRetType << std::endl;
 				Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
 				ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -22,9 +22,12 @@
 #include "InstantiateGeneric.h"
 
-#include "DeclMutator.h"
 #include "GenPoly.h"
 #include "ScopedSet.h"
 #include "ScrubTyVars.h"
-#include "PolyMutator.h"
+
+#include "Common/PassVisitor.h"
+#include "Common/ScopedMap.h"
+#include "Common/UniqueName.h"
+#include "Common/utility.h"
 
 #include "ResolvExpr/typeops.h"
@@ -34,7 +37,7 @@
 #include "SynTree/Type.h"
 
-#include "Common/ScopedMap.h"
-#include "Common/UniqueName.h"
-#include "Common/utility.h"
+
+#include "InitTweak/InitTweak.h"
+
 
 namespace GenPoly {
@@ -153,23 +156,6 @@
 	}
 
-	// collect the environments of each TypeInstType so that type variables can be replaced
-	// xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments.
-	class EnvFinder final : public GenPoly::PolyMutator {
-	public:
-		using GenPoly::PolyMutator::mutate;
-		virtual Type * mutate( TypeInstType * inst ) override {
-			if ( env ) envMap[inst] = env;
-			return inst;
-		}
-
-		// don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)?
-		virtual Type * mutate( FunctionType * ftype ) override {
-			return ftype;
-		}
-		std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;
-	};
-
 	/// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
-	class GenericInstantiator final : public DeclMutator {
+	struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
 		/// Map of (generic type, parameter list) pairs to concrete type instantiations
 		InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
@@ -178,15 +164,18 @@
 		/// Namer for concrete types
 		UniqueName typeNamer;
-		/// Reference to mapping of environments
-		const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap;
-	public:
-		GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {}
-
-		using DeclMutator::mutate;
-		virtual Type* mutate( StructInstType *inst ) override;
-		virtual Type* mutate( UnionInstType *inst ) override;
-
-		virtual void doBeginScope() override;
-		virtual void doEndScope() override;
+		/// Should not make use of type environment to replace types of function parameter and return values.
+		bool inFunctionType = false;
+		GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
+
+		Type* postmutate( StructInstType *inst );
+		Type* postmutate( UnionInstType *inst );
+
+		void premutate( FunctionType * ftype ) {
+			GuardValue( inFunctionType );
+			inFunctionType = true;
+		}
+
+		void beginScope();
+		void endScope();
 	private:
 		/// Wrap instantiation lookup for structs
@@ -207,8 +196,6 @@
 
 	void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
-		EnvFinder finder;
-		mutateAll( translationUnit, finder );
-		GenericInstantiator instantiator( finder.envMap );
-		instantiator.mutateDeclarationList( translationUnit );
+		PassVisitor<GenericInstantiator> instantiator;
+		mutateAll( translationUnit, instantiator );
 	}
 
@@ -306,6 +293,5 @@
 	Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) {
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
-			if ( envMap.count( typeInst ) ) {
-				TypeSubstitution * env = envMap.at( typeInst );
+			if ( env && ! inFunctionType ) {
 				Type *concrete = env->lookup( typeInst->get_name() );
 				if ( concrete ) {
@@ -331,10 +317,5 @@
 
 
-	Type* GenericInstantiator::mutate( StructInstType *inst ) {
-		// mutate subtypes
-		Type *mutated = Mutator::mutate( inst );
-		inst = dynamic_cast< StructInstType* >( mutated );
-		if ( ! inst ) return mutated;
-
+	Type* GenericInstantiator::postmutate( StructInstType *inst ) {
 		// exit early if no need for further mutation
 		if ( inst->get_parameters().empty() ) return inst;
@@ -368,6 +349,6 @@
 				substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
 				insert( inst, typeSubs, concDecl ); // must insert before recursion
-				concDecl->acceptMutator( *this ); // recursively instantiate members
-				DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
+				concDecl->acceptMutator( *visitor ); // recursively instantiate members
+				declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
 			}
 			StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
@@ -388,10 +369,5 @@
 	}
 
-	Type* GenericInstantiator::mutate( UnionInstType *inst ) {
-		// mutate subtypes
-		Type *mutated = Mutator::mutate( inst );
-		inst = dynamic_cast< UnionInstType* >( mutated );
-		if ( ! inst ) return mutated;
-
+	Type* GenericInstantiator::postmutate( UnionInstType *inst ) {
 		// exit early if no need for further mutation
 		if ( inst->get_parameters().empty() ) return inst;
@@ -423,6 +399,6 @@
 				substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
 				insert( inst, typeSubs, concDecl ); // must insert before recursion
-				concDecl->acceptMutator( *this ); // recursively instantiate members
-				DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
+				concDecl->acceptMutator( *visitor ); // recursively instantiate members
+				declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
 			}
 			UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
@@ -442,12 +418,10 @@
 	}
 
-	void GenericInstantiator::doBeginScope() {
-		DeclMutator::doBeginScope();
+	void GenericInstantiator::beginScope() {
 		instantiations.beginScope();
 		dtypeStatics.beginScope();
 	}
 
-	void GenericInstantiator::doEndScope() {
-		DeclMutator::doEndScope();
+	void GenericInstantiator::endScope() {
 		instantiations.endScope();
 		dtypeStatics.endScope();
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/InitTweak/FixInit.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -104,5 +104,6 @@
 			typedef AddStmtVisitor Parent;
 			using Parent::visit;
-			typedef std::set< ObjectDecl * > ObjectSet;
+			// use ordered data structure to maintain ordering for set_difference and for consistent error messages
+			typedef std::list< ObjectDecl * > ObjectSet;
 			virtual void visit( CompoundStmt *compoundStmt ) override;
 			virtual void visit( DeclStmt *stmt ) override;
@@ -116,10 +117,13 @@
 
 		// debug
-		struct printSet {
-			typedef ObjDeclCollector::ObjectSet ObjectSet;
-			printSet( const ObjectSet & objs ) : objs( objs ) {}
+		template<typename ObjectSet>
+		struct PrintSet {
+			PrintSet( const ObjectSet & objs ) : objs( objs ) {}
 			const ObjectSet & objs;
 		};
-		std::ostream & operator<<( std::ostream & out, const printSet & set) {
+		template<typename ObjectSet>
+		PrintSet<ObjectSet> printSet( const ObjectSet & objs ) { return PrintSet<ObjectSet>( objs ); }
+		template<typename ObjectSet>
+		std::ostream & operator<<( std::ostream & out, const PrintSet<ObjectSet> & set) {
 			out << "{ ";
 			for ( ObjectDecl * obj : set.objs ) {
@@ -724,5 +728,5 @@
 						// static bool __objName_uninitialized = true
 						BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
-						SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ), noDesignators );
+						SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) );
 						ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr );
 						isUninitializedVar->fixUniqueId();
@@ -745,6 +749,6 @@
 
 						Statement * dtor = ctorInit->get_dtor();
-						objDecl->set_init( NULL );
-						ctorInit->set_ctor( NULL );
+						objDecl->set_init( nullptr );
+						ctorInit->set_ctor( nullptr );
 						ctorInit->set_dtor( nullptr );
 						if ( dtor ) {
@@ -799,14 +803,14 @@
 						} else {
 							stmtsToAddAfter.push_back( ctor );
-							objDecl->set_init( NULL );
-							ctorInit->set_ctor( NULL );
+							objDecl->set_init( nullptr );
+							ctorInit->set_ctor( nullptr );
 						}
 					} // if
 				} else if ( Initializer * init = ctorInit->get_init() ) {
 					objDecl->set_init( init );
-					ctorInit->set_init( NULL );
+					ctorInit->set_init( nullptr );
 				} else {
 					// no constructor and no initializer, which is okay
-					objDecl->set_init( NULL );
+					objDecl->set_init( nullptr );
 				} // if
 				delete ctorInit;
@@ -816,5 +820,5 @@
 
 		void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) {
-			std::set< ObjectDecl * > prevVars = curVars;
+			ObjectSet prevVars = curVars;
 			Parent::visit( compoundStmt );
 			curVars = prevVars;
@@ -824,5 +828,5 @@
 			// keep track of all variables currently in scope
 			if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
-				curVars.insert( objDecl );
+				curVars.push_back( objDecl );
 			} // if
 			Parent::visit( stmt );
@@ -939,9 +943,12 @@
 			)
 			if ( ! diff.empty() ) {
+				// create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages.
+				std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() );
+
 				// go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor
 				OrderedDecls ordered;
 				for ( OrderedDecls & rdo : reverseDeclOrder ) {
 					// add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.
-					copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return diff.count( objDecl ); } );
+					copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
 				} // for
 				insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/InitTweak/GenInit.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -44,6 +44,5 @@
 	}
 
-	class ReturnFixer : public WithStmtsToAdd, public WithScopes {
-	  public:
+	struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
 		/// consistently allocates a temporary variable for the return value
 		/// of a function so that anything which the resolver decides can be constructed
@@ -59,8 +58,5 @@
 	};
 
-	class CtorDtor final : public GenPoly::PolyMutator {
-	  public:
-		typedef GenPoly::PolyMutator Parent;
-		using Parent::mutate;
+	struct CtorDtor : public WithGuards, public WithShortCircuiting  {
 		/// create constructor and destructor statements for object declarations.
 		/// the actual call statements will be added in after the resolver has run
@@ -69,18 +65,19 @@
 		static void generateCtorDtor( std::list< Declaration * > &translationUnit );
 
-		virtual DeclarationWithType * mutate( ObjectDecl * ) override;
-		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
+		void previsit( ObjectDecl * );
+		void previsit( FunctionDecl *functionDecl );
+
 		// should not traverse into any of these declarations to find objects
 		// that need to be constructed or destructed
-		virtual Declaration* mutate( StructDecl *aggregateDecl ) override;
-		virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
-		virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
-		virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
-		virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
-		virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
-
-		virtual Type * mutate( FunctionType *funcType ) override { return funcType; }
-
-		virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;
+		void previsit( StructDecl *aggregateDecl );
+		void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
+		void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
+		void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
+		void previsit( TypeDecl *typeDecl ) { visit_children = false; }
+		void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
+
+		void previsit( FunctionType *funcType ) { visit_children = false; }
+
+		void previsit( CompoundStmt * compoundStmt );
 
 	  private:
@@ -211,6 +208,6 @@
 
 	void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
-		CtorDtor ctordtor;
-		mutateAll( translationUnit, ctordtor );
+		PassVisitor<CtorDtor> ctordtor;
+		acceptAll( translationUnit, ctordtor );
 	}
 
@@ -289,5 +286,5 @@
 	}
 
-	DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
+	void CtorDtor::previsit( ObjectDecl * objDecl ) {
 		handleDWT( objDecl );
 		// hands off if @=, extern, builtin, etc.
@@ -301,14 +298,13 @@
 			objDecl->set_init( genCtorInit( objDecl ) );
 		}
-		return Parent::mutate( objDecl );
-	}
-
-	DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
-		ValueGuard< bool > oldInFunc = inFunction;
+	}
+
+	void CtorDtor::previsit( FunctionDecl *functionDecl ) {
+		GuardValue( inFunction );
 		inFunction = true;
 
 		handleDWT( functionDecl );
 
-		managedTypes.beginScope();
+		GuardScope( managedTypes );
 		// go through assertions and recursively add seen ctor/dtors
 		for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
@@ -317,12 +313,14 @@
 			}
 		}
-		// parameters should not be constructed and destructed, so don't mutate FunctionType
-		functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
-
-		managedTypes.endScope();
-		return functionDecl;
-	}
-
-	Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
+
+		PassVisitor<CtorDtor> newCtorDtor;
+		newCtorDtor.pass = *this;
+		maybeAccept( functionDecl->get_statements(), newCtorDtor );
+		visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
+	}
+
+	void CtorDtor::previsit( StructDecl *aggregateDecl ) {
+		visit_children = false; // do not try to construct and destruct aggregate members
+
 		// don't construct members, but need to take note if there is a managed member,
 		// because that means that this type is also managed
@@ -336,14 +334,9 @@
 			}
 		}
-		return aggregateDecl;
-	}
-
-	CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
-		managedTypes.beginScope();
-		CompoundStmt * stmt = Parent::mutate( compoundStmt );
-		managedTypes.endScope();
-		return stmt;
-	}
-
+	}
+
+	void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
+		GuardScope( managedTypes );
+	}
 } // namespace InitTweak
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/InitTweak/InitTweak.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -14,11 +14,8 @@
 		public:
 			bool hasDesignations = false;
-			template<typename Init>
-			void handleInit( Init * init ) {
-				if ( ! init->get_designators().empty() ) hasDesignations = true;
-				else Visitor::visit( init );
-			}
-			virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
-			virtual void visit( ListInit * listInit ) { handleInit( listInit); }
+			virtual void visit( Designation * des ) {
+				if ( ! des->get_designators().empty() ) hasDesignations = true;
+				else Visitor::visit( des );
+			}
 		};
 
Index: src/MakeLibCfa.cc
===================================================================
--- src/MakeLibCfa.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/MakeLibCfa.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -92,5 +92,5 @@
 		assert( ! objDecl->get_init() );
 		std::list< Expression* > noDesignators;
-		objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators, false ) ); // cannot be constructed
+		objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), false ) ); // cannot be constructed
 		newDecls.push_back( objDecl );
 	}
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Makefile.in	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -119,4 +119,5 @@
 	ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \
 	ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \
+	ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT) \
 	GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
 	GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
@@ -161,4 +162,5 @@
 	ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \
 	ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
+	ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
 	SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
 	SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
@@ -394,5 +396,6 @@
 	ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
 	ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
-	ControlStruct/ForExprMutator.cc GenPoly/Box.cc \
+	ControlStruct/ForExprMutator.cc \
+	ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
 	GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
 	GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
@@ -414,12 +417,12 @@
 	ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \
 	ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \
-	ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \
-	SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
-	SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
-	SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
-	SynTree/BasicType.cc SynTree/PointerType.cc \
-	SynTree/ArrayType.cc SynTree/FunctionType.cc \
-	SynTree/ReferenceToType.cc SynTree/TupleType.cc \
-	SynTree/TypeofType.cc SynTree/AttrType.cc \
+	ResolvExpr/TypeEnvironment.cc ResolvExpr/CurrentObject.cc \
+	SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
+	SymTab/FixFunction.cc SymTab/ImplementationType.cc \
+	SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \
+	SynTree/VoidType.cc SynTree/BasicType.cc \
+	SynTree/PointerType.cc SynTree/ArrayType.cc \
+	SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
+	SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
 	SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
 	SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
@@ -592,4 +595,7 @@
 	ControlStruct/$(DEPDIR)/$(am__dirstamp)
 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT):  \
+	ControlStruct/$(am__dirstamp) \
+	ControlStruct/$(DEPDIR)/$(am__dirstamp)
+ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT):  \
 	ControlStruct/$(am__dirstamp) \
 	ControlStruct/$(DEPDIR)/$(am__dirstamp)
@@ -721,4 +727,7 @@
 	ResolvExpr/$(am__dirstamp) \
 	ResolvExpr/$(DEPDIR)/$(am__dirstamp)
+ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT):  \
+	ResolvExpr/$(am__dirstamp) \
+	ResolvExpr/$(DEPDIR)/$(am__dirstamp)
 SymTab/$(am__dirstamp):
 	@$(MKDIR_P) SymTab
@@ -853,4 +862,5 @@
 	-rm -f Common/driver_cfa_cpp-UniqueName.$(OBJEXT)
 	-rm -f Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT)
+	-rm -f ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT)
 	-rm -f ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT)
 	-rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT)
@@ -890,4 +900,5 @@
 	-rm -f ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT)
 	-rm -f ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT)
+	-rm -f ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT)
 	-rm -f ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT)
 	-rm -f ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT)
@@ -965,4 +976,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@
@@ -1002,4 +1014,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
@@ -1355,4 +1368,18 @@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi`
 
+ControlStruct/driver_cfa_cpp-ExceptTranslate.o: ControlStruct/ExceptTranslate.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.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 ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
+
+ControlStruct/driver_cfa_cpp-ExceptTranslate.obj: ControlStruct/ExceptTranslate.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.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 ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
+
 GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc
@@ -1942,4 +1969,18 @@
 @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 ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
+
+ResolvExpr/driver_cfa_cpp-CurrentObject.o: ResolvExpr/CurrentObject.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.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 ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
+
+ResolvExpr/driver_cfa_cpp-CurrentObject.obj: ResolvExpr/CurrentObject.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.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 ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
 
 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
Index: src/Parser/InitializerNode.cc
===================================================================
--- src/Parser/InitializerNode.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Parser/InitializerNode.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -74,30 +74,27 @@
 
 	InitializerNode *moreInit;
-	if  ( get_next() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) != 0) )
+	if ( (moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) ) {
 		moreInit->printOneLine( os );
+	}
 }
 
 Initializer *InitializerNode::build() const {
 	if ( aggregate ) {
+		// steal designators from children
+		std::list< Designation * > designlist;
+		InitializerNode * child = next_init();
+		for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
+			std::list< Expression * > desList;
+			buildList< Expression, ExpressionNode >( child->designator, desList );
+			designlist.push_back( new Designation( desList ) );
+		} // for
 		std::list< Initializer * > initlist;
 		buildList< Initializer, InitializerNode >( next_init(), initlist );
-
-		std::list< Expression * > designlist;
-
-		if ( designator != 0 ) {
-			buildList< Expression, ExpressionNode >( designator, designlist );
-		} // if
-
 		return new ListInit( initlist, designlist, maybeConstructed );
 	} else {
-		std::list< Expression * > designators;
-
-		if ( designator != 0 )
-			buildList< Expression, ExpressionNode >( designator, designators );
-
-		if ( get_expression() != 0)
-			return new SingleInit( maybeBuild< Expression >( get_expression() ), designators, maybeConstructed );
+		if ( get_expression() != 0) {
+			return new SingleInit( maybeBuild< Expression >( get_expression() ), maybeConstructed );
+		}
 	} // if
-
 	return 0;
 }
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Parser/TypeData.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -760,5 +760,5 @@
 		if ( cur->has_enumeratorValue() ) {
 			ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
-			member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), list< Expression * >() ) );
+			member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
 		} // if
 	} // for
@@ -777,6 +777,7 @@
 TupleType * buildTuple( const TypeData * td ) {
 	assert( td->kind == TypeData::Tuple );
-	TupleType * ret = new TupleType( buildQualifiers( td ) );
-	buildTypeList( td->tuple, ret->get_types() );
+	std::list< Type * > types;
+	buildTypeList( td->tuple, types );
+	TupleType * ret = new TupleType( buildQualifiers( td ), types );
 	buildForall( td->forall, ret->get_forall() );
 	return ret;
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Parser/parser.yy	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -9,7 +9,7 @@
 // Author           : Peter A. Buhr
 // Created On       : Sat Sep  1 20:22:55 2001
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jun 28 22:11:22 2017
-// Update Count     : 2414
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Jun 30 15:38:00 2017
+// Update Count     : 2415
 //
 
@@ -104,4 +104,5 @@
 	std::string * str;
 	bool flag;
+	CatchStmt::Kind catch_kind;
 }
 
@@ -192,4 +193,5 @@
 %type<sn> switch_clause_list_opt		switch_clause_list			choose_clause_list_opt		choose_clause_list
 %type<sn> /* handler_list */			handler_clause				finally_clause
+%type<catch_kind> handler_key
 
 // declarations
@@ -958,17 +960,20 @@
 handler_clause:
 	// TEMPORARY, TEST EXCEPTIONS
-	CATCH '(' push push INTEGERconstant pop ')' compound_statement pop
-		{ $$ = new StatementNode( build_catch( CatchStmt::Terminate, nullptr, new ExpressionNode( build_constantInteger( *$5 ) ), $8 ) ); }
-	| handler_clause CATCH '(' push push INTEGERconstant pop ')' compound_statement pop
-		{ $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, nullptr, new ExpressionNode( build_constantInteger( *$6 ) ), $9 ) ) ); }
-
-	| CATCH '(' push push exception_declaration pop ')' compound_statement pop
-		{ $$ = new StatementNode( build_catch( CatchStmt::Terminate, $5, nullptr, $8 ) ); }
-	| handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop
-		{ $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, $6, nullptr, $9 ) ) ); }
-	| CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop
-		{ $$ = new StatementNode( build_catch( CatchStmt::Resume, $5, nullptr, $8 ) ); }
-	| handler_clause CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop
-		{ $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Resume, $6, nullptr, $9 ) ) ); }
+	handler_key '(' push push INTEGERconstant pop ')' compound_statement pop
+		{ $$ = new StatementNode( build_catch( $1, nullptr, new ExpressionNode( build_constantInteger( *$5 ) ), $8 ) ); }
+	| handler_clause handler_key '(' push push INTEGERconstant pop ')' compound_statement pop
+		{ $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, nullptr, new ExpressionNode( build_constantInteger( *$6 ) ), $9 ) ) ); }
+
+	| handler_key '(' push push exception_declaration pop ')' compound_statement pop
+		{ $$ = new StatementNode( build_catch( $1, $5, nullptr, $8 ) ); }
+	| handler_clause handler_key '(' push push exception_declaration pop ')' compound_statement pop
+		{ $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, nullptr, $9 ) ) ); }
+	;
+
+handler_key:
+	CATCH
+		{ $$ = CatchStmt::Terminate; }
+	| CATCHRESUME
+		{ $$ = CatchStmt::Resume; }
 	;
 
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -604,10 +604,10 @@
 //	    )
 		SymTab::Indexer decls( indexer );
-		PRINT(
-			std::cerr << "============= original indexer" << std::endl;
-			indexer.print( std::cerr );
-			std::cerr << "============= new indexer" << std::endl;
-			decls.print( std::cerr );
-		)
+		// PRINT(
+		// 	std::cerr << "============= original indexer" << std::endl;
+		// 	indexer.print( std::cerr );
+		// 	std::cerr << "============= new indexer" << std::endl;
+		// 	decls.print( std::cerr );
+		// )
 		addToIndexer( have, decls );
 		AssertionSet newNeed;
@@ -809,4 +809,30 @@
 	}
 
+	Expression * restructureCast( Expression * argExpr, Type * toType ) {
+		if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
+			// Argument expression is a tuple and the target type is not void. Cast each member of the tuple
+			// to its corresponding target type, producing the tuple of those cast expressions. If there are
+			// more components of the tuple than components in the target type, then excess components do not
+			// come out in the result expression (but UniqueExprs ensure that side effects will still be done).
+			if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
+				// expressions which may contain side effects require a single unique instance of the expression.
+				argExpr = new UniqueExpr( argExpr );
+			}
+			std::list< Expression * > componentExprs;
+			for ( unsigned int i = 0; i < toType->size(); i++ ) {
+				// cast each component
+				TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
+				componentExprs.push_back( restructureCast( idx, toType->getComponent( i ) ) );
+			}
+			delete argExpr;
+			assert( componentExprs.size() > 0 );
+			// produce the tuple of casts
+			return new TupleExpr( componentExprs );
+		} else {
+			// handle normally
+			return new CastExpr( argExpr, toType->clone() );
+		}
+	}
+
 	void AlternativeFinder::visit( CastExpr *castExpr ) {
 		Type *& toType = castExpr->get_result();
@@ -840,28 +866,5 @@
 				thisCost += Cost( 0, 0, discardedValues );
 
-				Expression * argExpr = i->expr->clone();
-				if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) {
-					// Argument expression is a tuple and the target type is not void. Cast each member of the tuple
-					// to its corresponding target type, producing the tuple of those cast expressions. If there are
-					// more components of the tuple than components in the target type, then excess components do not
-					// come out in the result expression (but UniqueExprs ensure that side effects will still be done).
-					if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
-						// expressions which may contain side effects require a single unique instance of the expression.
-						argExpr = new UniqueExpr( argExpr );
-					}
-					std::list< Expression * > componentExprs;
-					for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) {
-						// cast each component
-						TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
-						componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) );
-					}
-					delete argExpr;
-					assert( componentExprs.size() > 0 );
-					// produce the tuple of casts
-					candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) );
-				} else {
-					// handle normally
-					candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) );
-				}
+				candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
 			} // if
 		} // for
@@ -1182,4 +1185,51 @@
 	}
 
+	void AlternativeFinder::visit( UntypedInitExpr *initExpr ) {
+		// handle each option like a cast
+		AltList candidates;
+		PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; )
+		// O(N^2) checks of d-types with e-types
+		for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
+			Type * toType = resolveTypeof( initAlt.type, indexer );
+			SymTab::validateType( toType, &indexer );
+			adjustExprType( toType, env, indexer );
+			// Ideally the call to findWithAdjustment could be moved out of the loop, but unfortunately it currently has to occur inside or else
+			// polymorphic return types are not properly bound to the initialization type, since return type variables are only open for the duration of resolving
+			// the UntypedExpr. This is only actually an issue in initialization contexts that allow more than one possible initialization type, but it is still suboptimal.
+			AlternativeFinder finder( indexer, env );
+			finder.targetType = toType;
+			finder.findWithAdjustment( initExpr->get_expr() );
+			for ( Alternative & alt : finder.get_alternatives() ) {
+				TypeEnvironment newEnv( alt.env );
+				AssertionSet needAssertions, haveAssertions;
+				OpenVarSet openVars;  // find things in env that don't have a "representative type" and claim those are open vars?
+				PRINT( std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl; )
+				// It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
+				// cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
+				// that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
+				// to.
+				int discardedValues = alt.expr->get_result()->size() - toType->size();
+				if ( discardedValues < 0 ) continue;
+				// xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
+				// allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
+				// unification run for side-effects
+				unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
+
+				Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv );
+				if ( thisCost != Cost::infinity ) {
+					// count one safe conversion for each value that is thrown away
+					thisCost += Cost( 0, 0, discardedValues );
+					candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
+				}
+			}
+		}
+
+		// findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the
+		// cvtCost member to the cost member (since the old cost is now irrelevant).  Thus, calling findMinCost twice
+		// selects first based on argument cost, then on conversion cost.
+		AltList minArgCost;
+		findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
+		findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -73,4 +73,5 @@
 		virtual void visit( UniqueExpr *unqExpr );
 		virtual void visit( StmtExpr *stmtExpr );
+		virtual void visit( UntypedInitExpr *initExpr );
 		/// Runs a new alternative finder on each element in [begin, end)
 		/// and writes each alternative finder to out.
Index: src/ResolvExpr/CurrentObject.cc
===================================================================
--- src/ResolvExpr/CurrentObject.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
+++ src/ResolvExpr/CurrentObject.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -0,0 +1,587 @@
+//
+// 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.
+//
+// CurrentObject.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Tue Jun 13 15:28:32 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Jun 13 15:28:44 2017
+// Update Count     : 2
+//
+
+#include <stack>
+#include <iostream>
+
+#include "CurrentObject.h"
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Type.h"
+#include "SynTree/TypeSubstitution.h"
+
+#if 0
+#define PRINT(x) x
+#else
+#define PRINT(x)
+#endif
+
+namespace ResolvExpr {
+	long long int getConstValue( ConstantExpr * constExpr ) {
+		if ( BasicType * basicType = dynamic_cast< BasicType * >( constExpr->get_result() ) ) {
+			if ( basicType->isInteger() ) {
+				return constExpr->get_constant()->get_ival();
+			} else {
+				assertf( false, "Non-integer constant expression in getConstValue", toString( constExpr ).c_str() ); // xxx - might be semantic error
+			}
+		} else if ( dynamic_cast< OneType * >( constExpr->get_result() ) ) {
+			return 1;
+		} else if ( dynamic_cast< ZeroType * >( constExpr->get_result() ) ) {
+			return 0;
+		} else {
+			assertf( false, "unhandled type on getConstValue %s", toString( constExpr->get_result() ).c_str() ); // xxx - might be semantic error
+		}
+	}
+
+	struct Indenter {
+		static const int amt = 2;
+		unsigned int indent = 0;
+
+		Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; }
+		Indenter & operator-=(int nlevels) { indent -= amt*nlevels; return *this; }
+		Indenter operator+(int nlevels) { Indenter indenter = *this; return indenter += nlevels; }
+		Indenter operator-(int nlevels) { Indenter indenter = *this; return indenter -= nlevels; }
+		Indenter & operator++() { return *this += 1; }
+		Indenter & operator--() { return *this -= 1; }
+	};
+	std::ostream & operator<<( std::ostream & out, Indenter & indent ) {
+		return out << std::string(indent.indent, ' ');
+	}
+
+	template< typename AggrInst >
+	TypeSubstitution makeGenericSubstitution( AggrInst * inst ) {
+		assert( inst );
+		assert( inst->get_baseParameters() );
+		std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
+		std::list< Expression * > typeSubs = inst->get_parameters();
+		TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
+		return subs;
+	}
+
+	TypeSubstitution makeGenericSubstitution( Type * type ) {
+		if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) {
+			return makeGenericSubstitution( inst );
+		} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) {
+			return makeGenericSubstitution( inst );
+		} else {
+			return TypeSubstitution();
+		}
+	}
+
+	class MemberIterator {
+	public:
+		virtual ~MemberIterator() {}
+
+		virtual void setPosition( std::list< Expression * > & designators ) = 0;
+		virtual std::list<InitAlternative> operator*() const = 0;
+		virtual operator bool() const = 0;
+		virtual MemberIterator & bigStep() = 0;
+		virtual MemberIterator & smallStep() = 0;
+		virtual Type * getType() = 0;
+		virtual Type * getNext() = 0;
+
+		virtual void print( std::ostream & out, Indenter indent ) const = 0;
+
+		virtual std::list<InitAlternative> first() const = 0; // should be protected
+	};
+
+	std::ostream & operator<<(std::ostream & out, const MemberIterator & it) {
+		Indenter indenter;
+		it.print( out, indenter );
+		return out;
+	}
+
+	/// create a new MemberIterator that traverses a type correctly
+	MemberIterator * createMemberIterator( Type * type );
+
+	/// iterates "other" types, e.g. basic types, pointer types, etc. which do not change at list initializer entry
+	class SimpleIterator : public MemberIterator {
+	public:
+		SimpleIterator( Type * type ) : type( type ) {}
+
+		virtual void setPosition( std::list< Expression * > & designators ) {
+			assertf( designators.empty(), "simple iterator given non-empty designator..." ); // xxx - might be semantic error
+		}
+
+		virtual std::list<InitAlternative> operator*() const { return first(); }
+		virtual operator bool() const { return type; }
+
+		// big step is the same as small step
+		virtual MemberIterator & bigStep() { return smallStep(); }
+		virtual MemberIterator & smallStep() {
+			type = nullptr;  // type is nullified on increment since SimpleIterators do not have members
+			return *this;
+		}
+
+		virtual void print( std::ostream & out, Indenter indent ) const {
+			out << "SimpleIterator(" << type << ")";
+		}
+
+		virtual Type * getType() { return type; }
+		virtual Type * getNext() { return type; }
+
+	protected:
+		virtual std::list<InitAlternative> first() const {
+			if ( type ) return std::list<InitAlternative>{ { type->clone(), new Designation( {} ) } };
+			else return std::list<InitAlternative>{};
+		}
+	private:
+		Type * type = nullptr;
+	};
+
+	class ArrayIterator : public MemberIterator {
+	public:
+		ArrayIterator( ArrayType * at ) : array( at ) {
+			PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )
+			base = at->get_base();
+			memberIter = createMemberIterator( base );
+			setSize( at->get_dimension() );
+		}
+
+		~ArrayIterator() {
+			delete memberIter;
+		}
+
+	private:
+		void setSize( Expression * expr ) {
+			if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
+				size = getConstValue( constExpr );
+				PRINT( std::cerr << "array type with size: " << size << std::endl; )
+			}	else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
+				setSize( castExpr->get_arg() ); // xxx - need to perform the conversion specified by the cast
+			} else {
+				assertf( false, "unhandled expression in setSize: %s", toString( expr ).c_str() ); // xxx - if not a constant expression, it's not simple to determine how long the array actually is, which is necessary for initialization to be done correctly -- fix this
+			}
+		}
+
+	public:
+		void setPosition( Expression * expr ) {
+			// need to permit integer-constant-expressions, including: integer constants, enumeration constants, character constants, sizeof expressions, _Alignof expressions, cast expressions
+			if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
+				index = getConstValue( constExpr );
+			} else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
+				setPosition( castExpr->get_arg() );
+			} else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
+				assertf( dynamic_cast<EnumInstType *> ( varExpr->get_result() ), "ArrayIterator given variable that isn't an enum constant", toString( expr ).c_str() );
+				index = 0; // xxx - get actual value of enum constant
+			} else if ( dynamic_cast< SizeofExpr * >( expr ) || dynamic_cast< AlignofExpr * >( expr ) ) {
+				index = 0; // xxx - get actual sizeof/alignof value?
+			} else {
+				assertf( false, "bad designator given to ArrayIterator: %s", toString( expr ).c_str() );
+			}
+		}
+
+		virtual void setPosition( std::list< Expression * > & designators ) {
+			if ( ! designators.empty() ) {
+				setPosition( designators.front() );
+				designators.pop_front();
+				memberIter->setPosition( designators );
+			}
+		}
+
+		virtual std::list<InitAlternative> operator*() const {
+			return first();
+		}
+
+		virtual operator bool() const { return index < size; }
+
+		virtual MemberIterator & bigStep() {
+			PRINT( std::cerr << "bigStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
+			++index;
+			delete memberIter;
+			if ( index < size ) memberIter = createMemberIterator( base );
+			else memberIter = nullptr;
+			return *this;
+		}
+
+		virtual MemberIterator & smallStep() {
+			PRINT( std::cerr << "smallStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
+			if ( memberIter ) {
+				PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; )
+				memberIter->smallStep();
+				if ( *memberIter ) {
+					PRINT( std::cerr << "has valid member iter" << std::endl; )
+					return *this;
+				}
+			}
+			return bigStep();
+		}
+
+		virtual Type * getType() { return array; }
+		virtual Type * getNext() { return base; }
+
+		virtual std::list<InitAlternative> first() const {
+			PRINT( std::cerr << "first in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
+			if ( memberIter && *memberIter ) {
+				std::list<InitAlternative> ret = memberIter->first();
+				for ( InitAlternative & alt : ret ) {
+					alt.designation->get_designators().push_front( new ConstantExpr( Constant::from_ulong( index ) ) );
+				}
+				return ret;
+			}
+			return std::list<InitAlternative>();
+		}
+
+		virtual void print( std::ostream & out, Indenter indent ) const {
+			out << "ArrayIterator(Array of " << base << ")";
+			if ( memberIter ) {
+				Indenter childIndent = indent+1;
+				out << std::endl << childIndent;
+				memberIter->print( out, childIndent );
+			}
+		}
+
+	private:
+		ArrayType * array = nullptr;
+		Type * base = nullptr;
+		size_t index = 0;
+		size_t size = 0;
+		MemberIterator * memberIter = nullptr;
+	};
+
+	class AggregateIterator : public MemberIterator {
+	public:
+		typedef std::list<Declaration *> MemberList;
+		typedef MemberList::const_iterator iterator;
+		std::string kind = ""; // for debug
+		std::string name;
+		Type * inst = nullptr;
+		const MemberList & members;
+		iterator curMember;
+		bool atbegin = true; // false at first {small,big}Step -- this aggr type is only added to the possibilities at the beginning
+		Type * curType = nullptr;
+		MemberIterator * memberIter = nullptr;
+		mutable TypeSubstitution sub;
+
+		AggregateIterator( const std::string & kind, const std::string & name, Type * inst, const MemberList & members ) : kind( kind ), name( name ), inst( inst ), members( members ), curMember( members.begin() ), sub( makeGenericSubstitution( inst ) ) {
+			init();
+		}
+
+		virtual ~AggregateIterator() {
+			delete memberIter;
+		}
+
+		bool init() {
+			PRINT( std::cerr << "--init()--" << members.size() << std::endl; )
+			if ( curMember != members.end() ) {
+				if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( *curMember ) ) {
+					PRINT( std::cerr << "incremented to field: " << field << std::endl; )
+					curType = field->get_type();
+					memberIter = createMemberIterator( curType );
+					return true;
+				}
+			}
+			return false;
+		}
+
+		virtual std::list<InitAlternative> operator*() const {
+			if (memberIter && *memberIter) {
+				std::list<InitAlternative> ret = memberIter->first();
+				PRINT( std::cerr << "sub: " << sub << std::endl; )
+				for ( InitAlternative & alt : ret ) {
+					PRINT( std::cerr << "iterating and adding designators" << std::endl; )
+					alt.designation->get_designators().push_front( new VariableExpr( safe_dynamic_cast< ObjectDecl * >( *curMember ) ) );
+					// need to substitute for generic types, so that casts are to concrete types
+					PRINT( std::cerr << "  type is: " << alt.type; )
+					sub.apply( alt.type ); // also apply to designation??
+					PRINT( std::cerr << " ==> " << alt.type << std::endl; )
+				}
+				return ret;
+			}
+			return std::list<InitAlternative>();
+		}
+
+		virtual void setPosition( std::list< Expression * > & designators ) {
+			if ( ! designators.empty() ) {
+				if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( designators.front() ) ) {
+					for ( curMember = members.begin(); curMember != members.end(); ++curMember ) {
+						if ( *curMember == varExpr->get_var() ) {
+							designators.pop_front();
+							delete memberIter;
+							memberIter = createMemberIterator( varExpr->get_result() );
+							curType = varExpr->get_result();
+							atbegin = curMember == members.begin() && designators.empty(); // xxx - is this the right condition for atbegin??
+							memberIter->setPosition( designators );
+							return;
+						} // if
+					} // for
+					assertf( false, "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() );
+				} else {
+					assertf( false, "bad designator given to %s: %s", kind.c_str(), toString( designators.front() ).c_str() );
+				} // if
+			} // if
+		}
+
+		virtual MemberIterator & smallStep() {
+			PRINT( std::cerr << "smallStep in " << kind << std::endl; )
+			atbegin = false;
+			if ( memberIter ) {
+				PRINT( std::cerr << "has member iter, incrementing..." << std::endl; )
+				memberIter->smallStep();
+				if ( *memberIter ) {
+					PRINT( std::cerr << "success!" << std::endl; )
+					return *this;
+				}
+			}
+			return bigStep();
+		}
+
+		virtual Type * getType() { return inst; }
+		virtual Type * getNext() {
+			if ( memberIter && *memberIter ) return memberIter->getType(); // xxx - ??? recursive call???
+			return nullptr;
+		}
+
+		virtual std::list<InitAlternative> first() const {
+			std::list<InitAlternative> ret;
+			PRINT( std::cerr << "first " << kind << std::endl; )
+			if ( memberIter && *memberIter ) { // might not need *memberIter??
+				PRINT( std::cerr << "adding children" << std::endl; )
+				ret = memberIter->first();
+				for ( InitAlternative & alt : ret ) {
+					PRINT( std::cerr << "iterating and adding designators" << std::endl; )
+					alt.designation->get_designators().push_front( new VariableExpr( safe_dynamic_cast< ObjectDecl * >( *curMember ) ) );
+				}
+			}
+			// if ( curMember == std::next( decl->get_members().begin(), 1 ) ) { // xxx - this never triggers because curMember is incremented immediately on construction
+			if ( atbegin ) { // xxx - this never triggers because curMember is incremented immediately on construction
+				// xxx - what about case of empty struct??
+				// only add self if at the very beginning of the structure
+				PRINT( std::cerr << "adding self" << std::endl; )
+				ret.push_front( { inst->clone(), new Designation( {} ) } );
+			}
+			return ret;
+		}
+
+		virtual void print( std::ostream & out, Indenter indent ) const {
+			out << kind << "(" << name << ")";
+			if ( memberIter ) {
+				Indenter childIndent = indent+1;
+				out << std::endl << childIndent;
+				memberIter->print( out, childIndent );
+			}
+		}
+	};
+
+	class UnionIterator : public AggregateIterator {
+	public:
+		UnionIterator( UnionInstType * inst ) : AggregateIterator( "UnionIterator", inst->get_name(), inst, inst->get_baseUnion()->get_members() ) {}
+
+		virtual operator bool() const { return (memberIter && *memberIter); }
+		virtual MemberIterator & bigStep() {
+			// unions only initialize one member
+			PRINT( std::cerr << "bigStep in " << kind << std::endl; )
+			atbegin = false;
+			delete memberIter;
+			memberIter = nullptr;
+			curType = nullptr;
+			curMember = members.end();
+			return *this;
+		}
+		virtual std::list<InitAlternative> first() const { return std::list<InitAlternative>{}; }
+	};
+
+	class StructIterator : public AggregateIterator {
+	public:
+		StructIterator( StructInstType * inst ) : AggregateIterator( "StructIterator", inst->get_name(), inst, inst->get_baseStruct()->get_members() ) {}
+
+		virtual operator bool() const { return curMember != members.end() || (memberIter && *memberIter); }
+
+		virtual MemberIterator & bigStep() {
+			PRINT( std::cerr << "bigStep in " << kind << std::endl; )
+			atbegin = false;
+			delete memberIter;
+			memberIter = nullptr;
+			curType = nullptr;
+			for ( ; curMember != members.end(); ) {
+				++curMember;
+				if ( init() ) {
+					return *this;
+				}
+			}
+			return *this;
+		}
+	};
+
+	class TupleIterator : public AggregateIterator {
+	public:
+		TupleIterator( TupleType * inst ) : AggregateIterator( "TupleIterator", toString("Tuple", inst->size()), inst, inst->get_members() ) {}
+
+		virtual operator bool() const { return curMember != members.end() || (memberIter && *memberIter); }
+
+		virtual MemberIterator & bigStep() {
+			PRINT( std::cerr << "bigStep in " << kind << std::endl; )
+			atbegin = false;
+			delete memberIter;
+			memberIter = nullptr;
+			curType = nullptr;
+			for ( ; curMember != members.end(); ) {
+				++curMember;
+				if ( init() ) {
+					return *this;
+				}
+			}
+			return *this;
+		}
+	};
+
+	MemberIterator * createMemberIterator( Type * type ) {
+		if ( ReferenceToType * aggr = dynamic_cast< ReferenceToType * >( type ) ) {
+			if ( StructInstType * sit = dynamic_cast< StructInstType * >( aggr ) ) {
+				return new StructIterator( sit );
+			} else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( aggr ) ) {
+				return new UnionIterator( uit );
+			} else {
+				assertf( dynamic_cast< TypeInstType * >( type ), "some other reftotype" );
+				return new SimpleIterator( type );
+			}
+		} else if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
+			return new ArrayIterator( at );
+		} else if ( TupleType * tt = dynamic_cast< TupleType * >( type ) ) {
+			return new TupleIterator( tt );
+		} else {
+			return new SimpleIterator( type );
+		}
+	}
+
+	CurrentObject::CurrentObject() {}
+	CurrentObject::CurrentObject( Type * type ) {
+		objStack.push( new SimpleIterator( type ) );
+	}
+
+
+	void CurrentObject::setNext( Designation * designation ) {
+		assertf( ! objStack.empty(), "obj stack empty in setNext" );
+		PRINT( std::cerr << "____setNext" << designation << std::endl; )
+		objStack.top()->setPosition( designation->get_designators() );
+	}
+
+	Designation * CurrentObject::findNext( Designation * designation ) {
+		typedef std::list< Expression * > DesignatorChain;
+		PRINT( std::cerr << "___findNext" << std::endl; )
+		// find all the d's
+		std::list<DesignatorChain> desigAlts{ { } }, newDesigAlts;
+		std::list<Type *> curTypes { (objStack.top())->getType() }, newTypes;
+		for ( Expression * expr : designation->get_designators() ) {
+			PRINT( std::cerr << "____untyped: " << expr << std::endl; )
+			std::list<DesignatorChain>::iterator dit = desigAlts.begin();
+			if ( NameExpr * nexpr = dynamic_cast<NameExpr *>(expr) ) {
+				for ( Type * t : curTypes ) {
+					assert( dit != desigAlts.end() );
+					DesignatorChain & d = *dit;
+					PRINT( std::cerr << "____actual: " << t << std::endl; )
+					ReferenceToType * refType = dynamic_cast<ReferenceToType *>(t);
+					std::list<Declaration *> members;
+					if ( refType ) {
+						refType->lookup( nexpr->get_name(), members ); // concatenate identical field name
+						// xxx - need to also include anonymous members in this somehow...
+						for ( Declaration * mem: members ) {
+							if ( ObjectDecl * field = dynamic_cast<ObjectDecl *>(mem) ) {
+								PRINT( std::cerr << "____alt: " << field->get_type() << std::endl; )
+								DesignatorChain newD = d;
+								newD.push_back( new VariableExpr( field ) );
+								newDesigAlts.push_back( newD );
+								newTypes.push_back( field->get_type() );
+							} // if
+						} // for
+					} // if
+					++dit;
+				} // for
+			} else {
+				for ( Type * t : curTypes ) {
+					assert( dit != desigAlts.end() );
+					DesignatorChain & d = *dit;
+					if ( ArrayType * at = dynamic_cast< ArrayType * > ( t ) ) {
+						PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; )
+						d.push_back( expr );
+						newDesigAlts.push_back( d );
+						newTypes.push_back( at->get_base() );
+					}
+					++dit;
+				} // for
+			} // if
+			desigAlts = newDesigAlts;
+			newDesigAlts.clear();
+			curTypes = newTypes;
+			newTypes.clear();
+			assertf( desigAlts.size() == curTypes.size(), "Designator alternatives (%d) and current types (%d) out of sync", desigAlts.size(), curTypes.size() );
+		} // for
+		if ( desigAlts.size() > 1 ) {
+			throw SemanticError( toString("Too many alternatives (", desigAlts.size(), ") for designation: "), designation );
+		} else if ( desigAlts.size() == 0 ) {
+			throw SemanticError( "No reasonable alternatives for designation: ", designation );
+		}
+		DesignatorChain & d = desigAlts.back();
+		PRINT( for ( Expression * expr : d ) {
+			std::cerr << "____desig: " << expr << std::endl;
+		} ) // for
+		assertf( ! curTypes.empty(), "empty designator chosen");
+
+		// set new designators
+		assertf( ! objStack.empty(), "empty object stack when setting designation" );
+		Designation * actualDesignation = new Designation( d );
+		objStack.top()->setPosition( d ); // destroys d
+		return actualDesignation;
+	}
+
+	void CurrentObject::increment() {
+		PRINT( std::cerr << "____increment" << std::endl; )
+		if ( ! objStack.empty() ) {
+			PRINT( std::cerr << *objStack.top() << std::endl; )
+			objStack.top()->smallStep();
+		}
+	}
+
+	void CurrentObject::enterListInit() {
+		PRINT( std::cerr << "____entering list init" << std::endl; )
+		assertf( ! objStack.empty(), "empty obj stack entering list init" );
+		Type * type = objStack.top()->getNext();
+		if ( type ) {
+			objStack.push( createMemberIterator( type ) );
+		} else {
+			assertf( false, "not sure about this case..." );
+		}
+	}
+
+	void CurrentObject::exitListInit() {
+		PRINT( std::cerr << "____exiting list init" << std::endl; )
+		assertf( ! objStack.empty(), "objstack empty" );
+		delete objStack.top();
+		objStack.pop();
+		if ( ! objStack.empty() ) {
+			PRINT( std::cerr << *objStack.top() << std::endl; )
+			objStack.top()->bigStep();
+		}
+	}
+
+	std::list< InitAlternative > CurrentObject::getOptions() {
+		PRINT( std::cerr << "____getting current options" << std::endl; )
+		assertf( ! objStack.empty(), "objstack empty in getOptions" );
+		return **objStack.top();
+	}
+
+	Type * CurrentObject::getCurrentType() {
+		PRINT( std::cerr << "____getting current type" << std::endl; )
+		assertf( ! objStack.empty(), "objstack empty in getCurrentType" );
+		return objStack.top()->getNext();
+	}
+} // namespace ResolvExpr
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/CurrentObject.h
===================================================================
--- src/ResolvExpr/CurrentObject.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
+++ src/ResolvExpr/CurrentObject.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -0,0 +1,59 @@
+//
+// 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.
+//
+// CurrentObject.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Thu Jun  8 11:07:25 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Jun  8 11:07:41 2017
+// Update Count     : 2
+//
+
+#ifndef CURRENT_OBJECT_H
+#define CURRENT_OBJECT_H
+
+#include <stack>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Expression.h"
+
+namespace ResolvExpr {
+	class MemberIterator;
+
+	class CurrentObject {
+	public:
+		CurrentObject();
+		CurrentObject( Type * type );
+
+		/// resolves unresolved designation
+		Designation * findNext( Designation * designation );
+		/// sets current position using resolved designation
+		void setNext( Designation * designation );
+		/// steps to next sub-object of current-object
+		void increment();
+		/// sets new current-object for the duration of this brace-enclosed initializer-list
+		void enterListInit();
+		/// restores previous current-object
+		void exitListInit();
+		/// produces a list of alternatives (Type *, Designation *) for the current sub-object's initializer
+		std::list< InitAlternative > getOptions();
+		/// produces the type of the current object but no subobjects
+		Type * getCurrentType();
+
+	private:
+		std::stack< MemberIterator * > objStack;
+	};
+} // namespace ResolvExpr
+
+#endif // CURRENT_OBJECT_H
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
+
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ResolvExpr/Resolver.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -14,20 +14,26 @@
 //
 
+#include <iostream>
+
+#include "Alternative.h"
+#include "AlternativeFinder.h"
+#include "CurrentObject.h"
+#include "RenameVars.h"
 #include "Resolver.h"
-#include "AlternativeFinder.h"
-#include "Alternative.h"
-#include "RenameVars.h"
 #include "ResolveTypeof.h"
 #include "typeops.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
 #include "SynTree/Statement.h"
 #include "SynTree/Type.h"
-#include "SynTree/Expression.h"
-#include "SynTree/Initializer.h"
+
+#include "SymTab/Autogen.h"
 #include "SymTab/Indexer.h"
-#include "SymTab/Autogen.h"
+
 #include "Common/utility.h"
+
 #include "InitTweak/InitTweak.h"
 
-#include <iostream>
 using namespace std;
 
@@ -39,5 +45,5 @@
 			if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) {
 				functionReturn = res->functionReturn;
-				initContext = res->initContext;
+				currentObject = res->currentObject;
 				inEnumDecl = res->inEnumDecl;
 			}
@@ -64,4 +70,5 @@
 		virtual void visit( BranchStmt *branchStmt ) override;
 		virtual void visit( ReturnStmt *returnStmt ) override;
+		virtual void visit( ThrowStmt *throwStmt ) override;
 
 		virtual void visit( SingleInit *singleInit ) override;
@@ -79,5 +86,5 @@
 
 		Type * functionReturn = nullptr;
-		Type *initContext = nullptr;
+		CurrentObject currentObject = nullptr;
 		bool inEnumDecl = false;
 	};
@@ -186,17 +193,16 @@
 		// each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
 		// the RHS.
-		Type *temp = initContext;
-		initContext = new_type;
-		if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
+		ValueGuard<CurrentObject> temp( currentObject );
+		currentObject = CurrentObject( objectDecl->get_type() );
+		if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
 			// enumerator initializers should not use the enum type to initialize, since
 			// the enum type is still incomplete at this point. Use signed int instead.
-			initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
+			currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
 		}
 		Parent::visit( objectDecl );
-		if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
+		if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
 			// delete newly created signed int type
-			delete initContext;
-		}
-		initContext = temp;
+			// delete currentObject.getType();
+		}
 	}
 
@@ -315,5 +321,5 @@
 
 	void Resolver::visit( SwitchStmt *switchStmt ) {
-		ValueGuard< Type * > oldInitContext( initContext );
+		ValueGuard< CurrentObject > oldCurrentObject( currentObject );
 		Expression *newExpr;
 		newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
@@ -321,5 +327,5 @@
 		switchStmt->set_condition( newExpr );
 
-		initContext = newExpr->get_result();
+		currentObject = CurrentObject( newExpr->get_result() );
 		Parent::visit( switchStmt );
 	}
@@ -327,6 +333,7 @@
 	void Resolver::visit( CaseStmt *caseStmt ) {
 		if ( caseStmt->get_condition() ) {
-			assert( initContext );
-			CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() );
+			std::list< InitAlternative > initAlts = currentObject.getOptions();
+			assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
+			CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
 			Expression * newExpr = findSingleExpression( castExpr, *this );
 			castExpr = safe_dynamic_cast< CastExpr * >( newExpr );
@@ -360,4 +367,12 @@
 	}
 
+	void Resolver::visit( ThrowStmt *throwStmt ) {
+		if ( throwStmt->get_expr() ) {
+			Expression * wrapped = new CastExpr( throwStmt->get_expr(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+			Expression * newExpr = findSingleExpression( wrapped, *this );
+			throwStmt->set_expr( newExpr );
+		}
+	}
+
 	template< typename T >
 	bool isCharType( T t ) {
@@ -370,205 +385,75 @@
 
 	void Resolver::visit( SingleInit *singleInit ) {
-		if ( singleInit->get_value() ) {
-			// // find all the d's
-			// std::list<Expression *> &designators = singleInit->get_designators();
-			// std::list<Type *> types1{ initContext }, types2;
-			// for ( Expression * expr: designators ) {
-			// 	cerr << expr << endl;
-			// 	if ( NameExpr * nexpr = dynamic_cast<NameExpr *>( expr ) ) {
-			// 		for ( Type * type: types1 ) {
-			// 			cerr << type << endl;
-			// 			ReferenceToType * fred = dynamic_cast<ReferenceToType *>(type);
-			// 			std::list<Declaration *> members;
-			// 			if ( fred ) {
-			// 				fred->lookup( nexpr->get_name(), members ); // concatenate identical field name
-			// 				for ( Declaration * mem: members ) {
-			// 					if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>(mem) ) {
-			// 						types2.push_back( dwt->get_type() );
-			// 					} // if
-			// 				} // for
-			// 			} // if
-			// 		} // for
-			// 		types1 = types2;
-			// 		types2.clear();
-			// 	} // if
-			// } // for
-			// // for ( Type * type: types1 ) {
-			// // 	cerr << type << endl;
-			// // } // for
-
-			// // O(N^2) checks of d-types with f-types
-			// // find the minimum cost
-			CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
-			Expression *newExpr = findSingleExpression( castExpr, *this );
-			delete castExpr;
-			singleInit->set_value( newExpr );
-
-			// check if initializing type is char[]
-			if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
-				if ( isCharType( at->get_base() ) ) {
-					// check if the resolved type is char *
-					if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
-						if ( isCharType( pt->get_base() ) ) {
-							// strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
-							CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
-							singleInit->set_value( ce->get_arg() );
-							ce->set_arg( NULL );
-							delete ce;
-						}
+		// resolve initialization using the possibilities as determined by the currentObject cursor
+		UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
+		Expression * newExpr = findSingleExpression( untyped, *this );
+		InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr );
+
+		// move cursor to the object that is actually initialized
+		currentObject.setNext( initExpr->get_designation() );
+
+		// discard InitExpr wrapper and retain relevant pieces
+		newExpr = initExpr->get_expr();
+		newExpr->set_env( initExpr->get_env() );
+		initExpr->set_expr( nullptr );
+		initExpr->set_env( nullptr );
+		delete initExpr;
+
+		// get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
+		Type * initContext = currentObject.getCurrentType();
+
+		// check if actual object's type is char[]
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
+			if ( isCharType( at->get_base() ) ) {
+				// check if the resolved type is char *
+				if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
+					if ( isCharType( pt->get_base() ) ) {
+						// strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
+						CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr );
+						newExpr = ce->get_arg();
+						ce->set_arg( nullptr );
+						delete ce;
 					}
 				}
 			}
-		} // if
-	}
-
-	template< typename AggrInst >
-	TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) {
-		assert( inst );
-		assert( inst->get_baseParameters() );
-		std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
-		std::list< Expression * > typeSubs = inst->get_parameters();
-		TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
-		return subs;
-	}
-
-	ReferenceToType * isStructOrUnion( Type * type ) {
-		if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
-			return sit;
-		} else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
-			return uit;
-		}
-		return nullptr;
-	}
-
-	void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
-		DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl );
-		assert( dt );
-		// need to substitute for generic types, so that casts are to concrete types
-		initContext = dt->get_type()->clone();
-		sub.apply( initContext );
-
-		try {
-			if ( init == initEnd ) return; // stop when there are no more initializers
-			(*init)->accept( *this );
-			++init; // made it past an initializer
-		} catch( SemanticError & ) {
-			// need to delve deeper, if you can
-			if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
-				resolveAggrInit( type, init, initEnd );
-			} else {
-				// member is not an aggregate type, so can't go any deeper
-
-				// might need to rethink what is being thrown
-				throw;
-			} // if
-		}
-	}
-
-	void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
-		if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
-			TypeSubstitution sub = makeGenericSubstitutuion( sit );
-			StructDecl * st = sit->get_baseStruct();
-			if(st->get_members().empty()) return;
-			// want to resolve each initializer to the members of the struct,
-			// but if there are more initializers than members we should stop
-			list< Declaration * >::iterator it = st->get_members().begin();
-			for ( ; it != st->get_members().end(); ++it) {
-				resolveSingleAggrInit( *it, init, initEnd, sub );
-			}
-		} else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
-			TypeSubstitution sub = makeGenericSubstitutuion( uit );
-			UnionDecl * un = uit->get_baseUnion();
-			if(un->get_members().empty()) return;
-			// only resolve to the first member of a union
-			resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
-		} // if
+		}
+
+		// set initializer expr to resolved express
+		singleInit->set_value( newExpr );
+
+		// move cursor to next object in preparation for next initializer
+		currentObject.increment();
 	}
 
 	void Resolver::visit( ListInit * listInit ) {
-		InitIterator iter = listInit->begin();
-		InitIterator end = listInit->end();
-
-		if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
-			// resolve each member to the base type of the array
-			for ( ; iter != end; ++iter ) {
-				initContext = at->get_base();
-				(*iter)->accept( *this );
-			} // for
-		} else if ( TupleType * tt = dynamic_cast< TupleType * > ( initContext ) ) {
-			for ( Type * t : *tt ) {
-				if ( iter == end ) break;
-				initContext = t;
-				(*iter++)->accept( *this );
-			}
-		} else if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
-			resolveAggrInit( type, iter, end );
-		} else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
-			Type * base = tt->get_baseType()->get_base();
-			if ( base ) {
-				// know the implementation type, so try using that as the initContext
-				initContext = base;
-				visit( listInit );
-			} else {
-				// missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
-				Parent::visit( listInit );
-			}
-		} else {
-			assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext )
-			        || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) || dynamic_cast < EnumInstType * > ( initContext ) );
-			// basic types are handled here
-			Parent::visit( listInit );
-		}
-
-#if 0
-		if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
-			std::list<Initializer *>::iterator iter( listInit->begin_initializers() );
-			for ( ; iter != listInit->end_initializers(); ++iter ) {
-				initContext = at->get_base();
-				(*iter)->accept( *this );
-			} // for
-		} else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) {
-			StructDecl *baseStruct = st->get_baseStruct();
-			std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() );
-			std::list<Initializer *>::iterator iter2( listInit->begin_initializers() );
-			for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) {
-				if ( (*iter2)->get_designators().empty() ) {
-					DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 );
-					initContext = dt->get_type();
-					(*iter2)->accept( *this );
-					++iter1;
-				} else {
-					StructDecl *st = baseStruct;
-					iter1 = st->get_members().begin();
-					std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() );
-					for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) {
-						NameExpr *key = dynamic_cast<NameExpr *>( *iter3 );
-						assert( key );
-						for ( ; iter1 != st->get_members().end(); ++iter1 ) {
-							if ( key->get_name() == (*iter1)->get_name() ) {
-								(*iter1)->print( cout );
-								cout << key->get_name() << endl;
-								ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
-								assert( fred );
-								StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() );
-								assert( mary );
-								st = mary->get_baseStruct();
-								iter1 = st->get_members().begin();
-								break;
-							} // if
-						}  // for
-					} // for
-					ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
-					assert( fred );
-					initContext = fred->get_type();
-					(*listInit->begin_initializers())->accept( *this );
-				} // if
-			} // for
-		} else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) {
-			DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() );
-			initContext = dt->get_type();
-			(*listInit->begin_initializers())->accept( *this );
-		} // if
-#endif
+		// move cursor into brace-enclosed initializer-list
+		currentObject.enterListInit();
+		// xxx - fix this so that the list isn't copied, iterator should be used to change current element
+		std::list<Designation *> newDesignations;
+		for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
+			// iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving
+			// the initializer against that object.
+			Designation * des = std::get<0>(p);
+			Initializer * init = std::get<1>(p);
+			newDesignations.push_back( currentObject.findNext( des ) );
+			init->accept( *this );
+		}
+		// set the set of 'resolved' designations and leave the brace-enclosed initializer-list
+		listInit->get_designations() = newDesignations; // xxx - memory management
+		currentObject.exitListInit();
+
+		// xxx - this part has not be folded into CurrentObject yet
+		// } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
+		// 	Type * base = tt->get_baseType()->get_base();
+		// 	if ( base ) {
+		// 		// know the implementation type, so try using that as the initContext
+		// 		ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr );
+		// 		currentObject = &tmpObj;
+		// 		visit( listInit );
+		// 	} else {
+		// 		// missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
+		// 		Parent::visit( listInit );
+		// 	}
+		// } else {
 	}
 
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ResolvExpr/Unify.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -606,8 +606,8 @@
 			} else if ( tupleParam ) {
 				// bundle other parameters into tuple to match
-				TupleType* binder = new TupleType{ paramTy->get_qualifiers() };
+				std::list< Type * > binderTypes;
 
 				do {
-					binder->get_types().push_back( otherParam->get_type()->clone() );
+					binderTypes.push_back( otherParam->get_type()->clone() );
 					++jt;
 
@@ -618,12 +618,12 @@
 				} while (true);
 
-				otherParamTy = binder;
+				otherParamTy = new TupleType{ paramTy->get_qualifiers(), binderTypes };
 				++it;  // skip ttype parameter for break
 			} else if ( otherTupleParam ) {
 				// bundle parameters into tuple to match other
-				TupleType* binder = new TupleType{ otherParamTy->get_qualifiers() };
+				std::list< Type * > binderTypes;
 
 				do {
-					binder->get_types().push_back( param->get_type()->clone() );
+					binderTypes.push_back( param->get_type()->clone() );
 					++it;
 
@@ -634,5 +634,5 @@
 				} while (true);
 
-				paramTy = binder;
+				paramTy = new TupleType{ otherParamTy->get_qualifiers(), binderTypes };
 				++jt;  // skip ttype parameter for break
 			}
@@ -756,9 +756,9 @@
 			return function->get_returnVals().front()->get_type()->clone();
 		} else {
-			TupleType * tupleType = new TupleType( Type::Qualifiers() );
+			std::list< Type * > types;
 			for ( DeclarationWithType * decl : function->get_returnVals() ) {
-				tupleType->get_types().push_back( decl->get_type()->clone() );
+				types.push_back( decl->get_type()->clone() );
 			} // for
-			return tupleType;
+			return new TupleType( Type::Qualifiers(), types );
 		}
 	}
Index: src/ResolvExpr/module.mk
===================================================================
--- src/ResolvExpr/module.mk	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/ResolvExpr/module.mk	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -6,5 +6,5 @@
 ## file "LICENCE" distributed with Cforall.
 ##
-## module.mk -- 
+## module.mk --
 ##
 ## Author           : Richard C. Bilson
@@ -31,3 +31,4 @@
        ResolvExpr/PolyCost.cc \
        ResolvExpr/Occurs.cc \
-       ResolvExpr/TypeEnvironment.cc
+       ResolvExpr/TypeEnvironment.cc \
+       ResolvExpr/CurrentObject.cc
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SymTab/Autogen.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -25,21 +25,21 @@
 
 namespace SymTab {
-    /// Generates assignment operators, constructors, and destructor for aggregate types as required
-    void autogenerateRoutines( std::list< Declaration * > &translationUnit );
+	/// Generates assignment operators, constructors, and destructor for aggregate types as required
+	void autogenerateRoutines( std::list< Declaration * > &translationUnit );
 
-    /// returns true if obj's name is the empty string and it has a bitfield width
-    bool isUnnamedBitfield( ObjectDecl * obj );
+	/// returns true if obj's name is the empty string and it has a bitfield width
+	bool isUnnamedBitfield( ObjectDecl * obj );
 
-    /// size_t type - set when size_t typedef is seen. Useful in a few places,
-    /// such as in determining array dimension type
-    extern Type * SizeType;
+	/// size_t type - set when size_t typedef is seen. Useful in a few places,
+	/// such as in determining array dimension type
+	extern Type * SizeType;
 
-    /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
-    template< typename OutputIterator >
+	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
+	template< typename OutputIterator >
 	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
 
-    /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
-    /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
-    template< typename OutputIterator >
+	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
+	/// optionally returns a statement which must be inserted prior to the containing loop, if there is one
+	template< typename OutputIterator >
 	Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
 	// want to be able to generate assignment, ctor, and dtor generically,
@@ -50,16 +50,15 @@
 	dstParam = new AddressExpr( dstParam );
 	if ( addCast ) {
-	    // cast to T* with qualifiers removed, so that qualified objects can be constructed
-	    // and destructed with the same functions as non-qualified objects.
-	    // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
-	    // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
-	    // remove lvalue as a qualifier, this can change to
-	    //   type->get_qualifiers() = Type::Qualifiers();
-	    assert( type );
-	    Type * castType = type->clone();
-//			castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false);
-	    castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
-	    castType->set_lvalue( true ); // xxx - might not need this
-	    dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
+		// cast to T* with qualifiers removed, so that qualified objects can be constructed
+		// and destructed with the same functions as non-qualified objects.
+		// unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
+		// must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
+		// remove lvalue as a qualifier, this can change to
+		//   type->get_qualifiers() = Type::Qualifiers();
+		assert( type );
+		Type * castType = type->clone();
+		castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
+		castType->set_lvalue( true ); // xxx - might not need this
+		dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
 	}
 	fExpr->get_args().push_back( dstParam );
@@ -75,103 +74,103 @@
 
 	return listInit;
-    }
-
-    /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
-    /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
-    template< typename OutputIterator >
-	void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
-	static UniqueName indexName( "_index" );
-
-	// for a flexible array member nothing is done -- user must define own assignment
-	if ( ! array->get_dimension() ) return ;
-
-	Expression * begin, * end, * update, * cmp;
-	if ( forward ) {
-	    // generate: for ( int i = 0; i < N; ++i )
-	    begin = new ConstantExpr( Constant::from_int( 0 ) );
-	    end = array->get_dimension()->clone();
-	    cmp = new NameExpr( "?<?" );
-	    update = new NameExpr( "++?" );
-	} else {
-	    // generate: for ( int i = N-1; i >= 0; --i )
-	    begin = new UntypedExpr( new NameExpr( "?-?" ) );
-	    ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
-	    ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
-	    end = new ConstantExpr( Constant::from_int( 0 ) );
-	    cmp = new NameExpr( "?>=?" );
-	    update = new NameExpr( "--?" );
 	}
 
-	ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
+	/// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
+	/// If forward is true, loop goes from 0 to N-1, else N-1 to 0
+	template< typename OutputIterator >
+	void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
+		static UniqueName indexName( "_index" );
 
-	UntypedExpr *cond = new UntypedExpr( cmp );
-	cond->get_args().push_back( new VariableExpr( index ) );
-	cond->get_args().push_back( end );
+		// for a flexible array member nothing is done -- user must define own assignment
+		if ( ! array->get_dimension() ) return ;
 
-	UntypedExpr *inc = new UntypedExpr( update );
-	inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+		Expression * begin, * end, * update, * cmp;
+		if ( forward ) {
+			// generate: for ( int i = 0; i < N; ++i )
+			begin = new ConstantExpr( Constant::from_int( 0 ) );
+			end = array->get_dimension()->clone();
+			cmp = new NameExpr( "?<?" );
+			update = new NameExpr( "++?" );
+		} else {
+			// generate: for ( int i = N-1; i >= 0; --i )
+			begin = new UntypedExpr( new NameExpr( "?-?" ) );
+			((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
+			((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
+			end = new ConstantExpr( Constant::from_int( 0 ) );
+			cmp = new NameExpr( "?>=?" );
+			update = new NameExpr( "--?" );
+		}
 
-	UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
-	dstIndex->get_args().push_back( dstParam );
-	dstIndex->get_args().push_back( new VariableExpr( index ) );
-	dstParam = dstIndex;
+		ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin ) );
 
-	// srcParam must keep track of the array indices to build the
-	// source parameter and/or array list initializer
-	srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
+		UntypedExpr *cond = new UntypedExpr( cmp );
+		cond->get_args().push_back( new VariableExpr( index ) );
+		cond->get_args().push_back( end );
 
-	// for stmt's body, eventually containing call
-	CompoundStmt * body = new CompoundStmt( noLabels );
-	Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
+		UntypedExpr *inc = new UntypedExpr( update );
+		inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
 
-	// block containing for stmt and index variable
-	std::list<Statement *> initList;
-	CompoundStmt * block = new CompoundStmt( noLabels );
-	block->get_kids().push_back( new DeclStmt( noLabels, index ) );
-	if ( listInit ) block->get_kids().push_back( listInit );
-	block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
+		UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
+		dstIndex->get_args().push_back( dstParam );
+		dstIndex->get_args().push_back( new VariableExpr( index ) );
+		dstParam = dstIndex;
 
-	*out++ = block;
-    }
+		// srcParam must keep track of the array indices to build the
+		// source parameter and/or array list initializer
+		srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
 
-    template< typename OutputIterator >
+		// for stmt's body, eventually containing call
+		CompoundStmt * body = new CompoundStmt( noLabels );
+		Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
+
+		// block containing for stmt and index variable
+		std::list<Statement *> initList;
+		CompoundStmt * block = new CompoundStmt( noLabels );
+		block->get_kids().push_back( new DeclStmt( noLabels, index ) );
+		if ( listInit ) block->get_kids().push_back( listInit );
+		block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
+
+		*out++ = block;
+	}
+
+	template< typename OutputIterator >
 	Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
-	if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
-	    genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
-	    return 0;
-	} else {
-	    return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
+			genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
+			return 0;
+		} else {
+			return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
+		}
 	}
-    }
 
-    /// inserts into out a generated call expression to function fname with arguments dstParam
-    /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
-    /// object being constructed. The function wraps constructor and destructor calls in an
-    /// ImplicitCtorDtorStmt node.
-    template< typename OutputIterator >
+	/// inserts into out a generated call expression to function fname with arguments dstParam
+	/// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
+	/// object being constructed. The function wraps constructor and destructor calls in an
+	/// ImplicitCtorDtorStmt node.
+	template< typename OutputIterator >
 	void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
-	ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
-	assert( obj );
-	// unnamed bit fields are not copied as they cannot be accessed
-	if ( isUnnamedBitfield( obj ) ) return;
+		ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
+		assert( obj );
+		// unnamed bit fields are not copied as they cannot be accessed
+		if ( isUnnamedBitfield( obj ) ) return;
 
-	bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
-	std::list< Statement * > stmts;
-	genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
+		bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
+		std::list< Statement * > stmts;
+		genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
 
-	// currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
-	assert( stmts.size() <= 1 );
-	if ( stmts.size() == 1 ) {
-	    Statement * callStmt = stmts.front();
-	    if ( addCast ) {
-		// implicitly generated ctor/dtor calls should be wrapped
-		// so that later passes are aware they were generated.
-		// xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
-		// because this causes the address to be taken at codegen, which is illegal in C.
-		callStmt = new ImplicitCtorDtorStmt( callStmt );
-	    }
-	    *out++ = callStmt;
+		// currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
+		assert( stmts.size() <= 1 );
+		if ( stmts.size() == 1 ) {
+			Statement * callStmt = stmts.front();
+			if ( addCast ) {
+				// implicitly generated ctor/dtor calls should be wrapped
+				// so that later passes are aware they were generated.
+				// xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
+				// because this causes the address to be taken at codegen, which is illegal in C.
+				callStmt = new ImplicitCtorDtorStmt( callStmt );
+			}
+			*out++ = callStmt;
+		}
 	}
-    }
 } // namespace SymTab
 #endif // AUTOGEN_H
Index: src/SymTab/ImplementationType.cc
===================================================================
--- src/SymTab/ImplementationType.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SymTab/ImplementationType.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ImplementationType.cc -- 
+// ImplementationType.cc --
 //
 // Author           : Richard C. Bilson
@@ -92,11 +92,11 @@
 
 	void ImplementationType::visit(TupleType *tupleType) {
-		TupleType *newType = new TupleType( Type::Qualifiers() );
+		std::list< Type * > types;
 		for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
 			Type *implType = implementationType( *i, indexer );
 			implType->get_qualifiers() |= tupleType->get_qualifiers();
-			newType->get_types().push_back( implType );
+			types.push_back( implType );
 		} // for
-		result = newType;
+		result = new TupleType( Type::Qualifiers(), types );
 	}
 
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SymTab/Indexer.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -652,5 +652,5 @@
 			for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
 				// check for C decls with the same name, skipping those with a compatible type (by mangleName)
-				if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true;
+				if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true;
 			}
 		}
@@ -669,5 +669,5 @@
 				// check for C decls with the same name, skipping
 				// those with an incompatible type (by mangleName)
-				if ( decl->second->get_linkage() == LinkageSpec::C && decl->first == mangleName ) return true;
+				if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true;
 			}
 		}
@@ -724,5 +724,5 @@
 			// new definition shadows the autogenerated one, even at the same scope
 			return false;
-		} else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
+		} else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
 			// typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
 			// we should ignore outermost pointer qualifiers, except _Atomic?
@@ -765,5 +765,5 @@
 
 		// this ensures that no two declarations with the same unmangled name at the same scope both have C linkage
-		if ( decl->get_linkage() == LinkageSpec::C ) {
+		if ( ! LinkageSpec::isMangled( decl->get_linkage() ) ) {
 			// NOTE this is broken in Richard's original code in such a way that it never triggers (it
 			// doesn't check decls that have the same manglename, and all C-linkage decls are defined to
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SymTab/Validate.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -106,6 +106,5 @@
 
 	/// Fix return types so that every function returns exactly one value
-	class ReturnTypeFixer {
-	  public:
+	struct ReturnTypeFixer {
 		static void fix( std::list< Declaration * > &translationUnit );
 
@@ -115,6 +114,5 @@
 
 	/// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
-	class EnumAndPointerDecay {
-	public:
+	struct EnumAndPointerDecay {
 		void previsit( EnumDecl *aggregateDecl );
 		void previsit( FunctionType *func );
@@ -159,10 +157,9 @@
 	};
 
-	class ReturnChecker : public WithScopes {
-	  public:
+	struct ReturnChecker : public WithGuards {
 		/// Checks that return statements return nothing if their return type is void
 		/// and return something if the return type is non-void.
 		static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
-	  private:
+
 		void previsit( FunctionDecl * functionDecl );
 		void previsit( ReturnStmt * returnStmt );
@@ -205,6 +202,5 @@
 	};
 
-	class VerifyCtorDtorAssign {
-	public:
+	struct VerifyCtorDtorAssign {
 		/// ensure that constructors, destructors, and assignment have at least one
 		/// parameter, the first of which must be a pointer, and that ctor/dtors have no
@@ -216,12 +212,10 @@
 
 	/// ensure that generic types have the correct number of type arguments
-	class ValidateGenericParameters {
-	public:
+	struct ValidateGenericParameters {
 		void previsit( StructInstType * inst );
 		void previsit( UnionInstType * inst );
 	};
 
-	class ArrayLength {
-	public:
+	struct ArrayLength {
 		/// for array types without an explicit length, compute the length and store it so that it
 		/// is known to the rest of the phases. For example,
@@ -236,10 +230,9 @@
 	};
 
-	class CompoundLiteral final : public GenPoly::DeclMutator {
+	struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> {
 		Type::StorageClasses storageClasses;
 
-		using GenPoly::DeclMutator::mutate;
-		DeclarationWithType * mutate( ObjectDecl *objectDecl ) final;
-		Expression *mutate( CompoundLiteralExpr *compLitExpr ) final;
+		void premutate( ObjectDecl *objectDecl );
+		Expression * postmutate( CompoundLiteralExpr *compLitExpr );
 	};
 
@@ -248,5 +241,5 @@
 		LinkReferenceToTypes lrt( doDebug, 0 );
 		ForallPointerDecay fpd( 0 );
-		CompoundLiteral compoundliteral;
+		PassVisitor<CompoundLiteral> compoundliteral;
 		PassVisitor<ValidateGenericParameters> genericParams;
 
@@ -263,5 +256,5 @@
 		Concurrency::implementThreadStarter( translationUnit );
 		ReturnChecker::checkFunctionReturns( translationUnit );
-		compoundliteral.mutateDeclarationList( translationUnit );
+		mutateAll( translationUnit, compoundliteral );
 		acceptAll( translationUnit, fpd );
 		ArrayLength::computeLength( translationUnit );
@@ -883,22 +876,19 @@
 	}
 
-	DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
+	void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
 		storageClasses = objectDecl->get_storageClasses();
-		DeclarationWithType * temp = Mutator::mutate( objectDecl );
-		return temp;
-	}
-
-	Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
+	}
+
+	Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
 		// transform [storage_class] ... (struct S){ 3, ... };
 		// into [storage_class] struct S temp =  { 3, ... };
 		static UniqueName indexName( "_compLit" );
 
-		ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );
-		compLitExpr->set_result( 0 );
-		compLitExpr->set_initializer( 0 );
+		ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
+		compLitExpr->set_result( nullptr );
+		compLitExpr->set_initializer( nullptr );
 		delete compLitExpr;
-		DeclarationWithType * newtempvar = mutate( tempvar );
-		addDeclaration( newtempvar );					// add modified temporary to current block
-		return new VariableExpr( newtempvar );
+		declsToAddBefore.push_back( tempvar );					// add modified temporary to current block
+		return new VariableExpr( tempvar );
 	}
 
Index: src/SynTree/Constant.cc
===================================================================
--- src/SynTree/Constant.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Constant.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Constant.cc -- 
+// Constant.cc --
 //
 // Author           : Richard C. Bilson
@@ -46,4 +46,14 @@
 }
 
+unsigned long long Constant::get_ival() const {
+	assertf( safe_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve ival from non-integer constant." );
+	return val.ival;
+}
+
+double Constant::get_dval() const {
+	assertf( ! safe_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve dval from integer constant." );
+	return val.dval;
+}
+
 void Constant::print( std::ostream &os ) const {
 	os << "(" << rep << " " << val.ival;
Index: src/SynTree/Constant.h
===================================================================
--- src/SynTree/Constant.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Constant.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Constant.h -- 
+// Constant.h --
 //
 // Author           : Richard C. Bilson
@@ -32,4 +32,6 @@
 	std::string & get_value() { return rep; }
 	void set_value( std::string newValue ) { rep = newValue; }
+	unsigned long long get_ival() const;
+	double get_dval() const;
 
 	/// generates a boolean constant of the given bool
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Expression.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -21,11 +21,15 @@
 #include <iterator>
 
+#include "Declaration.h"
+#include "Expression.h"
+#include "Initializer.h"
+#include "Statement.h"
 #include "Type.h"
-#include "Initializer.h"
-#include "Expression.h"
-#include "Declaration.h"
-#include "Statement.h"
 #include "TypeSubstitution.h"
+#include "VarExprReplacer.h"
+
 #include "Common/utility.h"
+#include "Common/PassVisitor.h"
+
 #include "InitTweak/InitTweak.h"
 
@@ -92,5 +96,4 @@
 
 	Declaration *decl = get_var();
-	// if ( decl != 0) decl->print(os, indent + 2);
 	if ( decl != 0) decl->printShort(os, indent + 2);
 	os << std::endl;
@@ -657,4 +660,46 @@
 }
 
+InitAlternative::InitAlternative( Type * type, Designation * designation ) : type( type ), designation( designation ) {}
+InitAlternative::InitAlternative( const InitAlternative & other ) : type( maybeClone( other.type ) ), designation( maybeClone( other.designation ) ) {}
+InitAlternative::~InitAlternative() {
+	delete type;
+	delete designation;
+}
+
+UntypedInitExpr::UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts ) : expr( expr ), initAlts( initAlts ) {}
+UntypedInitExpr::UntypedInitExpr( const UntypedInitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), initAlts( other.initAlts ) {}
+UntypedInitExpr::~UntypedInitExpr() {
+	delete expr;
+}
+
+void UntypedInitExpr::print( std::ostream & os, int indent ) const {
+	os << "Untyped Init Expression" << std::endl << std::string( indent+2, ' ' );
+	expr->print( os, indent+2 );
+	if ( ! initAlts.empty() ) {
+		for ( const InitAlternative & alt : initAlts ) {
+			os << std::string( indent+2, ' ' ) <<  "InitAlternative: ";
+			alt.type->print( os, indent+2 );
+			alt.designation->print( os, indent+2 );
+		}
+	}
+}
+
+InitExpr::InitExpr( Expression * expr, Designation * designation ) : expr( expr ), designation( designation ) {
+	set_result( expr->get_result()->clone() );
+}
+InitExpr::InitExpr( const InitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), designation( maybeClone( other.designation) ) {}
+InitExpr::~InitExpr() {
+	delete expr;
+	delete designation;
+}
+
+void InitExpr::print( std::ostream & os, int indent ) const {
+	os << "Init Expression" << std::endl << std::string( indent+2, ' ' );
+	expr->print( os, indent+2 );
+	os << std::string( indent+2, ' ' ) << "with designation: ";
+	designation->print( os, indent+2 );
+}
+
+
 std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
 	if ( expr ) {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Expression.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -744,4 +744,56 @@
 };
 
+struct InitAlternative {
+public:
+	Type * type = nullptr;
+	Designation * designation = nullptr;
+	InitAlternative( Type * type, Designation * designation );
+	InitAlternative( const InitAlternative & other );
+	InitAlternative & operator=( const Initializer & other ) = delete; // at the moment this isn't used, and I don't want to implement it
+	~InitAlternative();
+};
+
+class UntypedInitExpr : public Expression {
+public:
+	UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts );
+	UntypedInitExpr( const UntypedInitExpr & other );
+	~UntypedInitExpr();
+
+	Expression * get_expr() const { return expr; }
+	UntypedInitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; }
+
+	std::list<InitAlternative> & get_initAlts() { return initAlts; }
+
+	virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); }
+	virtual void accept( Visitor & v ) { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const;
+private:
+	Expression * expr;
+	std::list<InitAlternative> initAlts;
+};
+
+class InitExpr : public Expression {
+public:
+	InitExpr( Expression * expr, Designation * designation );
+	InitExpr( const InitExpr & other );
+	~InitExpr();
+
+	Expression * get_expr() const { return expr; }
+	InitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; }
+
+	Designation * get_designation() const { return designation; }
+	InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; }
+
+	virtual InitExpr * clone() const { return new InitExpr( * this ); }
+	virtual void accept( Visitor & v ) { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const;
+private:
+	Expression * expr;
+	Designation * designation;
+};
+
+
 std::ostream & operator<<( std::ostream & out, const Expression * expr );
 
Index: src/SynTree/Initializer.cc
===================================================================
--- src/SynTree/Initializer.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Initializer.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -19,75 +19,82 @@
 #include "Common/utility.h"
 
+Designation::Designation( const std::list< Expression * > & designators ) : designators( designators ) {}
+Designation::Designation( const Designation & other ) : BaseSyntaxNode( other ) {
+	// std::cerr << "cloning designation" << std::endl;
+	cloneAll( other.designators, designators );
+	// std::cerr << "finished cloning designation" << std::endl;
+}
+
+Designation::~Designation() {
+	// std::cerr << "destroying designation" << std::endl;
+	deleteAll( designators );
+	// std::cerr << "finished destroying designation" << std::endl;
+}
+
+void Designation::print( std::ostream &os, int indent ) const {
+	if ( ! designators.empty() ) {
+		os << std::string(indent + 2, ' ' ) << "designated by: " << std::endl;
+		for ( std::list < Expression * >::const_iterator i = designators.begin(); i != designators.end(); i++ ) {
+			os << std::string(indent + 4, ' ' );
+			( *i )->print(os, indent + 4 );
+		}
+		os << std::endl;
+	} // if
+}
+
 Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
 Initializer::Initializer( const Initializer & other ) : BaseSyntaxNode( other ), maybeConstructed( other.maybeConstructed ) {
 }
-
-
 Initializer::~Initializer() {}
 
-std::string Initializer::designator_name( Expression *des ) {
-	if ( NameExpr *n = dynamic_cast<NameExpr *>(des) )
-		return n->get_name();
-	else
-		throw 0;
-}
-
-// void Initializer::print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent ) {}
-
-SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) {
+SingleInit::SingleInit( Expression *v, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ) {
 }
 
 SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) {
-	cloneAll(other.designators, designators );
 }
 
 SingleInit::~SingleInit() {
 	delete value;
-	deleteAll(designators);
 }
 
-void SingleInit::print( std::ostream &os, int indent ) {
-	os << std::endl << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl;
+void SingleInit::print( std::ostream &os, int indent ) const {
+	os << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl;
 	os << std::string(indent+4, ' ' );
 	value->print( os, indent+4 );
-
-	if ( ! designators.empty() ) {
-		os << std::endl << std::string(indent + 2, ' ' ) << "designated by: " << std::endl;
-		for ( std::list < Expression * >::iterator i = designators.begin(); i != designators.end(); i++ ) {
-			os << std::string(indent + 4, ' ' );
-			( *i )->print(os, indent + 4 );
-		}
-	} // if
 }
 
-ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
-	: Initializer( maybeConstructed ), initializers( _initializers ), designators( _designators ) {
+
+ListInit::ListInit( const std::list<Initializer*> &inits, const std::list<Designation *> &des, bool maybeConstructed )
+	: Initializer( maybeConstructed ), initializers( inits ), designations( des ) {
+		// handle the common case where a ListInit is created without designations by making a list of empty designations with the same length as the initializer
+		if ( designations.empty() ) {
+			for ( auto & i : initializers ) {
+				(void)i;
+				designations.push_back( new Designation( {} ) );
+			}
+		}
+		assertf( initializers.size() == designations.size(), "Created ListInit with mismatching initializers (%d) and designations (%d)", initializers.size(), designations.size() );
 }
 
 ListInit::ListInit( const ListInit & other ) : Initializer( other ) {
 	cloneAll( other.initializers, initializers );
-	cloneAll( other.designators, designators );
+	cloneAll( other.designations, designations );
 }
-
 
 ListInit::~ListInit() {
 	deleteAll( initializers );
-	deleteAll( designators );
+	deleteAll( designations );
 }
 
-void ListInit::print( std::ostream &os, int indent ) {
-	os << std::endl << std::string(indent, ' ') << "Compound initializer:  ";
-	if ( ! designators.empty() ) {
-		os << std::string(indent + 2, ' ' ) << "designated by: [";
-		for ( std::list < Expression * >::iterator i = designators.begin();
-			  i != designators.end(); i++ ) {
-			( *i )->print(os, indent + 4 );
-		} // for
+void ListInit::print( std::ostream &os, int indent ) const {
+	os << std::string(indent, ' ') << "Compound initializer:  " << std::endl;
+	for ( Designation * d : designations ) {
+		d->print( os, indent + 2 );
+	}
 
-		os << std::string(indent + 2, ' ' ) << "]";
-	} // if
-
-	for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ )
-		(*i)->print( os, indent + 2 );
+	for ( const Initializer * init : initializers ) {
+		init->print( os, indent + 2 );
+		os << std::endl;
+	}
 }
 
@@ -103,5 +110,5 @@
 }
 
-void ConstructorInit::print( std::ostream &os, int indent ) {
+void ConstructorInit::print( std::ostream &os, int indent ) const {
 	os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl;
 	if ( ctor ) {
@@ -124,6 +131,19 @@
 }
 
-std::ostream & operator<<( std::ostream & out, Initializer * init ) {
-	init->print( out );
+std::ostream & operator<<( std::ostream & out, const Initializer * init ) {
+	if ( init ) {
+		init->print( out );
+	} else {
+		out << "nullptr";
+	}
+	return out;
+}
+
+std::ostream & operator<<( std::ostream & out, const Designation * des ) {
+	if ( des ) {
+		des->print( out );
+	} else {
+		out << "nullptr";
+	}
 	return out;
 }
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Initializer.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -25,26 +25,29 @@
 #include "Visitor.h"
 
-const std::list<Expression*> noDesignators;
+// Designation: list of designator (NameExpr, VariableExpr, and ConstantExpr) expressions that specify an object being initialized.
+class Designation : public BaseSyntaxNode {
+public:
+	Designation( const std::list< Expression * > & designators );
+	Designation( const Designation & other );
+	virtual ~Designation();
+
+	std::list< Expression * > & get_designators() { return designators; }
+
+	virtual Designation * clone() const { return new Designation( *this ); };
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+private:
+	std::list< Expression * > designators;
+};
+
+const std::list<Designation *> noDesignators;
 
 // Initializer: base class for object initializers (provide default values)
 class Initializer : public BaseSyntaxNode {
   public:
-	//	Initializer( std::string _name = std::string(""), int _pos = 0 );
 	Initializer( bool maybeConstructed );
 	Initializer( const Initializer & other );
 	virtual ~Initializer();
-
-	static std::string designator_name( Expression *designator );
-
-	//	void set_name( std::string newValue ) { name = newValue; }
-	//	std::string get_name() const { return name; }
-
-	//	void set_pos( int newValue ) { pos = newValue; }
-	//	int get_pos() const { return pos; }
-	virtual void set_designators( std::list<Expression *> & ) { assert(false); }
-	virtual std::list<Expression *> &get_designators() {
-		assert(false);
-		std::list<Expression *> *ret = 0; return *ret;	// never reached
-	}
 
 	bool get_maybeConstructed() { return maybeConstructed; }
@@ -53,8 +56,6 @@
 	virtual void accept( Visitor &v ) = 0;
 	virtual Initializer *acceptMutator( Mutator &m ) = 0;
-	virtual void print( std::ostream &os, int indent = 0 ) = 0;
+	virtual void print( std::ostream &os, int indent = 0 ) const = 0;
   private:
-	//	std::string name;
-	//	int pos;
 	bool maybeConstructed;
 };
@@ -63,5 +64,5 @@
 class SingleInit : public Initializer {
   public:
-	SingleInit( Expression *value, const std::list< Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
+	SingleInit( Expression *value, bool maybeConstructed = false );
 	SingleInit( const SingleInit &other );
 	virtual ~SingleInit();
@@ -70,15 +71,11 @@
 	void set_value( Expression *newValue ) { value = newValue; }
 
-	std::list<Expression *> &get_designators() { return designators; }
-	void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
-
 	virtual SingleInit *clone() const { return new SingleInit( *this); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
 	virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 );
+	virtual void print( std::ostream &os, int indent = 0 ) const;
   private:
 	//Constant *value;
 	Expression *value;	// has to be a compile-time constant
-	std::list< Expression * > designators;
 };
 
@@ -88,24 +85,25 @@
   public:
 	ListInit( const std::list<Initializer*> &initializers,
-			  const std::list<Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
+			  const std::list<Designation *> &designators = {}, bool maybeConstructed = false );
 	ListInit( const ListInit & other );
 	virtual ~ListInit();
 
-	void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
-	std::list<Expression *> &get_designators() { return designators; }
-	void set_initializers( std::list<Initializer*> &newValue ) { initializers = newValue; }
-	std::list<Initializer*> &get_initializers() { return initializers; }
+	std::list<Designation *> & get_designations() { return designations; }
+	std::list<Initializer *> & get_initializers() { return initializers; }
 
 	typedef std::list<Initializer*>::iterator iterator;
+	typedef std::list<Initializer*>::const_iterator const_iterator;
 	iterator begin() { return initializers.begin(); }
 	iterator end() { return initializers.end(); }
+	const_iterator begin() const { return initializers.begin(); }
+	const_iterator end() const { return initializers.end(); }
 
 	virtual ListInit *clone() const { return new ListInit( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
 	virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 );
+	virtual void print( std::ostream &os, int indent = 0 ) const;
   private:
-	std::list<Initializer*> initializers;  // order *is* important
-	std::list<Expression *> designators;
+	std::list<Initializer *> initializers;  // order *is* important
+	std::list<Designation *> designations;  // order/length is consistent with initializers
 };
 
@@ -130,5 +128,5 @@
 	virtual void accept( Visitor &v ) { v.visit( this ); }
 	virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 );
+	virtual void print( std::ostream &os, int indent = 0 ) const;
 
   private:
@@ -140,5 +138,6 @@
 };
 
-std::ostream & operator<<( std::ostream & out, Initializer * init );
+std::ostream & operator<<( std::ostream & out, const Initializer * init );
+std::ostream & operator<<( std::ostream & out, const Designation * des );
 
 #endif // INITIALIZER_H
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Mutator.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -433,4 +433,20 @@
 }
 
+Expression *Mutator::mutate( UntypedInitExpr * initExpr ) {
+	initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
+	initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
+	initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) );
+	// not currently mutating initAlts, but this doesn't matter since this node is only used in the resolver.
+	return initExpr;
+}
+
+Expression *Mutator::mutate( InitExpr * initExpr ) {
+	initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
+	initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
+	initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) );
+	initExpr->set_designation( maybeMutate( initExpr->get_designation(), *this ) );
+	return initExpr;
+}
+
 
 Type *Mutator::mutate( VoidType *voidType ) {
@@ -499,4 +515,5 @@
 	mutateAll( tupleType->get_forall(), *this );
 	mutateAll( tupleType->get_types(), *this );
+	mutateAll( tupleType->get_members(), *this );
 	return tupleType;
 }
@@ -535,4 +552,9 @@
 
 
+Designation *Mutator::mutate( Designation * designation ) {
+	mutateAll( designation->get_designators(), *this );
+	return designation;
+}
+
 Initializer *Mutator::mutate( SingleInit *singleInit ) {
 	singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
@@ -541,5 +563,5 @@
 
 Initializer *Mutator::mutate( ListInit *listInit ) {
-	mutateAll( listInit->get_designators(), *this );
+	mutateAll( listInit->get_designations(), *this );
 	mutateAll( listInit->get_initializers(), *this );
 	return listInit;
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Mutator.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -85,4 +85,6 @@
 	virtual Expression* mutate( StmtExpr * stmtExpr );
 	virtual Expression* mutate( UniqueExpr * uniqueExpr );
+	virtual Expression* mutate( UntypedInitExpr * initExpr );
+	virtual Expression* mutate( InitExpr * initExpr );
 
 	virtual Type* mutate( VoidType *basicType );
@@ -103,4 +105,5 @@
 	virtual Type* mutate( OneType *oneType );
 
+	virtual Designation* mutate( Designation *designation );
 	virtual Initializer* mutate( SingleInit *singleInit );
 	virtual Initializer* mutate( ListInit *listInit );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/SynTree.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -93,4 +93,6 @@
 class StmtExpr;
 class UniqueExpr;
+class UntypedInitExpr;
+class InitExpr;
 
 class Type;
@@ -113,4 +115,5 @@
 class OneType;
 
+class Designation;
 class Initializer;
 class SingleInit;
Index: src/SynTree/TupleType.cc
===================================================================
--- src/SynTree/TupleType.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/TupleType.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -14,16 +14,31 @@
 //
 
+#include "Declaration.h"
+#include "Initializer.h"
 #include "Type.h"
 #include "Common/utility.h"
+#include "Parser/LinkageSpec.h"
 
 TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), types( types ) {
+	for ( Type * t : *this ) {
+		// xxx - this is very awkward. TupleTypes should contain objects so that members can be named, but if they don't have an initializer node then
+		// they end up getting constructors, which end up being inserted causing problems. This happens because the object decls have to be visited so that
+		// their types are kept in sync with the types list here. Ultimately, the types list here should be eliminated and perhaps replaced with a list-view
+		// of the object types list, but I digress. The temporary solution here is to make a ListInit with maybeConstructed = false, that way even when the
+		// object is visited, it is never constructed. Ultimately, a better solution might be either:
+		// a) to separate TupleType from its declarations, into TupleDecl and Tuple{Inst?}Type, ala StructDecl and StructInstType
+		// b) separate initializer nodes better, e.g. add a MaybeConstructed node that is replaced by genInit, rather than what currently exists in a bool
+		members.push_back( new ObjectDecl( "" , Type::StorageClasses(), LinkageSpec::Cforall, nullptr, t->clone(), new ListInit( {}, {}, false ) ) );
+	}
 }
 
 TupleType::TupleType( const TupleType& other ) : Type( other ) {
 	cloneAll( other.types, types );
+	cloneAll( other.members, members );
 }
 
 TupleType::~TupleType() {
 	deleteAll( types );
+	deleteAll( members );
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Type.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -481,5 +481,5 @@
 class TupleType : public Type {
   public:
-	TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types = std::list< Type * >(), const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
+	TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 	TupleType( const TupleType& );
 	virtual ~TupleType();
@@ -488,6 +488,10 @@
 	typedef value_type::iterator iterator;
 
-	std::list<Type*>& get_types() { return types; }
+	std::list<Type *> & get_types() { return types; }
 	virtual unsigned size() const { return types.size(); };
+
+	// For now, this is entirely synthetic -- tuple types always have unnamed members.
+	// Eventually, we may allow named tuples, in which case members should subsume types
+	std::list<Declaration *> & get_members() { return members; }
 
 	iterator begin() { return types.begin(); }
@@ -506,5 +510,6 @@
 	virtual void print( std::ostream & os, int indent = 0 ) const;
   private:
-	std::list<Type*> types;
+	std::list<Type *> types;
+	std::list<Declaration *> members;
 };
 
Index: src/SynTree/VarExprReplacer.cc
===================================================================
--- src/SynTree/VarExprReplacer.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/VarExprReplacer.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -14,14 +14,18 @@
 //
 
+#include "Declaration.h"
 #include "Expression.h"
 #include "VarExprReplacer.h"
 
-VarExprReplacer::VarExprReplacer( const DeclMap & declMap ) : declMap( declMap ) {}
+VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {}
 
 // replace variable with new node from decl map
 void VarExprReplacer::visit( VariableExpr * varExpr ) {
-  // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
-  if ( declMap.count( varExpr->get_var() ) ) {
-    varExpr->set_var( declMap.at( varExpr->get_var() ) );
-  }
+	// xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
+	if ( declMap.count( varExpr->get_var() ) ) {
+		if ( debug ) {
+			std::cerr << "replacing variable reference: " << (void*)varExpr->get_var() << " " << varExpr->get_var() << " with " << (void*)declMap.at( varExpr->get_var() ) << " " << declMap.at( varExpr->get_var() ) << std::endl;
+		}
+		varExpr->set_var( declMap.at( varExpr->get_var() ) );
+	}
 }
Index: src/SynTree/VarExprReplacer.h
===================================================================
--- src/SynTree/VarExprReplacer.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/VarExprReplacer.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -27,6 +27,7 @@
 private:
 	const DeclMap & declMap;
+  bool debug;
 public:
-	VarExprReplacer( const DeclMap & declMap );
+	VarExprReplacer( const DeclMap & declMap, bool debug = false );
 
 	// replace variable with new node from decl map
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Visitor.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -340,4 +340,16 @@
 }
 
+void Visitor::visit( UntypedInitExpr * initExpr ) {
+	maybeAccept( initExpr->get_result(), *this );
+	maybeAccept( initExpr->get_expr(), *this );
+	// not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
+}
+
+void Visitor::visit( InitExpr * initExpr ) {
+	maybeAccept( initExpr->get_result(), *this );
+	maybeAccept( initExpr->get_expr(), *this );
+	maybeAccept( initExpr->get_designation(), *this );
+}
+
 
 void Visitor::visit( VoidType *voidType ) {
@@ -395,4 +407,5 @@
 	acceptAll( tupleType->get_forall(), *this );
 	acceptAll( tupleType->get_types(), *this );
+	acceptAll( tupleType->get_members(), *this );
 }
 
@@ -424,4 +437,7 @@
 }
 
+void Visitor::visit( Designation * designation ) {
+	acceptAll( designation->get_designators(), *this );
+}
 
 void Visitor::visit( SingleInit *singleInit ) {
@@ -430,5 +446,5 @@
 
 void Visitor::visit( ListInit *listInit ) {
-	acceptAll( listInit->get_designators(), *this );
+	acceptAll( listInit->get_designations(), *this );
 	acceptAll( listInit->get_initializers(), *this );
 }
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/SynTree/Visitor.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -88,4 +88,6 @@
 	virtual void visit( StmtExpr * stmtExpr );
 	virtual void visit( UniqueExpr * uniqueExpr );
+	virtual void visit( UntypedInitExpr * initExpr );
+	virtual void visit( InitExpr * initExpr );
 
 	virtual void visit( VoidType *basicType );
@@ -106,4 +108,5 @@
 	virtual void visit( OneType *oneType );
 
+	virtual void visit( Designation *designation );
 	virtual void visit( SingleInit *singleInit );
 	virtual void visit( ListInit *listInit );
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/Tuples/TupleExpansion.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -192,5 +192,5 @@
 			}
 			ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ),
-													new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ), noDesignators ) );
+													new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) ) );
 			addDeclaration( finished );
 			// (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N))
@@ -310,20 +310,19 @@
 	Type * makeTupleType( const std::list< Expression * > & exprs ) {
 		// produce the TupleType which aggregates the types of the exprs
-		TupleType *tupleType = new TupleType( Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex ) );
-		Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
+		std::list< Type * > types;
+		Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex );
 		for ( Expression * expr : exprs ) {
 			assert( expr->get_result() );
 			if ( expr->get_result()->isVoid() ) {
 				// if the type of any expr is void, the type of the entire tuple is void
-				delete tupleType;
 				return new VoidType( Type::Qualifiers() );
 			}
 			Type * type = expr->get_result()->clone();
-			tupleType->get_types().push_back( type );
+			types.push_back( type );
 			// the qualifiers on the tuple type are the qualifiers that exist on all component types
 			qualifiers &= type->get_qualifiers();
 		} // for
 		if ( exprs.empty() ) qualifiers = Type::Qualifiers();
-		return tupleType;
+		return new TupleType( qualifiers, types );
 	}
 
Index: src/libcfa/Makefile.am
===================================================================
--- src/libcfa/Makefile.am	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/Makefile.am	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -50,5 +50,5 @@
 
 libobjs = ${headers:=.o}
-libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c}
+libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} exception.c
 
 # not all platforms support concurrency, add option do disable it
Index: src/libcfa/Makefile.in
===================================================================
--- src/libcfa/Makefile.in	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/Makefile.in	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -102,5 +102,5 @@
 	containers/pair.c containers/result.c containers/vector.c \
 	concurrency/coroutine.c concurrency/thread.c \
-	concurrency/kernel.c concurrency/monitor.c \
+	concurrency/kernel.c concurrency/monitor.c exception.c \
 	concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
 	concurrency/invoke.c concurrency/preemption.c
@@ -126,5 +126,5 @@
 	libcfa_d_a-interpose.$(OBJEXT) \
 	libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \
-	$(am__objects_3)
+	libcfa_d_a-exception.$(OBJEXT) $(am__objects_3)
 am_libcfa_d_a_OBJECTS = $(am__objects_4)
 libcfa_d_a_OBJECTS = $(am_libcfa_d_a_OBJECTS)
@@ -136,5 +136,5 @@
 	containers/pair.c containers/result.c containers/vector.c \
 	concurrency/coroutine.c concurrency/thread.c \
-	concurrency/kernel.c concurrency/monitor.c \
+	concurrency/kernel.c concurrency/monitor.c exception.c \
 	concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
 	concurrency/invoke.c concurrency/preemption.c
@@ -158,5 +158,5 @@
 	libcfa_a-interpose.$(OBJEXT) \
 	libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \
-	$(am__objects_7)
+	libcfa_a-exception.$(OBJEXT) $(am__objects_7)
 am_libcfa_a_OBJECTS = $(am__objects_8)
 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
@@ -328,5 +328,5 @@
 libobjs = ${headers:=.o}
 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
-	$(am__append_4)
+	exception.c $(am__append_4)
 libcfa_a_SOURCES = ${libsrc}
 libcfa_a_CFLAGS = -nodebug -O2
@@ -514,4 +514,5 @@
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-assert.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-exception.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-fstream.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-interpose.Po@am__quote@
@@ -524,4 +525,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-stdlib.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-assert.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-exception.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-fstream.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-interpose.Po@am__quote@
@@ -850,4 +852,11 @@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
 
+libcfa_d_a-exception.obj: exception.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-exception.Tpo -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-exception.Tpo $(DEPDIR)/libcfa_d_a-exception.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='exception.c' object='libcfa_d_a-exception.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
+
 concurrency/libcfa_d_a-alarm.o: concurrency/alarm.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-alarm.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-alarm.Tpo -c -o concurrency/libcfa_d_a-alarm.o `test -f 'concurrency/alarm.c' || echo '$(srcdir)/'`concurrency/alarm.c
@@ -1143,4 +1152,11 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
+
+libcfa_a-exception.obj: exception.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_a-exception.Tpo -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-exception.Tpo $(DEPDIR)/libcfa_a-exception.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='exception.c' object='libcfa_a-exception.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
 
 concurrency/libcfa_a-alarm.o: concurrency/alarm.c
Index: src/libcfa/exception.c
===================================================================
--- src/libcfa/exception.c	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/exception.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -44,16 +44,16 @@
 // RESUMPTION ================================================================
 
-void __cfaehm__throw_resume(exception except) {
-
-	// DEBUG
-	printf("Throwing resumption exception %d\n", except);
-
-	struct __try_resume_node * original_head = shared_stack.current_resume;
-	struct __try_resume_node * current =
+void __cfaehm__throw_resumption(exception * except) {
+
+	// DEBUG
+	printf("Throwing resumption exception %d\n", *except);
+
+	struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume;
+	struct __cfaehm__try_resume_node * current =
 		(original_head) ? original_head->next : shared_stack.top_resume;
 
 	for ( ; current ; current = current->next) {
 		shared_stack.current_resume = current;
-		if (current->try_to_handle(except)) {
+		if (current->handler(except)) {
 			shared_stack.current_resume = original_head;
 			return;
@@ -61,9 +61,9 @@
 	}
 
-	printf("Unhandled exception %d\n", except);
+	printf("Unhandled exception %d\n", *except);
 	shared_stack.current_resume = original_head;
 
 	// Fall back to termination:
-	__cfaehm__throw_terminate(except);
+	__cfaehm__throw_termination(except);
 	// TODO: Default handler for resumption.
 }
@@ -73,12 +73,12 @@
  * after the node is built but before it is made the top node.
  */
-void __try_resume_setup(struct __try_resume_node * node,
-                        bool (*handler)(exception except)) {
+void __cfaehm__try_resume_setup(struct __cfaehm__try_resume_node * node,
+                        int (*handler)(exception * except)) {
 	node->next = shared_stack.top_resume;
-	node->try_to_handle = handler;
+	node->handler = handler;
 	shared_stack.top_resume = node;
 }
 
-void __try_resume_cleanup(struct __try_resume_node * node) {
+void __cfaehm__try_resume_cleanup(struct __cfaehm__try_resume_node * node) {
 	shared_stack.top_resume = node->next;
 }
@@ -111,10 +111,10 @@
 }
 
-void __cfaehm__throw_terminate( int val ) {
+void __cfaehm__throw_termination( exception * val ) {
 	// Store the current exception
-	shared_stack.current_exception = val;
-
-	// DEBUG
-	printf("Throwing termination exception %d\n", val);
+	shared_stack.current_exception = *val;
+
+	// DEBUG
+	printf("Throwing termination exception %d\n", *val);
 
 	// Call stdlibc to raise the exception
@@ -147,9 +147,9 @@
 
 // Nesting this the other way would probably be faster.
-void __cfaehm__rethrow_terminate(void) {
+void __cfaehm__rethrow_termination(void) {
 	// DEBUG
 	printf("Rethrowing termination exception\n");
 
-	__cfaehm__throw_terminate(shared_stack.current_exception);
+	__cfaehm__throw_termination(&shared_stack.current_exception);
 }
 
@@ -322,7 +322,7 @@
 // for details
 __attribute__((noinline))
-void __try_terminate(void (*try_block)(),
-		void (*catch_block)(int index, exception except),
-		__attribute__((unused)) int (*match_block)(exception except)) {
+void __cfaehm__try_terminate(void (*try_block)(),
+		void (*catch_block)(int index, exception * except),
+		__attribute__((unused)) int (*match_block)(exception * except)) {
 	//! volatile int xy = 0;
 	//! printf("%p %p %p %p\n", &try_block, &catch_block, &match_block, &xy);
@@ -364,5 +364,5 @@
 	// Exception handler
 	catch_block(shared_stack.current_handler_index,
-	            shared_stack.current_exception);
+	            &shared_stack.current_exception);
 }
 
@@ -384,11 +384,11 @@
 	// Body uses language specific data and therefore could be modified arbitrarily
 	".LLSDACSBCFA2:\n"						// BODY start
-	"	.uleb128 .TRYSTART-__try_terminate\n"		// Handled area start  (relative to start of function)
+	"	.uleb128 .TRYSTART-__cfaehm__try_terminate\n"		// Handled area start  (relative to start of function)
 	"	.uleb128 .TRYEND-.TRYSTART\n"				// Handled area length
-	"	.uleb128 .CATCH-__try_terminate\n"				// Hanlder landing pad adress  (relative to start of function)
+	"	.uleb128 .CATCH-__cfaehm__try_terminate\n"				// Hanlder landing pad adress  (relative to start of function)
 	"	.uleb128 1\n"						// Action code, gcc seems to use always 0
 	".LLSDACSECFA2:\n"						// BODY end
 	"	.text\n"							// TABLE footer
-	"	.size	__try_terminate, .-__try_terminate\n"
+	"	.size	__cfaehm__try_terminate, .-__cfaehm__try_terminate\n"
 	"	.ident	\"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
 //	"	.section	.note.GNU-stack,\"x\",@progbits\n"
Index: src/libcfa/exception.h
===================================================================
--- src/libcfa/exception.h	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/exception.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -38,13 +38,13 @@
 // Data structure creates a list of resume handlers.
 struct __cfaehm__try_resume_node {
-    __cfaehm__try_resume_node * next;
+    struct __cfaehm__try_resume_node * next;
     int (*handler)(exception * except);
 };
 
 void __cfaehm__try_resume_setup(
-    __cfaehm__try_resume_node * node,
+    struct __cfaehm__try_resume_node * node,
     int (*handler)(exception * except));
 void __cfaehm__try_resume_cleanup(
-    __cfaehm__try_resume_node * node);
+    struct __cfaehm__try_resume_node * node);
 
 // Check for a standard way to call fake deconstructors.
Index: src/libcfa/fstream
===================================================================
--- src/libcfa/fstream	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/fstream	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 15 18:11:09 2017
-// Update Count     : 104
+// Last Modified On : Sat Jul  1 16:37:53 2017
+// Update Count     : 112
 //
 
@@ -24,4 +24,5 @@
 	_Bool sepDefault;
 	_Bool sepOnOff;
+	_Bool lastSepOn;
 	const char * sepCur;
 	char separator[separateSize];
@@ -35,4 +36,5 @@
 const char * sepGetCur( ofstream * );
 void sepSetCur( ofstream *, const char * );
+_Bool lastSepOn( ofstream * );
 
 // public
Index: src/libcfa/fstream.c
===================================================================
--- src/libcfa/fstream.c	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/fstream.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 15 18:11:11 2017
-// Update Count     : 234
+// Last Modified On : Sat Jul  1 16:37:54 2017
+// Update Count     : 242
 //
 
@@ -33,4 +33,5 @@
 	this->sepDefault = sepDefault;
 	this->sepOnOff = sepOnOff;
+	this->lastSepOn = false;
 	sepSet( this, separator );
 	sepSetCur( this, sepGet( this ) );
@@ -39,5 +40,6 @@
 
 // private
-_Bool sepPrt( ofstream * os ) { return os->sepOnOff; }
+_Bool lastSepOn( ofstream * os ) { return os->lastSepOn; }
+_Bool sepPrt( ofstream * os ) { os->lastSepOn = false; return os->sepOnOff; }
 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
@@ -46,10 +48,11 @@
 
 // public
-void sepOn( ofstream * os ) { os->sepOnOff = 1; }
-void sepOff( ofstream * os ) { os->sepOnOff = 0; }
+void sepOn( ofstream * os ) { os->lastSepOn = true; os->sepOnOff = true; }
+void sepOff( ofstream * os ) { os->lastSepOn = false; os->sepOnOff = 0; }
 
 _Bool sepDisable( ofstream *os ) {
 	_Bool temp = os->sepDefault;
 	os->sepDefault = false;
+	os->lastSepOn = false;
 	sepReset( os );
 	return temp;
@@ -92,5 +95,5 @@
 		exit( EXIT_FAILURE );
 	} // if
-	?{}( os, file, 1, 0, " ", ", " );
+	?{}( os, file, true, false, " ", ", " );
 } // open
 
@@ -132,7 +135,7 @@
 } // fmt
 
-static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, " ", ", " };
+static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), true, false, " ", ", " };
 ofstream *sout = &soutFile;
-static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, " ", ", " };
+static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), true, false, " ", ", " };
 ofstream *serr = &serrFile;
 
Index: src/libcfa/iostream
===================================================================
--- src/libcfa/iostream	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/iostream	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 15 18:08:44 2017
-// Update Count     : 105
+// Last Modified On : Sun Jul  2 08:42:56 2017
+// Update Count     : 110
 //
 
@@ -26,4 +26,5 @@
 	const char * sepGetCur( ostype * );					// get current separator string
 	void sepSetCur( ostype *, const char * );			// set current separator string
+	_Bool lastSepOn( ostype * );						// last manipulator is setOn (context sensitive)
 	// public
 	void sepOn( ostype * );								// turn separator state on
@@ -43,9 +44,9 @@
 	ostype * write( ostype *, const char *, unsigned long int );
 	int fmt( ostype *, const char fmt[], ... );
-};
+}; // ostream
 
 trait writeable( otype T ) {
 	forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T );
-};
+}; // writeable
 
 // implement writable for intrinsic types
@@ -103,9 +104,9 @@
 	istype * ungetc( istype *, char );
 	int fmt( istype *, const char fmt[], ... );
-};
+}; // istream
 
 trait readable( otype T ) {
 	forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T );
-};
+}; // readable
 
 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, char * );
Index: src/libcfa/iostream.c
===================================================================
--- src/libcfa/iostream.c	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/libcfa/iostream.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May  8 18:24:23 2017
-// Update Count     : 369
+// Last Modified On : Sun Jul  2 08:54:02 2017
+// Update Count     : 375
 //
 
@@ -201,6 +201,6 @@
 forall( dtype ostype, otype T, ttype Params | ostream( ostype ) | writeable( T ) | { ostype * ?|?( ostype *, Params ); } )
 ostype * ?|?( ostype * os, T arg, Params rest ) {
+	os | arg;											// print first argument
 	sepSetCur( os, sepGetTuple( os ) );					// switch to tuple separator
-	os | arg;											// print first argument
 	os | rest;											// print remaining arguments
 	sepSetCur( os, sepGet( os ) );						// switch to regular separator
@@ -217,4 +217,5 @@
 forall( dtype ostype | ostream( ostype ) )
 ostype * endl( ostype * os ) {
+	if ( lastSepOn( os ) ) fmt( os, "%s", sepGetCur( os ) );
 	os | '\n';
 	flush( os );
Index: src/libcfa/lsda.h
===================================================================
--- src/libcfa/lsda.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
+++ src/libcfa/lsda.h	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -0,0 +1,262 @@
+//This code was stolen from gcc to read exception tables
+
+
+/* If using C++, references to abort have to be qualified with std::.  */
+#if __cplusplus
+#define __gxx_abort std::abort
+#else
+#define __gxx_abort abort
+#endif
+
+/* Pointer encodings, from dwarf2.h.  */
+#define DW_EH_PE_absptr         0x00
+#define DW_EH_PE_omit           0xff
+
+#define DW_EH_PE_uleb128        0x01
+#define DW_EH_PE_udata2         0x02
+#define DW_EH_PE_udata4         0x03
+#define DW_EH_PE_udata8         0x04
+#define DW_EH_PE_sleb128        0x09
+#define DW_EH_PE_sdata2         0x0A
+#define DW_EH_PE_sdata4         0x0B
+#define DW_EH_PE_sdata8         0x0C
+#define DW_EH_PE_signed         0x08
+
+#define DW_EH_PE_pcrel          0x10
+#define DW_EH_PE_textrel        0x20
+#define DW_EH_PE_datarel        0x30
+#define DW_EH_PE_funcrel        0x40
+#define DW_EH_PE_aligned        0x50
+
+#define DW_EH_PE_indirect	0x80
+
+
+
+int handler_found = 0;
+
+/* Given an encoding, return the number of bytes the format occupies.
+This is only defined for fixed-size encodings, and so does not
+include leb128.  */
+static unsigned int size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
+
+static unsigned int size_of_encoded_value (unsigned char encoding)
+{
+	if (encoding == DW_EH_PE_omit) return 0;
+
+	switch (encoding & 0x07) {
+		case DW_EH_PE_absptr: return sizeof (void *);
+		case DW_EH_PE_udata2: return 2;
+		case DW_EH_PE_udata4: return 4;
+		case DW_EH_PE_udata8: return 8;
+	}
+	__gxx_abort ();
+}
+
+/* Given an encoding and an _Unwind_Context, return the base to which
+the encoding is relative.  This base may then be passed to
+read_encoded_value_with_base for use when the _Unwind_Context is
+not available.  */
+static _Unwind_Ptr base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
+{
+	if (encoding == DW_EH_PE_omit) return 0;
+
+	switch (encoding & 0x70) {
+		case DW_EH_PE_absptr:
+		case DW_EH_PE_pcrel:
+		case DW_EH_PE_aligned:
+			return 0;
+		case DW_EH_PE_textrel:
+			return _Unwind_GetTextRelBase (context);
+		case DW_EH_PE_datarel:
+			return _Unwind_GetDataRelBase (context);
+		case DW_EH_PE_funcrel:
+			return _Unwind_GetRegionStart (context);
+	}
+	__gxx_abort ();
+}
+
+/* Read an unsigned leb128 value from P, store the value in VAL, return
+P incremented past the value.  We assume that a word is large enough to
+hold any value so encoded; if it is smaller than a pointer on some target,
+pointers should not be leb128 encoded on that target.  */
+static const unsigned char * read_uleb128 (const unsigned char *p, _uleb128_t *val)
+{
+	unsigned int shift = 0;
+	unsigned char byte;
+	_uleb128_t result;
+
+	result = 0;
+	do
+	{
+		byte = *p++;
+		result |= ((_uleb128_t)byte & 0x7f) << shift;
+		shift += 7;
+	}
+	while (byte & 0x80);
+
+	*val = result;
+	return p;
+}
+
+/* Similar, but read a signed leb128 value.  */
+static const unsigned char * read_sleb128 (const unsigned char *p, _sleb128_t *val)
+{
+	unsigned int shift = 0;
+	unsigned char byte;
+	_uleb128_t result;
+
+	result = 0;
+	do
+	{
+		byte = *p++;
+		result |= ((_uleb128_t)byte & 0x7f) << shift;
+		shift += 7;
+	}
+	while (byte & 0x80);
+
+	/* Sign-extend a negative value.  */
+	if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) result |= -(((_uleb128_t)1L) << shift);
+
+	*val = (_sleb128_t) result;
+	return p;
+}
+
+/* Load an encoded value from memory at P.  The value is returned in VAL;
+The function returns P incremented past the value.  BASE is as given
+by base_of_encoded_value for this encoding in the appropriate context.  */
+
+static const unsigned char * read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, const unsigned char *p, _Unwind_Ptr *val)
+{
+	union unaligned
+	{
+		void *ptr;
+		unsigned u2 __attribute__ ((mode (HI)));
+		unsigned u4 __attribute__ ((mode (SI)));
+		unsigned u8 __attribute__ ((mode (DI)));
+		signed s2 __attribute__ ((mode (HI)));
+		signed s4 __attribute__ ((mode (SI)));
+		signed s8 __attribute__ ((mode (DI)));
+	} __attribute__((__packed__));
+
+	const union unaligned *u = (const union unaligned *) p;
+	_Unwind_Internal_Ptr result;
+
+	if (encoding == DW_EH_PE_aligned)
+	{
+		_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
+		a = (a + sizeof (void *) - 1) & - sizeof(void *);
+		result = *(_Unwind_Internal_Ptr *) a;
+		p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
+	}
+	else
+	{
+		switch (encoding & 0x0f)
+		{
+			case DW_EH_PE_absptr:
+				result = (_Unwind_Internal_Ptr) u->ptr;
+				p += sizeof (void *);
+				break;
+			case DW_EH_PE_uleb128:
+			{
+				_uleb128_t tmp;
+				p = read_uleb128 (p, &tmp);
+				result = (_Unwind_Internal_Ptr) tmp;
+			}
+			break;
+
+			case DW_EH_PE_sleb128:
+			{
+				_sleb128_t tmp;
+				p = read_sleb128 (p, &tmp);
+				result = (_Unwind_Internal_Ptr) tmp;
+			}
+			break;
+
+			case DW_EH_PE_udata2:
+				result = u->u2;
+				p += 2;
+				break;
+			case DW_EH_PE_udata4:
+				result = u->u4;
+				p += 4;
+				break;
+			case DW_EH_PE_udata8:
+				result = u->u8;
+				p += 8;
+				break;
+			case DW_EH_PE_sdata2:
+				result = u->s2;
+				p += 2;
+				break;
+			case DW_EH_PE_sdata4:
+				result = u->s4;
+				p += 4;
+				break;
+			case DW_EH_PE_sdata8:
+				result = u->s8;
+				p += 8;
+				break;
+			default:
+				__gxx_abort();
+		}
+
+		if (result != 0)
+		{
+			result += ((encoding & 0x70) == DW_EH_PE_pcrel ? (_Unwind_Internal_Ptr) u : base);
+			
+			if (encoding & DW_EH_PE_indirect) result = *(_Unwind_Internal_Ptr *) result;
+		}
+	}
+
+	*val = result;
+	return p;
+}
+
+/* Like read_encoded_value_with_base, but get the base from the context
+rather than providing it directly.  */
+static inline const unsigned char * read_encoded_value (struct _Unwind_Context *context, unsigned char encoding, const unsigned char *p, _Unwind_Ptr *val)
+{
+	return read_encoded_value_with_base (encoding, base_of_encoded_value (encoding, context), p, val);
+}
+
+typedef struct
+{
+	_Unwind_Ptr Start;
+	_Unwind_Ptr LPStart;
+	_Unwind_Ptr ttype_base;
+	const unsigned char *TType;
+	const unsigned char *action_table;
+	unsigned char ttype_encoding;
+	unsigned char call_site_encoding;
+} lsda_header_info;
+
+static const unsigned char * parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p, lsda_header_info *info)
+{
+	_uleb128_t tmp;
+	unsigned char lpstart_encoding;
+
+	info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
+
+	/* Find @LPStart, the base to which landing pad offsets are relative.  */
+	lpstart_encoding = *p++;
+	if (lpstart_encoding != DW_EH_PE_omit) p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
+
+	else info->LPStart = info->Start;
+
+	/* Find @TType, the base of the handler and exception spec type data.  */
+	info->ttype_encoding = *p++;
+	if (info->ttype_encoding != DW_EH_PE_omit)
+	{
+		p = read_uleb128 (p, &tmp);
+		info->TType = p + tmp;
+	}
+	else info->TType = 0;
+
+	/* The encoding and length of the call-site table; the action table
+	immediately follows.  */
+	info->call_site_encoding = *p++;
+	p = read_uleb128 (p, &tmp);
+	info->action_table = p + tmp;
+
+	return p;
+}
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/main.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -11,6 +11,6 @@
 // Created On       : Fri May 15 23:12:02 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jun 28 21:56:47 2017
-// Update Count     : 440
+// Last Modified On : Thu Jun 29 12:46:50 2017
+// Update Count     : 441
 //
 
@@ -39,4 +39,5 @@
 #include "CodeTools/TrackLoc.h"
 #include "ControlStruct/Mutate.h"
+#include "ControlStruct/ExceptTranslate.h"
 #include "SymTab/Validate.h"
 #include "ResolvExpr/AlternativePrinter.h"
@@ -290,4 +291,7 @@
 		Tuples::expandUniqueExpr( translationUnit );
 
+		OPTPRINT( "translateEHM" );
+		ControlStruct::translateEHM( translationUnit );
+
 		OPTPRINT( "convertSpecializations" ) // needs to happen before tuple types are expanded
 		GenPoly::convertSpecializations( translationUnit );
@@ -481,5 +485,9 @@
 			break;
 		  case '?':
-			assertf( false, "Unknown option: '%c'\n", (char)optopt );
+			if ( optopt ) {								// short option ?
+				assertf( false, "Unknown option: -%c\n", (char)optopt );
+			} else {
+				assertf( false, "Unknown option: %s\n", argv[optind - 1] );
+			} // if
 		  default:
 			abort();
Index: src/prelude/Makefile.am
===================================================================
--- src/prelude/Makefile.am	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/prelude/Makefile.am	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -23,4 +23,6 @@
 noinst_DATA = ../libcfa/libcfa-prelude.c
 
+CC = ${abs_top_srcdir}/src/driver/cfa
+
 $(DEPDIR) :
 	mkdir $(DEPDIR)
@@ -45,6 +47,6 @@
 
 # create forward declarations for cfa builtins
-builtins.cf : builtins.c
-	${AM_V_GEN}@BACKEND_CC@ -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
+builtins.cf : builtins.c ${CC}
+	${AM_V_GEN}${CC} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
 	${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
 
Index: src/prelude/Makefile.in
===================================================================
--- src/prelude/Makefile.in	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/prelude/Makefile.in	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -95,5 +95,5 @@
 AWK = @AWK@
 BACKEND_CC = @BACKEND_CC@
-CC = @CC@
+CC = ${abs_top_srcdir}/src/driver/cfa
 CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
@@ -444,6 +444,6 @@
 
 # create forward declarations for cfa builtins
-builtins.cf : builtins.c
-	${AM_V_GEN}@BACKEND_CC@ -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
+builtins.cf : builtins.c ${CC}
+	${AM_V_GEN}${CC} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po
 	${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
 
Index: src/tests/.expect/designations.txt
===================================================================
--- src/tests/.expect/designations.txt	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
+++ src/tests/.expect/designations.txt	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -0,0 +1,53 @@
+=====A=====
+(A){ 2 3 (nil) }
+(A){ 2 3 (nil) }
+(A){ 0 3 (nil) }
+=====A=====
+
+=====B=====
+(B){
+  (A){ 5 0 (nil) }
+  (A){ 0 0 (nil) }
+}
+(B){
+  (A){ 5 2 (nil) }
+  (A){ 6 0 (nil) }
+}
+(B){
+  (A){ 1 0 (nil) }
+  (A){ 2 3 (nil) }
+}
+(B){
+  (A){ 1 2 (nil) }
+  (A){ 4 5 (nil) }
+}
+(B){
+  (A){ 1 0 (nil) }
+  (A){ 2 3 (nil) }
+}
+(B){
+  (A){ 1 0 (nil) }
+  (A){ 2 3 (nil) }
+}
+=====B=====
+
+=====C=====
+(C){
+  (int[]{ 2 3 4 }
+  (B){
+    (A){ 5 6 (nil) }
+    (A){ 7 8 (nil) }
+  }
+}
+=====C=====
+
+=====E=====
+(A){ 2 3 (nil) }
+(A){ 2 3 (nil) }
+(A){ 2 3 (nil) }
+(B){
+  (A){ 2 3 (nil) }
+  (A){ 5 6 (nil) }
+}
+=====E=====
+
Index: src/tests/.expect/io.txt
===================================================================
--- src/tests/.expect/io.txt	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/tests/.expect/io.txt	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -4,6 +4,11 @@
 123
 
+opening delimiters 
 x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
-1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
+
+closing delimiters 
+1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x 
+
+opening/closing delimiters 
 x`1`x'2'x"3"x:4:x 5 x	6	x
 7
@@ -14,6 +19,12 @@
 x
 10
-x
+x 
+
+override opening/closing delimiters 
 x ( 1 ) x 2 , x 3 :x: 4
+
+input bacis types 
+
+output basic types 
 A 
 1 2 3 4 5 6 7 8
@@ -21,27 +32,47 @@
 1.1+2.3i 1.1-2.3i 1.1-2.3i
 
+tuples 
+1, 2, 3 3, 4, 5
+
+toggle separator 
 1.11.21.3
 1.1+2.3i1.1-2.3i1.1-2.3i
- abcxyz
-abcxyz
+ abcxyz 
+abcxyz 
 
+change separator 
+from "  "to " , $"
 1.1, $1.2, $1.3
 1.1+2.3i, $1.1-2.3i, $1.1-2.3i
-abc, $xyz
+abc, $xyz, $
+1, 2, 3, $3, 4, 5
 
-1, 2, 3, 4
-1, $2, $3 ", $"
-1 2 3 " "
+from ", $"to " "
+1.1 1.2 1.3
+1.1+2.3i 1.1-2.3i 1.1-2.3i
+abc xyz 
+1, 2, 3 3, 4, 5
+
+ 1 2 3 
+12 3
  1 2 3
-12 3
+1 2 3
+ 1 2 3
+
 123
 1 23
 1 2 3
-1 2 3 4 " "
-1, 2, 3, 4 ", "
-1, 2, 3, 4
+123
+1 2 3
+123 
+1 2 3
+
+1 2 3 3 4 5 " "
+1, 2, 3 3, 4, 5 ", "
+1, 2, 3 3, 4, 5
+
 3, 4, a, 7.2
 3, 4, a, 7.2
 3 4 a 7.2
  3 4 a 7.234a7.23 4 a 7.2
-3-4-a-7.2^3^4-3-4-a-7.2
+3-4-a-7.2^3^4^3-4-a-7.2
Index: src/tests/designations.c
===================================================================
--- src/tests/designations.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
+++ src/tests/designations.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -0,0 +1,246 @@
+//
+// 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.
+//
+// designations.c --
+//
+// Author           : Rob Schluntz
+// Created On       : Thu Jun 29 15:26:36 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Jun 29 15:27:05 2017
+// Update Count     : 2
+//
+
+// Note: this test case has been crafted so that it compiles with both cfa and with gcc without any modifications.
+// In particular, since the syntax for designations in Cforall differs from that of C, preprocessor substitution
+// is used for the designation syntax
+#ifdef __CFORALL__
+#define DES :
+#else
+int printf(const char *, ...);
+#define DES =
+#endif
+
+const int indentAmt = 2;
+void indent(int level) {
+	for (int i = 0; i < level; ++i) {
+		printf(" ");
+	}
+}
+
+// A contains fields with different types (int vs. int *)
+struct A {
+	int x, y;
+	int * ptr;
+};
+void printA(struct A a, int level) {
+	indent(level);
+	printf("(A){ %d %d %p }\n", a.x, a.y, a.ptr);
+}
+
+// B contains struct members
+struct B {
+	struct A a0, a1;
+};
+void printB(struct B b, int level) {
+	indent(level);
+	printf("(B){\n");
+	printA(b.a0, level+indentAmt);
+	printA(b.a1, level+indentAmt);
+	indent(level);
+	printf("}\n");
+}
+
+// C contains an array - tests that after 3 ints, the members of B are initialized.
+struct C {
+	int arr[3];
+	struct B b;
+};
+void printC(struct C c, int level) {
+	indent(level);
+	printf("(C){\n");
+	indent(level+indentAmt);
+	printf("(int[]{ %d %d %d }\n", c.arr[0], c.arr[1], c.arr[2]);
+	printB(c.b, level+indentAmt);
+	indent(level);
+	printf("}\n");
+}
+
+// D contains an unnamed aggregate - tests that this doesn't interfere with initialization.
+struct D {
+	struct {
+		int x;
+	};
+};
+void printD(struct D d, int level) {
+	indent(level);
+	printf("(D){ %d }\n", d.x);
+}
+
+// E tests unions
+union E {
+	struct A a;
+	struct B b;
+	struct C c;
+	struct D d;
+	int i;
+};
+
+int main() {
+	// simple designation case - starting from beginning of structure, leaves ptr default-initialized (zero)
+	struct A y0 = {
+		.x DES 2,
+		.y DES 3
+	};
+
+	// simple initializaiton case - initialize all elements explicitly with no designations
+	struct A y1 = {
+		2, 3, 0
+	};
+
+
+	// use designation to move to member y, leaving x default-initialized (zero)
+	struct A y2 = {
+		.y DES 3,
+		0
+	};
+
+#if ERROR
+	struct A yErr0 = {
+		{} // error - empty scalar initializer is illegal
+	};
+#endif
+
+	printf("=====A=====\n");
+	printA(y0, 0);
+	printA(y1, 0);
+	printA(y2, 0);
+	printf("=====A=====\n\n");
+
+	// initialize only first element (z0.a.x), leaving everything else default-initialized (zero), no nested curly-braces
+	struct B z0 = { 5 };
+
+	// some nested curly braces, use designation to 'jump around' within structure, leaving some members default-initialized
+	struct B z1 = {
+		{ 3 }, // z1.a0
+		{ 4 }, // z1.a1
+		.a0 DES { 5 }, // z1.a0
+		{ 6 }, // z1.a1
+		.a0.y DES 2, // z1.a0.y
+		0, // z1.a0.ptr
+	};
+
+	// z2.a0.y and z2.a0.ptr default-initialized, everything else explicit
+	struct B z2 = {
+		{ 1 },
+		{ 2, 3, 0 }
+	};
+
+	// initialize every member, omitting nested curly braces
+	struct B z3 = {
+		1, 2, 0, 4, 5, 0
+	};
+
+	// no initializer - legal C, but garbage values - don't print this one
+	struct B z4;
+
+	// no curly braces - initialize with object of same type
+	struct B z5 = z2;
+
+	// z6.a0.y and z6.a0.ptr default-initialized, everything else explicit.
+	// no curly braces on z6.a1 initializers
+	struct B z6 = {
+		{ 1 },
+		2, 3, 0
+	};
+
+	printf("=====B=====\n");
+	printB(z0, 0);
+	printB(z1, 0);
+	printB(z2, 0);
+	printB(z3, 0);
+	printB(z5, 0);
+	printB(z6, 0);
+	printf("=====B=====\n\n");
+
+	// TODO: what about extra things in a nested init? are empty structs skipped??
+
+	// test that initializing 'past array bound' correctly moves to next member.
+	struct C c1 = {
+		2, 3, 4,  // arr
+		5, 6, 0,  // b.a0
+		7, 8, 0,  // b.a1
+	};
+
+	printf("=====C=====\n");
+	printC(c1, 0);
+	printf("=====C=====\n\n");
+
+#if ERROR
+	// nested initializer can't refer to same type in C
+	struct C cErr0 = { c1 };
+
+	// must use curly braces to initialize members
+	struct C cErr1 = 2;
+
+	// can't initialize with array compound literal
+	struct C cErr2 = {
+		(int[3]) { 1, 2, 3 }  // error: array initialized from non-constant array expression
+	};
+#endif
+
+#if WARNING
+	// can't initialize array with array - converts to int*
+	int cWarn0_arr[3] = { 1, 2, 3 };
+	struct C cWarn0 = {
+		cWarn0_arr  // warning: initialization makes integer from ptr without cast
+	};
+#endif
+
+	// allowed to have 'too many' initialized lists - essentially they are ignored.
+	int i1 = { 3 };
+
+	// doesn't work yet.
+	// designate unnamed object's members
+	// struct D d = { .x DES 3 };
+#if ERROR
+	struct D d1 = { .y DES 3 };
+#endif
+
+	// simple union initialization - initialized first member (e0.a)
+	union E e0 = {
+		y0
+	};
+
+	// simple union initialization - initializes first member (e1.a) - with nested initializer list
+	union E e1 = {
+		{ 2, 3, 0 }
+	};
+
+	// simple union initialization - initializes first member (e2.a) - without nested initializer list
+	union E e2 = {
+		2, 3, 0
+	};
+
+	// move cursor to e4.b.a0.x and initialize until e3.b.a1.ptr inclusive
+	union E e3 = {
+		.b.a0.x DES 2, 3, 0, 5, 6, 0
+	};
+
+	printf("=====E=====\n");
+	printA(e0.a, 0);
+	printA(e1.a, 0);
+	printA(e2.a, 0);
+	printB(e3.b, 0);
+	printf("=====E=====\n\n");
+
+	// special case of initialization: char[] can be initialized with a string literal
+	const char * str0 = "hello";
+	char str1[] = "hello";
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// End: //
Index: src/tests/except-0.c
===================================================================
--- src/tests/except-0.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
+++ src/tests/except-0.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -0,0 +1,219 @@
+// Draft of tests for exception handling.
+
+#include <stdio.h>
+#include <stdbool.h>
+
+struct signal_exit {
+	const char * area;
+};
+
+void ?{}(signal_exit * this, const char * area) {
+	this->area = area;
+}
+
+void ^?{}(signal_exit * this) {
+	printf("Exiting: %s\n", this->area);
+//	sout | "Exiting:" | this->area | endl;
+}
+
+void terminate(int except_value) {
+	signal_exit a = {"terminate function"};
+	throw except_value;
+	printf("terminate returned\n");
+}
+
+void resume(int except_value) {
+	signal_exit a = {"resume function"};
+	throwResume except_value;
+	printf("resume returned\n");
+}
+
+// Termination Test: Two handlers: no catch, catch
+void bar() {
+	signal_exit a = {"bar function"};
+	try {
+		terminate(4);
+	} catch (3) {
+		printf("bar caught exception 3.\n");
+	}
+}
+
+void foo() {
+	signal_exit a = {"foo function"};
+	try {
+		bar();
+	} catch (4) {
+		printf("foo caught exception 4.\n");
+	} catch (2) {
+		printf("foo caught exception 2.\n");
+	}
+}
+
+// Resumption Two Handler Test: no catch, catch.
+void beta() {
+	signal_exit a = {"beta function"};
+	try {
+		resume(4);
+	} catchResume (3) {
+		printf("beta caught exception 3\n");
+	}
+}
+
+void alpha() {
+	signal_exit a = {"alpha function"};
+	try {
+		beta();
+	} catchResume (2) {
+		printf("alpha caught exception 2\n");
+	} catchResume (4) {
+		printf("alpha caught exception 4\n");
+	}
+}
+
+// Finally Test:
+void farewell(bool jump) {
+	try {
+		if (jump) {
+			printf("jump out of farewell\n");
+			goto endoffunction;
+		} else {
+			printf("walk out of farewell\n");
+		}
+	} finally {
+		printf("See you next time\n");
+	}
+	endoffunction:
+	printf("leaving farewell\n");
+}
+
+// Resume-to-Terminate Test:
+void fallback() {
+	try {
+		resume(2);
+	} catch (2) {
+		printf("fallback caught termination 2\n");
+	}
+}
+
+// Terminate Throw New Exception:
+void terminate_swap() {
+	signal_exit a = {"terminate_swap"};
+	try {
+		terminate(2);
+	} catch (2) {
+		terminate(3);
+	}
+}
+
+void terminate_swapped() {
+	signal_exit a = {"terminate_swapped"};
+	try {
+		terminate_swap();
+	} catch (3) {
+		printf("terminate_swapped caught exception 3\n");
+	}
+}
+
+// Resume Throw New Exception:
+void resume_swap() {
+	signal_exit a = {"terminate_swap"};
+	try {
+		resume(2);
+	} catchResume (2) {
+		resume(3);
+	}
+}
+
+void resume_swapped() {
+	try {
+		resume_swap();
+	} catchResume (3) {
+		printf("resume_swapped caught exception 3\n");
+	}
+}
+
+// Terminate Rethrow:
+void reterminate() {
+	try {
+		try {
+			terminate(2);
+		} catch (2) {
+			printf("reterminate 2 caught and "
+			       "will rethrow exception 2\n");
+			throw;
+		}
+	} catch (2) {
+		printf("reterminate 1 caught exception 2\n");
+	}
+}
+
+// Resume Rethrow:
+void reresume() {
+	try {
+		try {
+			resume(2);
+		} catchResume (2) {
+			printf("reresume 2 caught and rethrows exception 2\n");
+			throwResume;
+		}
+	} catchResume (2) {
+		printf("reresume 1 caught exception 2\n");
+	}
+}
+
+// Terminate-Resume interaction:
+void fum() {
+	// terminate block, call resume
+	try {
+		resume(3);
+	} catch (3) {
+		printf("fum caught exception 3\n");
+	}
+}
+
+void foe() {
+	// resume block, call terminate
+	try {
+		terminate(3);
+	} catchResume (3) {
+		printf("foe caught exception 3\n");
+	}
+}
+
+void fy() {
+	// terminate block calls fum, call foe
+	try {
+		foe();
+	} catch (3) {
+		printf("fy caught exception 3\n");
+		fum();
+	}
+}
+
+void fee() {
+	// resume block, call fy
+	try {
+		fy();
+	} catchResume (3) {
+		printf("fee caught exception 3\n");
+	}
+}
+
+
+// main: choose which tests to run
+int main(int argc, char * argv[]) {
+	signal_exit a = {"main function"};
+
+	foo(); printf("\n");
+	alpha(); printf("\n");
+	farewell(false); printf("\n");
+	farewell(true); printf("\n");
+	fallback(); printf("\n");
+	terminate_swapped(); printf("\n");
+	resume_swapped(); printf("\n");
+	reterminate(); printf("\n");
+	reresume(); printf("\n");
+	fee(); printf("\n");
+	// Uncaught termination test.
+	terminate(7);
+}
Index: c/tests/exception.c
===================================================================
--- src/tests/exception.c	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ 	(revision )
@@ -1,31 +1,0 @@
-//Testing esceptions syntax
-int fred() {
-    int x;
-    throw 3;
-    throw x = 5;
-
-    try {
-    } catch( int i ) {}
-
-    try {
-	x/4;
-    } catch( int ) {
-    } catch( float x ) {
-    } catch( struct { int i; } ) {
-    } catch( struct { int i; } x ) {
-    } catch( struct { int i; } *x ) {
-
-// Cforall extensions
-
-    } catch( * struct { int i; } ) {
-    } catch( * struct { int i; } x ) {
-    } catch( ... ) {
-    } finally {
-    } // try
-}
-
-//Dummy main
-int main(int argc, char const *argv[])
-{
-	return 0;
-}
Index: src/tests/io.c
===================================================================
--- src/tests/io.c	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ src/tests/io.c	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -10,6 +10,6 @@
 // Created On       : Wed Mar  2 16:56:02 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jun  8 09:52:10 2017
-// Update Count     : 51
+// Last Modified On : Sun Jul  2 09:40:58 2017
+// Update Count     : 68
 // 
 
@@ -42,6 +42,6 @@
 	sout | endl;
 
+	sout | "opening delimiters" | endl;
 	sout
-		// opening delimiters
 		| "x (" | 1
 		| "x [" | 2
@@ -54,7 +54,8 @@
 		| "x ¿" | 9
 		| "x «" | 10
-		| endl;
+		| endl | endl;
+
+	sout | "closing delimiters" | endl;
 	sout
-		// closing delimiters
 		| 1 | ", x"
 		| 2 | ". x"
@@ -68,7 +69,8 @@
 		| 10 | "] x"
 		| 11 | "} x"
-		| endl;
+		| endl | endl;
+
+	sout | "opening/closing delimiters" | endl;
 	sout
-		// opening-closing delimiters
 		| "x`" | 1 | "`x'" | 2
 		| "'x\"" | 3 | "\"x:" | 4
@@ -76,11 +78,15 @@
 		| "\tx\f" | 7 | "\fx\v" | 8
 		| "\vx\n" | 9 | "\nx\r" | 10
-		| "\rx" |
-		endl;
+		| "\rx"
+		| endl | endl;
+
+	sout | "override opening/closing delimiters" | endl;
 	sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;
+	sout | endl;
 
 	ifstream in;										// create / open file
 	open( &in, "io.data", "r" );
 
+	sout | "input bacis types" | endl;
 	&in | &c											// character
 		| &si | &usi | &i | &ui | &li | &uli | &lli | &ulli	// integral
@@ -88,5 +94,7 @@
 		| &fc | &dc | &ldc								// floating-point complex
 		| cstr( s1 ) | cstr( s2, size );				// C string, length unchecked and checked
+	sout | endl;
 
+	sout | "output basic types" | endl;
 	sout | c | ' ' | endl								// character
 		| si | usi | i | ui | li | uli | lli | ulli | endl // integral
@@ -94,4 +102,11 @@
 		| fc | dc | ldc | endl;							// complex
 	sout | endl;
+
+	sout | "tuples" | endl;
+	[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
+	sout | t1 | t2 | endl;								// print tuple
+	sout | endl;
+
+	sout | "toggle separator" | endl;
 	sout | f | "" | d | "" | ld | endl					// floating point without separator
 		| sepDisable | fc | dc | ldc | sepEnable | endl	// complex without separator
@@ -100,25 +115,37 @@
 	sout | endl;
 
+	sout | "change separator" | endl;
+	sout | "from \" " | sepGet( sout ) | "\"";
 	sepSet( sout, ", $" );								// change separator, maximum of 15 characters
+	sout | "to \" " | sepGet( sout ) | "\"" | endl;
 	sout | f | d | ld | endl
 		| fc | dc | ldc | endl
-		| s1 | s2 | endl;
+		| s1 | s2 | endl
+		| t1 | t2 | endl;								// print tuple
+	sout | endl;
+	sout | "from \"" | sepGet( sout ) | "\"";
+	sepSet( sout, " " );								// restore separator
+	sout | "to \"" | sepGet( sout ) | "\"" | endl;
+	sout | f | d | ld | endl
+		| fc | dc | ldc | endl
+		| s1 | s2 | endl
+		| t1 | t2 | endl;								// print tuple
 	sout | endl;
 
-	[int, int] t1 = [1, 2], t2 = [3, 4];
-	sout | t1 | t2 | endl;								// print tuple
-
-	sepSet( sout, " " );
-	sepSet( sout, ", $" );								// set separator from " " to ", $"
-	sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
-	sepSet( sout, " " );								// reset separator to " "
-	sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
-
-	sout | sepOn | 1 | 2 | 3 | sepOn | endl;			// separator at start of line
+	sout | sepOn | 1 | 2 | 3 | sepOn | endl;			// separator at start/end of line
 	sout | 1 | sepOff | 2 | 3 | endl;					// locally turn off implicit separator
+	sout | sepOn | 1 | 2 | 3 | sepOn | sepOff | endl;	// separator at start of line
+	sout | 1 | 2 | 3 | endl | sepOn;					// separator at start of next line
+	sout | 1 | 2 | 3 | endl;
+	sout | endl;
 
 	sout | sepDisable | 1 | 2 | 3 | endl;				// globally turn off implicit separation
 	sout | 1 | sepOn | 2 | 3 | endl;					// locally turn on implicit separator
-	sout | sepEnable | 1 | 2 | 3 | endl;				// globally turn on implicit separation
+	sout | sepEnable | 1 | 2 | 3 | endl | sepDisable;	// globally turn on/off implicit separation
+	sout | 1 | 2 | 3 | endl | sepEnable;				// globally turn on implicit separation
+	sout | 1 | 2 | 3 | sepOn | sepDisable | endl;		// ignore seperate at end of line
+	sout | 1 | 2 | 3 | sepOn | sepEnable | endl;		// separator at end of line
+	sout | 1 | 2 | 3 | endl;
+	sout | endl;
 
 	sepSetTuple( sout, " " );							// set tuple separator from ", " to " "
@@ -126,6 +153,6 @@
 	sepSetTuple( sout, ", " );							// reset tuple separator to ", "
 	sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl;
-
 	sout | t1 | t2 | endl;								// print tuple
+	sout | endl;
 
 	[int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
Index: tools/cfa.nanorc
===================================================================
--- tools/cfa.nanorc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ tools/cfa.nanorc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -2,6 +2,5 @@
 ## WIP
 
-syntax "cfa" "\.cfa$"
-## No magic
+syntax "cfa" "\.cfa"
 
 # Macros
@@ -19,8 +18,8 @@
 # Control Flow Structures
 color brightyellow "\<(if|else|while|do|for|switch|choose|case|default)\>"
-##color brightyellow "\<(try|catch|catchResume|finally)\>"
+color brightyellow "\<(try|catch(Resume)?|finally)\>"
 
 # Control Flow Statements
-color magenta "\<(return|break|continue|fallthru|throw)\>"
+color magenta "\<(goto|return|break|continue|fallthr(u|ough)|throw(Resume)?)\>"
 
 # Operator Names
@@ -46,5 +45,5 @@
 color brightmagenta "'\\(([0-3]?[0-7]{1,2}))'" "'\\x[0-9A-Fa-f]{1,2}'"
 # Strings and Angle Strings
-color brightyellow ""([^"]|\\")*"" "<[^[:blank:]=]*>"
+color yellow ""([^"]|\\")*"" "<[^[:blank:]=]*>"
 # Multiline Strings: This regex is VERY expencive and often too strong.
 ###color brightyellow start=""(\\.|[^"])*\\[[:space:]]*$" end="^(\\.|[^"])*""
Index: tools/prettyprinter/main.cc
===================================================================
--- tools/prettyprinter/main.cc	(revision 11dbfe1a3caa7b8b2ac60e61a9bee57433ea08bf)
+++ tools/prettyprinter/main.cc	(revision 67fa9f99aebe68e73094bddc3ebf1c0d1c2d7844)
@@ -1,4 +1,4 @@
 // 
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
 //
 // The contents of this file are covered under the licence agreement in the
@@ -10,6 +10,6 @@
 // Created On       : Wed Jun 28 22:57:26 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jun 29 09:02:37 2017
-// Update Count     : 15
+// Last Modified On : Thu Jun 29 13:09:32 2017
+// Update Count     : 58
 // 
 
@@ -19,56 +19,91 @@
 using namespace std;
 #include <unistd.h>										// close
+#include <getopt.h>										// getopt
 #include "filter.h"
 
 extern FILE * yyin;
-extern int yylineno;
 extern int yydebug;
 extern int yyparse( void );
 
+bool parse_cmdline( int argc, char * argv[] ) {
+	enum { Html, Identity, Latex, Nocode, ParseTree, };
+
+	static struct option long_opts[] = {
+		{ "html", no_argument, nullptr, Html },
+		{ "identity", no_argument, nullptr, Identity },
+		{ "latex", no_argument, nullptr, Latex },
+		{ "nocode", no_argument, nullptr, Nocode },
+		{ "parse-tree", no_argument, nullptr, ParseTree },
+		{ nullptr, 0, nullptr, 0 }
+	}; // long_opts
+	int long_index;
+
+	opterr = 0;											// (global) prevent getopt from printing error messages
+
+	int c;
+	while ( (c = getopt_long( argc, argv, "hilnp", long_opts, &long_index )) != -1 ) {
+		switch ( c ) {
+		  case Html:
+		  case 'h':
+			filter = HTML;
+			break;
+		  case Identity:
+		  case 'i':
+			filter = ::Identity;
+			break;
+		  case Latex:
+		  case 'l':
+			filter = LaTeX;
+			break;
+		  case Nocode:
+		  case 'n':
+			filter = ::Nocode;
+			break;
+		  case ParseTree:
+		  case 'p':
+			filter = Parse_Tree;
+		  case '?':
+			if ( optopt ) {								// short option ?
+				cerr << "Unknown option: -" << (char)optopt << endl;
+			} else {									// long option
+				cerr << "Unknown option: " << argv[optind - 1] << endl;
+			} // if
+			return false;
+		  default:
+			abort();
+		} // switch
+	} // while
+
+	if ( optind != argc ) {								// input files ?
+		if ( optind == argc - 1 ) {						// any commands after the flags ? => input file name
+			yyin = fopen( argv[ optind ], "r" );
+			if ( yyin == nullptr ) {
+				cerr << "Open failure for input file \"" << argv[ optind ] << "\"" << endl;
+				return false;
+			} // if
+		} else {
+			cerr << "Too many input files " << argv[ optind + 1 ] << endl;
+			return false;
+		} // if
+	} // if
+	return true;
+} // parse_cmdline
+
 int main( int argc, char *argv[] ) {
-	yyin = stdin;
+	yyin = stdin;										// defaults
 	filter = Nocode;
 
-	try {
-		switch ( argc ) {
-		  case 3:
-			yyin = fopen( argv[ 2 ], "r" );
-			if ( yyin == nullptr ) {
-				throw ios_base::failure( "unknown printer option arguments" );
-			} // if
-			// FALL THROUGH
-		  case 2: {
-			  string arg( argv[1] );
-
-			  if ( arg == "-identity" ) {
-				  filter = Identity;
-			  } else if ( arg == "-parse_tree" ) {
-				  filter = Parse_Tree;
-			  } else if ( arg == "-nocode" ) {
-				  filter = Nocode;
-			  } else if ( arg == "-latex" ) {
-				  filter = LaTeX;
-			  } else if ( arg == "-html" ) {
-				  filter = HTML;
-			  } else {
-				  throw ios_base::failure( "unknown printer option arguments" );
-			  } // if
-			  break;
-		  }
-		  default:
-			throw ios_base::failure( "wrong number of arguments" );
-		} // switch
-	} catch( ios_base::failure err ) {
-		cerr << err.what() << endl;
-		cerr << "Usage: [" << argv[0]
-			 << "-identity |"
-			 << "-parse_tree |"
-			 << "-nocode |"
-			 << "-latex |"
-			 << "-html"
+	if ( ! parse_cmdline( argc, argv ) ) {
+		cerr << "Usage: " << argv[0]
+			 << " ["
+			 << "-h/--html | "
+			 << "-i/--identity | "
+			 << "-l/--latex | "
+			 << "-n/--nocode | "
+			 << "-p/--parse-tree"
 			 << "] [input-file]"
 			 << endl;
 		exit( EXIT_FAILURE );							// TERMINATE
-	} // try
+	} // if
 
 	//yydebug = 1;
