]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/reflect.h
Consider expressions in array sizes when comparing types for equality
[libs/gl.git] / source / glsl / reflect.h
1 #ifndef MSP_GL_SL_REFLECT_H_
2 #define MSP_GL_SL_REFLECT_H_
3
4 #include "visitor.h"
5
6 namespace Msp {
7 namespace GL {
8 namespace SL {
9
10 bool is_scalar(const BasicTypeDeclaration &);
11 bool is_vector_or_matrix(const BasicTypeDeclaration &);
12 BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
13 bool can_convert(const BasicTypeDeclaration &, const BasicTypeDeclaration &);
14
15 /** Compares two types for equality.  Struct types are compared recursively. */
16 class TypeComparer: private NodeVisitor
17 {
18 private:
19         Node *first;
20         Node *second;
21         unsigned first_tag;
22         bool r_result;
23
24         static unsigned next_tag;
25
26 public:
27         TypeComparer();
28
29         bool apply(TypeDeclaration &t1, TypeDeclaration &t2) { compare(t1, t2); return r_result; }
30
31 private:
32         void compare(Node &, Node &);
33         template<typename T>
34         T *multi_visit(T &);
35         virtual void visit(Literal &);
36         virtual void visit(VariableReference &);
37         virtual void visit(UnaryExpression &);
38         virtual void visit(BinaryExpression &);
39         virtual void visit(TernaryExpression &);
40         virtual void visit(BasicTypeDeclaration &);
41         virtual void visit(ImageTypeDeclaration &);
42         virtual void visit(StructDeclaration &);
43         virtual void visit(VariableDeclaration &);
44 };
45
46 /** Determines the number of interface locations required by a variable. */
47 class LocationCounter: private NodeVisitor
48 {
49 private:
50         unsigned r_count;
51
52 public:
53         LocationCounter();
54
55         unsigned apply(VariableDeclaration &v) { v.visit(*this); return r_count; }
56
57 private:
58         virtual void visit(BasicTypeDeclaration &);
59         virtual void visit(ImageTypeDeclaration &);
60         virtual void visit(StructDeclaration &);
61         virtual void visit(VariableDeclaration &);
62 };
63
64 /** Determines the size and alignment of a variable or a type, in bytes. */
65 class MemoryRequirementsCalculator: private NodeVisitor
66 {
67 public:
68         struct Result
69         {
70                 unsigned size;
71                 unsigned alignment;
72                 unsigned stride;
73
74                 Result(unsigned s, unsigned a): size(s), alignment(a), stride(s+a-1-(s+a-1)%a) { }
75         };
76 private:
77         unsigned r_size;
78         unsigned r_alignment;
79         int r_offset;
80
81 public:
82         Result apply(VariableDeclaration &v) { v.visit(*this); return Result(r_size, r_alignment); }
83         Result apply(TypeDeclaration &t) { t.visit(*this); return Result(r_size, r_alignment); }
84
85 private:
86         virtual void visit(BasicTypeDeclaration &);
87         virtual void visit(StructDeclaration &);
88         virtual void visit(VariableDeclaration &);
89 };
90
91 /** Collects dependencies of a function.  This includes global variables,
92 interface blocks, other functions and types. */
93 class DependencyCollector: private TraversingVisitor
94 {
95 private:
96         std::set<Node *> dependencies;
97         std::set<Node *> locals;
98         std::set<FunctionDeclaration *> visited_functions;
99
100 public:
101         std::set<Node *> apply(FunctionDeclaration &);
102
103 private:
104         virtual void visit(VariableReference &);
105         virtual void visit(InterfaceBlockReference &);
106         virtual void visit(FunctionCall &);
107         virtual void visit(VariableDeclaration &);
108         virtual void visit(FunctionDeclaration &);
109 };
110
111 } // namespace SL
112 } // namespace GL
113 } // namespace Msp
114
115 #endif