Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision aca65621fec224ce52fce478fdf5225511cb845b)
+++ src/Makefile.in	(revision 0698aa1b5a7ea80416468a0bda92dba61d09df20)
@@ -221,4 +221,5 @@
 	SynTree/driver_cfa_cpp-PointerType.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT) \
+	SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-ReferenceToType.$(OBJEXT) \
@@ -517,6 +518,7 @@
 	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/ReferenceType.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 \
@@ -864,4 +866,6 @@
 SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
 	SynTree/$(DEPDIR)/$(am__dirstamp)
+SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT):  \
+	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
 SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT):  \
 	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
@@ -1058,4 +1062,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po@am__quote@
@@ -2154,4 +2159,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 SynTree/driver_cfa_cpp-ArrayType.obj `if test -f 'SynTree/ArrayType.cc'; then $(CYGPATH_W) 'SynTree/ArrayType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ArrayType.cc'; fi`
+
+SynTree/driver_cfa_cpp-ReferenceType.o: SynTree/ReferenceType.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.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 SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc
+
+SynTree/driver_cfa_cpp-ReferenceType.obj: SynTree/ReferenceType.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.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 SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi`
 
 SynTree/driver_cfa_cpp-FunctionType.o: SynTree/FunctionType.cc
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision aca65621fec224ce52fce478fdf5225511cb845b)
+++ src/SynTree/Expression.cc	(revision 0698aa1b5a7ea80416468a0bda92dba61d09df20)
@@ -335,5 +335,7 @@
 namespace {
 	TypeSubstitution makeSub( Type * t ) {
-		if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) {
+		if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( t ) ) {
+			return makeSub( refType->get_base() );
+		} else if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) {
 			return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() );
 		} else if ( UnionInstType * aggInst = dynamic_cast< UnionInstType * >( t ) ) {
@@ -400,9 +402,6 @@
 	if ( Type * type = expr->get_result() ) {
 		Type * base = InitTweak::getPointerBase( type );
-		if ( ! base ) {
-			std::cerr << type << std::endl;
-		}
-		assertf( base, "expected pointer type in dereference\n" );
-		ret->set_result( maybeClone( base ) );
+		assertf( base, "expected pointer type in dereference (type was %s)", toString( type ).c_str() );
+		ret->set_result( new ReferenceType( Type::Qualifiers(), base->clone() ) );
 	}
 	return ret;
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision aca65621fec224ce52fce478fdf5225511cb845b)
+++ src/SynTree/Type.cc	(revision 0698aa1b5a7ea80416468a0bda92dba61d09df20)
@@ -65,8 +65,16 @@
 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
 
-Type *Type::stripDeclarator() {
+Type * Type::stripDeclarator() {
 	Type * type = this;
 	while ( Type * at = InitTweak::getPointerBase( type ) ) {
 		type = at;
+	}
+	return type;
+}
+
+Type * Type::stripReferences() {
+	Type * type = this;
+	while ( ReferenceType * ref = dynamic_cast<ReferenceType *>( type ) ) {
+		type = ref->get_base();
 	}
 	return type;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision aca65621fec224ce52fce478fdf5225511cb845b)
+++ src/SynTree/Type.h	(revision 0698aa1b5a7ea80416468a0bda92dba61d09df20)
@@ -158,5 +158,8 @@
 
 	/// return type without outer pointers and arrays
-	Type *stripDeclarator();
+	Type * stripDeclarator();
+
+	/// return type without outer references
+	Type * stripReferences();
 
 	virtual bool isComplete() const { return true; }
