Index: src/ArgTweak/FunctionFixer.cc
===================================================================
--- src/ArgTweak/FunctionFixer.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/ArgTweak/FunctionFixer.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FunctionFixer.cc -- 
+// FunctionFixer.cc --
 //
 // Author           : Rodolfo G. Esteves
@@ -42,18 +42,15 @@
 	Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr ) throw ( SemanticError ) {
 		assert( untypedExpr != 0 );
-		NameExpr *function;
 
-		if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 ) {
+		if ( NameExpr * function = dynamic_cast< NameExpr *>(untypedExpr->get_function() ) ) {
 			std::list < DeclarationWithType * > options;
 			index->lookupId ( function->get_name(), options );
 			for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ ) {
-				FunctionType *f;
-				if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 )	{
+				if ( FunctionType * f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) )	{
 					std::list < DeclarationWithType * > &pars = f->get_parameters();
-
 					bool candidateExists ;
-					for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ )
+					for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ ) {
 						if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
-
+					}
 					if ( ! candidateExists ) throw SemanticError("Error in function call");
 				} // if
Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/InitTweak/FixGlobalInit.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -125,7 +125,5 @@
 		std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
 
-		// if ( objDecl->get_init() == NULL ) return;
 		if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
-		if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable
 		if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
 		// C allows you to initialize objects with constant expressions
@@ -146,10 +144,10 @@
 			init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
 			init->get_args().push_back( new VariableExpr( newObj ) );
-			initStatements.push_back( new ExprStmt( noLabels, init ) );
+			initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
 
 			// add destructor calls to global destroy function
 			UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
 			destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
-			destroyStatements.push_front( new ExprStmt( noLabels, destroy ) );
+			destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
 		}
 	}
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/InitTweak/FixInit.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -132,5 +132,4 @@
 				return appExpr;
 			} else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) {
-				// FunctionType * ftype = funcDecl->get_functionType();
 				FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
 				assert( ftype );
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/InitTweak/GenInit.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -143,10 +143,4 @@
 		if ( tryConstruct( objDecl ) ) {
 			if ( inFunction ) {
-				// remove qualifiers so that const objects can be initialized, and attach the
-				// qualifiers to ConstructorInit so that they can be replaced after resolving
-				Type * type = objDecl->get_type();
-				Type::Qualifiers qualifiers = type->get_qualifiers();
-				type->get_qualifiers() = Type::Qualifiers();
-
 				if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
 					// call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
@@ -170,6 +164,5 @@
 						assert( ctor.size() == 1 );
 						assert( dtor.size() == 1 );
-
-						objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init(), objDecl, qualifiers ) );
+						objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctor.front() ), new ImplicitCtorDtorStmt( dtor.front() ), objDecl->get_init() ) );
 					} else {
 						// array came with an initializer list: initialize each element
@@ -191,5 +184,5 @@
 					ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
 					ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
-					objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init(), objDecl, qualifiers ) );
+					objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
 				}
 			}
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/InitTweak/InitTweak.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -60,16 +60,8 @@
   }
 
-  bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
-    if ( stmt == NULL ) return false;
+  Expression * getCtorDtorCall( Statement * stmt ) {
+    if ( stmt == NULL ) return NULL;
     if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
-      ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
-      assert( appExpr );
-      VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
-      assert( function );
-      // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
-      // will call all member dtors, and some members may have a user defined dtor.
-      FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
-      assert( funcType );
-      return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
+      return exprStmt->get_expr();
     } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
       // could also be a compound statement with a loop, in the case of an array
@@ -77,8 +69,46 @@
       ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
       assert( forStmt && forStmt->get_body() );
