+/** Resolves types and lvalueness of expressions. */
+class ExpressionResolver: private TraversingVisitor
+{
+private:
+ enum Compatibility
+ {
+ NOT_COMPATIBLE,
+ LEFT_CONVERTIBLE,
+ RIGHT_CONVERTIBLE,
+ SAME_TYPE
+ };
+
+ Stage *stage;
+ std::vector<BasicTypeDeclaration *> basic_types;
+
+public:
+ void apply(Stage &s) { stage = &s; s.content.visit(*this); }
+
+private:
+ static bool is_scalar(BasicTypeDeclaration &);
+ static bool is_vector_or_matrix(BasicTypeDeclaration &);
+ static BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
+ static bool can_convert(BasicTypeDeclaration &, BasicTypeDeclaration &);
+ static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
+ BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
+ BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
+ void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
+ bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
+
+ virtual void visit(Literal &);
+ virtual void visit(ParenthesizedExpression &);
+ virtual void visit(VariableReference &);
+ virtual void visit(InterfaceBlockReference &);
+ virtual void visit(MemberAccess &);
+ virtual void visit(UnaryExpression &);
+ virtual void visit(BinaryExpression &);
+ virtual void visit(Assignment &);
+ virtual void visit(FunctionCall &);
+ virtual void visit(BasicTypeDeclaration &);
+ virtual void visit(VariableDeclaration &);
+};
+