Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/CodeGen/CodeGenerator.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Thu Jun  8 16:00:00 2017
-// Update Count     : 485
+// Last Modified On : Tus Jul 25 15:29:00 2017
+// Update Count     : 486
 //
 #include "CodeGenerator.h"
@@ -594,4 +594,12 @@
 	}
 
+	void CodeGenerator::visit( VirtualCastExpr * castExpr ) {
+		assertf( ! genC, "VirtualCastExpr should not reach code generation." );
+		extension( castExpr );
+		output << "(virtual ";
+		castExpr->get_arg()->accept( *this );
+		output << ")";
+	}
+
 	void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
 		assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/CodeGen/CodeGenerator.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul 21 22:16:21 2017
-// Update Count     : 53
+// Last Modified By : Andrew Beach
+// Last Modified On : Tus Jul 25 25:30:00 2017
+// Update Count     : 54
 //
 
@@ -59,4 +59,5 @@
 		virtual void visit( AddressExpr *addressExpr );
 		virtual void visit( CastExpr *castExpr );
+		virtual void visit( VirtualCastExpr *castExpr );
 		virtual void visit( UntypedMemberExpr *memberExpr );
 		virtual void visit( MemberExpr *memberExpr );
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Common/PassVisitor.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -81,4 +81,5 @@
 	virtual void visit( NameExpr *nameExpr ) override final;
 	virtual void visit( CastExpr *castExpr ) override final;
+	virtual void visit( VirtualCastExpr *castExpr ) override final;
 	virtual void visit( AddressExpr *addressExpr ) override final;
 	virtual void visit( LabelAddressExpr *labAddressExpr ) override final;
@@ -168,4 +169,5 @@
 	virtual Expression* mutate( LabelAddressExpr *labAddressExpr ) override final;
 	virtual Expression* mutate( CastExpr *castExpr ) override final;
+	virtual Expression* mutate( VirtualCastExpr *castExpr ) override final;
 	virtual Expression* mutate( UntypedMemberExpr *memberExpr ) override final;
 	virtual Expression* mutate( MemberExpr *memberExpr ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Common/PassVisitor.impl.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -607,4 +607,9 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
+	VISIT_BODY( node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( AddressExpr * node ) {
 	VISIT_BODY( node );
@@ -979,4 +984,9 @@
 
 template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
+	MUTATE_BODY( Expression, node );
+}
+
+template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
 	MUTATE_BODY( Expression, node );
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/GenPoly/Box.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -1750,5 +1750,5 @@
 
 		Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) {
-			Type *ty = sizeofExpr->get_type();
+			Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
 			if ( findGeneric( ty ) ) {
 				Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
@@ -1760,5 +1760,5 @@
 
 		Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) {
-			Type *ty = alignofExpr->get_type();
+			Type *ty = alignofExpr->get_isType() ? alignofExpr->get_type() : alignofExpr->get_expr()->get_result();
 			if ( findGeneric( ty ) ) {
 				Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) );
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Makefile.am	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,7 +10,7 @@
 ## Author           : Peter A. Buhr
 ## Created On       : Sun May 31 08:51:46 2015
-## Last Modified By : Peter A. Buhr
-## Last Modified On : Thu Oct 27 20:41:25 2016
-## Update Count     : 75
+## Last Modified By : Andrew Beach
+## Last Modified On : Tus Jul 25 10:34:00 2017
+## Update Count     : 76
 ###############################################################################
 
@@ -37,4 +37,5 @@
 include SynTree/module.mk
 include Tuples/module.mk
+include Virtual/module.mk
 
 # put into lib for now
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Makefile.in	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -23,4 +23,7 @@
 #SRC +=  ArgTweak/Rewriter.cc \
 #	ArgTweak/Mutate.cc
+
+######################### -*- Mode: Makefile-Gmake -*- ########################
+###############################################################################
 
 ######################### -*- Mode: Makefile-Gmake -*- ########################
@@ -255,5 +258,6 @@
 	Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \
 	Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT) \
-	Tuples/driver_cfa_cpp-Explode.$(OBJEXT)
+	Tuples/driver_cfa_cpp-Explode.$(OBJEXT) \
+	Virtual/driver_cfa_cpp-ExpandCasts.$(OBJEXT)
 am_driver_cfa_cpp_OBJECTS = $(am__objects_1)
 driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS)
