]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/syntax.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / glsl / syntax.h
1 #ifndef MSP_GL_SL_SYNTAX_H_
2 #define MSP_GL_SL_SYNTAX_H_
3
4 #include <list>
5 #include <map>
6 #include <set>
7 #include <string>
8 #include <vector>
9 #include <cstdint>
10 #include <msp/core/refptr.h>
11 #include <msp/core/variant.h>
12 #include "features.h"
13 #include "glsl_error.h"
14 #include "sourcemap.h"
15
16 #pragma push_macro("interface")
17 #undef interface
18
19 namespace Msp {
20 namespace GL {
21 namespace SL {
22
23 struct Operator
24 {
25         enum Type
26         {
27                 NO_OPERATOR,
28                 BINARY,
29                 PREFIX,
30                 POSTFIX,
31                 TERNARY
32         };
33
34         enum Associativity
35         {
36                 LEFT_TO_RIGHT,
37                 RIGHT_TO_LEFT,
38                 ASSOCIATIVE
39         };
40
41         char token[4];
42         char token2[2];
43         std::uint8_t precedence;
44         Type type;
45         Associativity assoc;
46
47         static const Operator operators[];
48
49         static const Operator &get_operator(const std::string &, Type);
50 };
51
52 enum
53 {
54         INTERNAL_SOURCE = -2,
55         BUILTIN_SOURCE = -1,
56         GENERATED_SOURCE = 0
57 };
58
59 struct NodeVisitor;
60
61 struct Node
62 {
63         int source = GENERATED_SOURCE;
64         unsigned line = 1;
65
66         Node() = default;
67         Node(const Node &) = default;
68 private:
69         Node &operator=(const Node &);
70 public:
71         virtual ~Node() = default;
72
73         virtual Node *clone() const = 0;
74         virtual void visit(NodeVisitor &) = 0;
75 };
76
77 template<typename T>
78 class NodePtr: public RefPtr<T>
79 {
80 public:
81         NodePtr() = default;
82         NodePtr(T *p): RefPtr<T>(p) { }
83         NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : 0) { }
84         NodePtr &operator=(const NodePtr &p) = default;
85
86         template<typename U>
87         NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
88
89         template<typename U>
90         NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
91 };
92
93 template<typename C>
94 class NodeContainer: public C
95 {
96 public:
97         NodeContainer() = default;
98         NodeContainer(const NodeContainer &);
99
100         void push_back_nocopy(const typename C::value_type &v)
101         { C::push_back(0); C::back() = v; }
102 };
103
104 template<typename T>
105 class NodeList: public NodeContainer<std::list<RefPtr<T> > >
106 { };
107
108 template<typename T>
109 class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
110 { };
111
112 struct TypeDeclaration;
113 struct VariableDeclaration;
114 struct FunctionDeclaration;
115
116 struct Statement: Node
117 {
118         virtual Statement *clone() const = 0;
119 };
120
121 struct Block: Node
122 {
123         NodeList<Statement> body;
124         bool use_braces = false;
125
126         std::map<std::string, VariableDeclaration *> variables;
127         Block *parent = 0;
128
129         Block() = default;
130         Block(const Block &);
131
132         virtual Block *clone() const { return new Block(*this); }
133         virtual void visit(NodeVisitor &);
134 };
135
136 struct Expression: Node
137 {
138         const Operator *oper = 0;
139
140         TypeDeclaration *type = 0;
141         bool lvalue = false;
142
143         virtual Expression *clone() const = 0;
144 };
145
146 struct Literal: Expression
147 {
148         std::string token;
149         Variant value;
150
151         virtual Literal *clone() const { return new Literal(*this); }
152         virtual void visit(NodeVisitor &);
153 };
154
155 struct VariableReference: Expression
156 {
157         std::string name;
158
159         VariableDeclaration *declaration = 0;
160
161         VariableReference() = default;
162         VariableReference(const VariableReference &);
163
164         virtual VariableReference *clone() const { return new VariableReference(*this); }
165         virtual void visit(NodeVisitor &);
166 };
167
168 struct MemberAccess: Expression
169 {
170         NodePtr<Expression> left;
171         std::string member;
172
173         VariableDeclaration *declaration = 0;
174         int index = -1;
175
176         MemberAccess() = default;
177         MemberAccess(const MemberAccess &);
178
179         virtual MemberAccess *clone() const { return new MemberAccess(*this); }
180         virtual void visit(NodeVisitor &);
181 };
182
183 struct Swizzle: Expression
184 {
185         NodePtr<Expression> left;
186         std::string component_group;
187         unsigned count = 0;
188         std::uint8_t components[4] = { 0, 0, 0, 0 };
189
190         virtual Swizzle *clone() const { return new Swizzle(*this); }
191         virtual void visit(NodeVisitor &);
192 };
193
194 struct UnaryExpression: Expression
195 {
196         NodePtr<Expression> expression;
197
198         virtual UnaryExpression *clone() const { return new UnaryExpression(*this); }
199         virtual void visit(NodeVisitor &);
200 };
201
202 struct BinaryExpression: Expression
203 {
204         NodePtr<Expression> left;
205         NodePtr<Expression> right;
206
207         virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
208         virtual void visit(NodeVisitor &);
209 };
210
211 struct Assignment: BinaryExpression
212 {
213         struct Target
214         {
215                 enum ChainType
216                 {
217                         MEMBER = 0x40,
218                         SWIZZLE = 0x80,
219                         ARRAY = 0xC0
220                 };
221
222                 VariableDeclaration *declaration = 0;
223                 std::uint8_t chain_len = 0;
224                 std::uint8_t chain[7] = { };
225
226                 Target(VariableDeclaration *d = 0): declaration(d) { }
227
228                 bool operator<(const Target &) const;
229         };
230
231         bool self_referencing = false;
232
233         Target target;
234
235         Assignment() = default;
236         Assignment(const Assignment &);
237
238         virtual Assignment *clone() const { return new Assignment(*this); }
239         virtual void visit(NodeVisitor &);
240 };
241
242 struct TernaryExpression: Expression
243 {
244         NodePtr<Expression> condition;
245         NodePtr<Expression> true_expr;
246         NodePtr<Expression> false_expr;
247
248         virtual TernaryExpression *clone() const { return new TernaryExpression(*this); }
249         virtual void visit(NodeVisitor &);
250 };
251
252 struct FunctionCall: Expression
253 {
254         std::string name;
255         bool constructor = false;
256         NodeArray<Expression> arguments;
257
258         FunctionDeclaration *declaration = 0;
259
260         FunctionCall() = default;
261         FunctionCall(const FunctionCall &);
262
263         virtual FunctionCall *clone() const { return new FunctionCall(*this); }
264         virtual void visit(NodeVisitor &);
265 };
266
267 struct ExpressionStatement: Statement
268 {
269         NodePtr<Expression> expression;
270
271         virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
272         virtual void visit(NodeVisitor &);
273 };
274
275 struct Import: Statement
276 {
277         std::string module;
278
279         virtual Import *clone() const { return new Import(*this); }
280         virtual void visit(NodeVisitor &);
281 };
282
283 struct Precision: Statement
284 {
285         std::string precision;
286         std::string type;
287
288         virtual Precision *clone() const { return new Precision(*this); }
289         virtual void visit(NodeVisitor &);
290 };
291
292 struct Layout: Node
293 {
294         struct Qualifier
295         {
296                 std::string name;
297                 bool has_value;
298                 int value;
299
300                 Qualifier(const std::string &n = std::string()): name(n), has_value(false), value(0) { }
301                 Qualifier(const std::string &n, int v): name(n), has_value(true), value(v) { }
302         };
303
304         std::vector<Qualifier> qualifiers;
305
306         virtual Layout *clone() const { return new Layout(*this); }
307         virtual void visit(NodeVisitor &);
308 };
309
310 struct InterfaceLayout: Statement
311 {
312         std::string interface;
313         Layout layout;
314
315         virtual InterfaceLayout *clone() const { return new InterfaceLayout(*this); }
316         virtual void visit(NodeVisitor &);
317 };
318
319 struct TypeDeclaration: Statement
320 {
321         std::string name;
322
323         virtual TypeDeclaration *clone() const = 0;
324 };
325
326 struct BasicTypeDeclaration: TypeDeclaration
327 {
328         enum Kind
329         {
330                 ALIAS,
331                 VOID,
332                 BOOL,
333                 INT,
334                 FLOAT,
335                 VECTOR,
336                 MATRIX,
337                 ARRAY
338         };
339
340         Kind kind = ALIAS;
341         unsigned size = 0;
342         bool sign = true;
343         bool extended_alignment = false;
344         std::string base;
345
346         TypeDeclaration *base_type = 0;
347
348         BasicTypeDeclaration() = default;
349         BasicTypeDeclaration(const BasicTypeDeclaration &);
350
351         virtual BasicTypeDeclaration *clone() const { return new BasicTypeDeclaration(*this); }
352         virtual void visit(NodeVisitor &);
353 };
354
355 struct ImageTypeDeclaration: TypeDeclaration
356 {
357         enum Dimensions
358         {
359                 ONE = 1,
360                 TWO,
361                 THREE,
362                 CUBE
363         };
364
365         Dimensions dimensions = TWO;
366         bool array = false;
367         bool sampled = false;
368         bool shadow = false;
369         bool multisample = false;
370         std::string base;
371         std::string format;
372
373         TypeDeclaration *base_type = 0;
374         ImageTypeDeclaration *base_image = 0;
375
376         virtual ImageTypeDeclaration *clone() const { return new ImageTypeDeclaration(*this); }
377         virtual void visit(NodeVisitor &);
378 };
379
380 struct StructDeclaration: TypeDeclaration
381 {
382         Block members;
383         std::string block_name;
384         bool extended_alignment = false;
385
386         VariableDeclaration *block_declaration = 0;
387
388         StructDeclaration();
389         StructDeclaration(const StructDeclaration &);
390
391         virtual StructDeclaration *clone() const { return new StructDeclaration(*this); }
392         virtual void visit(NodeVisitor &);
393 };
394
395 struct VariableDeclaration: Statement
396 {
397         NodePtr<Layout> layout;
398         bool constant = false;
399         std::string sampling;
400         std::string interpolation;
401         std::string interface;
402         std::string precision;
403         std::string type;
404         std::string name;
405         bool array = false;
406         NodePtr<Expression> array_size;
407         NodePtr<Expression> init_expression;
408
409         TypeDeclaration *type_declaration = 0;
410         StructDeclaration *block_declaration = 0;
411         VariableDeclaration *linked_declaration = 0;
412
413         VariableDeclaration() = default;
414         VariableDeclaration(const VariableDeclaration &);
415         ~VariableDeclaration();
416
417         virtual VariableDeclaration *clone() const { return new VariableDeclaration(*this); }
418         virtual void visit(NodeVisitor &);
419 };
420
421 struct FunctionDeclaration: Statement
422 {
423         std::string return_type;
424         std::string name;
425         NodeArray<VariableDeclaration> parameters;
426         bool virtua = false;
427         bool overrd = false;
428         Block body;
429
430         std::string signature;
431         FunctionDeclaration *definition = 0;
432         TypeDeclaration *return_type_declaration = 0;
433
434         FunctionDeclaration() = default;
435         FunctionDeclaration(const FunctionDeclaration &);
436
437         virtual FunctionDeclaration *clone() const { return new FunctionDeclaration(*this); }
438         virtual void visit(NodeVisitor &);
439 };
440
441 struct Conditional: Statement
442 {
443         NodePtr<Expression> condition;
444         Block body;
445         Block else_body;
446
447         virtual Conditional *clone() const { return new Conditional(*this); }
448         virtual void visit(NodeVisitor &);
449 };
450
451 struct Iteration: Statement
452 {
453         NodePtr<Statement> init_statement;
454         NodePtr<Expression> condition;
455         NodePtr<Expression> loop_expression;
456         Block body;
457
458         virtual Iteration *clone() const { return new Iteration(*this); }
459         virtual void visit(NodeVisitor &);
460 };
461
462 struct Passthrough: Statement
463 {
464         NodePtr<Expression> subscript;
465
466         virtual Passthrough *clone() const { return new Passthrough(*this); }
467         virtual void visit(NodeVisitor &);
468 };
469
470 struct Return: Statement
471 {
472         NodePtr<Expression> expression;
473
474         virtual Return *clone() const { return new Return(*this); }
475         virtual void visit(NodeVisitor &);
476 };
477
478 struct Jump: Statement
479 {
480         std::string keyword;
481
482         virtual Jump *clone() const { return new Jump(*this); }
483         virtual void visit(NodeVisitor &);
484 };
485
486 struct Stage
487 {
488         enum Type
489         {
490                 SHARED,
491                 VERTEX,
492                 TESS_CONTROL,
493                 TESS_EVAL,
494                 GEOMETRY,
495                 FRAGMENT,
496                 COMPUTE
497         };
498
499         Type type;
500         Stage *previous = 0;
501         Block content;
502         std::map<std::string, TypeDeclaration *> types;
503         std::map<std::string, VariableDeclaration *> interface_blocks;
504         std::map<std::string, FunctionDeclaration *> functions;
505         std::map<std::string, unsigned> locations;
506         std::map<std::string, unsigned> texture_bindings;
507         std::map<std::string, unsigned> uniform_block_bindings;
508         unsigned n_clip_distances = 0;
509         Features required_features;
510         std::vector<Diagnostic> diagnostics;
511
512         Stage(Type);
513
514         static const char *get_stage_name(Type);
515 };
516
517 struct Module
518 {
519         SourceMap source_map;
520         Stage shared;
521         std::list<Stage> stages;
522
523         Module();
524 };
525
526 std::string get_unused_variable_name(const Block &, const std::string &);
527 TypeDeclaration *get_ultimate_base_type(TypeDeclaration *);
528 bool has_layout_qualifier(const Layout *, const std::string &);
529 int get_layout_value(const Layout *, const std::string &, int = -1);
530 void add_layout_qualifier(RefPtr<Layout> &, const Layout::Qualifier &);
531 void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned);
532 bool targets_overlap(const Assignment::Target &, const Assignment::Target &);
533
534 } // namespace SL
535 } // namespace GL
536 } // namespace Msp
537
538 #pragma pop_macro("interface")
539
540 #endif