Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 746ae825da938dc811b235870e4be561b6aa1fb8)
+++ src/AST/Convert.cpp	(revision ed5e798d0f3f29bf7d35184b3a9df595b87a81dc)
@@ -571,85 +571,278 @@
 
 	const ast::Expr * visit( const ast::AddressExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new AddressExpr(
+				get<Expression>().accept1(node->arg)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new LabelAddressExpr(
+				makeLabel(nullptr, node->arg)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::CastExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new CastExpr(
+				get<Expression>().accept1(node->arg),
+				(node->isGenerated == ast::GeneratedCast)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
-		(void)node;
+		KeywordCastExpr::Target castTarget = KeywordCastExpr::NUMBER_OF_TARGETS;
+		switch (node->target) {
+			case ast::KeywordCastExpr::Coroutine:
+				castTarget = KeywordCastExpr::Coroutine;
+				break;
+			case ast::KeywordCastExpr::Thread:
+				castTarget = KeywordCastExpr::Thread;
+				break;
+			case ast::KeywordCastExpr::Monitor:
+				castTarget = KeywordCastExpr::Monitor;
+				break;
+			default:
+				break;
+		}
+		assert ( castTarget < KeywordCastExpr::NUMBER_OF_TARGETS );
+		auto expr = visitBaseExpr( node,
+			new KeywordCastExpr(
+				get<Expression>().accept1(node->arg),
+				castTarget
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new VirtualCastExpr(
+				get<Expression>().accept1(node->arg),
+				nullptr // cast's "to" type is expr's result type; converted in visitBaseExpr
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new UntypedMemberExpr(
+				get<Expression>().accept1(node->member),
+				get<Expression>().accept1(node->aggregate)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::MemberExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new MemberExpr(
+				inCache(node->member) ?
+					dynamic_cast<DeclarationWithType *>(this->node) :
+					get<DeclarationWithType>().accept1(node->member),
+				get<Expression>().accept1(node->aggregate)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::VariableExpr * node ) override final {
-		(void)node;
-		return nullptr;
+		auto expr = visitBaseExpr( node,
+			new VariableExpr(
+				inCache(node->var) ?
+					dynamic_cast<DeclarationWithType *>(this->node) :
+					get<DeclarationWithType>().accept1(node->var)
+			)
+		);
+		this->node = expr;
+		return nullptr;
+	}
+
+	bool isIntlikeConstantType(const ast::Type *t) {
+		if ( const ast::BasicType * basicType = dynamic_cast< const ast::BasicType * >( t ) ) {
+			if ( basicType->isInteger() ) {
+				return true;
+			}
+		} else if ( dynamic_cast< const ast::OneType * >( t ) ) {
+			return true;
+		} else if ( dynamic_cast< const ast::ZeroType * >( t ) ) {
+			return true;
+		} else if ( dynamic_cast< const ast::PointerType * >( t ) ) {
+			// null pointer constants, with zero int-values
+			return true;
+		}
+		return false;
+	}
+
+	bool isFloatlikeConstantType(const ast::Type *t) {
+		if ( const ast::BasicType * bty = dynamic_cast< const ast::BasicType * >( t ) ) {
+			if ( ! bty->isInteger() ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	bool isStringlikeConstantType(const ast::Type *t) {
+		if ( const ast::ArrayType * aty = dynamic_cast< const ast::ArrayType * >( t ) ) {
+			if ( const ast::BasicType * bty = aty->base.as<ast::BasicType>() ) {
+			   if ( bty->kind == ast::BasicType::Kind::Char ) {
+				   return true;
+			   }
+			}
+		}
+		return false;
 	}
 
 	const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
-		(void)node;
+		ConstantExpr *rslt = nullptr;
+		if (isIntlikeConstantType(node->result)) {
+			rslt = new ConstantExpr(Constant(
+				get<Type>().accept1(node->result),
+				node->rep,
+				(unsigned long long) node->intValue()
+			));
+		} else if (isFloatlikeConstantType(node->result)) {
+			rslt = new ConstantExpr(Constant(
+				get<Type>().accept1(node->result),
+				node->rep,
+				(double) node->floatValue()
+			));
+		} else if (isStringlikeConstantType(node->result)) {
+			rslt = new ConstantExpr(Constant::from_string(
+				node->rep
+			));
+		}
+		assert(rslt);
+		auto expr = visitBaseExpr( node, rslt );
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
-		(void)node;
+		assert (node->expr || node->type);
+		assert (! (node->expr && node->type));
+		SizeofExpr *rslt;
+		if (node->expr) {
+			rslt = new SizeofExpr(
+				get<Expression>().accept1(node->expr)
+			);
+			assert (!rslt->isType);
+		}
+		if (node->type) {
+			rslt = new SizeofExpr(
+				get<Type>().accept1(node->type)
+			);
+			assert (rslt->isType);
+		}
+		auto expr = visitBaseExpr( node, rslt );
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
-		(void)node;
+		assert (node->expr || node->type);
+		assert (! (node->expr && node->type));
+		AlignofExpr *rslt;
+		if (node->expr) {
+			rslt = new AlignofExpr(
+				get<Expression>().accept1(node->expr)
+			);
+			assert (!rslt->isType);
+		}
+		if (node->type) {
+			rslt = new AlignofExpr(
+				get<Type>().accept1(node->type)
+			);
+			assert (rslt->isType);
+		}
+		auto expr = visitBaseExpr( node, rslt );
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new UntypedOffsetofExpr(
+				get<Type>().accept1(node->type),
+				node->member
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new OffsetofExpr(
+				get<Type>().accept1(node->type),
+				inCache(node->member) ?
+					dynamic_cast<DeclarationWithType *>(this->node) :
+					get<DeclarationWithType>().accept1(node->member)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new OffsetPackExpr(
+				get<StructInstType>().accept1(node->type)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
-		(void)node;
+		assert (node->isAnd == ast::LogicalFlag::AndExpr ||
+				node->isAnd == ast::LogicalFlag::OrExpr	);
+		auto expr = visitBaseExpr( node,
+			new LogicalExpr(
+				get<Expression>().accept1(node->arg1),
+				get<Expression>().accept1(node->arg2),
+				(node->isAnd == ast::LogicalFlag::AndExpr)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new ConditionalExpr(
+				get<Expression>().accept1(node->arg1),
+				get<Expression>().accept1(node->arg2),
+				get<Expression>().accept1(node->arg3)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
 
 	const ast::Expr * visit( const ast::CommaExpr * node ) override final {
-		(void)node;
+		auto expr = visitBaseExpr( node,
+			new CommaExpr(
+				get<Expression>().accept1(node->arg1),
+				get<Expression>().accept1(node->arg2)
+			)
+		);
+		this->node = expr;
 		return nullptr;
 	}
@@ -1547,5 +1740,5 @@
 			new ast::CastExpr(
 				old->location,
-				nullptr, // cast's "to" type is expr's result type; converted in visitBaseExpr
+				GET_ACCEPT_1(arg, Expr),
 				old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
 			)
@@ -1553,66 +1746,257 @@
 	}
 
-	virtual void visit( KeywordCastExpr * ) override final {
-
-	}
-
-	virtual void visit( VirtualCastExpr * ) override final {
-
-	}
-
-	virtual void visit( AddressExpr * ) override final {
-
-	}
-
-	virtual void visit( LabelAddressExpr * ) override final {
-
-	}
-
-	virtual void visit( UntypedMemberExpr * ) override final {
-
-	}
-
-	virtual void visit( MemberExpr * ) override final {
-
-	}
-
-	virtual void visit( VariableExpr * ) override final {
-
-	}
-
-	virtual void visit( ConstantExpr * ) override final {
-
-	}
-
-	virtual void visit( SizeofExpr * ) override final {
-
-	}
-
-	virtual void visit( AlignofExpr * ) override final {
-
-	}
-
-	virtual void visit( UntypedOffsetofExpr * ) override final {
-
-	}
-
-	virtual void visit( OffsetofExpr * ) override final {
-
-	}
-
-	virtual void visit( OffsetPackExpr * ) override final {
-
-	}
-
-	virtual void visit( LogicalExpr * ) override final {
-
-	}
-
-	virtual void visit( ConditionalExpr * ) override final {
-
-	}
-
-	virtual void visit( CommaExpr * ) override final {
-
+	virtual void visit( KeywordCastExpr * old) override final {
+		ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
+		switch (old->target) {
+			case KeywordCastExpr::Coroutine:
+				castTarget = ast::KeywordCastExpr::Coroutine;
+				break;
+			case KeywordCastExpr::Thread:
+				castTarget = ast::KeywordCastExpr::Thread;
+				break;
+			case KeywordCastExpr::Monitor:
+				castTarget = ast::KeywordCastExpr::Monitor;
+				break;
+			default:
+				break;
+		}
+		assert ( castTarget < ast::KeywordCastExpr::NUMBER_OF_TARGETS );
+		this->node = visitBaseExpr( old,
+			new ast::KeywordCastExpr(
+				old->location,
+				GET_ACCEPT_1(arg, Expr),
+				castTarget
+			)
+		);
+	}
+
+	virtual void visit( VirtualCastExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::VirtualCastExpr(
+				old->location,
+				GET_ACCEPT_1(arg, Expr),
+				nullptr // cast's "to" type is expr's result type; converted in visitBaseExpr
+			)
+		);
+	}
+
+	virtual void visit( AddressExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::AddressExpr(
+				old->location,
+				GET_ACCEPT_1(arg, Expr)
+			)
+		);
+	}
+
+	virtual void visit( LabelAddressExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::LabelAddressExpr(
+				old->location,
+				make_label(&old->arg)
+			)
+		);
+	}
+
+	virtual void visit( UntypedMemberExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::UntypedMemberExpr(
+				old->location,
+				GET_ACCEPT_1(member, Expr),
+				GET_ACCEPT_1(aggregate, Expr)
+			)
+		);
+	}
+
+	virtual void visit( MemberExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::MemberExpr(
+				old->location,
+				inCache(old->member) ?
+					dynamic_cast<ast::DeclWithType *>(this->node) :
+					GET_ACCEPT_1(member, DeclWithType),
+				GET_ACCEPT_1(aggregate, Expr)
+			)
+		);
+	}
+
+	virtual void visit( VariableExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::VariableExpr(
+				old->location,
+				inCache(old->var) ?
+					dynamic_cast<ast::DeclWithType *>(this->node) :
+					GET_ACCEPT_1(var, DeclWithType)
+			)
+		);
+	}
+
+	bool isIntlikeConstantType(const Type *t) {
+		if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {
+			if ( basicType->isInteger() ) {
+				return true;
+			}
+		} else if ( dynamic_cast< const OneType * >( t ) ) {
+			return true;
+		} else if ( dynamic_cast< const ZeroType * >( t ) ) {
+			return true;
+		} else if ( dynamic_cast< const PointerType * >( t ) ) {
+			// null pointer constants, with zero int-values
+			return true;
+		}
+		return false;
+	}
+
+	int isFloatlikeConstantType(const Type *t) {
+		if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {
+			if ( ! bty->isInteger() ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	int isStringlikeConstantType(const Type *t) {
+		if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {
+			if ( const BasicType * bty = dynamic_cast< const BasicType * >( aty->base ) ) {
+			   if ( bty->kind == BasicType::Kind::Char ) {
+				   return true;
+			   }
+			}
+		}
+		return false;
+	}
+
+	virtual void visit( ConstantExpr * old ) override final {
+		ast::ConstantExpr *rslt = nullptr;
+		if (isIntlikeConstantType(old->result)) {
+			rslt = new ast::ConstantExpr(
+				old->location,
+				GET_ACCEPT_1(result, Type),
+				old->constant.get_value(),
+				(unsigned long long) old->intValue()
+			);
+		} else if (isFloatlikeConstantType(old->result)) {
+			rslt = new ast::ConstantExpr(
+				old->location,
+				GET_ACCEPT_1(result, Type), 
+				old->constant.get_value(), 
+				(double) old->constant.get_dval()
+			);
+		} else if (isStringlikeConstantType(old->result)) {
+			rslt = ast::ConstantExpr::from_string(
+				old->location,
+				old->constant.get_value()
+			);
+		}
+		assert(rslt);
+		this->node = visitBaseExpr( old, rslt );
+	}
+
+	virtual void visit( SizeofExpr * old ) override final {
+		assert (old->expr || old->type);
+		assert (! (old->expr && old->type));
+		ast::SizeofExpr *rslt;
+		if (old->expr) {
+			assert(!old->isType);
+			rslt = new ast::SizeofExpr(
+				old->location, 
+				GET_ACCEPT_1(expr, Expr)
+			);
+		}
+		if (old->type) {
+			assert(old->isType);
+			rslt = new ast::SizeofExpr(
+				old->location, 
+				GET_ACCEPT_1(type, Type)
+			);
+		}
+		this->node = visitBaseExpr( old, rslt );
+	}
+
+	virtual void visit( AlignofExpr * old ) override final {
+		assert (old->expr || old->type);
+		assert (! (old->expr && old->type));
+		ast::AlignofExpr *rslt;
+		if (old->expr) {
+			assert(!old->isType);
+			rslt = new ast::AlignofExpr(
+				old->location, 
+				GET_ACCEPT_1(expr, Expr)
+			);
+		}
+		if (old->type) {
+			assert(old->isType);
+			rslt = new ast::AlignofExpr(
+				old->location, 
+				GET_ACCEPT_1(type, Type)
+			);
+		}
+		this->node = visitBaseExpr( old, rslt );
+	}
+
+	virtual void visit( UntypedOffsetofExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::UntypedOffsetofExpr(
+				old->location,
+				GET_ACCEPT_1(type, Type),
+				old->member
+			)
+		);
+	}
+
+	virtual void visit( OffsetofExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::OffsetofExpr(
+				old->location,
+				GET_ACCEPT_1(type, Type),
+				inCache(old->member) ?
+					dynamic_cast<ast::DeclWithType *>(this->node) :
+					GET_ACCEPT_1(member, DeclWithType)
+			)
+		);
+	}
+
+	virtual void visit( OffsetPackExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::OffsetPackExpr(
+				old->location,
+				GET_ACCEPT_1(type, StructInstType)
+			)
+		);
+	}
+
+	virtual void visit( LogicalExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::LogicalExpr(
+				old->location,
+				GET_ACCEPT_1(arg1, Expr),
+				GET_ACCEPT_1(arg2, Expr),
+				old->get_isAnd() ? 
+					ast::LogicalFlag::AndExpr :
+					ast::LogicalFlag::OrExpr
+			)
+		);
+	}
+
+	virtual void visit( ConditionalExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::ConditionalExpr(
+				old->location,
+				GET_ACCEPT_1(arg1, Expr),
+				GET_ACCEPT_1(arg2, Expr),
+				GET_ACCEPT_1(arg3, Expr)
+			)
+		);
+	}
+
+	virtual void visit( CommaExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::CommaExpr(
+				old->location,
+				GET_ACCEPT_1(arg1, Expr),
+				GET_ACCEPT_1(arg2, Expr)
+			)
+		);
 	}
 