@@ -355,7 +359,7 @@
 	$(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk \
 	$(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk \
-	$(srcdir)/Tuples/module.mk $(top_srcdir)/automake/depcomp \
-	$(top_srcdir)/automake/ylwrap Parser/lex.cc Parser/parser.cc \
-	Parser/parser.hh
+	$(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk \
+	$(top_srcdir)/automake/depcomp $(top_srcdir)/automake/ylwrap \
+	Parser/lex.cc Parser/parser.cc Parser/parser.hh
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -533,5 +537,5 @@
 	SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
 	Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
-	Tuples/Explode.cc
+	Tuples/Explode.cc Virtual/ExpandCasts.cc
 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
 	${cfa_cpplib_PROGRAMS}}
@@ -552,5 +556,5 @@
 .SUFFIXES:
 .SUFFIXES: .cc .ll .o .obj .yy
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -572,5 +576,5 @@
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
-$(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(am__empty):
+$(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk $(am__empty):
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -941,4 +945,12 @@
 Tuples/driver_cfa_cpp-Explode.$(OBJEXT): Tuples/$(am__dirstamp) \
 	Tuples/$(DEPDIR)/$(am__dirstamp)
+Virtual/$(am__dirstamp):
+	@$(MKDIR_P) Virtual
+	@: > Virtual/$(am__dirstamp)
+Virtual/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) Virtual/$(DEPDIR)
+	@: > Virtual/$(DEPDIR)/$(am__dirstamp)
+Virtual/driver_cfa_cpp-ExpandCasts.$(OBJEXT): Virtual/$(am__dirstamp) \
+	Virtual/$(DEPDIR)/$(am__dirstamp)
 driver/$(am__dirstamp):
 	@$(MKDIR_P) driver
@@ -963,4 +975,5 @@
 	-rm -f SynTree/*.$(OBJEXT)
 	-rm -f Tuples/*.$(OBJEXT)
+	-rm -f Virtual/*.$(OBJEXT)
 
 distclean-compile:
@@ -1078,4 +1091,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po@am__quote@
 
 .cc.o:
@@ -2648,4 +2662,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 Tuples/driver_cfa_cpp-Explode.obj `if test -f 'Tuples/Explode.cc'; then $(CYGPATH_W) 'Tuples/Explode.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/Explode.cc'; fi`
+
+Virtual/driver_cfa_cpp-ExpandCasts.o: Virtual/ExpandCasts.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Virtual/driver_cfa_cpp-ExpandCasts.o -MD -MP -MF Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo -c -o Virtual/driver_cfa_cpp-ExpandCasts.o `test -f 'Virtual/ExpandCasts.cc' || echo '$(srcdir)/'`Virtual/ExpandCasts.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Virtual/ExpandCasts.cc' object='Virtual/driver_cfa_cpp-ExpandCasts.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 Virtual/driver_cfa_cpp-ExpandCasts.o `test -f 'Virtual/ExpandCasts.cc' || echo '$(srcdir)/'`Virtual/ExpandCasts.cc
+
+Virtual/driver_cfa_cpp-ExpandCasts.obj: Virtual/ExpandCasts.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Virtual/driver_cfa_cpp-ExpandCasts.obj -MD -MP -MF Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo -c -o Virtual/driver_cfa_cpp-ExpandCasts.obj `if test -f 'Virtual/ExpandCasts.cc'; then $(CYGPATH_W) 'Virtual/ExpandCasts.cc'; else $(CYGPATH_W) '$(srcdir)/Virtual/ExpandCasts.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Virtual/ExpandCasts.cc' object='Virtual/driver_cfa_cpp-ExpandCasts.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 Virtual/driver_cfa_cpp-ExpandCasts.obj `if test -f 'Virtual/ExpandCasts.cc'; then $(CYGPATH_W) 'Virtual/ExpandCasts.cc'; else $(CYGPATH_W) '$(srcdir)/Virtual/ExpandCasts.cc'; fi`
 
 .ll.cc:
@@ -2796,4 +2824,6 @@
 	-rm -f Tuples/$(DEPDIR)/$(am__dirstamp)
 	-rm -f Tuples/$(am__dirstamp)
+	-rm -f Virtual/$(DEPDIR)/$(am__dirstamp)
+	-rm -f Virtual/$(am__dirstamp)
 	-rm -f driver/$(am__dirstamp)
 
@@ -2811,5 +2841,5 @@
 
 distclean: distclean-am
-	-rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Virtual/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
@@ -2857,5 +2887,5 @@
 
 maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Virtual/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Parser/ExpressionNode.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 13:17:07 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Tus Jul 18 10:08:00 2017
-// Update Count     : 550
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu Jul 27 12:10:10 2017
+// Update Count     : 556
 //
 
@@ -62,7 +62,18 @@
 	bool dec = true, Unsigned = false;					// decimal, unsigned constant
 	int size;											// 0 => int, 1 => long, 2 => long long
-	unsigned long long int v;								// converted integral value
+	unsigned long long int v;							// converted integral value
 	size_t last = str.length() - 1;						// last character of constant
-
+	Expression * ret;
+
+	// special constants
+	if ( str == "0" ) {
+		ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ) );
+		goto CLEANUP;
+	} // if
+	if ( str == "1" ) {
+		ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ) );
+		goto CLEANUP;
+	} // if
+	
 	if ( str[0] == '0' ) {								// octal/hex constant ?
 		dec = false;
@@ -118,5 +129,6 @@
 	} // if
 
-	Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
+	ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
+  CLEANUP:
 	delete &str;										// created by lex
 	return ret;
@@ -174,11 +186,4 @@
 	return ret;
 } // build_constantStr
-
-Expression *build_constantZeroOne( const std::string & str ) {
-	Expression * ret = new ConstantExpr( Constant( str == "0" ? (Type *)new ZeroType( noQualifiers ) : (Type*)new OneType( noQualifiers ), str,
-												   str == "0" ? (unsigned long long int)0 : (unsigned long long int)1 ) );
-	delete &str;										// created by lex
-	return ret;
-} // build_constantChar
 
 Expression * build_field_name_FLOATINGconstant( const std::string & str ) {
@@ -252,4 +257,11 @@
 }
 
+
+Expression *build_virtual_cast( DeclarationNode *decl_node, ExpressionNode *expr_node ) {
+	Type *targetType = maybeMoveBuildType( decl_node );
+	Expression *castArg = maybeMoveBuild< Expression >( expr_node );
+	return new VirtualCastExpr( castArg, targetType );
+}
+
 Expression *build_fieldSel( ExpressionNode *expr_node, Expression *member ) {
 	UntypedMemberExpr *ret = new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Parser/ParseNode.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:32:30 2017
-// Update Count     : 786
+// Last Modified On : Thu Jul 27 12:08:08 2017
+// Update Count     : 788
 //
 
@@ -159,5 +159,4 @@
 Expression * build_constantFloat( const std::string &str );
 Expression * build_constantChar( const std::string &str );
-Expression * build_constantZeroOne( const std::string &str );
 ConstantExpr * build_constantStr( const std::string &str );
 Expression * build_field_name_FLOATINGconstant( const std::string & str );
@@ -170,4 +169,5 @@
 
 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
+Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Parser/lex.ll	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Mon Jul 24 08:27:23 2017
- * Update Count     : 545
+ * Last Modified On : Thu Jul 27 12:05:50 2017
+ * Update Count     : 549
  */
 
@@ -288,6 +288,4 @@
 
 				/* numeric constants */
-"0"				{ NUMERIC_RETURN(ZERO); }				// CFA
-"1"				{ NUMERIC_RETURN(ONE); }				// CFA
 {decimal_constant} { NUMERIC_RETURN(INTEGERconstant); }
 {octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/Parser/parser.yy	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jul 24 09:01:14 2017
-// Update Count     : 2463
+// Last Modified On : Thu Jul 27 12:08:08 2017
+// Update Count     : 2467
 //
 
@@ -142,5 +142,4 @@
 // converted into the tuple index (.)(1). e.g., 3.x
 %token<tok>	REALDECIMALconstant	REALFRACTIONconstant	FLOATINGconstant
-%token<tok> ZERO				ONE						// CFA
 
 // multi-character operators
@@ -159,5 +158,5 @@
 %token ATassign											// @=
 
-%type<tok> identifier  no_attr_identifier  zero_one
+%type<tok> identifier  no_attr_identifier
 %type<tok> identifier_or_type_name  no_attr_identifier_or_type_name  attr_name
 %type<constant> string_literal
@@ -360,9 +359,4 @@
 	;
 
-zero_one:												// CFA
-	ZERO
-	| ONE
- 	;
-
 string_literal:
 	string_literal_list							{ $$ = build_constantStr( *$1 ); }
@@ -384,6 +378,4 @@
 	IDENTIFIER											// typedef name cannot be used as a variable name
 		{ $$ = new ExpressionNode( build_varref( $1 ) ); }
-	| zero_one
-		{ $$ = new ExpressionNode( build_constantZeroOne( *$1 ) ); }
 	| tuple
 	| '(' comma_expression ')'
@@ -484,8 +476,4 @@
 		{
 			$$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
-		}
-	| zero_one fraction_constants
-		{
-			$$ = new ExpressionNode( build_field_name_fraction_constants( build_constantZeroOne( *$1 ), $2 ) );
 		}
 	;
@@ -573,7 +561,7 @@
 		// VIRTUAL cannot be opt because of look ahead issues
 	| '(' VIRTUAL ')' cast_expression
-		{ $$ = new ExpressionNode( build_cast( nullptr, $4 ) ); }
+		{ $$ = new ExpressionNode( build_virtual_cast( nullptr, $4 ) ); }
 	| '(' VIRTUAL type_no_function ')' cast_expression
-		{ $$ = new ExpressionNode( build_cast( $3, $5 ) ); }
+		{ $$ = new ExpressionNode( build_virtual_cast( $3, $5 ) ); }
 //	| '(' type_no_function ')' tuple
 //		{ $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 23:52:08 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Mar 17 09:14:17 2017
-// Update Count     : 30
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Jul 26 11:33:00 2017
+// Update Count     : 31
 //
 
@@ -878,4 +878,17 @@
 	}
 
+	void AlternativeFinder::visit( VirtualCastExpr * castExpr ) {
+		assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." );
+		AlternativeFinder finder( indexer, env );
+		// don't prune here, since it's guaranteed all alternatives will have the same type
+		// (giving the alternatives different types is half of the point of ConstructorExpr nodes)
+		finder.findWithAdjustment( castExpr->get_arg(), false );
+		for ( Alternative & alt : finder.alternatives ) {
+			alternatives.push_back( Alternative(
+				new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),
+				alt.env, alt.cost ) );
+		}
+	}
+
 	void AlternativeFinder::visit( UntypedMemberExpr *memberExpr ) {
 		AlternativeFinder funcFinder( indexer, env );
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 23:56:12 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:35:32 2017
-// Update Count     : 3
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Jul 26 11:24:00 2017
+// Update Count     : 4
 //
 
@@ -49,4 +49,5 @@
 		virtual void visit( AddressExpr *addressExpr );
 		virtual void visit( CastExpr *castExpr );
+		virtual void visit( VirtualCastExpr *castExpr );
 		virtual void visit( UntypedMemberExpr *memberExpr );
 		virtual void visit( MemberExpr *memberExpr );
Index: src/SynTree/ApplicationExpr.cc
===================================================================
--- src/SynTree/ApplicationExpr.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/ApplicationExpr.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -44,5 +44,5 @@
 }
 
-ApplicationExpr::ApplicationExpr( Expression *funcExpr ) : function( funcExpr ) {
+ApplicationExpr::ApplicationExpr( Expression *funcExpr, const std::list< Expression * > & argList ) : function( funcExpr ), args( argList ) {
 	PointerType *pointer = safe_dynamic_cast< PointerType* >( funcExpr->get_result() );
 	FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/Expression.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Mar 30 16:41:13 2017
-// Update Count     : 52
+// Last Modified On : Tue Jul 25 14:15:47 2017
+// Update Count     : 54
 //
 
@@ -298,4 +298,29 @@
 	if ( result->isVoid() ) {
 		os << "nothing";
+	} else {
+		result->print( os, indent+2 );
+	} // if
+	os << std::endl;
+	Expression::print( os, indent );
+}
+
+VirtualCastExpr::VirtualCastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
+	set_result(toType);
+}
+
+VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
+}
+
+VirtualCastExpr::~VirtualCastExpr() {
+	delete arg;
+}
+
+void VirtualCastExpr::print( std::ostream &os, int indent ) const {
+	os << "Virtual Cast of:" << std::endl << std::string( indent+2, ' ' );
+	arg->print(os, indent+2);
+	os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl;
+	os << std::string( indent+2, ' ' );
+	if ( ! result ) {
+		os << "unknown";
 	} else {
 		result->print( os, indent+2 );
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/Expression.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:53:16 2017
-// Update Count     : 42
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jul 24 16:27:00 2017
+// Update Count     : 43
 //
 
@@ -79,5 +79,5 @@
 class ApplicationExpr : public Expression {
   public:
-	ApplicationExpr( Expression * function );
+	ApplicationExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() );
 	ApplicationExpr( const ApplicationExpr & other );
 	virtual ~ApplicationExpr();
@@ -194,7 +194,25 @@
 
 	Expression * get_arg() const { return arg; }
-	void set_arg(Expression * newValue ) { arg = newValue; }
+	void set_arg( Expression * newValue ) { arg = newValue; }
 
 	virtual CastExpr * clone() const { return new CastExpr( * 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 * arg;
+};
+
+/// VirtualCastExpr repersents a virtual dynamic cast, e.g. (virtual exception)e
+class VirtualCastExpr : public Expression {
+  public:
+	VirtualCastExpr( Expression * arg, Type * toType );
+	VirtualCastExpr( const VirtualCastExpr & other );
+	virtual ~VirtualCastExpr();
+
+	Expression * get_arg() const { return arg; }
+	void set_arg( Expression * newValue ) { arg = newValue; }
+
+	virtual VirtualCastExpr * clone() const { return new VirtualCastExpr( * this ); }
 	virtual void accept( Visitor & v ) { v.visit( this ); }
 	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/Mutator.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Thu Jun 22 13:43:00 2017
-// Update Count     : 24
+// Last Modified On : Mon Jul 24 16:32:00 2017
+// Update Count     : 25
 //
 
@@ -235,4 +235,11 @@
 }
 
+Expression *Mutator::mutate( VirtualCastExpr *castExpr ) {
+	castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) );
+	castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
+	castExpr->set_arg( maybeMutate( castExpr->get_arg(), *this ) );
+	return castExpr;
+}
+
 Expression *Mutator::mutate( UntypedMemberExpr *memberExpr ) {
 	memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/Mutator.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:51:30 2017
-// Update Count     : 15
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jul 24 16:31:00 2017
+// Update Count     : 16
 //
 #include <cassert>
@@ -59,4 +59,5 @@
 	virtual Expression* mutate( LabelAddressExpr *labAddressExpr );
 	virtual Expression* mutate( CastExpr *castExpr );
+	virtual Expression* mutate( VirtualCastExpr *castExpr );
 	virtual Expression* mutate( UntypedMemberExpr *memberExpr );
 	virtual Expression* mutate( MemberExpr *memberExpr );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/SynTree.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:51:46 2017
-// Update Count     : 10
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jul 24 16:54:00 2017
+// Update Count     : 11
 //
 
@@ -66,4 +66,5 @@
 class LabelAddressExpr;
 class CastExpr;
+class VirtualCastExpr;
 class MemberExpr;
 class UntypedMemberExpr;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/Visitor.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Thu Jun 22 13:41:00 2017
-// Update Count     : 26
+// Last Modified On : Mon Jul 24 16:30:00 2017
+// Update Count     : 27
 //
 
@@ -192,4 +192,9 @@
 }
 
+void Visitor::visit( VirtualCastExpr *castExpr ) {
+	maybeAccept( castExpr->get_result(), *this );
+	maybeAccept( castExpr->get_arg(), *this );
+}
+
 void Visitor::visit( UntypedMemberExpr *memberExpr ) {
 	maybeAccept( memberExpr->get_result(), *this );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/SynTree/Visitor.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:54:04 2017
-// Update Count     : 12
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jul 24 16:28:00 2017
+// Update Count     : 13
 //
 
@@ -60,4 +60,5 @@
 	virtual void visit( NameExpr *nameExpr );
 	virtual void visit( CastExpr *castExpr );
+	virtual void visit( VirtualCastExpr *castExpr );
 	virtual void visit( AddressExpr *addressExpr );
 	virtual void visit( LabelAddressExpr *labAddressExpr );
Index: src/Virtual/ExpandCasts.cc
===================================================================
--- src/Virtual/ExpandCasts.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
+++ src/Virtual/ExpandCasts.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -0,0 +1,150 @@
+//
+// 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.
+//
+// ExpandCasts.cc --
+//
+// Author           : Andrew Beach
+// Created On       : Mon Jul 24 13:59:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Jul 26 14:16:00 2017
+// Update Count     : 0
+//
+
+#include "ExpandCasts.h"
+#include "Common/PassVisitor.h"
+
+namespace Virtual {
+
+	/* Currently virtual depends on the rather brittle name matching between
+	 * a (strict/explicate) virtual type, its vtable type and the vtable
+	 * instance.
+	 * A stronger implementation, would probably keep track of those triads
+	 * and use that information to create better error messages.
+	 */
+
+	std::string get_vtable_name( std::string const & name ) {
+		return name + "_vtable";
+	}
+
+	std::string get_vtable_inst_name( std::string const & name ) {
+		return std::string("_") + get_vtable_name( name ) + "_instance";
+	}
+
+	std::string get_vtable_name_root( std::string const & name ) {
+		return name.substr(0, name.size() - 7 );
+	}
+
+	std::string get_vtable_inst_name_root( std::string const & name ) {
+		return get_vtable_name_root( name.substr(1, name.size() - 10 ) );
+	}
+
+	bool is_vtable_name( std::string const & name ) {
+		return (name.substr( name.size() - 7 ) == "_vtable" );
+	}
+
+	bool is_vtable_inst_name( std::string const & name ) {
+		return 17 < name.size() &&
+			name == get_vtable_inst_name( get_vtable_inst_name_root( name ) );
+	}
+
+	class VirtualCastCore {
+        std::map<std::string, ObjectDecl *> vtable_instances;
+        FunctionDecl *vcast_decl;
+        StructDecl *pvt_decl;
+
+		Type * pointer_to_pvt(int level_of_indirection) {
+			Type * type = new StructInstType(
+				Type::Qualifiers( Type::Const ), pvt_decl );
+			for (int i = 0 ; i < level_of_indirection ; ++i) {
+				type = new PointerType( noQualifiers, type );
+			}
+			return type;
+		}
+
+	public:
+		VirtualCastCore() :
+			vtable_instances(), vcast_decl( nullptr ), pvt_decl( nullptr )
+		{}
+
+		void premutate( FunctionDecl * functionDecl );
+		void premutate( StructDecl * structDecl );
+		void premutate( ObjectDecl * objectDecl );
+
+		Expression * postmutate( VirtualCastExpr * castExpr );
+	};
+
+	void VirtualCastCore::premutate( FunctionDecl * functionDecl ) {
+		if ( (! vcast_decl) && functionDecl->get_statements() &&
+		     functionDecl->get_name() == "__cfa__virtual_cast" ) {
+			vcast_decl = functionDecl;
+		}
+	}
+
+	void VirtualCastCore::premutate( StructDecl * structDecl ) {
+		if ( pvt_decl || ! structDecl->has_body() ) {
+			return;
+		} else if ( structDecl->get_name() == "__cfa__parent_vtable" ) {
+			pvt_decl = structDecl;
+		}
+	}
+
+	void VirtualCastCore::premutate( ObjectDecl * objectDecl ) {
+		if ( is_vtable_inst_name( objectDecl->get_name() ) ) {
+			vtable_instances[objectDecl->get_name()] = objectDecl;
+		}
+	}
+
+	Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) {
+		assertf( castExpr->get_result(), "Virtual Cast target not found before expansion." );
+
+		//assert( vcast_decl );
+		assert( pvt_decl );
+
+		// May only cast to a pointer or reference type.
+		// A earlier validation should give a syntax error, this is
+		// just to make sure errors don't creep in.
+		PointerType * target_type =
+			dynamic_cast<PointerType *>( castExpr->get_result() );
+        assert( target_type );
+
+		StructInstType * target_struct =
+			dynamic_cast<StructInstType *>( target_type->get_base() );
+		StructDecl * target_decl = target_struct->get_baseStruct();
+
+		std::map<std::string, ObjectDecl *>::iterator found =
+			vtable_instances.find(
+				get_vtable_inst_name( target_decl->get_name() ) );
+		if ( vtable_instances.end() == found ) {
+			assertf( false, "virtual table instance not found." );
+		}
+		ObjectDecl * table = found->second;
+
+		Expression * result = new CastExpr(
+			//new ApplicationExpr( new VariableExpr( vcast_decl ), {
+			new UntypedExpr( new NameExpr( "__cfa__virtual_cast" ), {
+				new CastExpr(
+					new AddressExpr( new VariableExpr( table ) ),
+					pointer_to_pvt(1)
+					),
+				new CastExpr(
+					castExpr->get_arg(),
+					pointer_to_pvt(2)
+					) }
+				),
+			castExpr->get_result()
+			);
+
+		castExpr->set_arg( nullptr );
+		castExpr->set_result( nullptr );
+		delete castExpr;
+		return result;
+	}
+
+	void expandCasts( std::list< Declaration * > & translationUnit ) {
+		PassVisitor<VirtualCastCore> translator;
+		mutateAll( translationUnit, translator );
+	}
+}
Index: src/Virtual/ExpandCasts.h
===================================================================
--- src/Virtual/ExpandCasts.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
+++ src/Virtual/ExpandCasts.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -0,0 +1,27 @@
+//
+// 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.
+//
+// ExpandCasts.h --
+//
+// Author           : Andrew Beach
+// Created On       : Mon Jul 24 13:54:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Tus Jul 25 14:51:00 2017
+// Update Count     : 0
+//
+
+#pragma once
+
+#include <list>
+#include "SynTree/SynTree.h"
+
+namespace Virtual {
+	void expandCasts( std::list< Declaration * > & translationUnit );
+	// Breaks all virtual cast nodes up into translatable nodes.
+
+	// Later this might just set some information so it can happen at CodeGen.
+
+}
Index: src/Virtual/module.mk
===================================================================
--- src/Virtual/module.mk	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
+++ src/Virtual/module.mk	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -0,0 +1,17 @@
+######################### -*- Mode: Makefile-Gmake -*- ########################
+##
+## 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.
+##
+## module.mk --
+##
+## Author           : Andrew Beach
+## Created On       : Tus Jul 25 10:18:00 2017
+## Last Modified By : Andrew Beach
+## Last Modified On : Tus Jul 25 10:18:00 2017
+## Update Count     : 0
+###############################################################################
+
+SRC += Virtual/ExpandCasts.cc
Index: src/libcfa/Makefile.am
===================================================================
--- src/libcfa/Makefile.am	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/libcfa/Makefile.am	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -10,7 +10,7 @@
 ## Author           : Peter A. Buhr
 ## Created On       : Sun May 31 08:54:01 2015
-## Last Modified By : Peter A. Buhr
-## Last Modified On : Thu Jul 20 23:09:34 2017
-## Update Count     : 220
+## Last Modified By : Andrew Beach
+## Last Modified On : Wed Jul 26 14:15:00 2017
+## Update Count     : 221
 ###############################################################################
 
@@ -56,5 +56,5 @@
 libobjs = ${headers:=.o}
 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
-	 assert.c exception.c typeobject.c
+	 assert.c exception.c virtual.c
 
 # not all platforms support concurrency, add option do disable it
@@ -73,5 +73,5 @@
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
 
-libcfa_a-typeobject.o : typeobject.c
+libcfa_a-virtual.o : virtual.c
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
 
@@ -82,5 +82,5 @@
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $<
 
-libcfa_d_a-typeobject.o : typeobject.c
+libcfa_d_a-virtual.o : virtual.c
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $<
 
Index: src/libcfa/Makefile.in
===================================================================
--- src/libcfa/Makefile.in	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/libcfa/Makefile.in	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -154,7 +154,7 @@
 	concurrency/coroutine.c concurrency/thread.c \
 	concurrency/kernel.c concurrency/monitor.c assert.c \
-	exception.c typeobject.c \
-	concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
-	concurrency/invoke.c concurrency/preemption.c
+	exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
+	concurrency/alarm.c concurrency/invoke.c \
+	concurrency/preemption.c
 am__dirstamp = $(am__leading_dot)dirstamp
 @BUILD_CONCURRENCY_TRUE@am__objects_1 = concurrency/libcfa_d_a-coroutine.$(OBJEXT) \
@@ -178,5 +178,5 @@
 	libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \
 	libcfa_d_a-assert.$(OBJEXT) libcfa_d_a-exception.$(OBJEXT) \
-	libcfa_d_a-typeobject.$(OBJEXT) $(am__objects_3)
+	libcfa_d_a-virtual.$(OBJEXT) $(am__objects_3)
 am_libcfa_d_a_OBJECTS = $(am__objects_4)
 libcfa_d_a_OBJECTS = $(am_libcfa_d_a_OBJECTS)
@@ -189,7 +189,7 @@
 	concurrency/coroutine.c concurrency/thread.c \
 	concurrency/kernel.c concurrency/monitor.c assert.c \
-	exception.c typeobject.c \
-	concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
-	concurrency/invoke.c concurrency/preemption.c
+	exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
+	concurrency/alarm.c concurrency/invoke.c \
+	concurrency/preemption.c
 @BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \
 @BUILD_CONCURRENCY_TRUE@	concurrency/libcfa_a-thread.$(OBJEXT) \
@@ -211,5 +211,5 @@
 	libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \
 	libcfa_a-assert.$(OBJEXT) libcfa_a-exception.$(OBJEXT) \
-	libcfa_a-typeobject.$(OBJEXT) $(am__objects_7)
+	libcfa_a-virtual.$(OBJEXT) $(am__objects_7)
 am_libcfa_a_OBJECTS = $(am__objects_8)
 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
@@ -423,5 +423,5 @@
 libobjs = ${headers:=.o}
 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \
-	assert.c exception.c typeobject.c $(am__append_4)
+	assert.c exception.c virtual.c $(am__append_4)
 libcfa_a_SOURCES = ${libsrc}
 libcfa_a_CFLAGS = -nodebug -O2
@@ -598,5 +598,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-stdlib.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-typeobject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-virtual.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@
@@ -609,5 +609,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-rational.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-stdlib.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-typeobject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/CtxSwitch-@MACHINE_TYPE@.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-alarm.Po@am__quote@
@@ -920,10 +920,10 @@
 @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`
 
-libcfa_d_a-typeobject.obj: typeobject.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-typeobject.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-typeobject.Tpo -c -o libcfa_d_a-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-typeobject.Tpo $(DEPDIR)/libcfa_d_a-typeobject.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='typeobject.c' object='libcfa_d_a-typeobject.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-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi`
+libcfa_d_a-virtual.obj: virtual.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-virtual.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-virtual.Tpo -c -o libcfa_d_a-virtual.obj `if test -f 'virtual.c'; then $(CYGPATH_W) 'virtual.c'; else $(CYGPATH_W) '$(srcdir)/virtual.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-virtual.Tpo $(DEPDIR)/libcfa_d_a-virtual.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='virtual.c' object='libcfa_d_a-virtual.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-virtual.obj `if test -f 'virtual.c'; then $(CYGPATH_W) 'virtual.c'; else $(CYGPATH_W) '$(srcdir)/virtual.c'; fi`
 
 concurrency/libcfa_d_a-alarm.o: concurrency/alarm.c
@@ -1214,10 +1214,10 @@
 @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`
 
-libcfa_a-typeobject.obj: typeobject.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-typeobject.obj -MD -MP -MF $(DEPDIR)/libcfa_a-typeobject.Tpo -c -o libcfa_a-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-typeobject.Tpo $(DEPDIR)/libcfa_a-typeobject.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='typeobject.c' object='libcfa_a-typeobject.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-typeobject.obj `if test -f 'typeobject.c'; then $(CYGPATH_W) 'typeobject.c'; else $(CYGPATH_W) '$(srcdir)/typeobject.c'; fi`
+libcfa_a-virtual.obj: virtual.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-virtual.obj -MD -MP -MF $(DEPDIR)/libcfa_a-virtual.Tpo -c -o libcfa_a-virtual.obj `if test -f 'virtual.c'; then $(CYGPATH_W) 'virtual.c'; else $(CYGPATH_W) '$(srcdir)/virtual.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-virtual.Tpo $(DEPDIR)/libcfa_a-virtual.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='virtual.c' object='libcfa_a-virtual.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-virtual.obj `if test -f 'virtual.c'; then $(CYGPATH_W) 'virtual.c'; else $(CYGPATH_W) '$(srcdir)/virtual.c'; fi`
 
 concurrency/libcfa_a-alarm.o: concurrency/alarm.c
@@ -1513,5 +1513,5 @@
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
 
-libcfa_a-typeobject.o : typeobject.c
+libcfa_a-virtual.o : virtual.c
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -O2 ${EXTRA_FLAGS} -c -o $@ $<
 
@@ -1522,5 +1522,5 @@
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $<
 
-libcfa_d_a-typeobject.o : typeobject.c
+libcfa_d_a-virtual.o : virtual.c
 	${AM_V_CC}@BACKEND_CC@ -DHAVE_CONFIG_H -I. -I../.. -D__CFA_DEBUG__ -O0 ${EXTRA_FLAGS} -c -o $@ $<
 
Index: src/libcfa/virtual.c
===================================================================
--- src/libcfa/virtual.c	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
+++ src/libcfa/virtual.c	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -0,0 +1,31 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// virtual.c --
+//
+// Author           : Andrew Beach
+// Created On       : Tus Jul 11 15:10:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Jul 26 14:24:00 2017
+// Update Count     : 1
+//
+
+#include "virtual.h"
+
+int __cfa__is_parent( struct __cfa__parent_vtable const * parent,
+    	struct __cfa__parent_vtable const * child ) {
+	do {
+		if ( parent == child )
+			return 1;
+		child = child->parent;
+	} while ( child );
+	return 0;
+}
+
+void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent,
+    	struct __cfa__parent_vtable const * const * child ) {
+	return (__cfa__is_parent(parent, *child)) ? (void *)child : (void *)0;
+}
Index: src/libcfa/virtual.h
===================================================================
--- src/libcfa/virtual.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
+++ src/libcfa/virtual.h	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -0,0 +1,39 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// virtual.h -- Builtins for hierarchy objects.
+//
+// Author           : Andrew Beach
+// Created On       : Tus Jul 11 15:08:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Jul 26 14:18:00 2017
+// Update Count     : 1
+//
+
+#pragma once
+
+#ifdef __CFORALL__
+extern "C" {
+#endif
+
+// All strict/explicate vtables should have this head, showing their parent.
+struct __cfa__parent_vtable {
+    struct __cfa__parent_vtable const * const parent;
+};
+
+// Takes in two non-null pointers to type_objects.
+int __cfa__is_parent( struct __cfa__parent_vtable const * parent,
+		struct __cfa__parent_vtable const * child );
+
+// If parent is a parent of child then return child, otherwise return NULL.
+// Input pointers are none-null, child's first level should be an object with
+// a vtable
+void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent,
+		struct __cfa__parent_vtable const * const * child );
+
+#ifdef __CFORALL__
+}
+#endif
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/main.cc	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -11,6 +11,6 @@
 // Created On       : Fri May 15 23:12:02 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Jul  7 11:13:00 2017
-// Update Count     : 442
+// Last Modified On : Wed Jul 26 14:38:00 2017
+// Update Count     : 443
 //
 
@@ -58,4 +58,5 @@
 #include "SynTree/Visitor.h"                // for acceptAll
 #include "Tuples/Tuples.h"                  // for expandMemberTuples, expan...
+#include "Virtual/ExpandCasts.h"            // for expandCasts
 
 using namespace std;
@@ -313,4 +314,7 @@
 		}
 
+		OPTPRINT( "virtual expandCasts" ) // Must come after translateEHM
+		Virtual::expandCasts( translationUnit );
+
 		OPTPRINT("instantiateGenerics")
 		GenPoly::instantiateGeneric( translationUnit );
Index: src/prelude/builtins.c
===================================================================
--- src/prelude/builtins.c	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/prelude/builtins.c	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -1,16 +1,16 @@
-// 
+//
 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
 //
 // The contents of this file are covered under the licence agreement in the
 // file "LICENCE" distributed with Cforall.
-// 
-// builtins.c -- 
-// 
+//
+// builtins.c --
+//
 // Author           : Peter A. Buhr
 // Created On       : Fri Jul 21 16:21:03 2017
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 10:34:20 2017
-// Update Count     : 13
-// 
+// Last Modified By : Andrew Beach
+// Last Modified On : Tus Jul 25 15:33:00 2017
+// Update Count     : 14
+//
 
 // exception implementation
@@ -18,4 +18,5 @@
 typedef unsigned long long __cfaabi_exception_type_t;
 
+#include "../libcfa/virtual.h"
 #include "../libcfa/exception.h"
 
Index: src/tests/designations.c
===================================================================
--- src/tests/designations.c	(revision 4d4e5de154ff41edaa04c695f8a870dd5d794308)
+++ src/tests/designations.c	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -9,7 +9,7 @@
 // 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
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu Jul 27 11:46:35 2017
+// Update Count     : 3
 //
 
@@ -89,4 +89,17 @@
 };
 
+struct Fred {
+    double i[3];
+    int j;
+    struct Mary {
+	struct Jane {
+	    double j;
+	} j;
+	double i;
+    } m;
+};
+struct Fred s1 @= { .m.j : 3 };
+struct Fred s2 @= { .i : { [2] : 2 } };
+
 int main() {
 	// simple designation case - starting from beginning of structure, leaves ptr default-initialized (zero)
@@ -199,5 +212,6 @@
 	};
 #endif
-
+	// array designation
+	int i[2] = { [1] : 3 };
 	// allowed to have 'too many' initialized lists - essentially they are ignored.
 	int i1 = { 3 };
@@ -240,4 +254,7 @@
 	const char * str0 = "hello";
 	char str1[] = "hello";
+	const char c1[] = "abc";
+	const char c2[] = { 'a', 'b', 'c' };
+	const char c3[][2] = { { 'a', 'b' }, { 'c', 'd'}, { 'c', 'd'} };
 }
 
Index: src/tests/virtualCast.c
===================================================================
--- src/tests/virtualCast.c	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
+++ src/tests/virtualCast.c	(revision 874960bb718cca327cd78b5bbe5e995b770b03a7)
@@ -0,0 +1,76 @@
+// Testing the virtual cast, as part of strict inheritance.
+
+/* IMPORTANT: This test does not repersent the final feature set.
+ * We are missing a number of important aspects such as:
+ * + vtable type generation.
+ * + vtable instance generation, that might use different resolution rules.
+ * + Virtual syntax to force said generation on structures and traits.
+ * + Trait references/pointers that do the virtual_table lookup.
+ */
+
+#include <stdlib>
+#include <assert.h>
+
+struct alpha_vtable {
+	alpha_vtable const * const parent;
+	char (*code)(void);
+};
+
+struct alpha {
+	alpha_vtable const * virtual_table;
+};
+
+char ret_a(void) {
+	return 'a';
+}
+
+
+
+struct beta_vtable {
+	alpha_vtable const * const parent;
+	char (*code)(void);
+};
+
+struct beta {
+	beta_vtable const * virtual_table;
+};
+
+char ret_b(void) {
+	return 'b';
+}
+
+
+
+struct gamma_vtable {
+	beta_vtable const * const parent;
+	char (*code)(void);
+};
+
+struct gamma {
+	gamma_vtable const * virtual_table;
+};
+
+char ret_g(void) {
+	return 'g';
+}
+
+
+extern "C" {
+	alpha_vtable _alpha_vtable_instance = { 0, ret_a };
+	beta_vtable _beta_vtable_instance = { &_alpha_vtable_instance, ret_b };
+	gamma_vtable _gamma_vtable_instance = { &_beta_vtable_instance, ret_g };
+}
+
+int main (int argc, char * argv[]) {
+
+	gamma * tri = malloc(); tri->virtual_table = &_gamma_vtable_instance;
+	beta * mid = (virtual beta *)tri;
+	assert( 'g' == mid->virtual_table->code() );
+
+	alpha * top = malloc(); top->virtual_table = &_alpha_vtable_instance;
+	mid = (virtual beta *)top;
+	assert( ! mid );
+
+	free(tri);
+	free(top);
+}
