X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fsyntax.cpp;h=b224763248f26aa20f2d7e537ccbc6aa224acdb7;hb=fe7996a5985e8e7064004d2f42758d89ebf54b57;hp=cb50fee18b79538c126482594a023ea8f3864001;hpb=b89239e1d616f0c1d8e432b7df1eca149585cf5e;p=libs%2Fgl.git diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index cb50fee1..b2247632 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -138,14 +138,16 @@ void InterfaceBlockReference::visit(NodeVisitor &visitor) 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) @@ -369,7 +371,7 @@ InterfaceBlock::InterfaceBlock(): 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), @@ -465,34 +467,99 @@ Module::Module(): { } -string get_unused_variable_name(const Block &block, const string &base, const string &prefix_hint) +string get_unused_variable_name(const Block &block, const string &base) { string name = base; - bool prefixed = false; unsigned number = 1; - unsigned size_without_number = name.size(); - while(block.variables.count(name)) + unsigned base_size = name.size(); + while(1) { - if(!prefixed && !prefix_hint.empty()) - { - if(name.front()!='_') - name = "_"+name; - name = prefix_hint+name; - if(name.front()!='_') - name = "_"+name; - prefixed = true; - size_without_number = name.size(); - } + 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(&type1)) + { + const BasicTypeDeclaration *basic2 = dynamic_cast(&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(&type1)) + { + const ImageTypeDeclaration *image2 = dynamic_cast(&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(&type1)) + { + const StructDeclaration *strct2 = dynamic_cast(&type2); + if(!strct2) + return false; + + NodeList::const_iterator i = strct1->members.body.begin(); + NodeList::const_iterator j = strct2->members.body.begin(); + for(; (i!=strct1->members.body.end() && j!=strct2->members.body.end()); ++i, ++j) { - name.erase(size_without_number); - name += format("_%d", number); - ++number; + const VariableDeclaration *var1 = dynamic_cast(i->get()); + const VariableDeclaration *var2 = dynamic_cast(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::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i) + if(i->name==name) + return i->value; + return def_value; +} - return name; +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(index, 0x3F); + ++target.chain_len; } } // namespace SL