Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 15934a6a632325b8563214d12538dafc1749ef28)
+++ src/AST/Convert.cpp	(revision 4073b16c7e20b5853fcbce0adaaa3f578dc4b353)
@@ -265,4 +265,5 @@
 		stmt->location = node->location;
 		stmt->labels = makeLabelL( stmt, node->labels );
+		cache.emplace( node, stmt );
 		this->node = stmt;
 		return nullptr;
@@ -270,4 +271,5 @@
 
 	const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
 		stmtPostamble( stmt, node );
@@ -276,4 +278,5 @@
 
 	const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new ExprStmt( get<Expression>().accept1( node->expr ) );
 		return stmtPostamble( stmt, node );
@@ -281,4 +284,5 @@
 
 	const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new AsmStmt(
 			node->isVolatile,
@@ -293,4 +297,5 @@
 
 	const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new DirectiveStmt( node->directive );
 		return stmtPostamble( stmt, node );
@@ -298,4 +303,5 @@
 
 	const ast::Stmt * visit( const ast::IfStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new IfStmt(
 			get<Expression>().accept1( node->cond ),
@@ -308,4 +314,5 @@
 
 	const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new SwitchStmt(
 			get<Expression>().accept1( node->cond ),
@@ -316,4 +323,5 @@
 
 	const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new CaseStmt(
 			get<Expression>().accept1( node->cond ),
@@ -325,4 +333,5 @@
 
 	const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto inits = get<Statement>().acceptL( node->inits );
 		auto stmt = new WhileStmt(
@@ -336,4 +345,5 @@
 
 	const ast::Stmt * visit( const ast::ForStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new ForStmt(
 			get<Statement>().acceptL( node->inits ),
@@ -346,4 +356,5 @@
 
 	const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		BranchStmt * stmt;
 		if (node->computedTarget) {
@@ -375,4 +386,5 @@
 
 	const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) );
 		return stmtPostamble( stmt, node );
@@ -380,4 +392,5 @@
 
 	const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		ThrowStmt::Kind kind;
 		switch (node->kind) {
@@ -400,4 +413,5 @@
 
 	const ast::Stmt * visit( const ast::TryStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto handlers = get<CatchStmt>().acceptL( node->handlers );
 		auto stmt = new TryStmt(
@@ -410,4 +424,5 @@
 
 	const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		CatchStmt::Kind kind;
 		switch (node->kind) {
@@ -431,4 +446,5 @@
 
 	const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) );
 		return stmtPostamble( stmt, node );
@@ -436,4 +452,5 @@
 
 	const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new WaitForStmt;
 		stmt->clauses.reserve( node->clauses.size() );
@@ -460,4 +477,5 @@
 
 	const ast::Stmt * visit( const ast::WithStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new WithStmt(
 			get<Expression>().acceptL( node->exprs ),
@@ -468,4 +486,5 @@
 
 	const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new NullStmt();
 		stmtPostamble( stmt, node );
@@ -474,4 +493,5 @@
 
 	const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
+		if ( inCache( node ) ) return nullptr;
 		auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) );
 		return stmtPostamble( stmt, node );
@@ -479,6 +499,9 @@
 
 	const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
-		(void)node;
-		return nullptr;
+		if ( inCache( node ) ) return nullptr;
+		auto stmt = new ImplicitCtorDtorStmt{
+			get<Statement>().accept1( node->callStmt )
+		};
+		return stmtPostamble( stmt, node );
 	}
 
@@ -1564,4 +1587,5 @@
 
 	virtual void visit( CompoundStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		auto stmt = new ast::CompoundStmt(
 			old->location,
@@ -1571,7 +1595,9 @@
 
 		this->node = stmt;
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( ExprStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::ExprStmt(
 			old->location,
@@ -1579,7 +1605,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( AsmStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::AsmStmt(
 			old->location,
@@ -1592,7 +1620,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( DirectiveStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::DirectiveStmt(
 			old->location,
@@ -1600,7 +1630,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( IfStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::IfStmt(
 			old->location,
@@ -1611,7 +1643,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( SwitchStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::SwitchStmt(
 			old->location,
@@ -1620,7 +1654,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( CaseStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::CaseStmt(
 			old->location,
@@ -1629,7 +1665,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( WhileStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::WhileStmt(
 			old->location,
@@ -1640,7 +1678,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( ForStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::ForStmt(
 			old->location,
@@ -1651,7 +1691,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( BranchStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		if (old->computedTarget) {
 			this->node = new ast::BranchStmt(
@@ -1687,7 +1729,9 @@
 			this->node = stmt;
 		}
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( ReturnStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::ReturnStmt(
 			old->location,
@@ -1695,7 +1739,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( ThrowStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		ast::ThrowStmt::Kind kind;
 		switch (old->kind) {
@@ -1717,7 +1763,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( TryStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::TryStmt(
 			old->location,
@@ -1727,7 +1775,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( CatchStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		ast::CatchStmt::Kind kind;
 		switch (old->kind) {
@@ -1750,7 +1800,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( FinallyStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::FinallyStmt(
 			old->location,
@@ -1758,7 +1810,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( WaitForStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		ast::WaitForStmt * stmt = new ast::WaitForStmt(
 			old->location,
@@ -1788,7 +1842,9 @@
 
 		this->node = stmt;
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( WithStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::WithStmt(
 			old->location,
@@ -1797,14 +1853,18 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( NullStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::NullStmt(
 			old->location,
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( DeclStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::DeclStmt(
 			old->location,
@@ -1812,7 +1872,9 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
 	virtual void visit( ImplicitCtorDtorStmt * old ) override final {
+		if ( inCache( old ) ) return;
 		this->node = new ast::ImplicitCtorDtorStmt(
 			old->location,
@@ -1820,4 +1882,5 @@
 			GET_LABELS_V(old->labels)
 		);
+		cache.emplace( old, this->node );
 	}
 
