#include "reflect.h"
+using namespace std;
+
namespace Msp {
namespace GL {
namespace SL {
r_count *= literal->value.value<int>();
}
+
+void MemoryRequirementsCalculator::visit(BasicTypeDeclaration &basic)
+{
+ if(basic.kind==BasicTypeDeclaration::BOOL)
+ {
+ r_size = 1;
+ r_alignment = 1;
+ }
+ else if(basic.kind==BasicTypeDeclaration::INT || basic.kind==BasicTypeDeclaration::FLOAT)
+ {
+ r_size = basic.size/8;
+ r_alignment = r_size;
+ }
+ else if(basic.kind==BasicTypeDeclaration::VECTOR || basic.kind==BasicTypeDeclaration::MATRIX)
+ {
+ basic.base_type->visit(*this);
+ unsigned n_elem = basic.size&0xFFFF;
+ r_size *= n_elem;
+ if(basic.kind==BasicTypeDeclaration::VECTOR)
+ r_alignment *= (n_elem==3 ? 4 : n_elem);
+ }
+ else if(basic.kind==BasicTypeDeclaration::ARRAY)
+ basic.base_type->visit(*this);
+}
+
+void MemoryRequirementsCalculator::visit(StructDeclaration &strct)
+{
+ unsigned total = 0;
+ unsigned max_align = 1;
+ for(NodeList<Statement>::iterator i=strct.members.body.begin(); i!=strct.members.body.end(); ++i)
+ {
+ r_size = 0;
+ r_alignment = 1;
+ r_offset = -1;
+ (*i)->visit(*this);
+ if(r_offset)
+ total = r_offset;
+ total += r_alignment-1;
+ total -= total%r_alignment;
+ total += r_size;
+ max_align = max(max_align, r_alignment);
+ }
+ r_size = total;
+ r_alignment = max_align;
+}
+
+void MemoryRequirementsCalculator::visit(VariableDeclaration &var)
+{
+ if(var.layout)
+ {
+ const vector<Layout::Qualifier> qualifiers = var.layout->qualifiers;
+ for(vector<Layout::Qualifier>::const_iterator i=qualifiers.begin(); (r_offset<0 && i!=qualifiers.end()); ++i)
+ if(i->name=="offset")
+ r_offset = i->value;
+ }
+
+ if(var.type_declaration)
+ var.type_declaration->visit(*this);
+ if(var.array)
+ if(const Literal *literal = dynamic_cast<const Literal *>(var.array_size.get()))
+ if(literal->value.check_type<int>())
+ r_size += r_alignment*(literal->value.value<int>()-1);
+}
+
+
+set<Node *> DependencyCollector::apply(FunctionDeclaration &func)
+{
+ func.visit(*this);
+ return dependencies;
+}
+
+void DependencyCollector::visit(VariableReference &var)
+{
+ if(var.declaration && !locals.count(var.declaration))
+ {
+ dependencies.insert(var.declaration);
+ var.declaration->visit(*this);
+ }
+}
+
+void DependencyCollector::visit(InterfaceBlockReference &iface)
+{
+ if(iface.declaration)
+ {
+ dependencies.insert(iface.declaration);
+ iface.declaration->visit(*this);
+ }
+}
+
+void DependencyCollector::visit(FunctionCall &call)
+{
+ if(call.declaration)
+ dependencies.insert(call.declaration);
+ TraversingVisitor::visit(call);
+}
+
+void DependencyCollector::visit(VariableDeclaration &var)
+{
+ locals.insert(&var);
+ if(var.type_declaration)
+ {
+ dependencies.insert(var.type_declaration);
+ var.type_declaration->visit(*this);
+ }
+
+ TraversingVisitor::visit(var);
+}
+
} // namespace SL
} // namespace GL
} // namespace Msp