1 #ifndef MSP_GL_SL_VALIDATE_H_
2 #define MSP_GL_SL_VALIDATE_H_
6 #include "glsl_error.h"
13 /** Base class for validators. Contains some utilities for adding diagnostic
15 class Validator: protected TraversingVisitor
23 void diagnose(Node &, Node &, Diagnostic::Severity, const std::string &);
24 void diagnose(Node &n, Diagnostic::Severity s, const std::string &m) { diagnose(n, n, s, m); }
25 void error(Node &n, const std::string &m) { diagnose(n, Diagnostic::ERR, m); }
26 void add_info(Node &, const std::string &);
29 /** Verifies that declarations are valid in isolation. */
30 class DeclarationValidator: private Validator
43 InterfaceLayout *iface_layout;
44 InterfaceBlock *iface_block;
45 VariableDeclaration *variable;
48 DeclarationValidator();
50 void apply(Stage &s) { stage = &s; s.content.visit(*this); }
53 static const char *describe_variable(ScopeType);
55 virtual void visit(Layout &);
56 virtual void visit(InterfaceLayout &);
57 virtual void visit(BasicTypeDeclaration &);
58 virtual void visit(ImageTypeDeclaration &);
59 virtual void visit(StructDeclaration &);
60 virtual void visit(VariableDeclaration &);
61 virtual void visit(InterfaceBlock &);
62 virtual void visit(FunctionDeclaration &);
65 /** Verifies that identifiers are unique or, in the case of functions, are
66 overloaded only in valid ways. */
67 class IdentifierValidator: private Validator
70 typedef std::map<std::string, Statement *> BlockDeclarationMap;
72 std::map<Block *, BlockDeclarationMap> declarations;
73 std::map<std::string, InterfaceBlock *> interface_blocks;
74 std::map<std::string, FunctionDeclaration *> overloaded_functions;
78 IdentifierValidator();
80 void apply(Stage &s) { stage = &s; s.content.visit(*this); }
83 void multiple_definition(const std::string &, Statement &, Statement &);
84 Statement *find_definition(const std::string &);
85 void check_definition(const std::string &, Statement &);
86 void record_definition(const std::string &, Statement &);
88 virtual void visit(TypeDeclaration &);
89 virtual void visit(BasicTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
90 virtual void visit(ImageTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
91 virtual void visit(StructDeclaration &);
92 virtual void visit(VariableDeclaration &);
93 virtual void visit(InterfaceBlock &);
94 virtual void visit(FunctionDeclaration &);
97 /** Verifies that there are no unresolved references. */
98 class ReferenceValidator: private Validator
101 void apply(Stage &s) { stage = &s; s.content.visit(*this); }
104 virtual void visit(BasicTypeDeclaration &);
105 virtual void visit(ImageTypeDeclaration &);
106 virtual void visit(VariableReference &);
107 virtual void visit(MemberAccess &);
108 virtual void visit(InterfaceBlockReference &);
109 virtual void visit(FunctionCall &);
110 virtual void visit(VariableDeclaration &);
111 virtual void visit(InterfaceBlock &);
112 virtual void visit(FunctionDeclaration &);
115 /** Verifies that expressions are valid. In most cases an invalid expression
116 is indicated by a null result type. */
117 class ExpressionValidator: private Validator
120 FunctionDeclaration *current_function;
123 ExpressionValidator();
125 void apply(Stage &s) { stage = &s; s.content.visit(*this); }
128 virtual void visit(Swizzle &);
129 virtual void visit(UnaryExpression &);
130 virtual void visit(BinaryExpression &);
131 virtual void visit(Assignment &);
132 virtual void visit(TernaryExpression &);
133 virtual void visit(VariableDeclaration &);
134 virtual void visit(FunctionDeclaration &);
135 virtual void visit(Return &);
138 /** Verifies that stage input and output interfaces are valid. Linked
139 variables must have matching types and locations and there must not be any
140 overlap in locations. */
141 class StageInterfaceValidator: private Validator
144 std::map<std::string, std::map<unsigned, VariableDeclaration *> > used_locations;
147 void apply(Stage &s) { stage = &s; s.content.visit(*this); }
150 int get_location(const Layout &);
152 virtual void visit(VariableDeclaration &);
153 virtual void visit(FunctionDeclaration &) { }
156 /** Verifies that uniform interfaces are valid across the entire module.
157 Variables declared with the same binding must have the same name and type. */
158 class GlobalInterfaceValidator: private Validator
164 TypeDeclaration *type;
171 Uniform(): node(0), type(0), location(-1), loc_count(1), desc_set(0), bind_point(-1) { }
174 std::list<Uniform> uniforms;
175 std::map<std::string, const Uniform *> used_names;
176 std::map<unsigned, const Uniform *> used_locations;
177 std::map<unsigned, std::map<unsigned, const Uniform *> > used_bindings;
180 void apply(Module &);
183 void check_uniform(const Uniform &);
185 virtual void visit(VariableDeclaration &);
186 virtual void visit(InterfaceBlock &);
187 virtual void visit(FunctionDeclaration &) { }