From aac16a1dd54d78972c5b20c6f78e035299187d55 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 17 Dec 2023 10:43:03 +0200 Subject: [PATCH] Refactor the GLSL compiler to use unique pointers Both clone and move assignments are now explicit, although NodePtr still has an implicitly cloning copy constructor to facilitate automatically generated copy constructors in the node classes. Node containers wrap the std container instead of inheriting and only allow adding elements by move. --- source/glsl/builtin.cpp | 4 +- source/glsl/compiler.cpp | 14 +-- source/glsl/debug.cpp | 2 +- source/glsl/finalize.cpp | 58 ++++++------- source/glsl/finalize.h | 10 +-- source/glsl/generate.cpp | 86 ++++++++++--------- source/glsl/generate.h | 2 +- source/glsl/optimize.cpp | 99 +++++++++++----------- source/glsl/optimize.h | 28 +++--- source/glsl/output.cpp | 2 +- source/glsl/parser.cpp | 179 +++++++++++++++++++-------------------- source/glsl/parser.h | 55 ++++++------ source/glsl/reflect.cpp | 4 +- source/glsl/resolve.cpp | 109 ++++++++++++------------ source/glsl/resolve.h | 10 +-- source/glsl/spirv.cpp | 10 +-- source/glsl/syntax.cpp | 13 +-- source/glsl/syntax.h | 95 ++++++++++++++++----- source/glsl/validate.cpp | 4 +- source/glsl/visitor.cpp | 8 +- source/glsl/visitor.h | 2 +- 21 files changed, 424 insertions(+), 370 deletions(-) diff --git a/source/glsl/builtin.cpp b/source/glsl/builtin.cpp index 35042460..881bec76 100644 --- a/source/glsl/builtin.cpp +++ b/source/glsl/builtin.cpp @@ -12,14 +12,14 @@ namespace SL { void add_builtin_type(Stage &stage, const string &name, BasicTypeDeclaration::Kind kind, unsigned size, unsigned sign) { - RefPtr type = new BasicTypeDeclaration; + unique_ptr type = make_unique(); 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() diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 7da7fcd9..7d1db5a3 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -250,8 +250,8 @@ void Compiler::append_module(const Module &mod, ModuleCache &mod_cache) module->source_map.merge_from(mod.source_map); vector imports; - for(const RefPtr &s: mod.shared.content.body) - if(Import *imp = dynamic_cast(s.get())) + for(const NodePtr &s: mod.shared.content.body) + if(Import *imp = s.get_as()) imports.push_back(imp); for(Import *i: imports) import(mod_cache, i->module); @@ -284,9 +284,9 @@ void Compiler::append_stage(const Stage &stage) if(target->required_features.glsl_versionrequired_features.glsl_version = stage.required_features.glsl_version; - for(const RefPtr &s: stage.content.body) - if(!dynamic_cast(s.get())) - target->content.body.push_back(s); + for(const NodePtr &s: stage.content.body) + if(!s.get_as()) + target->content.body.push_back(s.clone()); } void Compiler::import(ModuleCache &mod_cache, const string &name) @@ -434,8 +434,8 @@ void Compiler::finalize(Stage &stage, Mode mode) void Compiler::inject_block(Block &target, const Block &source) { auto insert_point = target.body.begin(); - for(const RefPtr &s: source.body) - target.body.insert(insert_point, s->clone()); + for(const NodePtr &s: source.body) + target.body.insert(insert_point, s.clone()); } } // namespace SL diff --git a/source/glsl/debug.cpp b/source/glsl/debug.cpp index a090c362..f8d9515b 100644 --- a/source/glsl/debug.cpp +++ b/source/glsl/debug.cpp @@ -429,7 +429,7 @@ void DumpTree::visit(FunctionDeclaration &func) 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 &p: func.parameters) + for(const NodePtr &p: func.parameters) p->visit(*this); last_branch(); if(func.definition==&func) diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index c8fc04a9..e26b7b26 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -154,7 +154,7 @@ void LocationAllocator::allocate_locations(const string &iface) unplaced_variables.erase(write, unplaced_variables.end()); } -void LocationAllocator::bind_uniform(RefPtr &layout, const string &name, unsigned range) +void LocationAllocator::bind_uniform(NodePtr &layout, const string &name, unsigned range) { auto i = uniforms.find(name); @@ -178,7 +178,7 @@ void LocationAllocator::bind_uniform(RefPtr &layout, const string &name, } } -bool LocationAllocator::visit_uniform(const string &name, RefPtr &layout) +bool LocationAllocator::visit_uniform(const string &name, NodePtr &layout) { int desc_set = get_layout_value(layout.get(), "set"); int bind_point = get_layout_value(layout.get(), "binding"); @@ -264,40 +264,40 @@ void DepthRangeConverter::apply(Module &module, const Features &features) s->content.visit(*this); } -NodePtr DepthRangeConverter::create_conversion_statement() +unique_ptr DepthRangeConverter::create_conversion_statement() { - VariableReference *position = new VariableReference; + NodePtr position = make_unique(); position->name = "gl_Position"; - MemberAccess *z = new MemberAccess; - z->left = position; + NodePtr z = make_unique(); + z->left = position.clone(); z->member = "z"; - Literal *scale = new Literal; + unique_ptr scale = make_unique(); scale->token = "2.0"; scale->value = 2.0f; - BinaryExpression *multiply = new BinaryExpression; + unique_ptr multiply = make_unique(); 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 w = make_unique(); + w->left = move(position); w->member = "w"; - BinaryExpression *subtract = new BinaryExpression; + unique_ptr subtract = make_unique(); 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 assign = make_unique(); 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 statement = make_unique(); + statement->expression = move(assign); return statement; } @@ -310,7 +310,7 @@ void DepthRangeConverter::visit(Block &block) (*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; } } @@ -364,7 +364,7 @@ void DepthRangeConverter::visit(FunctionDeclaration &func) 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; } } @@ -426,10 +426,10 @@ void PrecisionConverter::visit(VariableDeclaration &var) if(!have_default.count(type->name)) { - Precision *prec = new Precision; + unique_ptr prec = make_unique(); 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); } @@ -498,12 +498,12 @@ void StructuralFeatureConverter::visit(Block &block) } } -void StructuralFeatureConverter::visit(RefPtr &expr) +void StructuralFeatureConverter::visit(NodePtr &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; } @@ -559,9 +559,9 @@ void StructuralFeatureConverter::visit(MemberAccess &memacc) visit(memacc.left); if(r_flattened_interface) { - VariableReference *var = new VariableReference; + unique_ptr var = make_unique(); var->name = memacc.member; - r_replaced_reference = var; + r_replaced_reference = move(var); } } @@ -654,7 +654,7 @@ void StructuralFeatureConverter::visit(VariableDeclaration &var) unsupported("ARB_uniform_buffer_object required for interface block instances"); else { - for(const RefPtr &s: var.block_declaration->members.body) + for(const NodePtr &s: var.block_declaration->members.body) if(VariableDeclaration *mem = dynamic_cast(s.get())) mem->interface = var.interface; stage->content.body.splice(uniform_insert_point, var.block_declaration->members.body); diff --git a/source/glsl/finalize.h b/source/glsl/finalize.h index fcacf774..5ec64d4b 100644 --- a/source/glsl/finalize.h +++ b/source/glsl/finalize.h @@ -53,9 +53,9 @@ private: void apply(Stage &); void allocate_locations(const std::string &); - void bind_uniform(RefPtr &, const std::string &, unsigned); + void bind_uniform(NodePtr &, const std::string &, unsigned); - bool visit_uniform(const std::string &, RefPtr &); + bool visit_uniform(const std::string &, NodePtr &); void visit(VariableDeclaration &) override; void visit(FunctionDeclaration &) override { } }; @@ -77,7 +77,7 @@ public: void apply(Module &, const Features &); private: - NodePtr create_conversion_statement(); + std::unique_ptr create_conversion_statement(); void visit(Block &) override; void visit(VariableReference &) override; @@ -135,7 +135,7 @@ private: VariableDeclaration *frag_out = nullptr; NodeList::iterator uniform_insert_point; std::set nodes_to_remove; - RefPtr r_replaced_reference; + std::unique_ptr r_replaced_reference; bool r_flattened_interface = false; public: @@ -144,7 +144,7 @@ private: void apply() override; void visit(Block &) override; - void visit(RefPtr &) override; + void visit(NodePtr &) override; bool supports_stage(Stage::Type) const; bool supports_unified_interface_syntax() const; void visit(VariableReference &) override; diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index de32b90a..c6aae64e 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -104,7 +104,7 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration if(stage->type==Stage::GEOMETRY && var.interface=="out" && var.array) return nullptr; - VariableDeclaration* iface_var = new VariableDeclaration; + unique_ptr iface_var = make_unique(); iface_var->sampling = var.sampling; if(stage->type==Stage::FRAGMENT && iface=="in") if(BasicTypeDeclaration *basic = dynamic_cast(var.type_declaration)) @@ -127,66 +127,70 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration 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 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 right) { - Assignment *assign = new Assignment; + unique_ptr assign = make_unique(); string::size_type dot = left.find('.'); - VariableReference *ref = new VariableReference; + unique_ptr ref = make_unique(); 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 memacc = make_unique(); + 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 stmt = make_unique(); + 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) @@ -242,7 +246,7 @@ void InterfaceGenerator::visit(VariableDeclaration &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; @@ -314,19 +318,19 @@ void InterfaceGenerator::visit(Passthrough &pass) { /* Special case for geometry shader: copy gl_Position from input to output. */ - VariableReference *ref = new VariableReference; + unique_ptr ref = make_unique(); ref->name = "gl_in"; - BinaryExpression *subscript = new BinaryExpression; - subscript->left = ref; + unique_ptr subscript = make_unique(); + 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 memacc = make_unique(); + 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) @@ -334,18 +338,18 @@ void InterfaceGenerator::visit(Passthrough &pass) string out_name = change_prefix(v->name, out_prefix); generate_interface(*v, "out", out_name); - VariableReference *ref = new VariableReference; + unique_ptr ref = make_unique(); ref->name = v->name; if(pass.subscript) { - BinaryExpression *subscript = new BinaryExpression; - subscript->left = ref; + unique_ptr subscript = make_unique(); + 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); @@ -400,10 +404,10 @@ void ArraySizer::apply(Stage &stage) if(size>0) { - Literal *literal_size = new Literal; + unique_ptr literal_size = make_unique(); literal_size->token = lexical_cast(size); literal_size->value = size; - kvp.first->array_size = literal_size; + kvp.first->array_size = move(literal_size); } } } diff --git a/source/glsl/generate.h b/source/glsl/generate.h index e43c5bd6..bc25a712 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -56,7 +56,7 @@ private: 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); void visit(VariableReference &) override; void visit(VariableDeclaration &) override; void visit(FunctionDeclaration &) override; diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 45d8745d..a3eb20f2 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -38,7 +38,7 @@ void ConstantSpecializer::visit(VariableDeclaration &var) auto i = values->find(var.name); if(i!=values->end()) { - RefPtr literal = new Literal; + unique_ptr literal = make_unique(); if(var.type=="bool") { literal->token = (i->second ? "true" : "false"); @@ -49,7 +49,7 @@ void ConstantSpecializer::visit(VariableDeclaration &var) literal->token = lexical_cast(i->second); literal->value = i->second; } - var.init_expression = literal; + var.init_expression = move(literal); } } } @@ -77,7 +77,7 @@ void InlineableFunctionLocator::visit(FunctionCall &call) void InlineableFunctionLocator::visit(FunctionDeclaration &func) { bool has_out_params = any_of(func.parameters.begin(), func.parameters.end(), - [](const RefPtr &p){ return p->interface=="out"; }); + [](const NodePtr &p){ return p->interface=="out"; }); unsigned &count = refcounts[func.definition]; if((count<=1 || func.source==BUILTIN_SOURCE) && !has_out_params) @@ -132,31 +132,31 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu staging_block.parent = &tgt_blk; staging_block.variables.clear(); - vector > params; + vector params; params.reserve(source_func->parameters.size()); - for(const RefPtr &p: source_func->parameters) + for(const NodePtr &p: source_func->parameters) { - RefPtr var = p->clone(); + NodePtr var = p.clone(); var->interface.clear(); SetForScope 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 &s: source_func->body.body) + for(const NodePtr &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 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 @@ -174,7 +174,7 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu // Put the argument expressions in place after all renaming has been done. for(unsigned i=0; iparameters.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); @@ -234,13 +234,13 @@ void InlineContentInjector::visit(Return &ret) { // Create a new variable to hold the return value of the inlined function. r_result_name = get_unused_variable_name(staging_block, "_return"); - RefPtr var = new VariableDeclaration; + unique_ptr var = make_unique(); 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); } } @@ -254,13 +254,13 @@ bool FunctionInliner::apply(Stage &s) return r_any_inlined; } -void FunctionInliner::visit(RefPtr &ptr) +void FunctionInliner::visit(NodePtr &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; @@ -297,9 +297,9 @@ void FunctionInliner::visit(FunctionCall &call) if(result_name.empty()) result_name = "_msp_unused_from_inline"; - RefPtr ref = new VariableReference; + unique_ptr ref = make_unique(); 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. */ @@ -341,7 +341,7 @@ bool ExpressionInliner::apply(Stage &s) for(ExpressionUse &u: e.uses) if(!u.blocked) { - *u.reference = e.expression->clone(); + *u.reference = unique_ptr(e.expression->clone()); if(u.containing_expr) u.containing_expr->expression = 0; any_inlined = true; @@ -351,7 +351,7 @@ bool ExpressionInliner::apply(Stage &s) return any_inlined; } -void ExpressionInliner::visit(RefPtr &expr) +void ExpressionInliner::visit(NodePtr &expr) { r_ref_info = nullptr; expr->visit(*this); @@ -436,7 +436,7 @@ void ExpressionInliner::visit(Assignment &assign) 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; } @@ -492,7 +492,7 @@ void ExpressionInliner::visit(VariableDeclaration &var) /* 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; } @@ -557,24 +557,25 @@ bool AggregateDismantler::apply(Stage &stage) 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 var = make_unique(); 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 *r: m.references) + for(NodePtr *r: m.references) { - VariableReference *ref = new VariableReference; - ref->name = var->name; - *r = ref; + unique_ptr ref = make_unique(); + ref->name = name; + *r = move(ref); } any_dismantled = true; @@ -594,7 +595,7 @@ void AggregateDismantler::visit(Block &block) } } -void AggregateDismantler::visit(RefPtr &expr) +void AggregateDismantler::visit(NodePtr &expr) { r_aggregate_ref = nullptr; expr->visit(*this); @@ -627,7 +628,7 @@ void AggregateDismantler::visit(VariableReference &var) } } -void AggregateDismantler::visit_composite(RefPtr &expr) +void AggregateDismantler::visit_composite(NodePtr &expr) { if(!composite_reference) r_reference = Assignment::Target(); @@ -662,7 +663,7 @@ void AggregateDismantler::visit(BinaryExpression &binary) } unsigned index = 0x3F; - if(Literal *literal_subscript = dynamic_cast(binary.right.get())) + if(Literal *literal_subscript = binary.right.get_as()) if(literal_subscript->value.has_type()) index = literal_subscript->value.value(); add_to_chain(r_reference, Assignment::Target::ARRAY, index); @@ -690,7 +691,7 @@ void AggregateDismantler::visit(VariableDeclaration &var) { if(const StructDeclaration *strct = dynamic_cast(var.type_declaration)) { - const FunctionCall *init_call = dynamic_cast(var.init_expression.get()); + const FunctionCall *init_call = var.init_expression.get_as(); if((init_call && init_call->constructor) || !var.init_expression) { @@ -700,21 +701,21 @@ void AggregateDismantler::visit(VariableDeclaration &var) aggre.insert_point = insert_point; unsigned i = 0; - for(const RefPtr &s: strct->members.body) + for(const NodePtr &s: strct->members.body) { - if(const VariableDeclaration *mem_decl = dynamic_cast(s.get())) + if(const VariableDeclaration *mem_decl = s.get_as()) { 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(var.array_size.get())) + else if(const Literal *literal_size = var.array_size.get_as()) { if(literal_size->value.has_type()) { @@ -811,7 +812,7 @@ void ConstantFolder::set_result(const Variant &value, bool literal) r_literal = literal; } -void ConstantFolder::visit(RefPtr &expr) +void ConstantFolder::visit(NodePtr &expr) { r_constant_value = Variant(); r_constant = false; @@ -824,7 +825,7 @@ void ConstantFolder::visit(RefPtr &expr) if(!r_constant || r_literal || r_uses_iter_var) return; - RefPtr literal = new Literal; + unique_ptr literal = make_unique(); if(r_constant_value.has_type()) literal->token = (r_constant_value.value() ? "true" : "false"); else if(r_constant_value.has_type()) @@ -843,7 +844,7 @@ void ConstantFolder::visit(RefPtr &expr) return; } literal->value = r_constant_value; - expr = literal; + expr = move(literal); r_any_folded = true; } @@ -1053,10 +1054,10 @@ void ConstantFolder::visit(Iteration &iter) visit(iter.condition); if(r_constant && r_constant_value.has_type() && !r_constant_value.value()) { - RefPtr literal = new Literal; + unique_ptr literal = make_unique(); literal->token = "false"; literal->value = r_constant_value; - iter.condition = literal; + iter.condition = move(literal); } } iteration_var = nullptr; @@ -1092,19 +1093,19 @@ void ConstantConditionEliminator::visit(Block &block) } } -void ConstantConditionEliminator::visit(RefPtr &expr) +void ConstantConditionEliminator::visit(NodePtr &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(unary.expression.get())) + if(const VariableReference *var = unary.expression.get_as()) { auto i = current_block->variables.find(var->name); r_external_side_effects = (i==current_block->variables.end() || i->second!=var->declaration); @@ -1126,7 +1127,7 @@ void ConstantConditionEliminator::visit(TernaryExpression &ternary) { 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; } @@ -1224,7 +1225,7 @@ bool UnusedTypeRemover::apply(Stage &stage) return !unused_nodes.empty(); } -void UnusedTypeRemover::visit(RefPtr &expr) +void UnusedTypeRemover::visit(NodePtr &expr) { unused_nodes.erase(expr->type); TraversingVisitor::visit(expr); @@ -1524,7 +1525,7 @@ void UnusedVariableRemover::visit(FunctionDeclaration &func) /* Always treat function parameters as referenced. Removing unused parameters is not currently supported. */ - for(const RefPtr &p: func.parameters) + for(const NodePtr &p: func.parameters) { auto j = variables.find(p.get()); if(j!=variables.end()) diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index 7f885360..d3d475b6 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -61,7 +61,7 @@ private: FunctionDeclaration *source_func = nullptr; Block staging_block; Pass pass = REFERENCED; - RefPtr r_inlined_statement; + NodePtr r_inlined_statement; std::set dependencies; std::set referenced_names; std::string r_result_name; @@ -86,7 +86,7 @@ private: std::set inlineable; FunctionDeclaration *current_function = nullptr; NodeList::iterator insert_point; - RefPtr r_inline_result; + std::unique_ptr r_inline_result; bool r_any_inlined = false; bool r_inlined_here = false; @@ -94,7 +94,7 @@ public: bool apply(Stage &); private: - void visit(RefPtr &) override; + void visit(NodePtr &) override; void visit(Block &) override; void visit(FunctionCall &) override; void visit(FunctionDeclaration &) override; @@ -111,7 +111,7 @@ private: struct ExpressionUse { - RefPtr *reference = nullptr; + NodePtr *reference = nullptr; Block *ref_scope = nullptr; ExpressionInfo *containing_expr = nullptr; bool blocked = false; @@ -120,7 +120,7 @@ private: struct ExpressionInfo { Assignment::Target target; - RefPtr expression; + const Expression *expression = nullptr; Block *assign_scope = nullptr; std::vector uses; bool trivial = false; @@ -142,7 +142,7 @@ public: bool apply(Stage &); private: - void visit(RefPtr &) override; + void visit(NodePtr &) override; void visit(VariableReference &) override; void visit(MemberAccess &) override; void visit(Swizzle &) override; @@ -166,8 +166,8 @@ private: { const VariableDeclaration *declaration = nullptr; unsigned index = 0; - RefPtr initializer; - std::vector *> references; + const NodePtr *initializer; + std::vector *> references; }; struct Aggregate @@ -191,9 +191,9 @@ public: private: void visit(Block &) override; - void visit(RefPtr &) override; + void visit(NodePtr &) override; void visit(VariableReference &) override; - void visit_composite(RefPtr &); + void visit_composite(NodePtr &); void visit(MemberAccess &) override; void visit(BinaryExpression &) override; void visit(StructDeclaration &) override { } @@ -231,7 +231,7 @@ private: void convert_to_result(const Variant &); void set_result(const Variant &, bool = false); - void visit(RefPtr &) override; + void visit(NodePtr &) override; void visit(Literal &) override; void visit(VariableReference &) override; void visit(MemberAccess &) override; @@ -260,7 +260,7 @@ private: NodeList::iterator insert_point; std::set nodes_to_remove; - RefPtr r_ternary_result; + NodePtr *r_ternary_result; bool r_external_side_effects = false; public: @@ -270,7 +270,7 @@ private: ConstantStatus check_constant_condition(const Expression &); void visit(Block &) override; - void visit(RefPtr &) override; + void visit(NodePtr &) override; void visit(UnaryExpression &) override; void visit(Assignment &) override; void visit(TernaryExpression &) override; @@ -308,7 +308,7 @@ public: bool apply(Stage &); private: - void visit(RefPtr &) override; + void visit(NodePtr &) override; void visit(BasicTypeDeclaration &) override; void visit(ImageTypeDeclaration &) override; void visit(StructDeclaration &) override; diff --git a/source/glsl/output.cpp b/source/glsl/output.cpp index 2b82ddbc..c6d0a3e2 100644 --- a/source/glsl/output.cpp +++ b/source/glsl/output.cpp @@ -91,7 +91,7 @@ void Formatter::visit(Block &block) SetForScope set(indent, indent+(indent>0 || use_braces)); string spaces(indent*2, ' '); bool first = true; - for(const RefPtr &s: block.body) + for(const NodePtr &s: block.body) { if(omit_builtin && s->source<=BUILTIN_SOURCE) continue; diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index a9962afe..b055c5da 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -64,14 +64,11 @@ void Parser::parse_source(const string &name, int index) tokenizer.begin(source, name); allow_stage_change = true; while(!tokenizer.peek_token().empty()) - if(RefPtr statement = parse_with_recovery(&Parser::parse_global_declaration)) + if(unique_ptr 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()) @@ -209,16 +206,16 @@ bool Parser::is_identifier(const string &token) } template -RefPtr Parser::create_node() +unique_ptr Parser::create_node() { - RefPtr node = new T; + unique_ptr node = make_unique(); node->source = source_index; node->line = tokenizer.get_location().line; return node; } template -RefPtr Parser::parse_with_recovery(RefPtr (Parser::*parse_func)()) +unique_ptr Parser::parse_with_recovery(unique_ptr (Parser::*parse_func)()) { tokenizer.clear_progress_mark(); try @@ -258,10 +255,10 @@ RefPtr Parser::parse_with_recovery(RefPtr (Parser::*parse_func)()) } } - return RefPtr(); + return unique_ptr(); } -RefPtr Parser::parse_global_declaration() +unique_ptr Parser::parse_global_declaration() { string token = tokenizer.peek_token(); SetFlag disallow(allow_stage_change, false); @@ -272,11 +269,11 @@ RefPtr Parser::parse_global_declaration() return parse_precision(); else if(token=="layout") { - RefPtr layout = parse_layout(); + unique_ptr layout = parse_layout(); token = tokenizer.peek_token(); if(is_interface_qualifier(token) && tokenizer.peek_token(1)==";") { - RefPtr iface_lo = create_node(); + unique_ptr iface_lo = create_node(); iface_lo->layout.source = layout->source; iface_lo->layout.line = layout->line; iface_lo->layout.qualifiers = layout->qualifiers; @@ -286,16 +283,16 @@ RefPtr Parser::parse_global_declaration() } else if(is_interface_qualifier(token) && tokenizer.peek_token(2)=="{") { - RefPtr iface_strct = parse_interface_block(); - VariableDeclaration *iface_var = iface_strct->block_declaration; - iface_var->layout = layout; - next_global_declaration = iface_var; + unique_ptr iface_strct = parse_interface_block(); + unique_ptr iface_var = unique_ptr(iface_strct->block_declaration); + iface_var->layout = move(layout); + next_global_declaration = move(iface_var); return iface_strct; } else { - RefPtr var = parse_variable_declaration(); - var->layout = layout; + unique_ptr var = parse_variable_declaration(); + var->layout = move(layout); return var; } } @@ -314,8 +311,8 @@ RefPtr Parser::parse_global_declaration() } else { - RefPtr iface_strct = parse_interface_block(); - next_global_declaration = iface_strct->block_declaration; + unique_ptr iface_strct = parse_interface_block(); + next_global_declaration = unique_ptr(iface_strct->block_declaration); return iface_strct; } } @@ -336,7 +333,7 @@ RefPtr Parser::parse_global_declaration() throw parse_error(tokenizer.get_location(), token, "a global declaration"); } -RefPtr Parser::parse_statement() +unique_ptr Parser::parse_statement() { string token = tokenizer.peek_token(); if(token=="if") @@ -351,7 +348,7 @@ RefPtr Parser::parse_statement() return parse_return(); else if(token=="break" || token=="continue" || token=="discard") { - RefPtr jump = create_node(); + unique_ptr jump = create_node(); jump->keyword = tokenizer.parse_token(); tokenizer.expect(";"); @@ -366,7 +363,7 @@ RefPtr Parser::parse_statement() } else if(!token.empty()) { - RefPtr expr = create_node(); + unique_ptr expr = create_node(); expr->expression = parse_expression(); tokenizer.expect(";"); @@ -376,13 +373,13 @@ RefPtr Parser::parse_statement() throw parse_error(tokenizer.get_location(), token, "a statement"); } -RefPtr Parser::parse_import() +unique_ptr 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 = create_node(); + unique_ptr import = create_node(); import->module = expect_identifier(); tokenizer.expect(";"); @@ -397,10 +394,10 @@ RefPtr Parser::parse_import() return import; } -RefPtr Parser::parse_precision() +unique_ptr Parser::parse_precision() { tokenizer.expect("precision"); - RefPtr precision = create_node(); + unique_ptr precision = create_node(); precision->precision = tokenizer.parse_token(); if(!is_precision_qualifier(precision->precision)) @@ -414,11 +411,11 @@ RefPtr Parser::parse_precision() return precision; } -RefPtr Parser::parse_layout() +unique_ptr Parser::parse_layout() { tokenizer.expect("layout"); tokenizer.expect("("); - RefPtr layout = create_node(); + unique_ptr layout = create_node(); while(1) { string token = tokenizer.parse_token(); @@ -450,7 +447,7 @@ RefPtr Parser::parse_layout() } template -void Parser::parse_block(Block &block, bool require_braces, RefPtr (Parser::*parse_content)()) +void Parser::parse_block(Block &block, bool require_braces, unique_ptr (Parser::*parse_content)()) { bool have_braces = (require_braces || tokenizer.peek_token()=="{"); if(have_braces) @@ -459,8 +456,8 @@ void Parser::parse_block(Block &block, bool require_braces, RefPtr (Parser::* if(have_braces) { while(tokenizer.peek_token()!="}") - if(RefPtr node = parse_with_recovery(parse_content)) - block.body.push_back(node); + if(unique_ptr node = parse_with_recovery(parse_content)) + block.body.push_back(move(node)); } else block.body.push_back((this->*parse_content)()); @@ -471,10 +468,10 @@ void Parser::parse_block(Block &block, bool require_braces, RefPtr (Parser::* tokenizer.expect("}"); } -RefPtr Parser::parse_expression(const Operator *outer_oper) +unique_ptr Parser::parse_expression(const Operator *outer_oper) { unsigned outer_precedence = (outer_oper ? outer_oper->precedence+(outer_oper->assoc==Operator::RIGHT_TO_LEFT) : 20); - RefPtr left; + unique_ptr left; VariableReference *left_var = nullptr; while(1) { @@ -503,25 +500,25 @@ RefPtr Parser::parse_expression(const Operator *outer_oper) } else if(token==".") { - RefPtr memacc = create_node(); - memacc->left = left; + unique_ptr memacc = create_node(); + 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 unary = create_node(); + unique_ptr unary = create_node(); 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; @@ -538,18 +535,18 @@ RefPtr Parser::parse_expression(const Operator *outer_oper) left = parse_literal(); else if(is_identifier(token)) { - RefPtr var = create_node(); + unique_ptr var = create_node(); var->name = expect_identifier(); - left = var; left_var = var.get(); + left = move(var); } else if(oper && oper->type==Operator::PREFIX) { - RefPtr unary = create_node(); + unique_ptr unary = create_node(); 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"); @@ -557,9 +554,9 @@ RefPtr Parser::parse_expression(const Operator *outer_oper) } } -RefPtr Parser::parse_literal() +unique_ptr Parser::parse_literal() { - RefPtr literal = create_node(); + unique_ptr literal = create_node(); literal->token = tokenizer.parse_token(); if(isdigit(literal->token[0])) { @@ -581,11 +578,11 @@ RefPtr Parser::parse_literal() return literal; } -RefPtr Parser::parse_binary(const RefPtr &left, const Operator &oper) +unique_ptr Parser::parse_binary(unique_ptr left, const Operator &oper) { - RefPtr binary = (oper.precedence==16 ? - static_cast >(create_node()) : create_node()); - binary->left = left; + unique_ptr binary = (oper.precedence==16 ? + static_cast >(create_node()) : create_node()); + binary->left = move(left); binary->oper = &oper; tokenizer.expect(oper.token); if(oper.token2[0]) @@ -598,10 +595,10 @@ RefPtr Parser::parse_binary(const RefPtr &left, co return binary; } -RefPtr Parser::parse_ternary(const RefPtr &cond, const Operator &oper) +unique_ptr Parser::parse_ternary(unique_ptr cond, const Operator &oper) { - RefPtr ternary = create_node(); - ternary->condition = cond; + unique_ptr ternary = create_node(); + ternary->condition = move(cond); ternary->oper = &oper; tokenizer.expect("?"); ternary->true_expr = parse_expression(&oper); @@ -610,9 +607,9 @@ RefPtr Parser::parse_ternary(const RefPtr &cond, return ternary; } -RefPtr Parser::parse_function_call(const VariableReference &var) +unique_ptr Parser::parse_function_call(const VariableReference &var) { - RefPtr call = create_node(); + unique_ptr call = create_node(); call->name = var.name; call->oper = &Operator::get_operator("(", Operator::POSTFIX); tokenizer.expect("("); @@ -635,11 +632,11 @@ void Parser::add_type(TypeDeclaration &type) stage_types.insert(type.name); } -RefPtr Parser::parse_type_declaration() +unique_ptr Parser::parse_type_declaration() { tokenizer.expect("typedef"); - RefPtr type; + unique_ptr type; if(tokenizer.peek_token()=="image") type = parse_image_type_declaration(); else @@ -650,9 +647,9 @@ RefPtr Parser::parse_type_declaration() return type; } -RefPtr Parser::parse_basic_type_declaration() +unique_ptr Parser::parse_basic_type_declaration() { - RefPtr type = create_node(); + unique_ptr type = create_node(); if(tokenizer.peek_token()=="vector") { @@ -676,12 +673,12 @@ RefPtr Parser::parse_basic_type_declaration() return type; } -RefPtr Parser::parse_image_type_declaration() +unique_ptr Parser::parse_image_type_declaration() { tokenizer.expect("image"); tokenizer.expect("("); - RefPtr type = create_node(); + unique_ptr type = create_node(); while(1) { string token = tokenizer.parse_token(); @@ -729,10 +726,10 @@ RefPtr Parser::parse_image_type_declaration() return type; } -RefPtr Parser::parse_struct_declaration() +unique_ptr Parser::parse_struct_declaration() { tokenizer.expect("struct"); - RefPtr strct = create_node(); + unique_ptr strct = create_node(); strct->name = expect_identifier(); parse_block(strct->members, true, &Parser::parse_variable_declaration); @@ -742,9 +739,9 @@ RefPtr Parser::parse_struct_declaration() return strct; } -RefPtr Parser::parse_variable_declaration() +unique_ptr Parser::parse_variable_declaration() { - RefPtr var = create_node(); + unique_ptr var = create_node(); string token = tokenizer.peek_token(); while(is_qualifier(token)) @@ -783,21 +780,21 @@ RefPtr Parser::parse_variable_declaration() return var; } -RefPtr Parser::parse_variable_declaration_with_layout() +unique_ptr Parser::parse_variable_declaration_with_layout() { - RefPtr layout; + unique_ptr layout; if(tokenizer.peek_token()=="layout") layout = parse_layout(); - RefPtr var = parse_variable_declaration(); - var->layout = layout; + unique_ptr var = parse_variable_declaration(); + var->layout = move(layout); return var; } -RefPtr Parser::parse_function_declaration() +unique_ptr Parser::parse_function_declaration() { - RefPtr func = create_node(); + unique_ptr func = create_node(); func->virtua = check("virtual"); func->return_type = expect_type(); @@ -808,13 +805,13 @@ RefPtr Parser::parse_function_declaration() if(!func->parameters.empty()) tokenizer.expect(","); - RefPtr var = create_node(); + unique_ptr var = create_node(); 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(")"); @@ -834,10 +831,10 @@ RefPtr Parser::parse_function_declaration() return func; } -RefPtr Parser::parse_interface_block() +unique_ptr Parser::parse_interface_block() { - RefPtr strct = create_node(); - RefPtr var = create_node(); + unique_ptr strct = create_node(); + unique_ptr var = create_node(); var->interface = tokenizer.parse_token(); if(!is_interface_qualifier(var->interface)) @@ -873,10 +870,10 @@ RefPtr Parser::parse_interface_block() return strct; } -RefPtr Parser::parse_conditional() +unique_ptr Parser::parse_conditional() { tokenizer.expect("if"); - RefPtr cond = create_node(); + unique_ptr cond = create_node(); tokenizer.expect("("); cond->condition = parse_expression(); tokenizer.expect(")"); @@ -893,10 +890,10 @@ RefPtr Parser::parse_conditional() return cond; } -RefPtr Parser::parse_for() +unique_ptr Parser::parse_for() { tokenizer.expect("for"); - RefPtr loop = create_node(); + unique_ptr loop = create_node(); tokenizer.expect("("); string token = tokenizer.peek_token(); if(is_type(token)) @@ -905,9 +902,9 @@ RefPtr Parser::parse_for() { if(token!=";") { - RefPtr expr = create_node(); + unique_ptr expr = create_node(); expr->expression = parse_expression(); - loop->init_statement = expr; + loop->init_statement = move(expr); } tokenizer.expect(";"); } @@ -923,10 +920,10 @@ RefPtr Parser::parse_for() return loop; } -RefPtr Parser::parse_while() +unique_ptr Parser::parse_while() { tokenizer.expect("while"); - RefPtr loop = create_node(); + unique_ptr loop = create_node(); tokenizer.expect("("); loop->condition = parse_expression(); tokenizer.expect(")"); @@ -936,10 +933,10 @@ RefPtr Parser::parse_while() return loop; } -RefPtr Parser::parse_passthrough() +unique_ptr Parser::parse_passthrough() { tokenizer.expect("passthrough"); - RefPtr pass = create_node(); + unique_ptr pass = create_node(); if(cur_stage->type==Stage::GEOMETRY) { tokenizer.expect("["); @@ -950,10 +947,10 @@ RefPtr Parser::parse_passthrough() return pass; } -RefPtr Parser::parse_return() +unique_ptr Parser::parse_return() { tokenizer.expect("return"); - RefPtr ret = create_node(); + unique_ptr ret = create_node(); if(tokenizer.peek_token()!=";") ret->expression = parse_expression(); tokenizer.expect(";"); diff --git a/source/glsl/parser.h b/source/glsl/parser.h index d46afcdc..43575232 100644 --- a/source/glsl/parser.h +++ b/source/glsl/parser.h @@ -1,6 +1,7 @@ #ifndef MSP_GL_SL_PARSER_H_ #define MSP_GL_SL_PARSER_H_ +#include #include #include #include @@ -30,7 +31,7 @@ private: std::set global_types; std::set stage_types; std::vector errors; - RefPtr next_global_declaration; + std::unique_ptr next_global_declaration; public: Parser(ModuleCache *); @@ -65,35 +66,35 @@ private: void preprocess_stage(); template - RefPtr create_node(); + std::unique_ptr create_node(); template - RefPtr parse_with_recovery(RefPtr (Parser::*)()); - RefPtr parse_global_declaration(); - RefPtr parse_statement(); - RefPtr parse_import(); - RefPtr parse_precision(); - RefPtr parse_layout(); + std::unique_ptr parse_with_recovery(std::unique_ptr (Parser::*)()); + std::unique_ptr parse_global_declaration(); + std::unique_ptr parse_statement(); + std::unique_ptr parse_import(); + std::unique_ptr parse_precision(); + std::unique_ptr parse_layout(); template - void parse_block(Block &, bool, RefPtr (Parser::*)()); - RefPtr parse_expression(const Operator * = nullptr); - RefPtr parse_literal(); - RefPtr parse_binary(const RefPtr &, const Operator &); - RefPtr parse_ternary(const RefPtr &, const Operator &); - RefPtr parse_function_call(const VariableReference &); + void parse_block(Block &, bool, std::unique_ptr (Parser::*)()); + std::unique_ptr parse_expression(const Operator * = nullptr); + std::unique_ptr parse_literal(); + std::unique_ptr parse_binary(std::unique_ptr, const Operator &); + std::unique_ptr parse_ternary(std::unique_ptr, const Operator &); + std::unique_ptr parse_function_call(const VariableReference &); void add_type(TypeDeclaration &); - RefPtr parse_type_declaration(); - RefPtr parse_basic_type_declaration(); - RefPtr parse_image_type_declaration(); - RefPtr parse_struct_declaration(); - RefPtr parse_variable_declaration(); - RefPtr parse_variable_declaration_with_layout(); - RefPtr parse_function_declaration(); - RefPtr parse_interface_block(); - RefPtr parse_conditional(); - RefPtr parse_for(); - RefPtr parse_while(); - RefPtr parse_passthrough(); - RefPtr parse_return(); + std::unique_ptr parse_type_declaration(); + std::unique_ptr parse_basic_type_declaration(); + std::unique_ptr parse_image_type_declaration(); + std::unique_ptr parse_struct_declaration(); + std::unique_ptr parse_variable_declaration(); + std::unique_ptr parse_variable_declaration_with_layout(); + std::unique_ptr parse_function_declaration(); + std::unique_ptr parse_interface_block(); + std::unique_ptr parse_conditional(); + std::unique_ptr parse_for(); + std::unique_ptr parse_while(); + std::unique_ptr parse_passthrough(); + std::unique_ptr parse_return(); }; } // namespace SL diff --git a/source/glsl/reflect.cpp b/source/glsl/reflect.cpp index c4fba068..702c8536 100644 --- a/source/glsl/reflect.cpp +++ b/source/glsl/reflect.cpp @@ -264,7 +264,7 @@ void LocationCounter::visit(ImageTypeDeclaration &) void LocationCounter::visit(StructDeclaration &strct) { unsigned total = 0; - for(const RefPtr &s: strct.members.body) + for(const NodePtr &s: strct.members.body) { r_count = 1; s->visit(*this); @@ -316,7 +316,7 @@ void MemoryRequirementsCalculator::visit(StructDeclaration &strct) { unsigned total = 0; unsigned max_align = 1; - for(const RefPtr &s: strct.members.body) + for(const NodePtr &s: strct.members.body) { r_size = 0; r_alignment = 1; diff --git a/source/glsl/resolve.cpp b/source/glsl/resolve.cpp index c1771ea7..bd835880 100644 --- a/source/glsl/resolve.cpp +++ b/source/glsl/resolve.cpp @@ -35,16 +35,18 @@ TypeDeclaration *TypeResolver::get_or_create_array_type(TypeDeclaration &type) if(i!=array_types.end()) return i->second; - BasicTypeDeclaration *array = new BasicTypeDeclaration; + unique_ptr array = make_unique(); 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) @@ -57,14 +59,16 @@ TypeDeclaration *TypeResolver::get_or_create_image_type(ImageTypeDeclaration &ty if(i!=image_types.end()) return i->second; - ImageTypeDeclaration *image = new ImageTypeDeclaration(type); + unique_ptr image = make_unique(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) @@ -204,13 +208,13 @@ void VariableResolver::enter(Block &block) block.variables.clear(); } -void VariableResolver::visit(RefPtr &expr) +void VariableResolver::visit(NodePtr &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; @@ -259,19 +263,19 @@ void VariableResolver::visit(VariableReference &var) { /* The name refers a member of an anonymous interface block. Prepare new syntax tree nodes accordingly. */ - VariableReference *iface_ref = new VariableReference; + unique_ptr iface_ref = make_unique(); 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 memacc = make_unique(); 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; } } @@ -317,15 +321,15 @@ void VariableResolver::visit(MemberAccess &memacc) if(ok) { - Swizzle *swizzle = new Swizzle; + unique_ptr swizzle = make_unique(); 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); } } } @@ -410,10 +414,10 @@ void VariableResolver::redeclare_builtin(VariableDeclaration &existing, Variable 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); } @@ -500,7 +504,7 @@ void VariableResolver::visit(VariableDeclaration &var) } 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; } @@ -542,17 +546,17 @@ BasicTypeDeclaration *ExpressionResolver::find_type(BasicTypeDeclaration &elem_t return (i!=basic_types.end() ? *i : 0); } -void ExpressionResolver::convert_to(RefPtr &expr, BasicTypeDeclaration &type) +void ExpressionResolver::convert_to(NodePtr &expr, BasicTypeDeclaration &type) { - RefPtr call = new FunctionCall; + unique_ptr call = make_unique(); 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 &expr, BasicTypeDeclaration &elem_type) +bool ExpressionResolver::convert_to_element(NodePtr &expr, BasicTypeDeclaration &elem_type) { if(BasicTypeDeclaration *expr_basic = dynamic_cast(expr->type)) { @@ -569,13 +573,13 @@ bool ExpressionResolver::convert_to_element(RefPtr &expr, BasicTypeD return false; } -bool ExpressionResolver::truncate_vector(RefPtr &expr, unsigned size) +bool ExpressionResolver::truncate_vector(NodePtr &expr, unsigned size) { if(BasicTypeDeclaration *expr_basic = dynamic_cast(expr->type)) if(BasicTypeDeclaration *expr_elem = get_element_type(*expr_basic)) { - RefPtr swizzle = new Swizzle; - swizzle->left = expr; + unique_ptr swizzle = make_unique(); + swizzle->left = move(expr); swizzle->oper = &Operator::get_operator(".", Operator::POSTFIX); swizzle->component_group = string("xyzw", size); swizzle->count = size; @@ -585,7 +589,7 @@ bool ExpressionResolver::truncate_vector(RefPtr &expr, unsigned size swizzle->type = expr_elem; else swizzle->type = find_type(*expr_elem, BasicTypeDeclaration::VECTOR, size); - expr = swizzle; + expr = move(swizzle); return true; } @@ -921,7 +925,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) unsigned arg_component_total = 0; bool homogeneous_args = true; bool has_matrices = false; - for(const RefPtr &a: call.arguments) + for(const NodePtr &a: call.arguments) { ArgumentInfo info; if(!(info.type=dynamic_cast(a->type))) @@ -978,7 +982,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) unsigned column_count = basic->size&0xFFFF; unsigned row_count = basic->size>>16; - vector > columns; + NodeArray columns; columns.reserve(column_count); bool changed_columns = false; @@ -997,29 +1001,30 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) /* Always generate a temporary here and let the optimization stage inline it if that's reasonable. */ - RefPtr temporary = new VariableDeclaration; + unique_ptr temporary = make_unique(); 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 ref = new VariableReference; - ref->name = temporary->name; + unique_ptr ref = make_unique(); + ref->name = temp_name; - RefPtr index = new Literal; + unique_ptr index = make_unique(); index->token = lexical_cast(j); index->value = static_cast(j); - RefPtr subscript = new BinaryExpression; - subscript->left = ref; + unique_ptr subscript = make_unique(); + 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); } @@ -1051,7 +1056,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) return; } - vector > column_args; + NodeArray column_args; column_args.reserve(row_count); column_component_count = 0; @@ -1061,25 +1066,24 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) 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 column_call = new FunctionCall; + unique_ptr column_call = make_unique(); 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; @@ -1094,8 +1098,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) 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. */ @@ -1109,7 +1112,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) if(convert_args) { // The argument list may have changed so can't rely on args. - for(RefPtr &a: call.arguments) + for(NodePtr &a: call.arguments) if(BasicTypeDeclaration *basic_arg = dynamic_cast(a->type)) { BasicTypeDeclaration *elem_arg = get_element_type(*basic_arg); @@ -1124,7 +1127,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) return; auto j = call.arguments.begin(); - for(const RefPtr &s: strct->members.body) + for(const NodePtr &s: strct->members.body) { if(VariableDeclaration *var = dynamic_cast(s.get())) { @@ -1310,7 +1313,7 @@ void FunctionResolver::visit(FunctionDeclaration &func) if(func.signature.empty()) { string param_types; - for(const RefPtr &p: func.parameters) + for(const NodePtr &p: func.parameters) { if(p->type_declaration) append(param_types, ",", p->type_declaration->name); diff --git a/source/glsl/resolve.h b/source/glsl/resolve.h index 5cb77c19..563c1a57 100644 --- a/source/glsl/resolve.h +++ b/source/glsl/resolve.h @@ -57,7 +57,7 @@ class VariableResolver: private TraversingVisitor { private: Stage *stage = nullptr; - RefPtr r_replacement_expr; + std::unique_ptr r_replacement_expr; bool r_any_resolved = false; bool record_target = false; bool r_self_referencing = false; @@ -70,7 +70,7 @@ public: private: void enter(Block &) override; - void visit(RefPtr &) override; + void visit(NodePtr &) override; void check_assignment_target(VariableDeclaration *); void visit(VariableReference &) override; void visit(MemberAccess &) override; @@ -113,9 +113,9 @@ private: 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 &, BasicTypeDeclaration &); - bool convert_to_element(RefPtr &, BasicTypeDeclaration &); - bool truncate_vector(RefPtr &, unsigned); + void convert_to(NodePtr &, BasicTypeDeclaration &); + bool convert_to_element(NodePtr &, BasicTypeDeclaration &); + bool truncate_vector(NodePtr &, unsigned); void resolve(Expression &, TypeDeclaration *, bool); void visit(Block &) override; diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index ce8da1ed..3f4559c3 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -557,7 +557,7 @@ SpirVGenerator::Id SpirVGenerator::write_construct(Id type_id, const Id *elem_id void SpirVGenerator::visit(Block &block) { - for(const RefPtr &s: block.body) + for(const NodePtr &s: block.body) s->visit(*this); } @@ -1133,7 +1133,7 @@ void SpirVGenerator::visit(FunctionCall &call) vector argument_ids; argument_ids.reserve(call.arguments.size()); bool all_args_const = true; - for(const RefPtr &a: call.arguments) + for(const NodePtr &a: call.arguments) { a->visit(*this); argument_ids.push_back(r_expression_result_id); @@ -1151,7 +1151,7 @@ void SpirVGenerator::visit(FunctionCall &call) else if(call.declaration->source==BUILTIN_SOURCE) { string arg_types; - for(const RefPtr &a: call.arguments) + for(const NodePtr &a: call.arguments) if(BasicTypeDeclaration *basic_arg = dynamic_cast(a->type)) { BasicTypeDeclaration &elem_arg = *get_element_type(*basic_arg); @@ -1655,7 +1655,7 @@ void SpirVGenerator::visit(StructDeclaration &strct) bool builtin = !strct.block_name.compare(0, 3, "gl_"); vector member_type_ids; member_type_ids.reserve(strct.members.body.size()); - for(const RefPtr &s: strct.members.body) + for(const NodePtr &s: strct.members.body) { const VariableDeclaration *var = dynamic_cast(s.get()); if(!var) @@ -1925,7 +1925,7 @@ void SpirVGenerator::visit(FunctionDeclaration &func) Id return_type_id = get_id(*func.return_type_declaration); vector param_type_ids; param_type_ids.reserve(func.parameters.size()); - for(const RefPtr &p: func.parameters) + for(const NodePtr &p: func.parameters) param_type_ids.push_back(get_variable_type_id(*p)); string sig_with_return = func.return_type+func.signature; diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index f69c70bf..4c3d468c 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -66,15 +66,6 @@ const Operator &Operator::get_operator(const string &token, Type type) } -template -NodeContainer::NodeContainer(const NodeContainer &c): - C(c) -{ - for(auto &i: *this) - i = i->clone(); -} - - Block::Block(const Block &other): Node(other), body(other.body), @@ -391,10 +382,10 @@ int get_layout_value(const Layout *layout, const string &name, int def_value) return (i!=layout->qualifiers.end() ? i->value : def_value); } -void add_layout_qualifier(RefPtr &layout, const Layout::Qualifier &q) +void add_layout_qualifier(NodePtr &layout, const Layout::Qualifier &q) { if(!layout) - layout = new Layout; + layout = make_unique(); layout->qualifiers.push_back(q); } diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index 03c5b80d..61083dee 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -3,11 +3,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include "features.h" @@ -76,42 +76,99 @@ public: }; template -class NodePtr: public RefPtr +class NodePtr { + template + friend class NodePtr; + +private: + std::unique_ptr ptr; + public: NodePtr() = default; - NodePtr(T *p): RefPtr(p) { } - NodePtr(const NodePtr &p): RefPtr(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 - NodePtr(const RefPtr &p): RefPtr(p) { } + NodePtr(NodePtr &&p): ptr(std::move(p.ptr)) { } template - NodePtr(const NodePtr &p): RefPtr(p ? p->clone() : 0) { } + NodePtr(std::unique_ptr &&p): ptr(std::move(p)) { } + + template + NodePtr &operator=(std::unique_ptr &&p) { ptr = std::move(p); return *this; } + + template + U *get_as() const { return dynamic_cast(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(ptr); } + + std::unique_ptr clone() const { return std::unique_ptr(ptr ? ptr->clone() : nullptr); } }; template -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 -class NodeList: public NodeContainer > > -{ }; +class NodeList: public NodeContainer>> +{ +private: + using Base = NodeContainer>>; + +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 -class NodeArray: public NodeContainer > > -{ }; +class NodeArray: public NodeContainer>> +{ +private: + using Base = NodeContainer>>; + +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; @@ -531,7 +588,7 @@ std::string get_unused_variable_name(const Block &, const std::string &); 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 &, const Layout::Qualifier &); +void add_layout_qualifier(NodePtr &, const Layout::Qualifier &); void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned); bool targets_overlap(const Assignment::Target &, const Assignment::Target &); diff --git a/source/glsl/validate.cpp b/source/glsl/validate.cpp index f4dd42ac..3a438a77 100644 --- a/source/glsl/validate.cpp +++ b/source/glsl/validate.cpp @@ -418,7 +418,7 @@ void DeclarationValidator::visit(VariableDeclaration &var) void DeclarationValidator::visit(FunctionDeclaration &func) { SetForScope set_scope(scope, FUNCTION_PARAM); - for(const RefPtr &p: func.parameters) + for(const NodePtr &p: func.parameters) p->visit(*this); scope = FUNCTION; func.body.visit(*this); @@ -810,7 +810,7 @@ void ExpressionValidator::visit(Return &ret) void FlowControlValidator::visit(Block &block) { - for(const RefPtr &s: block.body) + for(const NodePtr &s: block.body) { if(!reachable) { diff --git a/source/glsl/visitor.cpp b/source/glsl/visitor.cpp index d3a08d8d..0bb13c62 100644 --- a/source/glsl/visitor.cpp +++ b/source/glsl/visitor.cpp @@ -12,11 +12,11 @@ void TraversingVisitor::visit(Block &block) if(&block!=current_block) enter(block); SetForScope set_block(current_block, &block); - for(const RefPtr &s: block.body) + for(const NodePtr &s: block.body) s->visit(*this); } -void TraversingVisitor::visit(RefPtr &expr) +void TraversingVisitor::visit(NodePtr &expr) { expr->visit(*this); } @@ -57,7 +57,7 @@ void TraversingVisitor::visit(TernaryExpression &ternary) void TraversingVisitor::visit(FunctionCall &call) { - for(RefPtr &a: call.arguments) + for(NodePtr &a: call.arguments) visit(a); } @@ -90,7 +90,7 @@ void TraversingVisitor::visit(FunctionDeclaration &func) { enter(func.body); SetForScope set_block(current_block, &func.body); - for(const RefPtr &p: func.parameters) + for(const NodePtr &p: func.parameters) p->visit(*this); func.body.visit(*this); } diff --git a/source/glsl/visitor.h b/source/glsl/visitor.h index 7cd5cb61..7833914d 100644 --- a/source/glsl/visitor.h +++ b/source/glsl/visitor.h @@ -55,7 +55,7 @@ protected: public: virtual void enter(Block &) { } void visit(Block &) override; - virtual void visit(RefPtr &); + virtual void visit(NodePtr &); void visit(MemberAccess &) override; void visit(Swizzle &) override; void visit(UnaryExpression &) override; -- 2.45.2