MemberAccess::MemberAccess():
- declaration(0)
+ declaration(0),
+ index(-1)
{ }
MemberAccess::MemberAccess(const MemberAccess &other):
Expression(other),
left(other.left),
member(other.member),
- declaration(0)
+ declaration(0),
+ index(-1)
{ }
void MemberAccess::visit(NodeVisitor &visitor)
InterfaceBlock::InterfaceBlock(const InterfaceBlock &other):
Statement(other),
interface(other.interface),
- name(other.name),
+ block_name(other.block_name),
members(other.members),
instance_name(other.instance_name),
array(other.array),
shared(Stage::SHARED)
{ }
+
+string get_unused_variable_name(const Block &block, const string &base)
+{
+ string name = base;
+
+ unsigned number = 1;
+ unsigned base_size = name.size();
+ while(1)
+ {
+ bool unused = true;
+ for(const Block *b=█ (unused && b); b=b->parent)
+ unused = !b->variables.count(name);
+ if(unused)
+ return name;
+
+ name.erase(base_size);
+ name += format("_%d", number);
+ ++number;
+ }
+}
+
+bool is_same_type(const TypeDeclaration &type1, const TypeDeclaration &type2)
+{
+ if(const BasicTypeDeclaration *basic1 = dynamic_cast<const BasicTypeDeclaration *>(&type1))
+ {
+ const BasicTypeDeclaration *basic2 = dynamic_cast<const BasicTypeDeclaration *>(&type2);
+ if(!basic2)
+ return false;
+
+ if(basic1->kind!=basic2->kind || basic1->size!=basic2->size)
+ return false;
+
+ if(basic1->base_type && basic2->base_type)
+ return is_same_type(*basic1->base_type, *basic2->base_type);
+ else
+ return (!basic1->base_type && !basic2->base_type);
+ }
+ else if(const ImageTypeDeclaration *image1 = dynamic_cast<const ImageTypeDeclaration *>(&type1))
+ {
+ const ImageTypeDeclaration *image2 = dynamic_cast<const ImageTypeDeclaration *>(&type2);
+ if(!image2)
+ return false;
+
+ if(image1->dimensions!=image2->dimensions || image1->array!=image2->array)
+ return false;
+ if(image1->sampled!=image2->sampled || image1->shadow!=image2->shadow)
+ return false;
+
+ if(image1->base_type && image2->base_type)
+ return is_same_type(*image1->base_type, *image2->base_type);
+ else
+ return (!image1->base_type && !image2->base_type);
+ }
+ else if(const StructDeclaration *strct1 = dynamic_cast<const StructDeclaration *>(&type1))
+ {
+ const StructDeclaration *strct2 = dynamic_cast<const StructDeclaration *>(&type2);
+ if(!strct2)
+ return false;
+
+ NodeList<Statement>::const_iterator i = strct1->members.body.begin();
+ NodeList<Statement>::const_iterator j = strct2->members.body.begin();
+ for(; (i!=strct1->members.body.end() && j!=strct2->members.body.end()); ++i, ++j)
+ {
+ const VariableDeclaration *var1 = dynamic_cast<const VariableDeclaration *>(i->get());
+ const VariableDeclaration *var2 = dynamic_cast<const VariableDeclaration *>(j->get());
+ if(!var1 || !var1->type_declaration || !var2 || !var2->type_declaration)
+ return false;
+ if(!is_same_type(*var1->type_declaration, *var2->type_declaration))
+ return false;
+ if(var1->name!=var2->name || var1->array!=var2->array)
+ return false;
+ // TODO Compare array sizes
+ // TODO Compare layout qualifiers for interface block members
+ }
+
+ return (i==strct1->members.body.end() && j==strct2->members.body.end());
+ }
+ else
+ return false;
+}
+
+int get_layout_value(const Layout &layout, const string &name, int def_value)
+{
+ for(vector<Layout::Qualifier>::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i)
+ if(i->name==name)
+ return i->value;
+ return def_value;
+}
+
+void add_to_chain(Assignment::Target &target, Assignment::Target::ChainType type, unsigned index)
+{
+ if(target.chain_len<7)
+ target.chain[target.chain_len] = type | min<unsigned>(index, 0x3F);
+ ++target.chain_len;
+}
+
} // namespace SL
} // namespace GL
} // namespace Msp