+ unused_nodes.erase(memacc.declaration);
+}
+
+void ProgramCompiler::UnusedVariableLocator::visit(BinaryExpression &binary)
+{
+ if(binary.assignment)
+ {
+ assignment = true;
+ {
+ SetFlag set(record_target);
+ binary.left->visit(*this);
+ }
+ if(binary.oper!="=")
+ self_referencing = true;
+ binary.right->visit(*this);
+ }
+ else if(record_target && binary.oper=="[")
+ {
+ binary.left->visit(*this);
+ SetForScope<bool> set(record_target, false);
+ binary.right->visit(*this);
+ }
+ else
+ TraversingVisitor::visit(binary);
+}
+
+void ProgramCompiler::UnusedVariableLocator::visit(ExpressionStatement &expr)
+{
+ assignment = false;
+ assignment_target = 0;
+ indeterminate_target = false;
+ self_referencing = false;
+ TraversingVisitor::visit(expr);
+ if(assignment && assignment_target && !indeterminate_target)
+ {
+ Node *&assign = assignments[assignment_target];
+ if(self_referencing)
+ unused_nodes.erase(assign);
+ else if(assign)
+ unused_nodes.insert(assign);
+ assign = &expr;
+ if(assignment_target->interface=="out" && (stage->type==FRAGMENT || assignment_target->linked_declaration))
+ unused_nodes.erase(assignment_target);
+ else
+ unused_nodes.insert(&expr);
+ }
+ assignment = false;
+}
+
+void ProgramCompiler::UnusedVariableLocator::visit(StructDeclaration &strct)
+{
+ SetForScope<Node *> set(aggregate, &strct);
+ unused_nodes.insert(&strct);
+ TraversingVisitor::visit(strct);