]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/syntax.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / glsl / syntax.h
index 682a0f5aeeaa2246b01226df25536a23a91d9c7a..ebe188e1f6afa932fe5fd697509c043cfeb5ef23 100644 (file)
@@ -6,8 +6,11 @@
 #include <set>
 #include <string>
 #include <vector>
+#include <cstdint>
 #include <msp/core/refptr.h>
+#include <msp/core/variant.h>
 #include "features.h"
+#include "glsl_error.h"
 #include "sourcemap.h"
 
 #pragma push_macro("interface")
@@ -24,17 +27,20 @@ struct Operator
                NO_OPERATOR,
                BINARY,
                PREFIX,
-               POSTFIX
+               POSTFIX,
+               TERNARY
        };
 
        enum Associativity
        {
                LEFT_TO_RIGHT,
-               RIGHT_TO_LEFT
+               RIGHT_TO_LEFT,
+               ASSOCIATIVE
        };
 
        char token[4];
-       unsigned precedence;
+       char token2[2];
+       std::uint8_t precedence;
        Type type;
        Associativity assoc;
 
@@ -45,6 +51,7 @@ struct Operator
 
 enum
 {
+       INTERNAL_SOURCE = -2,
        BUILTIN_SOURCE = -1,
        GENERATED_SOURCE = 0
 };