-      return isInstrinsicSingleArgCallStmt( forStmt->get_body() );
+      return getCtorDtorCall( forStmt->get_body() );
+    } if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) {
+      return getCtorDtorCall( impCtorDtorStmt->get_callStmt() );
     } else {
       // should never get here
       assert( false && "encountered unknown call statement" );
+    }
+  }
+
+  bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
+    Expression * callExpr = getCtorDtorCall( stmt );
+    if ( ! callExpr ) return false;
+    ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr );
+    assert( appExpr );
+    VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
+    assert( function );
+    // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
+    // will call all member dtors, and some members may have a user defined dtor.
+    FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
+    assert( funcType );
+    return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
+  }
+
+  namespace {
+    template<typename CallExpr>
+    Expression * callArg( CallExpr * callExpr, unsigned int pos ) {
+      if ( pos >= callExpr->get_args().size() ) assert( false && "asking for argument that doesn't exist. Return NULL/throw exception?" );
+      for ( Expression * arg : callExpr->get_args() ) {
+        if ( pos == 0 ) return arg;
+        pos--;
+      }
+      assert( false );
+    }
+  }
+
+  Expression * getCallArg( Expression * callExpr, unsigned int pos ) {
+    if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr ) ) {
+      return callArg( appExpr, pos );
+    } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) {
+      return callArg( untypedExpr, pos );
+    } else {
+      assert( false && "Unexpected expression type passed to getCallArg" );
     }
   }
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/InitTweak/InitTweak.h	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -40,6 +40,12 @@
   bool isInstrinsicSingleArgCallStmt( Statement * expr );
 
+  /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
+  Expression * getCtorDtorCall( Statement * stmt );
+
   /// returns the name of the function being called
-  std::string getFunctionName(Expression * expr);
+  std::string getFunctionName( Expression * expr );
+
+  /// returns the argument to a call expression in position N indexed from 0
+  Expression * getCallArg( Expression * callExpr, unsigned int pos );
 } // namespace
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/ResolvExpr/Resolver.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -52,4 +52,5 @@
 		virtual void visit( BranchStmt *branchStmt );
 		virtual void visit( ReturnStmt *returnStmt );
+		virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
 
 		virtual void visit( SingleInit *singleInit );
@@ -493,12 +494,7 @@
 			// no alternatives for the constructor initializer - fallback on C-style initializer
 			// xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
-
-			// reset type qualifiers
-			ctorInit->get_object()->get_type()->get_qualifiers() = ctorInit->get_qualifiers();
 			fallbackInit( ctorInit );
 			return;
 		}
-		// reset type qualifiers
-		ctorInit->get_object()->get_type()->get_qualifiers() = ctorInit->get_qualifiers();
 
 		// found a constructor - can get rid of C-style initializer
@@ -518,4 +514,50 @@
 		}
 	}
+
+	void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
+		// this code is fairly gross. If VariableExpr didn't have its own results list then this could be cleaned up a bit
+		// by remembering the ObjectDecl in the ImplicitCtorDtorStmt and changing the ObjectDecl's type temporarily, but currently
+		// VariableExprs have their own type list which is manipulated in AlternativeFinder (e.g. in inferRecursive).
+
+		// before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed)
+		Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
+		assert( callExpr );
+		Expression * constructee = InitTweak::getCallArg( callExpr, 0 );
+		Type * type = 0;
+		if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
+			// constructee is <array>+<index>
+			// get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
+			Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
+			assert( dynamic_cast< VariableExpr * >( arr ) );
+			assert( arr && arr->get_results().size() == 1 );
+			ArrayType * arrType = dynamic_cast< ArrayType * >( arr->get_results().front() );
+			assert( arrType );
+			type = arrType->get_base();
+		} else {
+			// otherwise, constructing a plain object, which means the object's address is being taken.
+			// Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
+			// type of the VariableExpr to do so.
+			assert( constructee->get_results().size() == 1 );
+			AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
+			assert( addrExpr );
+			VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() );
+			assert( varExpr && varExpr->get_results().size() == 1 );
+			type = varExpr->get_results().front();
+		}
+		// remember qualifiers so they can be replaced
+		Type::Qualifiers qualifiers = type->get_qualifiers();
+
+		// 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();
+		type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
+
+		// finally, resolve the ctor/dtor
+		impCtorDtorStmt->get_callStmt()->accept( *this );
+
+		// and reset type qualifiers after resolving
+		type->get_qualifiers() = qualifiers;
+	}
 } // namespace ResolvExpr
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SymTab/Validate.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -291,6 +291,6 @@
 
 	namespace {
-		template< typename DWTIterator >
-		void fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) {
+		template< typename DWTIterator, typename DWTList >
+		void fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func, DWTList & dwts ) {
 			// the only case in which "void" is valid is where it is the only one in the list; then it should be removed
 			// entirely other fix ups are handled by the FixFunction class
@@ -298,9 +298,9 @@
 			FixFunction fixer;
 			DWTIterator i = begin;
-			*i = (*i )->acceptMutator( fixer );
+			*i = (*i)->acceptMutator( fixer );
 			if ( fixer.get_isVoid() ) {
 				DWTIterator j = i;
 				++i;
-				func->get_parameters().erase( j );
+				dwts.erase( j );
 				if ( i != end ) {
 					throw SemanticError( "invalid type void in function type ", func );
@@ -321,6 +321,6 @@
 	void Pass1::visit( FunctionType *func ) {
 		// Fix up parameters and return types
-		fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
-		fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
+		fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func, func->get_parameters() );
+		fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func, func->get_returnVals() );
 		Visitor::visit( func );
 	}
Index: src/SynTree/Initializer.cc
===================================================================
--- src/SynTree/Initializer.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Initializer.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -86,6 +86,6 @@
 
 
-ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init, ObjectDecl * object, Type::Qualifiers qualifiers ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ), object( object ), qualifiers( qualifiers ) {}
-ConstructorInit::ConstructorInit( const ConstructorInit &other ) : Initializer( other ), ctor( maybeClone( other.ctor ) ), dtor( maybeClone( other.dtor ) ), init( maybeClone( other.init ) ), object( other.object ), qualifiers( other.qualifiers ) {
+ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
+ConstructorInit::ConstructorInit( const ConstructorInit &other ) : Initializer( other ), ctor( maybeClone( other.ctor ) ), dtor( maybeClone( other.dtor ) ), init( maybeClone( other.init ) ) {
 }
 
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Initializer.h	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -109,5 +109,5 @@
 class ConstructorInit : public Initializer {
   public:
-	ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init, ObjectDecl * objectDecl, Type::Qualifiers qualifiers );
+	ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init );
 	ConstructorInit( const ConstructorInit &other );
 	virtual ~ConstructorInit();
