Do a better job of figuring the vtype of an expression.
This commit is contained in:
parent
d630e4dfe9
commit
8487cb5616
|
|
@ -40,7 +40,7 @@ Expression::~Expression()
|
|||
|
||||
void Expression::set_type(const VType*typ)
|
||||
{
|
||||
assert(type_ == 0);
|
||||
assert(type_==0 || type_==typ);
|
||||
type_ = typ;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,6 +193,9 @@ class ExpBinary : public Expression {
|
|||
|
||||
void dump_operands(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
virtual const VType*resolve_operand_types_(const VType*t1, const VType*t2) const;
|
||||
|
||||
private:
|
||||
Expression*operand1_;
|
||||
Expression*operand2_;
|
||||
|
|
@ -305,6 +308,9 @@ class ExpArithmetic : public ExpBinary {
|
|||
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
const VType* resolve_operand_types_(const VType*t1, const VType*t2) const;
|
||||
|
||||
private:
|
||||
fun_t fun_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -328,6 +328,9 @@ const VType* ExpBinary::probe_type(Entity*ent, Architecture*arc) const
|
|||
if (t1 == t2)
|
||||
return t1;
|
||||
|
||||
if (const VType*tb = resolve_operand_types_(t1, t2))
|
||||
return tb;
|
||||
|
||||
// FIXME: I should at this point try harder to find an
|
||||
// operator that has the proper argument list and use this
|
||||
// here, but for now we leave it for the back-end to figure out.
|
||||
|
|
@ -337,6 +340,11 @@ const VType* ExpBinary::probe_type(Entity*ent, Architecture*arc) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
const VType*ExpBinary::resolve_operand_types_(const VType*t1, const VType*t2) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ExpBinary::elaborate_exprs(Entity*ent, Architecture*arc, const VType*ltype)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
@ -491,6 +499,21 @@ int ExpArithmetic::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltyp
|
|||
return errors;
|
||||
}
|
||||
|
||||
const VType* ExpArithmetic::resolve_operand_types_(const VType*t1, const VType*t2) const
|
||||
{
|
||||
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t1))
|
||||
t1 = tmp->base_type();
|
||||
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t2))
|
||||
t2 = tmp->base_type();
|
||||
|
||||
if (t1->type_match(t2))
|
||||
return t1;
|
||||
if (t2->type_match(t2))
|
||||
return t2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const VType* ExpAttribute::probe_type(Entity*ent, Architecture*arc) const
|
||||
{
|
||||
base_->probe_type(ent, arc);
|
||||
|
|
|
|||
|
|
@ -205,6 +205,10 @@ class VTypeRange : public VType {
|
|||
VTypeRange(const VType*base, int64_t max_val, int64_t min_val);
|
||||
~VTypeRange();
|
||||
|
||||
// Get the type that is limited by the range.
|
||||
inline const VType* base_type() const { return base_; }
|
||||
|
||||
public: // Virtual methods
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
int emit_def(std::ostream&out) const;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue