1 #ifndef MSP_GL_SL_SYNTAX_H_
2 #define MSP_GL_SL_SYNTAX_H_
10 #include <msp/core/refptr.h>
11 #include <msp/core/variant.h>
13 #include "glsl_error.h"
14 #include "sourcemap.h"
16 #pragma push_macro("interface")
43 std::uint8_t precedence;
47 static const Operator operators[];
49 static const Operator &get_operator(const std::string &, Type);
63 int source = GENERATED_SOURCE;
67 Node(const Node &) = default;
69 Node &operator=(const Node &);
71 virtual ~Node() = default;
73 virtual Node *clone() const = 0;
74 virtual void visit(NodeVisitor &) = 0;
78 class NodePtr: public RefPtr<T>
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;
87 NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
90 NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
94 class NodeContainer: public C
97 NodeContainer() = default;
98 NodeContainer(const NodeContainer &);
100 void push_back_nocopy(const typename C::value_type &v)
101 { C::push_back(0); C::back() = v; }
105 class NodeList: public NodeContainer<std::list<RefPtr<T> > >
109 class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
112 struct TypeDeclaration;
113 struct VariableDeclaration;
114 struct InterfaceBlock;
115 struct FunctionDeclaration;
117 struct Statement: Node
119 virtual Statement *clone() const = 0;
124 NodeList<Statement> body;
125 bool use_braces = false;
127 std::map<std::string, VariableDeclaration *> variables;
131 Block(const Block &);
133 virtual Block *clone() const { return new Block(*this); }
134 virtual void visit(NodeVisitor &);
137 struct Expression: Node
139 const Operator *oper = 0;
141 TypeDeclaration *type = 0;
144 virtual Expression *clone() const = 0;
147 struct Literal: Expression
152 virtual Literal *clone() const { return new Literal(*this); }
153 virtual void visit(NodeVisitor &);
156 struct VariableReference: Expression
160 VariableDeclaration *declaration = 0;
162 VariableReference() = default;
163 VariableReference(const VariableReference &);
165 virtual VariableReference *clone() const { return new VariableReference(*this); }
166 virtual void visit(NodeVisitor &);
169 struct InterfaceBlockReference: Expression
173 InterfaceBlock *declaration = 0;
175 InterfaceBlockReference() = default;
176 InterfaceBlockReference(const InterfaceBlockReference &);
178 virtual InterfaceBlockReference *clone() const { return new InterfaceBlockReference(*this); }
179 virtual void visit(NodeVisitor &);
182 struct MemberAccess: Expression
184 NodePtr<Expression> left;
187 VariableDeclaration *declaration = 0;
190 MemberAccess() = default;
191 MemberAccess(const MemberAccess &);
193 virtual MemberAccess *clone() const { return new MemberAccess(*this); }
194 virtual void visit(NodeVisitor &);
197 struct Swizzle: Expression
199 NodePtr<Expression> left;
200 std::string component_group;
202 std::uint8_t components[4] = { 0, 0, 0, 0 };
204 virtual Swizzle *clone() const { return new Swizzle(*this); }
205 virtual void visit(NodeVisitor &);
208 struct UnaryExpression: Expression
210 NodePtr<Expression> expression;
212 virtual UnaryExpression *clone() const { return new UnaryExpression(*this); }
213 virtual void visit(NodeVisitor &);
216 struct BinaryExpression: Expression
218 NodePtr<Expression> left;
219 NodePtr<Expression> right;
221 virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
222 virtual void visit(NodeVisitor &);
225 struct Assignment: BinaryExpression
236 Statement *declaration = 0;
237 std::uint8_t chain_len = 0;
238 std::uint8_t chain[7] = { };
240 Target(Statement *d = 0): declaration(d) { }
242 bool operator<(const Target &) const;
245 bool self_referencing = false;
249 Assignment() = default;
250 Assignment(const Assignment &);
252 virtual Assignment *clone() const { return new Assignment(*this); }
253 virtual void visit(NodeVisitor &);
256 struct TernaryExpression: Expression
258 NodePtr<Expression> condition;
259 NodePtr<Expression> true_expr;
260 NodePtr<Expression> false_expr;
262 virtual TernaryExpression *clone() const { return new TernaryExpression(*this); }
263 virtual void visit(NodeVisitor &);
266 struct FunctionCall: Expression
269 bool constructor = false;
270 NodeArray<Expression> arguments;
272 FunctionDeclaration *declaration = 0;
274 FunctionCall() = default;
275 FunctionCall(const FunctionCall &);
277 virtual FunctionCall *clone() const { return new FunctionCall(*this); }
278 virtual void visit(NodeVisitor &);
281 struct ExpressionStatement: Statement
283 NodePtr<Expression> expression;
285 virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
286 virtual void visit(NodeVisitor &);
289 struct Import: Statement
293 virtual Import *clone() const { return new Import(*this); }
294 virtual void visit(NodeVisitor &);
297 struct Precision: Statement
299 std::string precision;
302 virtual Precision *clone() const { return new Precision(*this); }
303 virtual void visit(NodeVisitor &);
314 Qualifier(const std::string &n = std::string()): name(n), has_value(false), value(0) { }
315 Qualifier(const std::string &n, int v): name(n), has_value(true), value(v) { }
318 std::vector<Qualifier> qualifiers;
320 virtual Layout *clone() const { return new Layout(*this); }
321 virtual void visit(NodeVisitor &);
324 struct InterfaceLayout: Statement
326 std::string interface;
329 virtual InterfaceLayout *clone() const { return new InterfaceLayout(*this); }
330 virtual void visit(NodeVisitor &);
333 struct TypeDeclaration: Statement
337 virtual TypeDeclaration *clone() const = 0;
340 struct BasicTypeDeclaration: TypeDeclaration
357 bool extended_alignment = false;
360 TypeDeclaration *base_type = 0;
362 BasicTypeDeclaration() = default;
363 BasicTypeDeclaration(const BasicTypeDeclaration &);
365 virtual BasicTypeDeclaration *clone() const { return new BasicTypeDeclaration(*this); }
366 virtual void visit(NodeVisitor &);
369 struct ImageTypeDeclaration: TypeDeclaration
379 Dimensions dimensions = TWO;
385 TypeDeclaration *base_type = 0;
387 virtual ImageTypeDeclaration *clone() const { return new ImageTypeDeclaration(*this); }
388 virtual void visit(NodeVisitor &);
391 struct StructDeclaration: TypeDeclaration
394 bool extended_alignment = false;
396 InterfaceBlock *interface_block = 0;
399 StructDeclaration(const StructDeclaration &);
400 ~StructDeclaration();
402 virtual StructDeclaration *clone() const { return new StructDeclaration(*this); }
403 virtual void visit(NodeVisitor &);
406 struct VariableDeclaration: Statement
408 NodePtr<Layout> layout;
409 bool constant = false;
410 std::string sampling;
411 std::string interpolation;
412 std::string interface;
413 std::string precision;
417 NodePtr<Expression> array_size;
418 NodePtr<Expression> init_expression;
420 TypeDeclaration *type_declaration = 0;
421 VariableDeclaration *linked_declaration = 0;
423 VariableDeclaration() = default;
424 VariableDeclaration(const VariableDeclaration &);
425 ~VariableDeclaration();
427 virtual VariableDeclaration *clone() const { return new VariableDeclaration(*this); }
428 virtual void visit(NodeVisitor &);
431 struct InterfaceBlock: Statement
433 NodePtr<Layout> layout;
434 std::string interface;
435 std::string block_name;
436 NodePtr<Block> members;
437 std::string instance_name;
440 /* An interface block's ultimate base type is always a struct. The
441 immediate type may be either that same struct or an array of it. */
442 TypeDeclaration *type_declaration = 0;
443 StructDeclaration *struct_declaration = 0;
444 InterfaceBlock *linked_block = 0;
446 InterfaceBlock() = default;
447 InterfaceBlock(const InterfaceBlock &);
450 virtual InterfaceBlock *clone() const { return new InterfaceBlock(*this); }
451 virtual void visit(NodeVisitor &);
454 struct FunctionDeclaration: Statement
456 std::string return_type;
458 NodeArray<VariableDeclaration> parameters;
463 std::string signature;
464 FunctionDeclaration *definition = 0;
465 TypeDeclaration *return_type_declaration = 0;
467 FunctionDeclaration() = default;
468 FunctionDeclaration(const FunctionDeclaration &);
470 virtual FunctionDeclaration *clone() const { return new FunctionDeclaration(*this); }
471 virtual void visit(NodeVisitor &);
474 struct Conditional: Statement
476 NodePtr<Expression> condition;
480 virtual Conditional *clone() const { return new Conditional(*this); }
481 virtual void visit(NodeVisitor &);
484 struct Iteration: Statement
486 NodePtr<Statement> init_statement;
487 NodePtr<Expression> condition;
488 NodePtr<Expression> loop_expression;
491 virtual Iteration *clone() const { return new Iteration(*this); }
492 virtual void visit(NodeVisitor &);
495 struct Passthrough: Statement
497 NodePtr<Expression> subscript;
499 virtual Passthrough *clone() const { return new Passthrough(*this); }
500 virtual void visit(NodeVisitor &);
503 struct Return: Statement
505 NodePtr<Expression> expression;
507 virtual Return *clone() const { return new Return(*this); }
508 virtual void visit(NodeVisitor &);
511 struct Jump: Statement
515 virtual Jump *clone() const { return new Jump(*this); }
516 virtual void visit(NodeVisitor &);
532 std::map<std::string, TypeDeclaration *> types;
533 std::map<std::string, InterfaceBlock *> interface_blocks;
534 std::map<std::string, FunctionDeclaration *> functions;
535 std::map<std::string, unsigned> locations;
536 std::map<std::string, unsigned> texture_bindings;
537 std::map<std::string, unsigned> uniform_block_bindings;
538 unsigned n_clip_distances = 0;
539 Features required_features;
540 std::vector<Diagnostic> diagnostics;
544 static const char *get_stage_name(Type);
549 SourceMap source_map;
551 std::list<Stage> stages;
556 std::string get_unused_variable_name(const Block &, const std::string &);
557 const TypeDeclaration *get_ultimate_base_type(const TypeDeclaration *);
558 bool has_layout_qualifier(const Layout *, const std::string &);
559 int get_layout_value(const Layout *, const std::string &, int = -1);
560 void add_layout_qualifier(RefPtr<Layout> &, const Layout::Qualifier &);
561 void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned);
562 bool targets_overlap(const Assignment::Target &, const Assignment::Target &);
568 #pragma pop_macro("interface")