ptr = r_inline_result;
r_any_inlined = true;
}
+ r_inline_result = 0;
}
void FunctionInliner::visit(Block &block)
void FunctionInliner::visit(UnaryExpression &unary)
{
visit_and_inline(unary.expression);
- r_inline_result = 0;
}
void FunctionInliner::visit(BinaryExpression &binary)
{
visit_and_inline(binary.left);
visit_and_inline(binary.right);
- r_inline_result = 0;
}
void FunctionInliner::visit(MemberAccess &memacc)
{
visit_and_inline(memacc.left);
- r_inline_result = 0;
+}
+
+void FunctionInliner::visit(Swizzle &swizzle)
+{
+ visit_and_inline(swizzle.left);
}
void FunctionInliner::visit(FunctionCall &call)
inlined further. */
inlineable.erase(current_function);
}
- else
- r_inline_result = 0;
}
void FunctionInliner::visit(ExpressionStatement &expr)
{
if(var.init_expression)
visit_and_inline(var.init_expression);
- r_inline_result = 0;
}
void FunctionInliner::visit(FunctionDeclaration &func)
r_ref_info->inline_on_rhs = on_rhs;
}
}
+ r_ref_info = 0;
}
void ExpressionInliner::inline_expression(Expression &expr, RefPtr<Expression> &ptr, const Operator *outer_oper, const Operator *inner_oper, bool on_rhs)
void ExpressionInliner::visit(MemberAccess &memacc)
{
visit_and_record(memacc.left, memacc.oper, false);
- r_ref_info = 0;
r_oper = memacc.oper;
r_trivial = false;
}
+void ExpressionInliner::visit(Swizzle &swizzle)
+{
+ visit_and_record(swizzle.left, swizzle.oper, false);
+ r_oper = swizzle.oper;
+ r_trivial = false;
+}
+
void ExpressionInliner::visit(UnaryExpression &unary)
{
SetFlag set_target(mutating, mutating || unary.oper->token[1]=='+' || unary.oper->token[1]=='-');
visit_and_record(unary.expression, unary.oper, false);
- r_ref_info = 0;
r_oper = unary.oper;
r_trivial = false;
}
SetFlag clear_target(mutating, false);
visit_and_record(binary.right, binary.oper, true);
}
- r_ref_info = 0;
r_oper = binary.oper;
r_trivial = false;
}
r_oper = 0;
visit_and_record(assign.right, assign.oper, true);
- if(assign.target_declaration)
+ if(VariableDeclaration *target_var = dynamic_cast<VariableDeclaration *>(assign.target.declaration))
{
- map<VariableDeclaration *, ExpressionInfo>::iterator i = expressions.find(assign.target_declaration);
+ map<VariableDeclaration *, ExpressionInfo>::iterator i = expressions.find(target_var);
if(i!=expressions.end())
{
/* Self-referencing assignments can't be inlined without additional
}
}
- r_ref_info = 0;
r_oper = assign.oper;
r_trivial = false;
}
{
for(NodeArray<Expression>::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
visit_and_record(*i, 0, false);
- r_ref_info = 0;
r_oper = 0;
r_trivial = false;
}
return !unused_nodes.empty();
}
+void UnusedTypeRemover::visit(Literal &literal)
+{
+ unused_nodes.erase(literal.type);
+}
+
+void UnusedTypeRemover::visit(UnaryExpression &unary)
+{
+ unused_nodes.erase(unary.type);
+ TraversingVisitor::visit(unary);
+}
+
+void UnusedTypeRemover::visit(BinaryExpression &binary)
+{
+ unused_nodes.erase(binary.type);
+ TraversingVisitor::visit(binary);
+}
+
+void UnusedTypeRemover::visit(FunctionCall &call)
+{
+ unused_nodes.erase(call.type);
+ TraversingVisitor::visit(call);
+}
+
void UnusedTypeRemover::visit(BasicTypeDeclaration &type)
{
if(type.base_type)
void UnusedTypeRemover::visit(StructDeclaration &strct)
{
unused_nodes.insert(&strct);
+ TraversingVisitor::visit(strct);
}
void UnusedTypeRemover::visit(VariableDeclaration &var)
unused_nodes.erase(var.type_declaration);
}
+void UnusedTypeRemover::visit(InterfaceBlock &iface)
+{
+ unused_nodes.erase(iface.type_declaration);
+}
+
+void UnusedTypeRemover::visit(FunctionDeclaration &func)
+{
+ unused_nodes.erase(func.return_type_declaration);
+ TraversingVisitor::visit(func);
+}
+
UnusedVariableRemover::UnusedVariableRemover():
aggregate(0),
BlockVariableMap &global_variables = variables.back();
for(BlockVariableMap::iterator i=global_variables.begin(); i!=global_variables.end(); ++i)
{
+ string interface = i->first->interface;
+ bool linked = i->first->linked_declaration;
+ map<VariableDeclaration *, Node *>::iterator j = aggregates.find(i->first);
+ if(j!=aggregates.end())
+ if(InterfaceBlock *iface = dynamic_cast<InterfaceBlock *>(j->second))
+ {
+ interface = iface->interface;
+ linked = iface->linked_block;
+ }
+
/* Don't remove output variables which are used by the next stage or the
graphics API. */
- if(i->first->interface=="out" && (stage.type==Stage::FRAGMENT || i->first->linked_declaration || !i->first->name.compare(0, 3, "gl_")))
+ if(interface=="out" && (stage.type==Stage::FRAGMENT || linked || !i->first->name.compare(0, 3, "gl_")))
continue;
// Mark other unreferenced global variables as unused.
unused_nodes.erase(memacc.declaration);
}
+void UnusedVariableRemover::visit(Swizzle &swizzle)
+{
+ if(assignment_target)
+ r_assign_to_subfield = true;
+ TraversingVisitor::visit(swizzle);
+}
+
void UnusedVariableRemover::visit(UnaryExpression &unary)
{
TraversingVisitor::visit(unary);
r_assign_to_subfield = false;
r_side_effects = false;
TraversingVisitor::visit(expr);
- if(r_assignment && r_assignment->target_declaration)
- record_assignment(*r_assignment->target_declaration, expr, (r_assignment->self_referencing || r_assign_to_subfield));
+ if(r_assignment && r_assignment->target.declaration)
+ if(VariableDeclaration *target_var = dynamic_cast<VariableDeclaration *>(r_assignment->target.declaration))
+ record_assignment(*target_var, expr, (r_assignment->self_referencing || r_assign_to_subfield));
if(!r_side_effects)
unused_nodes.insert(&expr);
}
{
SetForScope<Node *> set(aggregate, &iface);
unused_nodes.insert(&iface);
- TraversingVisitor::visit(iface);
+ iface.struct_declaration->members.visit(*this);
}
void UnusedVariableRemover::visit(FunctionDeclaration &func)