@@ -119,8 +119,4 @@
 	void set_init( Initializer * newValue ) { init = newValue; }
 	Initializer * get_init() const { return init; }
-	void set_object( ObjectDecl * newValue ) { object = newValue; }
-	ObjectDecl * get_object() const { return object; }
-	void set_qualifiers( Type::Qualifiers newValue ) { qualifiers = newValue; }
-	Type::Qualifiers get_qualifiers() { return qualifiers; }
 
 	ConstructorInit *clone() const { return new ConstructorInit( *this ); }
@@ -135,9 +131,4 @@
 	// if an appropriate constructor definition is not found by the resolver
 	Initializer * init;
-	// Non-owned pointer back to the object being constructed
-	ObjectDecl * object;
-	// to construct const objects, need to first remove type qualifiers, then resolve
-	// then add qualifiers back onto object
-	Type::Qualifiers qualifiers;
 };
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Mutator.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -182,4 +182,9 @@
 }
 
+Statement *Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
+	impCtorDtorStmt->set_callStmt( maybeMutate( impCtorDtorStmt->get_callStmt(), *this ) );
+	return impCtorDtorStmt;
+}
+
 Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) {
 	mutateAll( applicationExpr->get_results(), *this );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Mutator.h	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -52,4 +52,5 @@
 	virtual NullStmt* mutate( NullStmt *nullStmt );
 	virtual Statement* mutate( DeclStmt *declStmt );
+	virtual Statement* mutate( ImplicitCtorDtorStmt *impCtorDtorStmt );
 
 	virtual Expression* mutate( ApplicationExpr *applicationExpr );
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Statement.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -358,5 +358,5 @@
 
 void CatchStmt::print( std::ostream &os, int indent ) const {
-	os << string( indent, ' ' ) << "Catch Statement" << endl;
+	os << "Catch Statement" << endl;
 
 	os << string( indent, ' ' ) << "... catching" << endl;
@@ -383,5 +383,5 @@
 
 void FinallyStmt::print( std::ostream &os, int indent ) const {
-	os << string( indent, ' ' ) << "Finally Statement" << endl;
+	os << "Finally Statement" << endl;
 	os << string( indent + 2, ' ' ) << "with block: " << endl;
 	block->print( os, indent + 4 );
@@ -393,4 +393,21 @@
 void NullStmt::print( std::ostream &os, int indent ) const {
 	os << "Null Statement" << endl ;
+}
+
+ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( Statement * callStmt ) : Statement( std::list<Label>() ), callStmt( callStmt ) {
+	assert( callStmt );
+}
+
+ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( const ImplicitCtorDtorStmt & other ) : Statement( other ), callStmt( other.callStmt ) {
+}
+
+ImplicitCtorDtorStmt::~ImplicitCtorDtorStmt() {
+}
+
+void ImplicitCtorDtorStmt::print( std::ostream &os, int indent ) const {
+	os << "Implicit Ctor Dtor Statement" << endl;
+	os << string( indent + 2, ' ' ) << "with Ctor/Dtor: ";
+	callStmt->print( os, indent + 2);
+	os << endl;
 }
 
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Statement.h	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -21,4 +21,5 @@
 #include "Mutator.h"
 #include "Common/SemanticError.h"
+#include "Type.h"
 
 class Statement {
@@ -394,5 +395,5 @@
 	virtual ~DeclStmt();
 
-	Declaration *get_decl() { return decl; }
+	Declaration *get_decl() const { return decl; }
 	void set_decl( Declaration *newValue ) { decl = newValue; }
 
@@ -404,4 +405,28 @@
 	Declaration *decl;
 };
+
+
+/// represents an implicit application of a constructor or destructor. Qualifiers are replaced
+/// immediately before and after the call so that qualified objects can be constructed
+/// with the same functions as unqualified objects.
+class ImplicitCtorDtorStmt : public Statement {
+  public:
+	ImplicitCtorDtorStmt( Statement * callStmt );
+	ImplicitCtorDtorStmt( const ImplicitCtorDtorStmt & other );
+	virtual ~ImplicitCtorDtorStmt();
+
+	Statement *get_callStmt() const { return callStmt; }
+	void set_callStmt( Statement * newValue ) { callStmt = newValue; }
+
+	virtual ImplicitCtorDtorStmt *clone() const { return new ImplicitCtorDtorStmt( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+
+  private:
+	// Non-owned pointer to the constructor/destructor statement
+	Statement * callStmt;
+};
+
 
 std::ostream & operator<<( std::ostream & out, Statement * statement );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/SynTree.h	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -56,4 +56,5 @@
 class DeclStmt;
 class NullStmt;
+class ImplicitCtorDtorStmt;
 
 class Expression;
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Type.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Type.cc -- 
+// Type.cc --
 //
 // Author           : Richard C. Bilson
@@ -54,4 +54,25 @@
 }
 
+void Type::Qualifiers::print( std::ostream &os, int indent ) const {
+	if ( isConst ) {
+		os << "const ";
+	} // if
+	if ( isVolatile ) {
+		os << "volatile ";
+	} // if
+	if ( isRestrict ) {
+		os << "restrict ";
+	} // if
+	if ( isLvalue ) {
+		os << "lvalue ";
+	} // if
+	if ( isAtomic ) {
+		os << "_Atomic ";
+	} // if
+	if ( isAttribute ) {
+		os << "__attribute(( )) ";
+	} // if
+}
+
 void Type::print( std::ostream &os, int indent ) const {
 	if ( ! forall.empty() ) {
@@ -60,22 +81,5 @@
 		os << std::string( indent+2, ' ' );
 	} // if
-	if ( tq.isConst ) {
-		os << "const ";
-	} // if
-	if ( tq.isVolatile ) {
-		os << "volatile ";
-	} // if
-	if ( tq.isRestrict ) {
-		os << "restrict ";
-	} // if
-	if ( tq.isLvalue ) {
-		os << "lvalue ";
-	} // if
-	if ( tq.isAtomic ) {
-		os << "_Atomic ";
-	} // if
-	if ( tq.isAttribute ) {
-		os << "__attribute(( )) ";
-	} // if
+	tq.print( os, indent );
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Type.h	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -36,4 +36,5 @@
 		bool operator<( const Qualifiers &other );
 		bool operator>( const Qualifiers &other );
+		void print( std::ostream &os, int indent = 0 ) const;
 
 		bool isConst;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Visitor.cc	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -152,4 +152,8 @@
 }
 
+void Visitor::visit( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
+	maybeAccept( impCtorDtorStmt->get_callStmt(), *this );
+}
+
 void Visitor::visit( ApplicationExpr *applicationExpr ) {
 	acceptAll( applicationExpr->get_results(), *this );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 70f89d00f25700f0fc226d5210840f0199c6d9f0)
+++ src/SynTree/Visitor.h	(revision f1b1e4c22ee1c825678ab38142bbcf3879708434)
@@ -52,4 +52,5 @@
 	virtual void visit( NullStmt *nullStmt );
 	virtual void visit( DeclStmt *declStmt );
+	virtual void visit( ImplicitCtorDtorStmt *impCtorDtorStmt );
 
 	virtual void visit( ApplicationExpr *applicationExpr );
