{
public:
Export_function_body(Export* exp, int indent)
- : exp_(exp), indent_(indent)
+ : exp_(exp), type_context_(NULL), indent_(indent)
{ }
// Write a character to the body.
write_type(const Type* type)
{ this->exp_->write_type_to(type, this); }
+ // Return the current type context.
+ Type*
+ type_context() const
+ { return this->type_context_; }
+
+ // Set the current type context.
+ void
+ set_type_context(Type* type)
+ { this->type_context_ = type; }
+
// Append as many spaces as the current indentation level.
void
indent()
Export* exp_;
// The body we are building.
std::string body_;
+ // Current type context. Used to avoid duplicate type conversions.
+ Type* type_context_;
// Current indentation level: the number of spaces before each statement.
int indent_;
};
void
Integer_expression::do_export(Export_function_body* efb) const
{
+ bool added_type = false;
+ if (this->type_ != NULL
+ && !this->type_->is_abstract()
+ && this->type_ != efb->type_context())
+ {
+ efb->write_c_string("$convert(");
+ efb->write_type(this->type_);
+ efb->write_c_string(", ");
+ added_type = true;
+ }
+
Integer_expression::export_integer(efb, this->val_);
if (this->is_character_constant_)
efb->write_c_string("'");
// A trailing space lets us reliably identify the end of the number.
efb->write_c_string(" ");
+
+ if (added_type)
+ efb->write_c_string(")");
}
// Import an integer, floating point, or complex value. This handles
void
Float_expression::do_export(Export_function_body* efb) const
{
+ bool added_type = false;
+ if (this->type_ != NULL
+ && !this->type_->is_abstract()
+ && this->type_ != efb->type_context())
+ {
+ efb->write_c_string("$convert(");
+ efb->write_type(this->type_);
+ efb->write_c_string(", ");
+ added_type = true;
+ }
+
Float_expression::export_float(efb, this->val_);
// A trailing space lets us reliably identify the end of the number.
efb->write_c_string(" ");
+
+ if (added_type)
+ efb->write_c_string(")");
}
// Dump a floating point number to the dump file.
void
Complex_expression::do_export(Export_function_body* efb) const
{
+ bool added_type = false;
+ if (this->type_ != NULL
+ && !this->type_->is_abstract()
+ && this->type_ != efb->type_context())
+ {
+ efb->write_c_string("$convert(");
+ efb->write_type(this->type_);
+ efb->write_c_string(", ");
+ added_type = true;
+ }
+
Complex_expression::export_complex(efb, this->val_);
// A trailing space lets us reliably identify the end of the number.
efb->write_c_string(" ");
+
+ if (added_type)
+ efb->write_c_string(")");
}
// Dump a complex expression to the dump file.
efb->write_c_string("$convert(");
efb->write_type(this->type_);
efb->write_c_string(", ");
+
+ Type* old_context = efb->type_context();
+ efb->set_type_context(this->type_);
+
this->expr_->export_expression(efb);
+
+ efb->set_type_context(old_context);
+
efb->write_c_string(")");
}