@@ -53,13 +60,15 @@ struct NodeVisitor;
 
 struct Node
 {
-protected:
-       Node() { }
-       Node(const Node &) { }
+       int source = GENERATED_SOURCE;
+       unsigned line = 1;
+
+       Node() = default;
+       Node(const Node &) = default;
 private:
        Node &operator=(const Node &);
 public:
-       virtual ~Node() { }
+       virtual ~Node() = default;
 
        virtual Node *clone() const = 0;
        virtual void visit(NodeVisitor &) = 0;
@@ -69,10 +78,10 @@ template<typename T>
 class NodePtr: public RefPtr<T>
 {
 public:
-       NodePtr() { }
+       NodePtr() = default;
        NodePtr(T *p): RefPtr<T>(p) { }
        NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : 0) { }
-       NodePtr &operator=(const NodePtr &p) { RefPtr<T>::operator=(p); return *this; }
+       NodePtr &operator=(const NodePtr &p) = default;
 
        template<typename U>
        NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
@@ -85,8 +94,11 @@ template<typename C>
 class NodeContainer: public C
 {
 public:
-       NodeContainer() { }
+       NodeContainer() = default;
        NodeContainer(const NodeContainer &);
+
+       void push_back_nocopy(const typename C::value_type &v)
+       { C::push_back(0); C::back() = v; }
 };
 
 template<typename T>
@@ -97,30 +109,24 @@ template<typename T>
 class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
 { };
 
-struct StructDeclaration;
+struct TypeDeclaration;
 struct VariableDeclaration;
-struct InterfaceBlock;
 struct FunctionDeclaration;
 
 struct Statement: Node
 {
-       int source;
-       unsigned line;
-
-       Statement();
-
        virtual Statement *clone() const = 0;
 };
 
 struct Block: Node
 {
        NodeList<Statement> body;
-       bool use_braces;
+       bool use_braces = false;
 
        std::map<std::string, VariableDeclaration *> variables;
-       Block *parent;
+       Block *parent = 0;
 
-       Block();
+       Block() = default;
        Block(const Block &);
 
        virtual Block *clone() const { return new Block(*this); }
@@ -129,9 +135,10 @@ struct Block: Node
 
 struct Expression: Node
 {
-       const Operator *oper;
+       const Operator *oper = 0;
 
-       Expression();
+       TypeDeclaration *type = 0;
+       bool lvalue = false;
 
        virtual Expression *clone() const = 0;
 };
@@ -139,56 +146,48 @@ struct Expression: Node
 struct Literal: Expression
 {
        std::string token;
+       Variant value;
 
        virtual Literal *clone() const { return new Literal(*this); }
        virtual void visit(NodeVisitor &);
 };
 
-struct ParenthesizedExpression: Expression
-{
-       NodePtr<Expression> expression;
-
-       virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
-       virtual void visit(NodeVisitor &);
-};
-
 struct VariableReference: Expression
 {
        std::string name;
 
-       VariableDeclaration *declaration;
+       VariableDeclaration *declaration = 0;
 
-       VariableReference();
+       VariableReference() = default;
        VariableReference(const VariableReference &);
 
        virtual VariableReference *clone() const { return new VariableReference(*this); }
        virtual void visit(NodeVisitor &);
 };
 
-struct InterfaceBlockReference: Expression
+struct MemberAccess: Expression
 {
-       std::string name;
+       NodePtr<Expression> left;
+       std::string member;
 
-       InterfaceBlock *declaration;
+       VariableDeclaration *declaration = 0;
+       int index = -1;
 
-       InterfaceBlockReference();
-       InterfaceBlockReference(const InterfaceBlockReference &);
+       MemberAccess() = default;
+       MemberAccess(const MemberAccess &);
 
-       virtual InterfaceBlockReference *clone() const { return new InterfaceBlockReference(*this); }
+       virtual MemberAccess *clone() const { return new MemberAccess(*this); }
        virtual void visit(NodeVisitor &);
 };
 
-struct MemberAccess: Expression
+struct Swizzle: Expression
 {
        NodePtr<Expression> left;
-       std::string member;
+       std::string component_group;
+       unsigned count = 0;
+       std::uint8_t components[4] = { 0, 0, 0, 0 };
 
-       VariableDeclaration *declaration;
-
-       MemberAccess();
-       MemberAccess(const MemberAccess &);
-
-       virtual MemberAccess *clone() const { return new MemberAccess(*this); }
+       virtual Swizzle *clone() const { return new Swizzle(*this); }
        virtual void visit(NodeVisitor &);
 };
 
@@ -211,26 +210,54 @@ struct BinaryExpression: Expression
 
 struct Assignment: BinaryExpression
 {
-       bool self_referencing;
+       struct Target
+       {
+               enum ChainType
+               {
+                       MEMBER = 0x40,
+                       SWIZZLE = 0x80,
+                       ARRAY = 0xC0
+               };
+
+               VariableDeclaration *declaration = 0;
+               std::uint8_t chain_len = 0;
+               std::uint8_t chain[7] = { };
+
+               Target(VariableDeclaration *d = 0): declaration(d) { }
+
+               bool operator<(const Target &) const;
+       };
 
-       VariableDeclaration *target_declaration;
+       bool self_referencing = false;
 
-       Assignment();
+       Target target;
+
+       Assignment() = default;
        Assignment(const Assignment &);
 
        virtual Assignment *clone() const { return new Assignment(*this); }
        virtual void visit(NodeVisitor &);
 };
 
+struct TernaryExpression: Expression
+{
+       NodePtr<Expression> condition;
+       NodePtr<Expression> true_expr;
+       NodePtr<Expression> false_expr;
+
+       virtual TernaryExpression *clone() const { return new TernaryExpression(*this); }
+       virtual void visit(NodeVisitor &);
+};
+
 struct FunctionCall: Expression
 {
        std::string name;
-       bool constructor;
+       bool constructor = false;
        NodeArray<Expression> arguments;
 
-       FunctionDeclaration *declaration;
+       FunctionDeclaration *declaration = 0;
 
-       FunctionCall();
+       FunctionCall() = default;
        FunctionCall(const FunctionCall &);
 
        virtual FunctionCall *clone() const { return new FunctionCall(*this); }
@@ -269,6 +296,9 @@ struct Layout: Node
                std::string name;
                bool has_value;
                int value;
+
+               Qualifier(const std::string &n = std::string()): name(n), has_value(false), value(0) { }
+               Qualifier(const std::string &n, int v): name(n), has_value(true), value(v) { }
        };
 
        std::vector<Qualifier> qualifiers;
@@ -286,12 +316,77 @@ struct InterfaceLayout: Statement
        virtual void visit(NodeVisitor &);
 };
 
-struct StructDeclaration: Statement
+struct TypeDeclaration: Statement
 {
        std::string name;
+
+       virtual TypeDeclaration *clone() const = 0;
+};
+
+struct BasicTypeDeclaration: TypeDeclaration
+{
+       enum Kind
+       {
+               ALIAS,
+               VOID,
+               BOOL,
+               INT,
+               FLOAT,
+               VECTOR,
+               MATRIX,
+               ARRAY
+       };
+
+       Kind kind = ALIAS;
+       unsigned size = 0;
+       bool sign = true;
+       bool extended_alignment = false;
+       std::string base;
+
+       TypeDeclaration *base_type = 0;
+
+       BasicTypeDeclaration() = default;
+       BasicTypeDeclaration(const BasicTypeDeclaration &);
+
+       virtual BasicTypeDeclaration *clone() const { return new BasicTypeDeclaration(*this); }
+       virtual void visit(NodeVisitor &);
+};
+
+struct ImageTypeDeclaration: TypeDeclaration
+{
+       enum Dimensions
+       {
+               ONE = 1,
+               TWO,
+               THREE,
+               CUBE
+       };
+
+       Dimensions dimensions = TWO;
+       bool array = false;
+       bool sampled = false;
+       bool shadow = false;
+       bool multisample = false;
+       std::string base;
+       std::string format;
+
+       TypeDeclaration *base_type = 0;
+       ImageTypeDeclaration *base_image = 0;
+
+       virtual ImageTypeDeclaration *clone() const { return new ImageTypeDeclaration(*this); }
+       virtual void visit(NodeVisitor &);
+};
+
+struct StructDeclaration: TypeDeclaration
+{
        Block members;
+       std::string block_name;
+       bool extended_alignment = false;
+
+       VariableDeclaration *block_declaration = 0;
 
        StructDeclaration();
+       StructDeclaration(const StructDeclaration &);
 
        virtual StructDeclaration *clone() const { return new StructDeclaration(*this); }
        virtual void visit(NodeVisitor &);
@@ -300,21 +395,22 @@ struct StructDeclaration: Statement
 struct VariableDeclaration: Statement
 {
        NodePtr<Layout> layout;
-       bool constant;
+       bool constant = false;
        std::string sampling;
        std::string interpolation;
        std::string interface;
        std::string precision;
        std::string type;
        std::string name;
-       bool array;
+       bool array = false;
        NodePtr<Expression> array_size;
        NodePtr<Expression> init_expression;
 
-       StructDeclaration *type_declaration;
-       VariableDeclaration *linked_declaration;
+       TypeDeclaration *type_declaration = 0;
+       StructDeclaration *block_declaration = 0;
+       VariableDeclaration *linked_declaration = 0;
 
-       VariableDeclaration();
+       VariableDeclaration() = default;
        VariableDeclaration(const VariableDeclaration &);
        ~VariableDeclaration();
 
@@ -322,34 +418,20 @@ struct VariableDeclaration: Statement
        virtual void visit(NodeVisitor &);
 };
 
-struct InterfaceBlock: Statement
-{
-       std::string interface;
-       std::string name;
-       Block members;
-       std::string instance_name;
-       bool array;
-
-       InterfaceBlock *linked_block;
-
-       InterfaceBlock();
-       InterfaceBlock(const InterfaceBlock &);
-       ~InterfaceBlock();
-
-       virtual InterfaceBlock *clone() const { return new InterfaceBlock(*this); }
-       virtual void visit(NodeVisitor &);
-};
-
 struct FunctionDeclaration: Statement
 {
        std::string return_type;
        std::string name;
        NodeArray<VariableDeclaration> parameters;
+       bool virtua = false;
+       bool overrd = false;
        Block body;
 
-       FunctionDeclaration *definition;
+       std::string signature;
+       FunctionDeclaration *definition = 0;
+       TypeDeclaration *return_type_declaration = 0;
 
-       FunctionDeclaration();
+       FunctionDeclaration() = default;
        FunctionDeclaration(const FunctionDeclaration &);
 
        virtual FunctionDeclaration *clone() const { return new FunctionDeclaration(*this); }
@@ -368,7 +450,7 @@ struct Conditional: Statement
 
 struct Iteration: Statement
 {
-       NodePtr<Node> init_statement;
+       NodePtr<Statement> init_statement;
        NodePtr<Expression> condition;
        NodePtr<Expression> loop_expression;
        Block body;
@@ -407,18 +489,25 @@ struct Stage
        {
                SHARED,
                VERTEX,
+               TESS_CONTROL,
+               TESS_EVAL,
                GEOMETRY,
-               FRAGMENT
+               FRAGMENT,
+               COMPUTE
        };
 
        Type type;
-       Stage *previous;
+       Stage *previous = 0;
        Block content;
-       std::map<std::string, StructDeclaration *> types;
-       std::map<std::string, InterfaceBlock *> interface_blocks;
+       std::map<std::string, TypeDeclaration *> types;
+       std::map<std::string, VariableDeclaration *> interface_blocks;
        std::map<std::string, FunctionDeclaration *> functions;
        std::map<std::string, unsigned> locations;
+       std::map<std::string, unsigned> texture_bindings;
+       std::map<std::string, unsigned> uniform_block_bindings;
+       unsigned n_clip_distances = 0;
        Features required_features;
+       std::vector<Diagnostic> diagnostics;
 
        Stage(Type);
 
@@ -434,6 +523,14 @@ struct Module
        Module();
 };
 
+std::string get_unused_variable_name(const Block &, const std::string &);
+TypeDeclaration *get_ultimate_base_type(TypeDeclaration *);
+bool has_layout_qualifier(const Layout *, const std::string &);
+int get_layout_value(const Layout *, const std::string &, int = -1);
+void add_layout_qualifier(RefPtr<Layout> &, const Layout::Qualifier &);
+void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned);
+bool targets_overlap(const Assignment::Target &, const Assignment::Target &);
+
 } // namespace SL
 } // namespace GL
 } // namespace Msp