void add_builtin_type(Stage &stage, const string &name, BasicTypeDeclaration::Kind kind, unsigned size, unsigned sign)
{
- RefPtr<BasicTypeDeclaration> type = new BasicTypeDeclaration;
+ unique_ptr<BasicTypeDeclaration> type = make_unique<BasicTypeDeclaration>();
type->source = BUILTIN_SOURCE;
type->name = name;
type->kind = kind;
type->size = size;
type->sign = sign;
- stage.content.body.push_back(type);
stage.types[name] = type.get();
+ stage.content.body.push_back(move(type));
}
Module *get_builtins_module()
module->source_map.merge_from(mod.source_map);
vector<Import *> imports;
- for(const RefPtr<Statement> &s: mod.shared.content.body)
- if(Import *imp = dynamic_cast<Import *>(s.get()))
+ for(const NodePtr<Statement> &s: mod.shared.content.body)
+ if(Import *imp = s.get_as<Import>())
imports.push_back(imp);
for(Import *i: imports)
import(mod_cache, i->module);
if(target->required_features.glsl_version<stage.required_features.glsl_version)
target->required_features.glsl_version = stage.required_features.glsl_version;
- for(const RefPtr<Statement> &s: stage.content.body)
- if(!dynamic_cast<Import *>(s.get()))
- target->content.body.push_back(s);
+ for(const NodePtr<Statement> &s: stage.content.body)
+ if(!s.get_as<Import>())
+ target->content.body.push_back(s.clone());
}
void Compiler::import(ModuleCache &mod_cache, const string &name)
void Compiler::inject_block(Block &target, const Block &source)
{
auto insert_point = target.body.begin();
- for(const RefPtr<Statement> &s: source.body)
- target.body.insert(insert_point, s->clone());
+ for(const NodePtr<Statement> &s: source.body)
+ target.body.insert(insert_point, s.clone());
}
} // namespace SL
begin_sub();
if(func.return_type_declaration)
append(format("Return type: %s %s", get_label(*func.return_type_declaration), format_type(func.return_type_declaration)));
- for(const RefPtr<VariableDeclaration> &p: func.parameters)
+ for(const NodePtr<VariableDeclaration> &p: func.parameters)
p->visit(*this);
last_branch();
if(func.definition==&func)
unplaced_variables.erase(write, unplaced_variables.end());
}
-void LocationAllocator::bind_uniform(RefPtr<Layout> &layout, const string &name, unsigned range)
+void LocationAllocator::bind_uniform(NodePtr<Layout> &layout, const string &name, unsigned range)
{
auto i = uniforms.find(name);
}
}
-bool LocationAllocator::visit_uniform(const string &name, RefPtr<Layout> &layout)
+bool LocationAllocator::visit_uniform(const string &name, NodePtr<Layout> &layout)
{
int desc_set = get_layout_value(layout.get(), "set");
int bind_point = get_layout_value(layout.get(), "binding");
s->content.visit(*this);
}
-NodePtr<Statement> DepthRangeConverter::create_conversion_statement()
+unique_ptr<Statement> DepthRangeConverter::create_conversion_statement()
{
- VariableReference *position = new VariableReference;
+ NodePtr<VariableReference> position = make_unique<VariableReference>();
position->name = "gl_Position";
- MemberAccess *z = new MemberAccess;
- z->left = position;
+ NodePtr<MemberAccess> z = make_unique<MemberAccess>();
+ z->left = position.clone();
z->member = "z";
- Literal *scale = new Literal;
+ unique_ptr<Literal> scale = make_unique<Literal>();
scale->token = "2.0";
scale->value = 2.0f;
- BinaryExpression *multiply = new BinaryExpression;
+ unique_ptr<BinaryExpression> multiply = make_unique<BinaryExpression>();
multiply->oper = &Operator::get_operator("*", Operator::BINARY);
- multiply->left = z;
- multiply->right = scale;
+ multiply->left = z.clone();
+ multiply->right = move(scale);
- MemberAccess *w = new MemberAccess;
- w->left = position->clone();
+ unique_ptr<MemberAccess> w = make_unique<MemberAccess>();
+ w->left = move(position);
w->member = "w";
- BinaryExpression *subtract = new BinaryExpression;
+ unique_ptr<BinaryExpression> subtract = make_unique<BinaryExpression>();
subtract->oper = &Operator::get_operator("-", Operator::BINARY);
- subtract->left = multiply;
- subtract->right = w;
+ subtract->left = move(multiply);
+ subtract->right = move(w);
- Assignment *assign = new Assignment;
+ unique_ptr<Assignment> assign = make_unique<Assignment>();
assign->oper = &Operator::get_operator("=", Operator::BINARY);
- assign->left = z->clone();
- assign->right = subtract;
+ assign->left = move(z);
+ assign->right = move(subtract);
- ExpressionStatement *statement = new ExpressionStatement;
- statement->expression = assign;
+ unique_ptr<ExpressionStatement> statement = make_unique<ExpressionStatement>();
+ statement->expression = move(assign);
return statement;
}
(*i)->visit(*this);
if(r_emitvertex && !r_position_z_assigned)
{
- block.body.insert_nocopy(i, create_conversion_statement());
+ block.body.insert(i, create_conversion_statement());
r_position_z_assigned = true;
}
}
if(func.definition==&func && func.name=="main" && r_position_assigned && !r_position_z_assigned)
{
- func.body.body.push_back_nocopy(create_conversion_statement());
+ func.body.body.push_back(create_conversion_statement());
r_position_z_assigned = true;
}
}
if(!have_default.count(type->name))
{
- Precision *prec = new Precision;
+ unique_ptr<Precision> prec = make_unique<Precision>();
prec->precision = default_prec;
prec->type = type->name;
- stage->content.body.insert(insert_point, prec);
+ stage->content.body.insert(insert_point, move(prec));
have_default.insert(type->name);
}
}
}
-void StructuralFeatureConverter::visit(RefPtr<Expression> &expr)
+void StructuralFeatureConverter::visit(NodePtr<Expression> &expr)
{
r_replaced_reference = nullptr;
expr->visit(*this);
if(r_replaced_reference)
- expr = r_replaced_reference;
+ expr = move(r_replaced_reference);
r_replaced_reference = nullptr;
}
visit(memacc.left);
if(r_flattened_interface)
{
- VariableReference *var = new VariableReference;
+ unique_ptr<VariableReference> var = make_unique<VariableReference>();
var->name = memacc.member;
- r_replaced_reference = var;
+ r_replaced_reference = move(var);
}
}
unsupported("ARB_uniform_buffer_object required for interface block instances");
else
{
- for(const RefPtr<Statement> &s: var.block_declaration->members.body)
+ for(const NodePtr<Statement> &s: var.block_declaration->members.body)
if(VariableDeclaration *mem = dynamic_cast<VariableDeclaration *>(s.get()))
mem->interface = var.interface;
stage->content.body.splice(uniform_insert_point, var.block_declaration->members.body);
void apply(Stage &);
void allocate_locations(const std::string &);
- void bind_uniform(RefPtr<Layout> &, const std::string &, unsigned);
+ void bind_uniform(NodePtr<Layout> &, const std::string &, unsigned);
- bool visit_uniform(const std::string &, RefPtr<Layout> &);
+ bool visit_uniform(const std::string &, NodePtr<Layout> &);
void visit(VariableDeclaration &) override;
void visit(FunctionDeclaration &) override { }
};
void apply(Module &, const Features &);
private:
- NodePtr<Statement> create_conversion_statement();
+ std::unique_ptr<Statement> create_conversion_statement();
void visit(Block &) override;
void visit(VariableReference &) override;
VariableDeclaration *frag_out = nullptr;
NodeList<Statement>::iterator uniform_insert_point;
std::set<Node *> nodes_to_remove;
- RefPtr<Expression> r_replaced_reference;
+ std::unique_ptr<Expression> r_replaced_reference;
bool r_flattened_interface = false;
public:
void apply() override;
void visit(Block &) override;
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
bool supports_stage(Stage::Type) const;
bool supports_unified_interface_syntax() const;
void visit(VariableReference &) override;
if(stage->type==Stage::GEOMETRY && var.interface=="out" && var.array)
return nullptr;
- VariableDeclaration* iface_var = new VariableDeclaration;
+ unique_ptr<VariableDeclaration> iface_var = make_unique<VariableDeclaration>();
iface_var->sampling = var.sampling;
if(stage->type==Stage::FRAGMENT && iface=="in")
if(BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(var.type_declaration))
else
iface_var->array = var.array;
if(iface_var->array)
- iface_var->array_size = var.array_size;
+ iface_var->array_size = var.array_size.clone();
if(iface=="in")
{
- iface_var->layout = var.layout;
+ iface_var->layout = var.layout.clone();
iface_var->linked_declaration = &var;
- var.linked_declaration = iface_var;
+ var.linked_declaration = iface_var.get();
}
if(var.block_declaration)
{
- StructDeclaration *iface_type = var.block_declaration->clone();
+ unique_ptr<StructDeclaration> iface_type(var.block_declaration->clone());
iface_type->name = format("_%s_%s", iface, var.block_declaration->block_name);
- iface_target_block->body.insert(iface_insert_point, iface_type);
iface_var->type = iface_type->name;
if(name.empty())
iface_var->name = format("%s %s", iface, var.block_declaration->block_name);
- stage->interface_blocks.insert(make_pair("in "+var.block_declaration->block_name, iface_var));
+ stage->interface_blocks.insert(make_pair("in "+var.block_declaration->block_name, iface_var.get()));
if(!name.empty())
- stage->interface_blocks.insert(make_pair(name, iface_var));
+ stage->interface_blocks.insert(make_pair(name, iface_var.get()));
+
+ iface_target_block->body.insert(iface_insert_point, move(iface_type));
}
- iface_target_block->body.insert(iface_insert_point, iface_var);
- iface_target_block->variables.insert(make_pair(name, iface_var));
+ iface_target_block->variables.insert(make_pair(name, iface_var.get()));
if(iface_target_block==&stage->content && iface=="in")
- declared_inputs.push_back(iface_var);
+ declared_inputs.push_back(iface_var.get());
+
+ VariableDeclaration *result = iface_var.get();
+ iface_target_block->body.insert(iface_insert_point, move(iface_var));
- return iface_var;
+ return result;
}
-ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, Expression *right)
+ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, unique_ptr<Expression> right)
{
- Assignment *assign = new Assignment;
+ unique_ptr<Assignment> assign = make_unique<Assignment>();
string::size_type dot = left.find('.');
- VariableReference *ref = new VariableReference;
+ unique_ptr<VariableReference> ref = make_unique<VariableReference>();
ref->name = left.substr(0, dot);
- assign->left = ref;
+ assign->left = move(ref);
while(dot!=string::npos)
{
string::size_type start = dot+1;
dot = left.find('.', start);
- MemberAccess *memacc = new MemberAccess;
- memacc->left = assign->left;
+ unique_ptr<MemberAccess> memacc = make_unique<MemberAccess>();
+ memacc->left = move(assign->left);
memacc->member = left.substr(start, dot-start);
- assign->left = memacc;
+ assign->left = move(memacc);
}
assign->oper = &Operator::get_operator("=", Operator::BINARY);
- assign->right = right;
+ assign->right = move(right);
- ExpressionStatement *stmt = new ExpressionStatement;
- stmt->expression = assign;
- current_block->body.insert(assignment_insert_point, stmt);
- stmt->visit(*this);
+ unique_ptr<ExpressionStatement> stmt = make_unique<ExpressionStatement>();
+ stmt->expression = move(assign);
+ ExpressionStatement *result = stmt.get();
+ current_block->body.insert(assignment_insert_point, move(stmt));
+ result->visit(*this);
- return *stmt;
+ return *result;
}
void InterfaceGenerator::visit(VariableReference &var)
nodes_to_remove.insert(&var);
if(var.init_expression)
{
- ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone());
+ ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression.clone());
stmt.source = var.source;
stmt.line = var.line;
return;
{
/* Special case for geometry shader: copy gl_Position from input to
output. */
- VariableReference *ref = new VariableReference;
+ unique_ptr<VariableReference> ref = make_unique<VariableReference>();
ref->name = "gl_in";
- BinaryExpression *subscript = new BinaryExpression;
- subscript->left = ref;
+ unique_ptr<BinaryExpression> subscript = make_unique<BinaryExpression>();
+ subscript->left = move(ref);
subscript->oper = &Operator::get_operator("[", Operator::BINARY);
- subscript->right = pass.subscript;
+ subscript->right = pass.subscript.clone();
- MemberAccess *memacc = new MemberAccess;
- memacc->left = subscript;
+ unique_ptr<MemberAccess> memacc = make_unique<MemberAccess>();
+ memacc->left = move(subscript);
memacc->member = "gl_Position";
- insert_assignment("out gl_PerVertex.gl_Position", memacc);
+ insert_assignment("out gl_PerVertex.gl_Position", move(memacc));
}
for(VariableDeclaration *v: pass_vars)
string out_name = change_prefix(v->name, out_prefix);
generate_interface(*v, "out", out_name);
- VariableReference *ref = new VariableReference;
+ unique_ptr<VariableReference> ref = make_unique<VariableReference>();
ref->name = v->name;
if(pass.subscript)
{
- BinaryExpression *subscript = new BinaryExpression;
- subscript->left = ref;
+ unique_ptr<BinaryExpression> subscript = make_unique<BinaryExpression>();
+ subscript->left = move(ref);
subscript->oper = &Operator::get_operator("[", Operator::BINARY);
- subscript->right = pass.subscript;
- insert_assignment(out_name, subscript);
+ subscript->right = pass.subscript.clone();
+ insert_assignment(out_name, move(subscript));
}
else
- insert_assignment(out_name, ref);
+ insert_assignment(out_name, move(ref));
}
nodes_to_remove.insert(&pass);
if(size>0)
{
- Literal *literal_size = new Literal;
+ unique_ptr<Literal> literal_size = make_unique<Literal>();
literal_size->token = lexical_cast<string>(size);
literal_size->value = size;
- kvp.first->array_size = literal_size;
+ kvp.first->array_size = move(literal_size);
}
}
}
std::string change_prefix(const std::string &, const std::string &) const;
void visit(Block &) override;
VariableDeclaration *generate_interface(VariableDeclaration &, const std::string &, const std::string &);
- ExpressionStatement &insert_assignment(const std::string &, Expression *);
+ ExpressionStatement &insert_assignment(const std::string &, std::unique_ptr<Expression>);
void visit(VariableReference &) override;
void visit(VariableDeclaration &) override;
void visit(FunctionDeclaration &) override;
auto i = values->find(var.name);
if(i!=values->end())
{
- RefPtr<Literal> literal = new Literal;
+ unique_ptr<Literal> literal = make_unique<Literal>();
if(var.type=="bool")
{
literal->token = (i->second ? "true" : "false");
literal->token = lexical_cast<string>(i->second);
literal->value = i->second;
}
- var.init_expression = literal;
+ var.init_expression = move(literal);
}
}
}
void InlineableFunctionLocator::visit(FunctionDeclaration &func)
{
bool has_out_params = any_of(func.parameters.begin(), func.parameters.end(),
- [](const RefPtr<VariableDeclaration> &p){ return p->interface=="out"; });
+ [](const NodePtr<VariableDeclaration> &p){ return p->interface=="out"; });
unsigned &count = refcounts[func.definition];
if((count<=1 || func.source==BUILTIN_SOURCE) && !has_out_params)
staging_block.parent = &tgt_blk;
staging_block.variables.clear();
- vector<RefPtr<VariableDeclaration> > params;
+ vector<VariableDeclaration *> params;
params.reserve(source_func->parameters.size());
- for(const RefPtr<VariableDeclaration> &p: source_func->parameters)
+ for(const NodePtr<VariableDeclaration> &p: source_func->parameters)
{
- RefPtr<VariableDeclaration> var = p->clone();
+ NodePtr<VariableDeclaration> var = p.clone();
var->interface.clear();
SetForScope<Pass> set_pass(pass, RENAME);
var->visit(*this);
- staging_block.body.push_back_nocopy(var);
- params.push_back(var);
+ params.push_back(var.get());
+ staging_block.body.push_back(move(var));
}
- for(const RefPtr<Statement> &s: source_func->body.body)
+ for(const NodePtr<Statement> &s: source_func->body.body)
{
r_inlined_statement = nullptr;
s->visit(*this);
if(!r_inlined_statement)
- r_inlined_statement = s->clone();
+ r_inlined_statement = s.clone();
SetForScope<Pass> set_pass(pass, RENAME);
r_inlined_statement->visit(*this);
- staging_block.body.push_back_nocopy(r_inlined_statement);
+ staging_block.body.push_back(move(r_inlined_statement));
}
/* Now collect names from the staging block. Local variables that would
// Put the argument expressions in place after all renaming has been done.
for(unsigned i=0; i<source_func->parameters.size(); ++i)
- params[i]->init_expression = call.arguments[i]->clone();
+ params[i]->init_expression = call.arguments[i].clone();
tgt_blk.body.splice(ins_pt, staging_block.body);
{
// Create a new variable to hold the return value of the inlined function.
r_result_name = get_unused_variable_name(staging_block, "_return");
- RefPtr<VariableDeclaration> var = new VariableDeclaration;
+ unique_ptr<VariableDeclaration> var = make_unique<VariableDeclaration>();
var->source = ret.source;
var->line = ret.line;
var->type = source_func->return_type;
var->name = r_result_name;
- var->init_expression = ret.expression->clone();
- r_inlined_statement = var;
+ var->init_expression = ret.expression.clone();
+ r_inlined_statement = move(var);
}
}
return r_any_inlined;
}
-void FunctionInliner::visit(RefPtr<Expression> &ptr)
+void FunctionInliner::visit(NodePtr<Expression> &ptr)
{
r_inline_result = nullptr;
ptr->visit(*this);
if(r_inline_result)
{
- ptr = r_inline_result;
+ ptr = move(r_inline_result);
r_any_inlined = true;
}
r_inline_result = nullptr;
if(result_name.empty())
result_name = "_msp_unused_from_inline";
- RefPtr<VariableReference> ref = new VariableReference;
+ unique_ptr<VariableReference> ref = make_unique<VariableReference>();
ref->name = result_name;
- r_inline_result = ref;
+ r_inline_result = move(ref);
/* Inlined variables need to be resolved before this function can be
inlined further. */
for(ExpressionUse &u: e.uses)
if(!u.blocked)
{
- *u.reference = e.expression->clone();
+ *u.reference = unique_ptr<Expression>(e.expression->clone());
if(u.containing_expr)
u.containing_expr->expression = 0;
any_inlined = true;
return any_inlined;
}
-void ExpressionInliner::visit(RefPtr<Expression> &expr)
+void ExpressionInliner::visit(NodePtr<Expression> &expr)
{
r_ref_info = nullptr;
expr->visit(*this);
info->target = assign.target;
// Self-referencing assignments can't be inlined without additional work.
if(!assign.self_referencing)
- info->expression = assign.right;
+ info->expression = assign.right.get();
info->assign_scope = current_block;
}
/* Assume variables declared in an iteration initialization statement
will have their values change throughout the iteration. */
if(!iteration_init)
- info->expression = var.init_expression;
+ info->expression = var.init_expression.get();
info->assign_scope = current_block;
}
name = format("%s_%s", kvp.second.declaration->name, m.declaration->name);
else
name = format("%s_%d", kvp.second.declaration->name, m.index);
+ name = get_unused_variable_name(*kvp.second.decl_scope, name);
- VariableDeclaration *var = new VariableDeclaration;
+ unique_ptr<VariableDeclaration> var = make_unique<VariableDeclaration>();
var->source = kvp.first->source;
var->line = kvp.first->line;
- var->name = get_unused_variable_name(*kvp.second.decl_scope, name);
+ var->name = name;
/* XXX This is kind of brittle and depends on the array declaration's
textual type not having brackets in it. */
var->type = (m.declaration ? m.declaration : kvp.second.declaration)->type;
if(m.initializer)
var->init_expression = m.initializer->clone();
- kvp.second.decl_scope->body.insert(kvp.second.insert_point, var);
+ kvp.second.decl_scope->body.insert(kvp.second.insert_point, move(var));
- for(RefPtr<Expression> *r: m.references)
+ for(NodePtr<Expression> *r: m.references)
{
- VariableReference *ref = new VariableReference;
- ref->name = var->name;
- *r = ref;
+ unique_ptr<VariableReference> ref = make_unique<VariableReference>();
+ ref->name = name;
+ *r = move(ref);
}
any_dismantled = true;
}
}
-void AggregateDismantler::visit(RefPtr<Expression> &expr)
+void AggregateDismantler::visit(NodePtr<Expression> &expr)
{
r_aggregate_ref = nullptr;
expr->visit(*this);
}
}
-void AggregateDismantler::visit_composite(RefPtr<Expression> &expr)
+void AggregateDismantler::visit_composite(NodePtr<Expression> &expr)
{
if(!composite_reference)
r_reference = Assignment::Target();
}
unsigned index = 0x3F;
- if(Literal *literal_subscript = dynamic_cast<Literal *>(binary.right.get()))
+ if(Literal *literal_subscript = binary.right.get_as<Literal>())
if(literal_subscript->value.has_type<int>())
index = literal_subscript->value.value<int>();
add_to_chain(r_reference, Assignment::Target::ARRAY, index);
{
if(const StructDeclaration *strct = dynamic_cast<const StructDeclaration *>(var.type_declaration))
{
- const FunctionCall *init_call = dynamic_cast<const FunctionCall *>(var.init_expression.get());
+ const FunctionCall *init_call = var.init_expression.get_as<const FunctionCall>();
if((init_call && init_call->constructor) || !var.init_expression)
{
aggre.insert_point = insert_point;
unsigned i = 0;
- for(const RefPtr<Statement> &s: strct->members.body)
+ for(const NodePtr<Statement> &s: strct->members.body)
{
- if(const VariableDeclaration *mem_decl = dynamic_cast<const VariableDeclaration *>(s.get()))
+ if(const VariableDeclaration *mem_decl = s.get_as<const VariableDeclaration>())
{
AggregateMember &member = aggre.members.emplace_back();
member.declaration = mem_decl;
member.index = i;
if(init_call)
- member.initializer = init_call->arguments[i];
+ member.initializer = &init_call->arguments[i];
}
++i;
}
}
}
- else if(const Literal *literal_size = dynamic_cast<const Literal *>(var.array_size.get()))
+ else if(const Literal *literal_size = var.array_size.get_as<const Literal>())
{
if(literal_size->value.has_type<int>())
{
r_literal = literal;
}
-void ConstantFolder::visit(RefPtr<Expression> &expr)
+void ConstantFolder::visit(NodePtr<Expression> &expr)
{
r_constant_value = Variant();
r_constant = false;
if(!r_constant || r_literal || r_uses_iter_var)
return;
- RefPtr<Literal> literal = new Literal;
+ unique_ptr<Literal> literal = make_unique<Literal>();
if(r_constant_value.has_type<bool>())
literal->token = (r_constant_value.value<bool>() ? "true" : "false");
else if(r_constant_value.has_type<int>())
return;
}
literal->value = r_constant_value;
- expr = literal;
+ expr = move(literal);
r_any_folded = true;
}
visit(iter.condition);
if(r_constant && r_constant_value.has_type<bool>() && !r_constant_value.value<bool>())
{
- RefPtr<Literal> literal = new Literal;
+ unique_ptr<Literal> literal = make_unique<Literal>();
literal->token = "false";
literal->value = r_constant_value;
- iter.condition = literal;
+ iter.condition = move(literal);
}
}
iteration_var = nullptr;
}
}
-void ConstantConditionEliminator::visit(RefPtr<Expression> &expr)
+void ConstantConditionEliminator::visit(NodePtr<Expression> &expr)
{
r_ternary_result = nullptr;
expr->visit(*this);
if(r_ternary_result)
- expr = r_ternary_result;
+ expr = move(*r_ternary_result);
r_ternary_result = nullptr;
}
void ConstantConditionEliminator::visit(UnaryExpression &unary)
{
if(unary.oper->token[1]=='+' || unary.oper->token[1]=='-')
- if(const VariableReference *var = dynamic_cast<const VariableReference *>(unary.expression.get()))
+ if(const VariableReference *var = unary.expression.get_as<const VariableReference>())
{
auto i = current_block->variables.find(var->name);
r_external_side_effects = (i==current_block->variables.end() || i->second!=var->declaration);
{
ConstantStatus result = check_constant_condition(*ternary.condition);
if(result!=NOT_CONSTANT)
- r_ternary_result = (result==CONSTANT_TRUE ? ternary.true_expr : ternary.false_expr);
+ r_ternary_result = (result==CONSTANT_TRUE ? &ternary.true_expr : &ternary.false_expr);
else
r_ternary_result = nullptr;
}
return !unused_nodes.empty();
}
-void UnusedTypeRemover::visit(RefPtr<Expression> &expr)
+void UnusedTypeRemover::visit(NodePtr<Expression> &expr)
{
unused_nodes.erase(expr->type);
TraversingVisitor::visit(expr);
/* Always treat function parameters as referenced. Removing unused
parameters is not currently supported. */
- for(const RefPtr<VariableDeclaration> &p: func.parameters)
+ for(const NodePtr<VariableDeclaration> &p: func.parameters)
{
auto j = variables.find(p.get());
if(j!=variables.end())
FunctionDeclaration *source_func = nullptr;
Block staging_block;
Pass pass = REFERENCED;
- RefPtr<Statement> r_inlined_statement;
+ NodePtr<Statement> r_inlined_statement;
std::set<Node *> dependencies;
std::set<std::string> referenced_names;
std::string r_result_name;
std::set<FunctionDeclaration *> inlineable;
FunctionDeclaration *current_function = nullptr;
NodeList<Statement>::iterator insert_point;
- RefPtr<Expression> r_inline_result;
+ std::unique_ptr<Expression> r_inline_result;
bool r_any_inlined = false;
bool r_inlined_here = false;
bool apply(Stage &);
private:
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
void visit(Block &) override;
void visit(FunctionCall &) override;
void visit(FunctionDeclaration &) override;
struct ExpressionUse
{
- RefPtr<Expression> *reference = nullptr;
+ NodePtr<Expression> *reference = nullptr;
Block *ref_scope = nullptr;
ExpressionInfo *containing_expr = nullptr;
bool blocked = false;
struct ExpressionInfo
{
Assignment::Target target;
- RefPtr<Expression> expression;
+ const Expression *expression = nullptr;
Block *assign_scope = nullptr;
std::vector<ExpressionUse> uses;
bool trivial = false;
bool apply(Stage &);
private:
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
void visit(VariableReference &) override;
void visit(MemberAccess &) override;
void visit(Swizzle &) override;
{
const VariableDeclaration *declaration = nullptr;
unsigned index = 0;
- RefPtr<Expression> initializer;
- std::vector<RefPtr<Expression> *> references;
+ const NodePtr<Expression> *initializer;
+ std::vector<NodePtr<Expression> *> references;
};
struct Aggregate
private:
void visit(Block &) override;
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
void visit(VariableReference &) override;
- void visit_composite(RefPtr<Expression> &);
+ void visit_composite(NodePtr<Expression> &);
void visit(MemberAccess &) override;
void visit(BinaryExpression &) override;
void visit(StructDeclaration &) override { }
void convert_to_result(const Variant &);
void set_result(const Variant &, bool = false);
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
void visit(Literal &) override;
void visit(VariableReference &) override;
void visit(MemberAccess &) override;
NodeList<Statement>::iterator insert_point;
std::set<Node *> nodes_to_remove;
- RefPtr<Expression> r_ternary_result;
+ NodePtr<Expression> *r_ternary_result;
bool r_external_side_effects = false;
public:
ConstantStatus check_constant_condition(const Expression &);
void visit(Block &) override;
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
void visit(UnaryExpression &) override;
void visit(Assignment &) override;
void visit(TernaryExpression &) override;
bool apply(Stage &);
private:
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
void visit(BasicTypeDeclaration &) override;
void visit(ImageTypeDeclaration &) override;
void visit(StructDeclaration &) override;
SetForScope<unsigned> set(indent, indent+(indent>0 || use_braces));
string spaces(indent*2, ' ');
bool first = true;
- for(const RefPtr<Statement> &s: block.body)
+ for(const NodePtr<Statement> &s: block.body)
{
if(omit_builtin && s->source<=BUILTIN_SOURCE)
continue;
tokenizer.begin(source, name);
allow_stage_change = true;
while(!tokenizer.peek_token().empty())
- if(RefPtr<Statement> statement = parse_with_recovery(&Parser::parse_global_declaration))
+ if(unique_ptr<Statement> statement = parse_with_recovery(&Parser::parse_global_declaration))
{
- cur_stage->content.body.push_back(statement);
+ cur_stage->content.body.push_back(move(statement));
if(next_global_declaration)
- {
- cur_stage->content.body.push_back(next_global_declaration);
- next_global_declaration = nullptr;
- }
+ cur_stage->content.body.push_back(move(next_global_declaration));
}
if(!errors.empty())
}
template<typename T>
-RefPtr<T> Parser::create_node()
+unique_ptr<T> Parser::create_node()
{
- RefPtr<T> node = new T;
+ unique_ptr<T> node = make_unique<T>();
node->source = source_index;
node->line = tokenizer.get_location().line;
return node;
}
template<typename T>
-RefPtr<T> Parser::parse_with_recovery(RefPtr<T> (Parser::*parse_func)())
+unique_ptr<T> Parser::parse_with_recovery(unique_ptr<T> (Parser::*parse_func)())
{
tokenizer.clear_progress_mark();
try
}
}
- return RefPtr<T>();
+ return unique_ptr<T>();
}
-RefPtr<Statement> Parser::parse_global_declaration()
+unique_ptr<Statement> Parser::parse_global_declaration()
{
string token = tokenizer.peek_token();
SetFlag disallow(allow_stage_change, false);
return parse_precision();
else if(token=="layout")
{
- RefPtr<Layout> layout = parse_layout();
+ unique_ptr<Layout> layout = parse_layout();
token = tokenizer.peek_token();
if(is_interface_qualifier(token) && tokenizer.peek_token(1)==";")
{
- RefPtr<InterfaceLayout> iface_lo = create_node<InterfaceLayout>();
+ unique_ptr<InterfaceLayout> iface_lo = create_node<InterfaceLayout>();
iface_lo->layout.source = layout->source;
iface_lo->layout.line = layout->line;
iface_lo->layout.qualifiers = layout->qualifiers;
}
else if(is_interface_qualifier(token) && tokenizer.peek_token(2)=="{")
{
- RefPtr<StructDeclaration> iface_strct = parse_interface_block();
- VariableDeclaration *iface_var = iface_strct->block_declaration;
- iface_var->layout = layout;
- next_global_declaration = iface_var;
+ unique_ptr<StructDeclaration> iface_strct = parse_interface_block();
+ unique_ptr<VariableDeclaration> iface_var = unique_ptr<VariableDeclaration>(iface_strct->block_declaration);
+ iface_var->layout = move(layout);
+ next_global_declaration = move(iface_var);
return iface_strct;
}
else
{
- RefPtr<VariableDeclaration> var = parse_variable_declaration();
- var->layout = layout;
+ unique_ptr<VariableDeclaration> var = parse_variable_declaration();
+ var->layout = move(layout);
return var;
}
}
}
else
{
- RefPtr<StructDeclaration> iface_strct = parse_interface_block();
- next_global_declaration = iface_strct->block_declaration;
+ unique_ptr<StructDeclaration> iface_strct = parse_interface_block();
+ next_global_declaration = unique_ptr<Statement>(iface_strct->block_declaration);
return iface_strct;
}
}
throw parse_error(tokenizer.get_location(), token, "a global declaration");
}
-RefPtr<Statement> Parser::parse_statement()
+unique_ptr<Statement> Parser::parse_statement()
{
string token = tokenizer.peek_token();
if(token=="if")
return parse_return();
else if(token=="break" || token=="continue" || token=="discard")
{
- RefPtr<Jump> jump = create_node<Jump>();
+ unique_ptr<Jump> jump = create_node<Jump>();
jump->keyword = tokenizer.parse_token();
tokenizer.expect(";");
}
else if(!token.empty())
{
- RefPtr<ExpressionStatement> expr = create_node<ExpressionStatement>();
+ unique_ptr<ExpressionStatement> expr = create_node<ExpressionStatement>();
expr->expression = parse_expression();
tokenizer.expect(";");
throw parse_error(tokenizer.get_location(), token, "a statement");
}
-RefPtr<Import> Parser::parse_import()
+unique_ptr<Import> Parser::parse_import()
{
if(cur_stage->type!=Stage::SHARED)
throw invalid_shader_source(tokenizer.get_location(), "Imports are only allowed in the shared section");
tokenizer.expect("import");
- RefPtr<Import> import = create_node<Import>();
+ unique_ptr<Import> import = create_node<Import>();
import->module = expect_identifier();
tokenizer.expect(";");
return import;
}
-RefPtr<Precision> Parser::parse_precision()
+unique_ptr<Precision> Parser::parse_precision()
{
tokenizer.expect("precision");
- RefPtr<Precision> precision = create_node<Precision>();
+ unique_ptr<Precision> precision = create_node<Precision>();
precision->precision = tokenizer.parse_token();
if(!is_precision_qualifier(precision->precision))
return precision;
}
-RefPtr<Layout> Parser::parse_layout()
+unique_ptr<Layout> Parser::parse_layout()
{
tokenizer.expect("layout");
tokenizer.expect("(");
- RefPtr<Layout> layout = create_node<Layout>();
+ unique_ptr<Layout> layout = create_node<Layout>();
while(1)
{
string token = tokenizer.parse_token();
}
template<typename T>
-void Parser::parse_block(Block &block, bool require_braces, RefPtr<T> (Parser::*parse_content)())
+void Parser::parse_block(Block &block, bool require_braces, unique_ptr<T> (Parser::*parse_content)())
{
bool have_braces = (require_braces || tokenizer.peek_token()=="{");
if(have_braces)
if(have_braces)
{
while(tokenizer.peek_token()!="}")
- if(RefPtr<Statement> node = parse_with_recovery(parse_content))
- block.body.push_back(node);
+ if(unique_ptr<Statement> node = parse_with_recovery(parse_content))
+ block.body.push_back(move(node));
}
else
block.body.push_back((this->*parse_content)());
tokenizer.expect("}");
}
-RefPtr<Expression> Parser::parse_expression(const Operator *outer_oper)
+unique_ptr<Expression> Parser::parse_expression(const Operator *outer_oper)
{
unsigned outer_precedence = (outer_oper ? outer_oper->precedence+(outer_oper->assoc==Operator::RIGHT_TO_LEFT) : 20);
- RefPtr<Expression> left;
+ unique_ptr<Expression> left;
VariableReference *left_var = nullptr;
while(1)
{
}
else if(token==".")
{
- RefPtr<MemberAccess> memacc = create_node<MemberAccess>();
- memacc->left = left;
+ unique_ptr<MemberAccess> memacc = create_node<MemberAccess>();
+ memacc->left = move(left);
memacc->oper = oper;
tokenizer.parse_token();
memacc->member = expect_identifier();
- left = memacc;
+ left = move(memacc);
}
else if(oper && oper->type==Operator::POSTFIX)
{
- RefPtr<UnaryExpression> unary = create_node<UnaryExpression>();
+ unique_ptr<UnaryExpression> unary = create_node<UnaryExpression>();
unary->oper = oper;
tokenizer.parse_token();
- unary->expression = left;
- left = unary;
+ unary->expression = move(left);
+ left = move(unary);
}
else if(oper && oper->type==Operator::BINARY)
- left = parse_binary(left, *oper);
+ left = parse_binary(move(left), *oper);
else if(oper && oper->type==Operator::TERNARY)
- left = parse_ternary(left, *oper);
+ left = parse_ternary(move(left), *oper);
else
throw parse_error(tokenizer.get_location(), token, "an operator");
left_var = nullptr;
left = parse_literal();
else if(is_identifier(token))
{
- RefPtr<VariableReference> var = create_node<VariableReference>();
+ unique_ptr<VariableReference> var = create_node<VariableReference>();
var->name = expect_identifier();
- left = var;
left_var = var.get();
+ left = move(var);
}
else if(oper && oper->type==Operator::PREFIX)
{
- RefPtr<UnaryExpression> unary = create_node<UnaryExpression>();
+ unique_ptr<UnaryExpression> unary = create_node<UnaryExpression>();
unary->oper = oper;
tokenizer.parse_token();
unary->expression = parse_expression(oper);
- left = unary;
+ left = move(unary);
}
else
throw parse_error(tokenizer.get_location(), token, "an expression");
}
}
-RefPtr<Literal> Parser::parse_literal()
+unique_ptr<Literal> Parser::parse_literal()
{
- RefPtr<Literal> literal = create_node<Literal>();
+ unique_ptr<Literal> literal = create_node<Literal>();
literal->token = tokenizer.parse_token();
if(isdigit(literal->token[0]))
{
return literal;
}
-RefPtr<BinaryExpression> Parser::parse_binary(const RefPtr<Expression> &left, const Operator &oper)
+unique_ptr<BinaryExpression> Parser::parse_binary(unique_ptr<Expression> left, const Operator &oper)
{
- RefPtr<BinaryExpression> binary = (oper.precedence==16 ?
- static_cast<RefPtr<BinaryExpression> >(create_node<Assignment>()) : create_node<BinaryExpression>());
- binary->left = left;
+ unique_ptr<BinaryExpression> binary = (oper.precedence==16 ?
+ static_cast<unique_ptr<BinaryExpression> >(create_node<Assignment>()) : create_node<BinaryExpression>());
+ binary->left = move(left);
binary->oper = &oper;
tokenizer.expect(oper.token);
if(oper.token2[0])
return binary;
}
-RefPtr<TernaryExpression> Parser::parse_ternary(const RefPtr<Expression> &cond, const Operator &oper)
+unique_ptr<TernaryExpression> Parser::parse_ternary(unique_ptr<Expression> cond, const Operator &oper)
{
- RefPtr<TernaryExpression> ternary = create_node<TernaryExpression>();
- ternary->condition = cond;
+ unique_ptr<TernaryExpression> ternary = create_node<TernaryExpression>();
+ ternary->condition = move(cond);
ternary->oper = &oper;
tokenizer.expect("?");
ternary->true_expr = parse_expression(&oper);
return ternary;
}
-RefPtr<FunctionCall> Parser::parse_function_call(const VariableReference &var)
+unique_ptr<FunctionCall> Parser::parse_function_call(const VariableReference &var)
{
- RefPtr<FunctionCall> call = create_node<FunctionCall>();
+ unique_ptr<FunctionCall> call = create_node<FunctionCall>();
call->name = var.name;
call->oper = &Operator::get_operator("(", Operator::POSTFIX);
tokenizer.expect("(");
stage_types.insert(type.name);
}
-RefPtr<TypeDeclaration> Parser::parse_type_declaration()
+unique_ptr<TypeDeclaration> Parser::parse_type_declaration()
{
tokenizer.expect("typedef");
- RefPtr<TypeDeclaration> type;
+ unique_ptr<TypeDeclaration> type;
if(tokenizer.peek_token()=="image")
type = parse_image_type_declaration();
else
return type;
}
-RefPtr<BasicTypeDeclaration> Parser::parse_basic_type_declaration()
+unique_ptr<BasicTypeDeclaration> Parser::parse_basic_type_declaration()
{
- RefPtr<BasicTypeDeclaration> type = create_node<BasicTypeDeclaration>();
+ unique_ptr<BasicTypeDeclaration> type = create_node<BasicTypeDeclaration>();
if(tokenizer.peek_token()=="vector")
{
return type;
}
-RefPtr<ImageTypeDeclaration> Parser::parse_image_type_declaration()
+unique_ptr<ImageTypeDeclaration> Parser::parse_image_type_declaration()
{
tokenizer.expect("image");
tokenizer.expect("(");
- RefPtr<ImageTypeDeclaration> type = create_node<ImageTypeDeclaration>();
+ unique_ptr<ImageTypeDeclaration> type = create_node<ImageTypeDeclaration>();
while(1)
{
string token = tokenizer.parse_token();
return type;
}
-RefPtr<StructDeclaration> Parser::parse_struct_declaration()
+unique_ptr<StructDeclaration> Parser::parse_struct_declaration()
{
tokenizer.expect("struct");
- RefPtr<StructDeclaration> strct = create_node<StructDeclaration>();
+ unique_ptr<StructDeclaration> strct = create_node<StructDeclaration>();
strct->name = expect_identifier();
parse_block(strct->members, true, &Parser::parse_variable_declaration);
return strct;
}
-RefPtr<VariableDeclaration> Parser::parse_variable_declaration()
+unique_ptr<VariableDeclaration> Parser::parse_variable_declaration()
{
- RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
+ unique_ptr<VariableDeclaration> var = create_node<VariableDeclaration>();
string token = tokenizer.peek_token();
while(is_qualifier(token))
return var;
}
-RefPtr<VariableDeclaration> Parser::parse_variable_declaration_with_layout()
+unique_ptr<VariableDeclaration> Parser::parse_variable_declaration_with_layout()
{
- RefPtr<Layout> layout;
+ unique_ptr<Layout> layout;
if(tokenizer.peek_token()=="layout")
layout = parse_layout();
- RefPtr<VariableDeclaration> var = parse_variable_declaration();
- var->layout = layout;
+ unique_ptr<VariableDeclaration> var = parse_variable_declaration();
+ var->layout = move(layout);
return var;
}
-RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
+unique_ptr<FunctionDeclaration> Parser::parse_function_declaration()
{
- RefPtr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
+ unique_ptr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
func->virtua = check("virtual");
func->return_type = expect_type();
if(!func->parameters.empty())
tokenizer.expect(",");
- RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
+ unique_ptr<VariableDeclaration> var = create_node<VariableDeclaration>();
string token = tokenizer.peek_token();
if(token=="in" || token=="out" || token=="inout")
var->interface = tokenizer.parse_token();
var->type = expect_type();
var->name = expect_identifier();
- func->parameters.push_back(var);
+ func->parameters.push_back(move(var));
}
tokenizer.expect(")");
return func;
}
-RefPtr<StructDeclaration> Parser::parse_interface_block()
+unique_ptr<StructDeclaration> Parser::parse_interface_block()
{
- RefPtr<StructDeclaration> strct = create_node<StructDeclaration>();
- RefPtr<VariableDeclaration> var = create_node<VariableDeclaration>();
+ unique_ptr<StructDeclaration> strct = create_node<StructDeclaration>();
+ unique_ptr<VariableDeclaration> var = create_node<VariableDeclaration>();
var->interface = tokenizer.parse_token();
if(!is_interface_qualifier(var->interface))
return strct;
}
-RefPtr<Conditional> Parser::parse_conditional()
+unique_ptr<Conditional> Parser::parse_conditional()
{
tokenizer.expect("if");
- RefPtr<Conditional> cond = create_node<Conditional>();
+ unique_ptr<Conditional> cond = create_node<Conditional>();
tokenizer.expect("(");
cond->condition = parse_expression();
tokenizer.expect(")");
return cond;
}
-RefPtr<Iteration> Parser::parse_for()
+unique_ptr<Iteration> Parser::parse_for()
{
tokenizer.expect("for");
- RefPtr<Iteration> loop = create_node<Iteration>();
+ unique_ptr<Iteration> loop = create_node<Iteration>();
tokenizer.expect("(");
string token = tokenizer.peek_token();
if(is_type(token))
{
if(token!=";")
{
- RefPtr<ExpressionStatement> expr = create_node<ExpressionStatement>();
+ unique_ptr<ExpressionStatement> expr = create_node<ExpressionStatement>();
expr->expression = parse_expression();
- loop->init_statement = expr;
+ loop->init_statement = move(expr);
}
tokenizer.expect(";");
}
return loop;
}
-RefPtr<Iteration> Parser::parse_while()
+unique_ptr<Iteration> Parser::parse_while()
{
tokenizer.expect("while");
- RefPtr<Iteration> loop = create_node<Iteration>();
+ unique_ptr<Iteration> loop = create_node<Iteration>();
tokenizer.expect("(");
loop->condition = parse_expression();
tokenizer.expect(")");
return loop;
}
-RefPtr<Passthrough> Parser::parse_passthrough()
+unique_ptr<Passthrough> Parser::parse_passthrough()
{
tokenizer.expect("passthrough");
- RefPtr<Passthrough> pass = create_node<Passthrough>();
+ unique_ptr<Passthrough> pass = create_node<Passthrough>();
if(cur_stage->type==Stage::GEOMETRY)
{
tokenizer.expect("[");
return pass;
}
-RefPtr<Return> Parser::parse_return()
+unique_ptr<Return> Parser::parse_return()
{
tokenizer.expect("return");
- RefPtr<Return> ret = create_node<Return>();
+ unique_ptr<Return> ret = create_node<Return>();
if(tokenizer.peek_token()!=";")
ret->expression = parse_expression();
tokenizer.expect(";");
#ifndef MSP_GL_SL_PARSER_H_
#define MSP_GL_SL_PARSER_H_
+#include <memory>
#include <set>
#include <string>
#include <msp/io/base.h>
std::set<std::string> global_types;
std::set<std::string> stage_types;
std::vector<std::string> errors;
- RefPtr<Statement> next_global_declaration;
+ std::unique_ptr<Statement> next_global_declaration;
public:
Parser(ModuleCache *);
void preprocess_stage();
template<typename T>
- RefPtr<T> create_node();
+ std::unique_ptr<T> create_node();
template<typename T>
- RefPtr<T> parse_with_recovery(RefPtr<T> (Parser::*)());
- RefPtr<Statement> parse_global_declaration();
- RefPtr<Statement> parse_statement();
- RefPtr<Import> parse_import();
- RefPtr<Precision> parse_precision();
- RefPtr<Layout> parse_layout();
+ std::unique_ptr<T> parse_with_recovery(std::unique_ptr<T> (Parser::*)());
+ std::unique_ptr<Statement> parse_global_declaration();
+ std::unique_ptr<Statement> parse_statement();
+ std::unique_ptr<Import> parse_import();
+ std::unique_ptr<Precision> parse_precision();
+ std::unique_ptr<Layout> parse_layout();
template<typename T>
- void parse_block(Block &, bool, RefPtr<T> (Parser::*)());
- RefPtr<Expression> parse_expression(const Operator * = nullptr);
- RefPtr<Literal> parse_literal();
- RefPtr<BinaryExpression> parse_binary(const RefPtr<Expression> &, const Operator &);
- RefPtr<TernaryExpression> parse_ternary(const RefPtr<Expression> &, const Operator &);
- RefPtr<FunctionCall> parse_function_call(const VariableReference &);
+ void parse_block(Block &, bool, std::unique_ptr<T> (Parser::*)());
+ std::unique_ptr<Expression> parse_expression(const Operator * = nullptr);
+ std::unique_ptr<Literal> parse_literal();
+ std::unique_ptr<BinaryExpression> parse_binary(std::unique_ptr<Expression>, const Operator &);
+ std::unique_ptr<TernaryExpression> parse_ternary(std::unique_ptr<Expression>, const Operator &);
+ std::unique_ptr<FunctionCall> parse_function_call(const VariableReference &);
void add_type(TypeDeclaration &);
- RefPtr<TypeDeclaration> parse_type_declaration();
- RefPtr<BasicTypeDeclaration> parse_basic_type_declaration();
- RefPtr<ImageTypeDeclaration> parse_image_type_declaration();
- RefPtr<StructDeclaration> parse_struct_declaration();
- RefPtr<VariableDeclaration> parse_variable_declaration();
- RefPtr<VariableDeclaration> parse_variable_declaration_with_layout();
- RefPtr<FunctionDeclaration> parse_function_declaration();
- RefPtr<StructDeclaration> parse_interface_block();
- RefPtr<Conditional> parse_conditional();
- RefPtr<Iteration> parse_for();
- RefPtr<Iteration> parse_while();
- RefPtr<Passthrough> parse_passthrough();
- RefPtr<Return> parse_return();
+ std::unique_ptr<TypeDeclaration> parse_type_declaration();
+ std::unique_ptr<BasicTypeDeclaration> parse_basic_type_declaration();
+ std::unique_ptr<ImageTypeDeclaration> parse_image_type_declaration();
+ std::unique_ptr<StructDeclaration> parse_struct_declaration();
+ std::unique_ptr<VariableDeclaration> parse_variable_declaration();
+ std::unique_ptr<VariableDeclaration> parse_variable_declaration_with_layout();
+ std::unique_ptr<FunctionDeclaration> parse_function_declaration();
+ std::unique_ptr<StructDeclaration> parse_interface_block();
+ std::unique_ptr<Conditional> parse_conditional();
+ std::unique_ptr<Iteration> parse_for();
+ std::unique_ptr<Iteration> parse_while();
+ std::unique_ptr<Passthrough> parse_passthrough();
+ std::unique_ptr<Return> parse_return();
};
} // namespace SL
void LocationCounter::visit(StructDeclaration &strct)
{
unsigned total = 0;
- for(const RefPtr<Statement> &s: strct.members.body)
+ for(const NodePtr<Statement> &s: strct.members.body)
{
r_count = 1;
s->visit(*this);
{
unsigned total = 0;
unsigned max_align = 1;
- for(const RefPtr<Statement> &s: strct.members.body)
+ for(const NodePtr<Statement> &s: strct.members.body)
{
r_size = 0;
r_alignment = 1;
if(i!=array_types.end())
return i->second;
- BasicTypeDeclaration *array = new BasicTypeDeclaration;
+ unique_ptr<BasicTypeDeclaration> array = make_unique<BasicTypeDeclaration>();
array->source = INTERNAL_SOURCE;
array->name = type.name+"[]";
array->kind = BasicTypeDeclaration::ARRAY;
array->extended_alignment = extended_alignment;
array->base = type.name;
array->base_type = &type;
- stage->content.body.insert(type_insert_point, array);
- array_types[key] = array;
- return array;
+
+ BasicTypeDeclaration *result = array.get();
+ stage->content.body.insert(type_insert_point, move(array));
+ array_types[key] = result;
+ return result;
}
TypeDeclaration *TypeResolver::get_or_create_image_type(ImageTypeDeclaration &type, const std::string &texel_format)
if(i!=image_types.end())
return i->second;
- ImageTypeDeclaration *image = new ImageTypeDeclaration(type);
+ unique_ptr<ImageTypeDeclaration> image = make_unique<ImageTypeDeclaration>(type);
image->source = INTERNAL_SOURCE;
image->name = format("%s_%s", type.name, texel_format);
image->format = texel_format;
image->base_image = &type;
- stage->content.body.insert(type_insert_point, image);
- image_types[key] = image;
- return image;
+
+ ImageTypeDeclaration *result = image.get();
+ stage->content.body.insert(type_insert_point, move(image));
+ image_types[key] = result;
+ return result;
}
void TypeResolver::resolve_type(TypeDeclaration *&type, const string &name, bool array, const Layout *layout)
block.variables.clear();
}
-void VariableResolver::visit(RefPtr<Expression> &expr)
+void VariableResolver::visit(NodePtr<Expression> &expr)
{
r_replacement_expr = nullptr;
expr->visit(*this);
if(r_replacement_expr)
{
- expr = r_replacement_expr;
+ expr = move(r_replacement_expr);
/* Don't record assignment target when doing a replacement, because chain
information won't be correct. */
r_assignment_target.declaration = nullptr;
{
/* The name refers a member of an anonymous interface block. Prepare
new syntax tree nodes accordingly. */
- VariableReference *iface_ref = new VariableReference;
+ unique_ptr<VariableReference> iface_ref = make_unique<VariableReference>();
iface_ref->name = kvp.first;
iface_ref->source = var.source;
iface_ref->line = var.line;
iface_ref->declaration = kvp.second;
- MemberAccess *memacc = new MemberAccess;
+ unique_ptr<MemberAccess> memacc = make_unique<MemberAccess>();
memacc->source = var.source;
memacc->line = var.line;
- memacc->left = iface_ref;
+ memacc->left = move(iface_ref);
memacc->member = var.name;
- r_replacement_expr = memacc;
+ r_replacement_expr = move(memacc);
break;
}
}
if(ok)
{
- Swizzle *swizzle = new Swizzle;
+ unique_ptr<Swizzle> swizzle = make_unique<Swizzle>();
swizzle->source = memacc.source;
swizzle->line = memacc.line;
swizzle->oper = memacc.oper;
- swizzle->left = memacc.left;
+ swizzle->left = move(memacc.left);
swizzle->component_group = memacc.member;
swizzle->count = memacc.member.size();
copy(components, components+memacc.member.size(), swizzle->components);
- r_replacement_expr = swizzle;
+ r_replacement_expr = move(swizzle);
}
}
}
if(existing.layout)
merge_layouts(*existing.layout, *var.layout);
else
- existing.layout = var.layout;
+ existing.layout = var.layout.clone();
}
if(var.array_size)
- existing.array_size = var.array_size;
+ existing.array_size = var.array_size.clone();
redeclared_builtins.push_back(&existing);
}
}
else if(existing->array && !existing->array_size && var.type==existing->type && !var.layout && !var.init_expression)
{
- existing->array_size = var.array_size;
+ existing->array_size = move(var.array_size);
nodes_to_remove.insert(&var);
r_any_resolved = true;
}
return (i!=basic_types.end() ? *i : 0);
}
-void ExpressionResolver::convert_to(RefPtr<Expression> &expr, BasicTypeDeclaration &type)
+void ExpressionResolver::convert_to(NodePtr<Expression> &expr, BasicTypeDeclaration &type)
{
- RefPtr<FunctionCall> call = new FunctionCall;
+ unique_ptr<FunctionCall> call = make_unique<FunctionCall>();
call->name = type.name;
call->constructor = true;
- call->arguments.push_back_nocopy(expr);
+ call->arguments.push_back(move(expr));
call->type = &type;
- expr = call;
+ expr = move(call);
}
-bool ExpressionResolver::convert_to_element(RefPtr<Expression> &expr, BasicTypeDeclaration &elem_type)
+bool ExpressionResolver::convert_to_element(NodePtr<Expression> &expr, BasicTypeDeclaration &elem_type)
{
if(BasicTypeDeclaration *expr_basic = dynamic_cast<BasicTypeDeclaration *>(expr->type))
{
return false;
}
-bool ExpressionResolver::truncate_vector(RefPtr<Expression> &expr, unsigned size)
+bool ExpressionResolver::truncate_vector(NodePtr<Expression> &expr, unsigned size)
{
if(BasicTypeDeclaration *expr_basic = dynamic_cast<BasicTypeDeclaration *>(expr->type))
if(BasicTypeDeclaration *expr_elem = get_element_type(*expr_basic))
{
- RefPtr<Swizzle> swizzle = new Swizzle;
- swizzle->left = expr;
+ unique_ptr<Swizzle> swizzle = make_unique<Swizzle>();
+ swizzle->left = move(expr);
swizzle->oper = &Operator::get_operator(".", Operator::POSTFIX);
swizzle->component_group = string("xyzw", size);
swizzle->count = size;
swizzle->type = expr_elem;
else
swizzle->type = find_type(*expr_elem, BasicTypeDeclaration::VECTOR, size);
- expr = swizzle;
+ expr = move(swizzle);
return true;
}
unsigned arg_component_total = 0;
bool homogeneous_args = true;
bool has_matrices = false;
- for(const RefPtr<Expression> &a: call.arguments)
+ for(const NodePtr<Expression> &a: call.arguments)
{
ArgumentInfo info;
if(!(info.type=dynamic_cast<BasicTypeDeclaration *>(a->type)))
unsigned column_count = basic->size&0xFFFF;
unsigned row_count = basic->size>>16;
- vector<RefPtr<Expression> > columns;
+ NodeArray<Expression> columns;
columns.reserve(column_count);
bool changed_columns = false;
/* Always generate a temporary here and let the optimization
stage inline it if that's reasonable. */
- RefPtr<VariableDeclaration> temporary = new VariableDeclaration;
+ unique_ptr<VariableDeclaration> temporary = make_unique<VariableDeclaration>();
temporary->type = args.front().type->name;
temporary->name = get_unused_variable_name(*current_block, "_temp");
- temporary->init_expression = call.arguments.front();
- current_block->body.insert(insert_point, temporary);
+ temporary->init_expression = move(call.arguments.front());
+ string temp_name = temporary->name;
+ current_block->body.insert(insert_point, move(temporary));
// Create expressions to build each column.
for(unsigned j=0; j<column_count; ++j)
{
- RefPtr<VariableReference> ref = new VariableReference;
- ref->name = temporary->name;
+ unique_ptr<VariableReference> ref = make_unique<VariableReference>();
+ ref->name = temp_name;
- RefPtr<Literal> index = new Literal;
+ unique_ptr<Literal> index = make_unique<Literal>();
index->token = lexical_cast<string>(j);
index->value = static_cast<int>(j);
- RefPtr<BinaryExpression> subscript = new BinaryExpression;
- subscript->left = ref;
+ unique_ptr<BinaryExpression> subscript = make_unique<BinaryExpression>();
+ subscript->left = move(ref);
subscript->oper = &Operator::get_operator("[", Operator::BINARY);
- subscript->right = index;
+ subscript->right = move(index);
subscript->type = args.front().type->base_type;
- columns.push_back(subscript);
+ columns.push_back(move(subscript));
if(arg_rows>row_count)
truncate_vector(columns.back(), row_count);
}
return;
}
- vector<RefPtr<Expression> > column_args;
+ NodeArray<Expression> column_args;
column_args.reserve(row_count);
column_component_count = 0;
if(!column_component_count && info.component_count==row_count)
{
// A vector filling the entire column can be used as is.
- columns.push_back(call.arguments[j]);
+ columns.push_back(move(call.arguments[j]));
convert_args = true;
}
else
{
- column_args.push_back(call.arguments[j]);
+ column_args.push_back(move(call.arguments[j]));
column_component_count += info.component_count;
if(column_component_count==row_count)
{
/* The column has filled up. Create a vector constructor
for it.*/
- RefPtr<FunctionCall> column_call = new FunctionCall;
+ unique_ptr<FunctionCall> column_call = make_unique<FunctionCall>();
column_call->name = basic->base_type->name;
column_call->constructor = true;
- column_call->arguments.resize(column_args.size());
- copy(column_args.begin(), column_args.end(), column_call->arguments.begin());
+ column_call->arguments = move(column_args);
column_call->type = basic->base_type;
visit_constructor(*column_call);
- columns.push_back(column_call);
+ columns.push_back(move(column_call));
column_args.clear();
column_component_count = 0;
if(changed_columns)
{
- call.arguments.resize(column_count);
- copy(columns.begin(), columns.end(), call.arguments.begin());
+ call.arguments = move(columns);
/* Let VariableResolver process the new nodes and finish
resolving the constructor on the next pass. */
if(convert_args)
{
// The argument list may have changed so can't rely on args.
- for(RefPtr<Expression> &a: call.arguments)
+ for(NodePtr<Expression> &a: call.arguments)
if(BasicTypeDeclaration *basic_arg = dynamic_cast<BasicTypeDeclaration *>(a->type))
{
BasicTypeDeclaration *elem_arg = get_element_type(*basic_arg);
return;
auto j = call.arguments.begin();
- for(const RefPtr<Statement> &s: strct->members.body)
+ for(const NodePtr<Statement> &s: strct->members.body)
{
if(VariableDeclaration *var = dynamic_cast<VariableDeclaration *>(s.get()))
{
if(func.signature.empty())
{
string param_types;
- for(const RefPtr<VariableDeclaration> &p: func.parameters)
+ for(const NodePtr<VariableDeclaration> &p: func.parameters)
{
if(p->type_declaration)
append(param_types, ",", p->type_declaration->name);
{
private:
Stage *stage = nullptr;
- RefPtr<Expression> r_replacement_expr;
+ std::unique_ptr<Expression> r_replacement_expr;
bool r_any_resolved = false;
bool record_target = false;
bool r_self_referencing = false;
private:
void enter(Block &) override;
- void visit(RefPtr<Expression> &) override;
+ void visit(NodePtr<Expression> &) override;
void check_assignment_target(VariableDeclaration *);
void visit(VariableReference &) override;
void visit(MemberAccess &) override;
static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned, bool = true);
BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
- void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
- bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
- bool truncate_vector(RefPtr<Expression> &, unsigned);
+ void convert_to(NodePtr<Expression> &, BasicTypeDeclaration &);
+ bool convert_to_element(NodePtr<Expression> &, BasicTypeDeclaration &);
+ bool truncate_vector(NodePtr<Expression> &, unsigned);
void resolve(Expression &, TypeDeclaration *, bool);
void visit(Block &) override;
void SpirVGenerator::visit(Block &block)
{
- for(const RefPtr<Statement> &s: block.body)
+ for(const NodePtr<Statement> &s: block.body)
s->visit(*this);
}
vector<Id> argument_ids;
argument_ids.reserve(call.arguments.size());
bool all_args_const = true;
- for(const RefPtr<Expression> &a: call.arguments)
+ for(const NodePtr<Expression> &a: call.arguments)
{
a->visit(*this);
argument_ids.push_back(r_expression_result_id);
else if(call.declaration->source==BUILTIN_SOURCE)
{
string arg_types;
- for(const RefPtr<Expression> &a: call.arguments)
+ for(const NodePtr<Expression> &a: call.arguments)
if(BasicTypeDeclaration *basic_arg = dynamic_cast<BasicTypeDeclaration *>(a->type))
{
BasicTypeDeclaration &elem_arg = *get_element_type(*basic_arg);
bool builtin = !strct.block_name.compare(0, 3, "gl_");
vector<Id> member_type_ids;
member_type_ids.reserve(strct.members.body.size());
- for(const RefPtr<Statement> &s: strct.members.body)
+ for(const NodePtr<Statement> &s: strct.members.body)
{
const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(s.get());
if(!var)
Id return_type_id = get_id(*func.return_type_declaration);
vector<unsigned> param_type_ids;
param_type_ids.reserve(func.parameters.size());
- for(const RefPtr<VariableDeclaration> &p: func.parameters)
+ for(const NodePtr<VariableDeclaration> &p: func.parameters)
param_type_ids.push_back(get_variable_type_id(*p));
string sig_with_return = func.return_type+func.signature;
}
-template<typename C>
-NodeContainer<C>::NodeContainer(const NodeContainer &c):
- C(c)
-{
- for(auto &i: *this)
- i = i->clone();
-}
-
-
Block::Block(const Block &other):
Node(other),
body(other.body),
return (i!=layout->qualifiers.end() ? i->value : def_value);
}
-void add_layout_qualifier(RefPtr<Layout> &layout, const Layout::Qualifier &q)
+void add_layout_qualifier(NodePtr<Layout> &layout, const Layout::Qualifier &q)
{
if(!layout)
- layout = new Layout;
+ layout = make_unique<Layout>();
layout->qualifiers.push_back(q);
}
#include <list>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
#include <cstdint>
-#include <msp/core/refptr.h>
#include <msp/core/variant.h>
#include <msp/gl/mspgl_api.h>
#include "features.h"
};
template<typename T>
-class NodePtr: public RefPtr<T>
+class NodePtr
{
+ template<typename U>
+ friend class NodePtr;
+
+private:
+ std::unique_ptr<T> ptr;
+
public:
NodePtr() = default;
- NodePtr(T *p): RefPtr<T>(p) { }
- NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : nullptr) { }
- NodePtr &operator=(const NodePtr &p) = default;
+ NodePtr(const NodePtr &p): ptr(p ? p->clone() : nullptr) { }
+ NodePtr(NodePtr &&) = default;
+ NodePtr &operator=(NodePtr &&) = default;
+ NodePtr &operator=(nullptr_t) { ptr = nullptr; return *this; }
template<typename U>
- NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
+ NodePtr(NodePtr<U> &&p): ptr(std::move(p.ptr)) { }
template<typename U>
- NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
+ NodePtr(std::unique_ptr<U> &&p): ptr(std::move(p)) { }
+
+ template<typename U>
+ NodePtr &operator=(std::unique_ptr<U> &&p) { ptr = std::move(p); return *this; }
+
+ template<typename U>
+ U *get_as() const { return dynamic_cast<U *>(ptr.get()); }
+
+ T *get() const { return ptr.get(); }
+ T *operator->() const { return ptr.get(); }
+ T &operator*() const { return *ptr; }
+
+ explicit operator bool() const { return static_cast<bool>(ptr); }
+
+ std::unique_ptr<T> clone() const { return std::unique_ptr<T>(ptr ? ptr->clone() : nullptr); }
};
template<typename C>
-class NodeContainer: public C
+class NodeContainer
{
public:
- NodeContainer() = default;
- NodeContainer(const NodeContainer &);
+ using size_type = typename C::size_type;
+ using value_type = typename C::value_type;
+ using iterator = typename C::iterator;
+ using const_iterator = typename C::const_iterator;
+
+protected:
+ C container;
+
+public:
+ size_type size() const { return container.size(); }
+ bool empty() const { return container.empty(); }
+
+ iterator begin() { return container.begin(); }
+ iterator end() { return container.end(); }
+ const_iterator begin() const { return container.begin(); }
+ const_iterator end() const { return container.end(); }
+ const_iterator cbegin() const { return container.begin(); }
+ const_iterator cend() const { return container.end(); }
- void push_back_nocopy(const typename C::value_type &v)
- { C::push_back(0); C::back() = v; }
+ value_type &front() { return container.front(); }
+ const value_type &front() const { return container.front(); }
+ value_type &back() { return container.back(); }
+ const value_type &back() const { return container.back(); }
- void insert_nocopy(typename C::iterator i, const typename C::value_type &v)
- { i = C::insert(i, 0); *i = v; }
+ void push_back(value_type &&v) { container.push_back(std::move(v)); }
+ iterator insert(iterator i, value_type &&v) { return container.insert(i, std::move(v)); }
+ iterator erase(iterator i) { return container.erase(i); }
+ void clear() { container.clear(); }
};
template<typename T>
-class NodeList: public NodeContainer<std::list<RefPtr<T> > >
-{ };
+class NodeList: public NodeContainer<std::list<NodePtr<T>>>
+{
+private:
+ using Base = NodeContainer<std::list<NodePtr<T>>>;
+
+public:
+ void splice(typename Base::iterator i, NodeList &l) { this->container.splice(i, l.container); }
+ void splice(typename Base::iterator i, NodeList &l, typename Base::iterator j) { this->container.splice(i, l.container, j); }
+};
template<typename T>
-class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
-{ };
+class NodeArray: public NodeContainer<std::vector<NodePtr<T>>>
+{
+private:
+ using Base = NodeContainer<std::vector<NodePtr<T>>>;
+
+public:
+ typename Base::value_type &operator[](std::size_t i) { return this->container[i]; }
+ const typename Base::value_type &operator[](std::size_t i) const { return this->container[i]; }
+
+ void reserve(typename Base::size_type s) { this->container.reserve(s); }
+};
struct TypeDeclaration;
struct VariableDeclaration;
TypeDeclaration *get_ultimate_base_type(TypeDeclaration *);
bool has_layout_qualifier(const Layout *, const std::string &);
int get_layout_value(const Layout *, const std::string &, int = -1);
-void add_layout_qualifier(RefPtr<Layout> &, const Layout::Qualifier &);
+void add_layout_qualifier(NodePtr<Layout> &, const Layout::Qualifier &);
void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned);
bool targets_overlap(const Assignment::Target &, const Assignment::Target &);
void DeclarationValidator::visit(FunctionDeclaration &func)
{
SetForScope<ScopeType> set_scope(scope, FUNCTION_PARAM);
- for(const RefPtr<VariableDeclaration> &p: func.parameters)
+ for(const NodePtr<VariableDeclaration> &p: func.parameters)
p->visit(*this);
scope = FUNCTION;
func.body.visit(*this);
void FlowControlValidator::visit(Block &block)
{
- for(const RefPtr<Statement> &s: block.body)
+ for(const NodePtr<Statement> &s: block.body)
{
if(!reachable)
{
if(&block!=current_block)
enter(block);
SetForScope<Block *> set_block(current_block, &block);
- for(const RefPtr<Statement> &s: block.body)
+ for(const NodePtr<Statement> &s: block.body)
s->visit(*this);
}
-void TraversingVisitor::visit(RefPtr<Expression> &expr)
+void TraversingVisitor::visit(NodePtr<Expression> &expr)
{
expr->visit(*this);
}
void TraversingVisitor::visit(FunctionCall &call)
{
- for(RefPtr<Expression> &a: call.arguments)
+ for(NodePtr<Expression> &a: call.arguments)
visit(a);
}
{
enter(func.body);
SetForScope<Block *> set_block(current_block, &func.body);
- for(const RefPtr<VariableDeclaration> &p: func.parameters)
+ for(const NodePtr<VariableDeclaration> &p: func.parameters)
p->visit(*this);
func.body.visit(*this);
}
public:
virtual void enter(Block &) { }
void visit(Block &) override;
- virtual void visit(RefPtr<Expression> &);
+ virtual void visit(NodePtr<Expression> &);
void visit(MemberAccess &) override;
void visit(Swizzle &) override;
void visit(UnaryExpression &) override;