]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/validate.h
Validate location overlap and type matching for GLSL interfaces
[libs/gl.git] / source / glsl / validate.h
1 #ifndef MSP_GL_SL_VALIDATE_H_
2 #define MSP_GL_SL_VALIDATE_H_
3
4 #include <string>
5 #include <vector>
6 #include "glsl_error.h"
7 #include "visitor.h"
8
9 namespace Msp {
10 namespace GL {
11 namespace SL {
12
13 class Validator: protected TraversingVisitor
14 {
15 protected:
16         Stage *stage;
17         Node *last_provoker;
18
19         Validator();
20
21         void diagnose(Node &, Node &, Diagnostic::Severity, const std::string &);
22         void diagnose(Node &n, Diagnostic::Severity s, const std::string &m) { diagnose(n, n, s, m); }
23         void error(Node &n, const std::string &m) { diagnose(n, Diagnostic::ERR, m); }
24         void add_info(Node &, const std::string &);
25 };
26
27 class DeclarationValidator: private Validator
28 {
29 private:
30         enum ScopeType
31         {
32                 GLOBAL,
33                 STRUCT,
34                 INTERFACE_BLOCK,
35                 FUNCTION_PARAM,
36                 FUNCTION
37         };
38
39         ScopeType scope;
40         InterfaceLayout *iface_layout;
41         InterfaceBlock *iface_block;
42         VariableDeclaration *variable;
43
44 public:
45         DeclarationValidator();
46
47         void apply(Stage &s) { stage = &s; s.content.visit(*this); }
48
49 private:
50         static const char *describe_variable(ScopeType);
51
52         virtual void visit(Layout &);
53         virtual void visit(InterfaceLayout &);
54         virtual void visit(BasicTypeDeclaration &);
55         virtual void visit(ImageTypeDeclaration &);
56         virtual void visit(StructDeclaration &);
57         virtual void visit(VariableDeclaration &);
58         virtual void visit(InterfaceBlock &);
59         virtual void visit(FunctionDeclaration &);
60 };
61
62 class IdentifierValidator: private Validator
63 {
64 private:
65         typedef std::map<std::string, Statement *> BlockDeclarationMap;
66
67         std::map<Block *, BlockDeclarationMap> declarations;
68         std::map<std::string, InterfaceBlock *> interface_blocks;
69         std::map<std::string, FunctionDeclaration *> overloaded_functions;
70         bool anonymous_block;
71
72 public:
73         IdentifierValidator();
74
75         void apply(Stage &s) { stage = &s; s.content.visit(*this); }
76
77 private:
78         void multiple_definition(const std::string &, Statement &, Statement &);
79         Statement *find_definition(const std::string &);
80         void check_definition(const std::string &, Statement &);
81         void record_definition(const std::string &, Statement &);
82
83         virtual void visit(TypeDeclaration &);
84         virtual void visit(BasicTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
85         virtual void visit(ImageTypeDeclaration &t) { visit(static_cast<TypeDeclaration &>(t)); }
86         virtual void visit(StructDeclaration &);
87         virtual void visit(VariableDeclaration &);
88         virtual void visit(InterfaceBlock &);
89         virtual void visit(FunctionDeclaration &);
90 };
91
92 class ReferenceValidator: private Validator
93 {
94 public:
95         void apply(Stage &s) { stage = &s; s.content.visit(*this); }
96
97 private:
98         virtual void visit(BasicTypeDeclaration &);
99         virtual void visit(ImageTypeDeclaration &);
100         virtual void visit(VariableReference &);
101         virtual void visit(MemberAccess &);
102         virtual void visit(InterfaceBlockReference &);
103         virtual void visit(FunctionCall &);
104         virtual void visit(VariableDeclaration &);
105         virtual void visit(InterfaceBlock &);
106         virtual void visit(FunctionDeclaration &);
107 };
108
109 class ExpressionValidator: private Validator
110 {
111 private:
112         FunctionDeclaration *current_function;
113
114 public:
115         ExpressionValidator();
116
117         void apply(Stage &s) { stage = &s; s.content.visit(*this); }
118
119 private:
120         virtual void visit(Swizzle &);
121         virtual void visit(UnaryExpression &);
122         virtual void visit(BinaryExpression &);
123         virtual void visit(Assignment &);
124         virtual void visit(TernaryExpression &);
125         virtual void visit(VariableDeclaration &);
126         virtual void visit(FunctionDeclaration &);
127         virtual void visit(Return &);
128 };
129
130 class StageInterfaceValidator: private Validator
131 {
132 private:
133         std::map<std::string, std::map<unsigned, VariableDeclaration *> > used_locations;
134
135 public:
136         void apply(Stage &s) { stage = &s; s.content.visit(*this); }
137
138 private:
139         int get_location(const Layout &);
140
141         virtual void visit(VariableDeclaration &);
142         virtual void visit(FunctionDeclaration &) { }
143 };
144
145 class GlobalInterfaceValidator: private Validator
146 {
147 private:
148         struct Binding
149         {
150                 Node *node;
151                 TypeDeclaration *type;
152                 std::string name;
153
154                 Binding(VariableDeclaration &v): node(&v), type(v.type_declaration), name(v.name) { }
155                 Binding(InterfaceBlock &i): node(&i), type(i.struct_declaration), name(i.block_name) { }
156         };
157
158         std::map<unsigned, std::map<unsigned, Binding> > used_bindings;
159
160 public:
161         void apply(Module &);
162
163 private:
164         void get_binding(const Layout &, unsigned &, int &);
165         void check_binding(const Layout &, const Binding &);
166
167         virtual void visit(VariableDeclaration &);
168         virtual void visit(InterfaceBlock &);
169         virtual void visit(FunctionDeclaration &) { }
170 };
171
172 } // namespace SL
173 } // namespace GL
174 } // namespace Msp
175
176 #endif